问题
So this might be a bit basic of a question, but I don't have much experience on the hardware side of things. I am using DJI Android Mobile SDK to communicate with a M600 flight controller and have a FTDI CU/TTY device I am trying to send info back and forth.
This successfully works to send "Hello World" to my USB device:
//sends data to onboard sdk device
final byte[] helloWorld = "HelloWorld".getBytes();
mFlightController.sendDataToOnboardSDKDevice(helloWorld, new CommonCallbacks.CompletionCallback() {
@Override
public void onResult(DJIError djiError) {
if (djiError != null) {
showToast(djiError.getDescription());
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(djiError.getDescription(), "sendOnboardErrorFile.txt");
} else {
showToast("Hopefully Hello World");
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(helloWorld.toString(), "sendOnboardSuccessFile.txt");
}
}
});
I can see this when I run either of the following in terminal:
screen /dev/cu.usbserial-BLAHBLAH 38400
screen /dev/tty.usbserial-BLAHBLAH 38400
A bunch of gibberish/ hieroglyphics show up and then the text "Hello World" pops up every time I click a button that triggers the above DJI code.
Now, I want to get the flips side of this working i.e. send something back from the USB to the DJI sdk using the following:
if (mFlightController.isOnboardSDKDeviceAvailable()) {
showToast("Set Onboard SDk Callback");
mFlightController.setOnboardSDKDeviceDataCallback(new FlightController.OnboardSDKDeviceDataCallback() {
@Override
public void onReceive(byte[] bytes) {
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(bytes.toString(), "onboardCallbackFile.txt");
}
});
}
The trouble is I never seem to get anything in response.
As per this question, I made sure I have read write permission on the USB device:
chmod o+rw /dev/ttyS1
And I have tried all sorts of echo and cat commands (I don't know which one is read and write). They either say device is busy, or if not, they seem to open a port of communication (the terminal blinks indefinitely), but nothing sends to my device.
Commands I've tried:
echo 'HelloTest' > /dev/cu.usbserial-BLAHBLAH
Nothing special happens, goes to next terminal line
echo 'HelloTest' > /dev/tty.usbserial-BLAHBLAH
Terminal returns HelloTest
echo 'HelloTest' < /dev/tty.usbserial-BLAHBLAH
cursor blinks indefinitely
echo 'HelloTest' < /dev/cu.usbserial-BLAHBLAH
Terminal returns HelloTest
cat < /dev/cu.usbserial-BLAHBLAH
cat -v < /dev/tty.usbserial-BLAHBLAH
cat -v > /dev/tty.usbserial-BLAHBLAH
cat -v > /dev/cu.usbserial-BLAHBLAH
No such file or directory (I guess I need 2 terminals running for this?)
Questions
Does this have to do with Baud rate? I have set that up in DJI Assistant. What is the difference between TTY and CU and Echo and Cat? I have tried all sorts of combinations. I am able to use the screen command with both cu and tty. Finally, what is a simple hello world I can send back to the sdk to see that I am actually receiving data from my usb device? I would think echo would success, but I'm not receiving anything.
Edit
I almost feel like I need to use something like usb-serial-for-android; however, I'm not actually connecting the usb device to my android device. Instead, I am connecting to the DJI RC Controller, which connects to Lightbridge/ M600, which connects through the API port with my usb device.
回答1:
I believe you need to understand the DJI OpenProtocol to make this work. The "bunch of gibberish" is in fact the problem here. That gibberish is the protocol that DJI drones use to properly relay communications.
In order to send from "Onboard" to "Mobile" with the latest code you need the 0xFE CMD_Set Id as a header to your data:
https://developer.dji.com/onboard-sdk/documentation/protocol-doc/open-protocol.html
So, either, figure out the proper format to your data or buy a cheap PC and install the OSDK.
回答2:
I came across this issue a while back as well using the Matrice M100 with the ROS onboardSDK.
if (mFlightController.isOnboardSDKDeviceAvailable()) {
showToast("Set Onboard SDk Callback");
mFlightController.setOnboardSDKDeviceDataCallback(new FlightController.OnboardSDKDeviceDataCallback() {
@Override
public void onReceive(byte[] bytes) {
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(bytes.toString(), "onboardCallbackFile.txt");
}
});
}
Where are you calling this?. Here's how I solved my issue: I wrote a function:
private void addCallback()
{
mFlightController.setOnboardSDKDeviceDataCallback(new
FlightController.OnboardSDKDeviceDataCallback() {
@Override
public void onReceive(byte[] bytes) {
// Do stuff with the data here..
}
});
}
Then in my onResume
method I did something like:
@Override
public void onResume() {
Log.e(TAG, "onResume");
super.onResume();
if (mFlightController != null) {
addCallback();
}
}
It's not the most elegant way but it seemed to do the trick for me. You can find my solution here. It's been a while since I worked on it though!
回答3:
If you have an FTDI device then you need an FTDI driver. :)
Did you install something like this by chance? https://www.ftdichip.com/FTDrivers.htm
Serial port emulation through USB requires virtual serial port software to function.
来源:https://stackoverflow.com/questions/54298058/how-to-send-data-from-usb-device-to-dji-sdk