背景介绍:
Sugar 玩 ArduPilot 开源飞控,离开顺手的地面站很难玩好飞控。
地面站跟飞机间采用 mavlink 通信,而 mavlink 是个独立的通信协议,并不依赖于飞控。
当华夏骄子 RT-Thread 遇上洋气的 mavlink,中西合璧下能否给让物联网锦上添花,那还得看有多少人愿意并能够让两者协起手来。
相比于 Sugar 写过的一篇《物联网通信,如何应用 mavlink 通信协议》,本篇比较干,直击技术层面的代码对接方法。程序员做媒,就是这么强硬。先上视频
视频加载失败
无线通信步骤
当我们想要达到某个目标时,三思而后行,把大目标拆成有序的小目标来实现。这样除了更稳,也会更快,回头再看时也更清晰。
先实现不带协议的无线通信
这一步的目标是:确定会用通信相关硬件。
再用 mavlink 报文进行通信
这一步的目标是:会用 mavlink 进行通信。
本次使用到的硬件有:RT-Thread IoT 开发板(即:正点原子潘多拉开发板)、小马哥四轴遥控器、nRF24L01 无线通信模块。
nRF24L01 双向通信
RT-Thread 代码质量非常高,使用起来也很方便。下面看一下在 RT-Thread 上使用 nRF24L01 的过程。
nRF24L01 在小马哥四轴遥控器上调试的时候没调通,解决办法见《为了解决 RT-Thread nRF24L01 软件包在 STM32F103C8 上死活调不通的问题,我都干了啥?》
源码只需要改 2 个文件一共 4 个地方:
nrf24l01_init.c 有 1 处
改使用哪个 spi 以及 spi 的片选引脚
sample.h 有 3 处
改 nRF24L01 使用的 spi 设备是哪个
改 nRF24L01 的 CE 引脚
改 nRF24L01 的 IRQ 引脚
改驱动要看原理图,如下:

小马哥四轴遥控器的代码见如下 github 链接:
https://github.com/SuWeipeng/xm_rc
项目使用 progen 自动生成目标工程,不会用 progen 的请看 Sugar 写过的《一招通吃MDK5、IAR、GCC》
牵手 mavlink
因为加入了 mavlink,消息的打包、解包都需要更多栈空间;
所以首先“加大栈空间”,把收发双方的栈大小加到 2048因为 nRF24L01 硬件限制一次通信最多 32 个字节,所以报文设计时要注意包长度。相比于 mavlink 2.0,使用 mavlink 1.0 报文的有效载荷会更多一些,因此 Sugar 采用 mavlink 1.0 协议的通信报文。
一、上哪找 mavlink 生成器
通过 Sugar 改过的 mavlink 三平台(MDK5、IAR 和 GCC)代码生成器生成 C 语言头文件。
生成器的开源地址是:
https://github.com/SuWeipeng/mavlink
二、怎样获得需要的 mavlink 源码
1、选择 xml 模板
2、选择生成代码的储存位置
3、选择目标语言为 C 语言
4、选择协议版本为 1.0
5、不勾选 Validate
6、点击 Generate 按钮进行生成
三、发送端使用 mavlink 的方法
1、配置工程头文件的搜索路径,加入 mavlink 相关文件夹
2、在使用 mavlink 的源文件中加入
#
3、定义一个 mavlink 消息包
mavlink_message_t msg;
4、通过生成的目标 API 打包消息内容
mavlink_msg_simple_pack(0,0,&msg,0);
5、将 msg 内容进行重新排列,送入发送缓冲区 tbuf
mavlink_msg_to_send_buffer(tbuf, &msg);
6、为了方便,将发送长度改为 32 个字节
因为 mavlink 本身有校验机制,所以多发几个字节并不影响什么,按 nRF24L01 最大包长度放心发 32 个就好。
7、解包过程
当收到遥控返回的摇杆速度时,对其进行解包,并从串口打印出来。
(1) 先定义 3 个用于解包的变量
uint8_t i;
mavlink_message_t msg_receive;
mavlink_status_t mav_status;
(2) 解包框架
for(i=0; i<32; i++) {
if(mavlink_parse_char(0, rbuf[i], &msg_receive, &mav_status)
) {
switch (msg_receive.msgid) {
case MAVLINK_MSG_ID_VELOCITY: {
break;
}
}
}
}
(3) 解包
mavlink_velocity_t packet;
mavlink_msg_velocity_decode(&msg_receive, &packet);
(4) 从调试口打印包内容
char get_info[50];
sprintf(get_info, "vel_x:%.3f, vel_y:%.3f, rad_z:%.3f\n", packe
t.vel_x, packet.vel_y, packet.rad_z);
rt_kputs(get_info);
(5) 因为用到了 sprintf() 函数,所以要加入头文件
#
四、接收端使用 mavlink 的方法
出于方便考虑,将接收改为直接取 32 字节,并加大线程栈到 2048。
小马哥四轴遥控器的代码见如下 github 链接:
https://github.com/SuWeipeng/xm_rc
1、在 progen 的 *.yaml 配置文件中加入 mavlink 头文件路径
不了解 *.yaml 配置文件的请看 Sugar 写过的《一招通吃MDK5、IAR、GCC》
2、在使用 mavlink 的源文件中加入
#
#
) 解包框架
for(i=0; i<32; i++) {
PS
本篇内容按功能对代码进行模块化展开,读者只注重使用思路就行了。就像是给孩子们玩儿的图形化编程一样,清楚使用思路之后“拼”就完了。
如果觉得本篇讲得不够易懂,可以在公众号后台回复 mavlink 获得微课视频链接,Sugar 第一次做付费视频,定价 9.9 元(希望能长长久久地做下去)。
如果看过淘宝教育视频还觉得不够,可以在“关于我”页面最下方扫码加 Sugar 为好友,约时间在线一对一讲解(收费会更高一些)。
关注作者
欢迎扫码关注我的公众号MultiMCU EDU
。
