DJI-Onboard-SDK-Raspberry-Transparent-Transmission
Intro
This a simple demo for DJI Onboard SDK Transparent Transmission function. Also I run this demo on a Raspberry Pi.
I make this demo to detect PM 2.5 in air. And I believe everyone can obtain his/her own sensor data in the same way.
First, Pi gets sensor data from a PM 2.5 sensor. (I bought one from Taobao, which contains a USB-TTL moudel)
Second, Pi sends the data to M100 for Transparent Transmission.
Finially, the data shows on my phone or pad which is connected with M100's controllor.
Fly your M100 with RPi instead of expensive NUC !
Also Fly your M100 with your own sensors too !
Requirement
- M100
- Raspberry Pi
- PM2.5 Sensor
Setup
1. Connect Pi and M100
As we know, RPi has a serial port with 3.3V. We can use it directly, so there is no need to purchase a USB-TTL model.
Here is the definition of M100's serial port.
And this is the definition of RPI's serial port.
M100 | RPin |
---|---|
RXD | Tx (PIN 08) |
TXD | Rx (PIN 10) |
GND | GND (PIN 06) |
The connection looks like this.
However, the serial port of RPi is designed for kernel, therefore we need to configure it.- edit cmdline.txt
sudo nano /boot/cmdline.txt
change
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
into
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
- edit inittab
sudo nano /etc/inittab
Invaild the last line#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
In addition, to use this serial port within 230400 baudrate, we need to change uart clock.
edit config.txt
sudo nano /boot/config.txt
Add this in lastinit_uart_clock=64000000
At last, restart your Pi and we can use /dev/ttyAMA0
to communicate with M100.
2. Connect Pi and Sensor
My PM2.5 sensor is driven by a arduino, so this part is sample. I just install arduino for RPi, then I can find my sensor which is /dev/ttyUSB0
In other cases, this part depends your specific sensors.
3. Code (DJI Onboard SDK Part)
I use DJI_LIB
to develop the Onboard Part. All I need to do is call relative function to init Onboard SDK and send my data.
PM25.cpp
is interface of my PM2.5 sensor, developers can use yourselves code instead.
BTW: you can find
DJI_LIB
in Samples of DJI Onboard SDK.
1. Modify Makefile
to add DJI_LIB
in your progject. (You can refer to Makefile
in this project)
2. Init Onboard SDK
if(Pro_Hw_Setup("/dev/ttyAMA0", 230400) < 0) /* Open RPi <-> DJI Serial Port */
{
perror( "UAV Serial Port Open ERROR" );
return 0;
}
DJI_Pro_Setup(NULL);
3. Init PM25 (Change it into your sensor interface)
if(init_pm25("/dev/ttyUSB0", 2400) <0) /* Open RPi <-> PM25 Serial Port */
{
perror( "PM25 Serial Port Open ERROR" );
return 0;
}
4. Activation
Just need to edit key_buf
, app_id
and app_level
.
For Transparent-Transmission, either level 1 or level 2 is ok.
activate_data_t user_act_data;
void activation()
{
char key_buf[65] = "input your key"; /* Input your app_key */
char app_bundle_id[32] = "1234567890";
user_act_data.app_id = id; /* Input your app_id */
user_act_data.app_api_level = level; /* Input your app_level */
user_act_data.app_ver = 0x02030A00;
user_act_data.app_key = key_buf;
strcpy((char*)user_act_data.app_bundle_id, app_bundle_id);
DJI_Pro_Activate_API(&user_act_data,cb_fun);
}
5. Loop
Get pm25 data and call sdk function to send it.
while(1)
{
if(run_flag)
{
int nbyte;
nbyte = read_pm25(buffer, 1024);
if (nbyte > 0)
{
transparent_transission_send((uint8_t*)buffer, nbyte);
//printf("%s", buffer);
}
}
sleep(1);
}
Transparent-Transmission Send
void transparent_transission_send(uint8_t* pbuf, uint16_t len)
{
DJI_Pro_App_Send_Data(0 , 0, MY_ACTIVATION_SET, 0xFE, pbuf, len,NULL,0,1);
//printf("[send_data],send len %d data %s\n", len, pbuf);
}
Transparent-Transmission Receive
First, register Transparent-Transmission callback function.
DJI_Pro_Register_Transparent_Transmission_Callback(transparent_transission_receive);
Then, implement the callback function.
Here is a simple interactive cmd list.
void transparent_transission_receive(unsigned char *buf,unsigned char len)
{
unsigned char cmd;
cmd = buf[0];
// printf("[recv_data],send len %d data %s\n", len, buf);
switch(cmd)
{
case 'a':
activation();
break;
case 'b':
run_flag = true;
break;
case 'c':
run_flag = false;
break;
default:
break;
}
}
4. Code (DJI Mobile SDK Part)
Import the DJI_SDK_Android_Transparent_Trasmit code tu your Android studio or Eclipes.
The following code shows you how to send and receive data.
send data:
int16_t sdk_pure_transfer_hander(uint8_t* pbuf, uint16_t len)
{
if ("" != mSendOnBoardEdit.getText().toString()){
DJIDrone.getDjiMC().sendDataToExternalDevice(mSendOnBoardEdit.getText().toString().getBytes(),new DJIExecuteResultCallback(){
@Override
public void onResult(DJIError result)
{
// TODO Auto-generated method stub
}
});
Log.d(TAG, "Submit1");
}
}
receive data:
mExtDevReceiveDataCallBack = new DJIMainControllerExternalDeviceRecvDataCallBack() {
@Override
public void onResult(final byte[] data)
{
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append(getString(R.string.external_device_recv_data)).append("\n");
sb.append(new String(data)).append("\n");
McRecvOnBoard = sb.toString();
SelectDroneTypeActivity.this.runOnUiThread(new Runnable(){
@Override
public void run()
{
mRecvTextView.setText(McRecvOnBoard);
}
});
}
};
//设置回调接口
DJIDrone.getDjiMC().setExternalDeviceRecvDataCallBack(mExtDevReceiveDataCallBack);
5. Compile & Run
copy pm25
folder into your Pi.
Then execute the following cmd.
cd cmake
make
cd ../output
./pm25
The terminal should be like this.
Acttivation Successfully
0.0,25.0,59.8
[pure_transfer],send len 15 data 0.0,25.0,59.8
0.5,25.0,59.8
[pure_transfer],send len 15 data 0.05,25.0,59.8
0.9,25.0,59.8
[pure_transfer],send len 15 data 0.9,25.0,59.8
Run the App by Mobile device.
This is a sample App, but you can see the date has been received.