如何接入sbus航模遥控器?
最近队内大疆的遥控器短缺,故自行购买一款便宜好用的遥控器来替代,但是协议与dbus不同,研究了一阵子,所以诞生了这一篇文章来帮助大家少走弯路。
遥控器构成
一般都有发射端和接收端:发射端为主遥控器
接收端为接收机:
SBUS协议
上面写的虽然是m.bus但其实基本都是sbus只是商家的名字是以m开头。
大疆的dbus还是与sbus不同,是18字节的,sbus是25字节。
详细的电压是多少啥的参看对应的手册即可
一般的航模遥控器通信协议都是采用的sbus协议(使用串口):
以microzone的c6遥控器说明书举例(入门级6通道遥控器)
说明书网址:MC6C说明书(中文)未转曲.cdr
SBUS: ⾼电平为3.3V, 100k波特率,8位数据位(在stm32中要选择9位),偶校验(EVEN),2位停⽌位, 以0x0F开头,0x00结 尾,共个字节, 每隔14ms⼀帧数据; 排列如下: data [0x0F] [data ] [data ] [data ] [data ] ... [data ] [flag] [0x00]; data : 对应16个通道(ch1-ch16),每个通道11bit, 通道数据取值范围是200-1800
可以简单的理解为串口,波特率为100k,但是这是不能直接与单片机上的rx相接的,因为它采用的是相反的电平信号,如果你的接收机不自带反转可能得自制一个反转电平(输入0输出1,输入1输出0)的小玩意了(不能软件翻转,除了数据位它的校验位也是反转的。。。)
取反电路制作
这个也好做,电路图就长这样:
三极管的话我目前研究不深,可以参考这篇文章
https://blog.csdn.net/chenhuanqiangnihao/article/details/112979214
我制作取反电路的成功案例是使用的手上现有的直插2n3904三极管和贴片电阻临时焊接完成的。
验证电路方法
可以直接使用万用表测量输出端在输入端使用3.3v高电平输入观察输出是否为低电平即可,注意共地。
SBUS协议解析
收到数据后一共会有25字节的数据包,起始字节是x0f,还有一个falg字节 和 终止字节x00,中间22字节一共
22*8个bit,每个通道占用11位,所以一共解析出来有16个通道。并不是一字节就是一个通道,这个要注意。
协议解析代码如下想研究可以细品:
void parse_sbus_data(uint8_t *buffer, uint16_t *channels) {// 解析SBUS数据channels[0] = ((buffer[1] | buffer[2] << 8) & 0x07FF);channels[1] = ((buffer[2] >> 3 | buffer[3] << 5) & 0x07FF);channels[2] = ((buffer[3] >> 6 | buffer[4] << 2 | buffer[5] << 10) & 0x07FF);channels[3] = ((buffer[5] >> 1 | buffer[6] << 7) & 0x07FF);channels[4] = ((buffer[6] >> 4 | buffer[7] << 4) & 0x07FF);channels[5] = ((buffer[7] >> 7 | buffer[8] << 1 | buffer[9] << 9) & 0x07FF);channels[6] = ((buffer[9] >> 2 | buffer[10] << 6) & 0x07FF);channels[7] = ((buffer[10] >> 5 | buffer[11] << 3) & 0x07FF);channels[8] = ((buffer[12] | buffer[13] << 8) & 0x07FF);channels[9] = ((buffer[13] >> 3 | buffer[14] << 5) & 0x07FF);channels[10] = ((buffer[14] >> 6 | buffer[15] << 2 | buffer[16] << 10) & 0x07FF);channels[11] = ((buffer[16] >> 1 | buffer[17] << 7) & 0x07FF);channels[12] = ((buffer[17] >> 4 | buffer[18] << 4) & 0x07FF);channels[13] = ((buffer[18] >> 7 | buffer[19] << 1 | buffer[20] << 9) & 0x07FF);channels[14] = ((buffer[20] >> 2 | buffer[21] << 6) & 0x07FF);channels[15] = ((buffer[21] >> 5 | buffer[22] << 3) & 0x07FF);
}