Matsemann / mDjiController

Connect your DJI Remote Controller to your computer and use it to play simulators
Apache License 2.0
94 stars 30 forks source link

Matrice 600 Controller doesn't respond to messages? #3

Open fake-name opened 7 years ago

fake-name commented 7 years ago

Hi there!

I'm doing a project that would benefit from being able to interact with the dji controller, so I ran across this project which seems to do that a little bit, but it appears to not work at this point?

Where did the mysterious hexadecimal constants in 'main.cpp' come from? I assume that the remote controller has a communication interface protocol of some sort, but I've been completely unable to find any documentation of how to talk to the RC controller.

Thanks!

Timebutt commented 7 years ago

Hi @fake-name, what do you mean 'it does not appear to work at this point'? I can confirm the correct functionality of mDjiController, as I use it on a daily basis as controller for my AirSim setup.

Moreover: I have just added a pull request (#4) completing the mDjiController functionality for the Phantom 2 controller (all buttons and the camera wheel are working now).

I have written a small Python script that reads the values directly from the serial port using Python, to help figure out how the other buttons and camera scroll wheel were reporting their data. Does this help you out?


import serial
s=serial.Serial(port='COM4', timeout=0.1)
print("Connected to serial device " + str(s.name))

initData = bytearray([ 0x55, 0xaa, 0x55, 0xaa, 0x1e, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x00, 0x04, 0x04, 0x74, 0x94, 0x35, 0x00, 0xd8, 0xc0, 0x41, 0x00, 0x30, 0xf6, 0x08, 0x00, 0x00, 0xf6, 0x69, 0x9c, 0x01, 0xe8 ]);
pingData = bytearray([ 0x55, 0xaa, 0x55, 0xaa, 0x1e, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x80, 0x00, 0x06, 0x01, 0x28, 0x97, 0xae, 0x03, 0x28, 0x36, 0xa4, 0x03, 0x28, 0x36, 0xa4, 0x03, 0xab, 0xa7, 0x30, 0x00, 0x03, 0x53 ]);

s.write(initData)
print("Init data written to " + str(s.name))

while(True):

    s.write(pingData)
    print("Ping data written to " + str(s.name))

    data = s.readline()
    print(data)

If not, please elaborate on what's not working out for you at the moment, I will gladly help you out ;)

fake-name commented 7 years ago

"Doesn't work" meaning I ran it, and my controller didn't respond or do anything whatsoever. In my case, I'm using the controller from a Matrice 600, possibly that could be the issue?

Anyways, I'm more interested in where you got the initData and pingData arrays from. Is there some program that uses the controller that you're reversing?

For testing, I plug the remote control into my computer with a USB -> Micro-USB cable, it shows up as a COM port. I run something like your test script, and the controller seems to just do nothing.

Timebutt commented 7 years ago

Ah, ok I understand. My idea was, that this repository is mainly focused on providing an interface for the DJI Phantom 2 controller to a Windows machine. It's how I found this repository in any case ;) I too use the Phantom 2 controller via USB at the moment. Maybe this should be indicated more clearly in the documentation.

Interesting enough, I also have a DJI Matrice 100 and its controller lying around. I see the M600 controller is optically quite identical, maybe they are comparable on a software level too. It sure would be interesting to also get these controllers working, I will help you tackle this issue.

Your question is very valid in this case, maybe the initDataand pingDatadiffer for these devices, and we need to find out what they are so that we can communicate with them over a serial port. @Matsemann, can you shed some light on how you got those values?

Another way of tackling the problem could be to use a solution similar like the one proposed in this forum post. Frank Buss presents his solution for a Phantom 3 controller by connection to its WiFi network and reading the data this way.

I don't have my M100 controller lying around this weekend, will look into both possible solutions starting next week.

fake-name commented 7 years ago

Actually, I don't have any interest in using the controller as a input device with a PC. I'm hoping to get access to the one of the Matrice SDK interfaces remotely, without having to add an additional onboard wireless serial link.

Really, I'm just curious what facilities the controller exposes. The TL;DR is I have a project where I need API access like either the moble SDK or onboard SDK from a normal PC, rather then having to have a phone in the loop. At the moment, DJI seems to have no way to control the drone from any platform but a phone, or a computer on the drone.

Matsemann commented 7 years ago

Hi, to answer where the magic hex values come from:

When I made this project a few years ago, I saw that the DJI software on my computer could read and display the positions of the sticks. So I knew that making this program should be possible. I used some software for serial ports to see what was being sent back and forth when using the DJI software, and found a pattern where the messages starting with 0x55 changed when adjusting the sticks. So that's where that magic number comes from.

I guess the two huge arrays are more interesting. When I wrote a small script to read the data on the serial port, the controller didn't send anything! So I watched again what the DJI software and controller sent back and forth, and found this pattern. What the values mean, I don't know. I don't know if they are needed anymore, or if one maybe could send anything. I just reverse engineered the protocol as much as I need to get this to work. :)

I don't know of any documentation of any protocol, but it's more than two years since I looked for it myself. They communicate through serial/COM, and if this program doesn't work for your controller, seeing how it communicates with the software to update firmware could be useful to understand the protocol.

I don't really know more than that, and as I said it's a few years since I dabbled in this, so I can't answer the points in your last comment.

fake-name commented 7 years ago

Ah, I see. FWIW, 0x55, 0xaa, 0x55, 0xaa at least is a extremely common set of values, used for synchronization. They might be doing auto-bauding, which could be why it's there (it's 0b01010101 and 0b10101010 respectively).

Anyways, if the values were reversed from a piece of DJI software, that doesn't help much. Maybe I'll try and see if I can find something that can talk to the matrice remote, and see about disassembling it to have a look.

Timebutt commented 7 years ago

Just as a confirmation: my DJI M100 controller doesn't respond to the serial messages either. I've tried to get anything out of the controller over the serial connection, but no luck so far. There is - to my knowledge - no comparable software tool available that reads the sticks (as was the case for the Phantom 2) so reverse engineering the communication for the M100 controller will be a bit more difficult ...

Any idea on how we could set up communication with different DJI controllers to extract data out of them over USB? I don't think others will be eager to open their controllers up ;)

slaterbbx commented 6 years ago

I have started messing with this now, new to C++ but using this to learn as I build it up / optimize later lol.

Very cool program, came across it because I purchased "Liftoff" and only had a phantom 2 controller around.

Available as a fork ;-)