查看: 1091|回复: 0

给DJI Tello加个航模遥控器吧~

[复制链接]

233

主题

263

帖子

730

积分

高级飞友

Rank: 4

积分
730
飞币
465
注册时间
2017-7-12
发表于 2023-1-25 14:52:22 | 显示全部楼层 |阅读模式
我在很久以前写过一个几乎重合的帖子,但是我觉得当时的我太年轻了,很多东西没有写明白,而一年后我决定重新搞一下这个东西。

FlySky+A8S(SBUS接收机)+ESP8266控制大疆Tello无人机.准备

红红火火的DJI官网

怎么说呢,EDU版本有个ESP32的扩展模块,现在下载的SDK文档里面没有这部分内容了。

我不妨大胆的想想这个问题,DJI确实是做出来了牛逼的东西,但是面向用户的话,用户不太行,玩不转。(本身产品也是毛病星星点点的,有些也不能克服)

最后DJI索性,玩尼玛,桌子都给你掀了:

给DJI Tello加个航模遥控器吧~w2.jpg

乌鸦哥真帅啊

。。。我土狗了,原来在后面有这部分内容,上面是我辛苦写的,就不删除了

给DJI Tello加个航模遥控器吧~w3.jpg

搞错了

害,有个教育群是有些人希望推出教育产品的无刷版本,对的,现在TT的最大问题就是续航和动力问题,其它的都很棒。

害,无所谓啦~想以前我还差点变成大疆的KOL,妈的,我自己不争气,不搞视频,写文章谁看啊!(鄙人技术垃圾也是个问题,hhhhh,都可以补足了)

给DJI Tello加个航模遥控器吧~w4.jpg

对的,机会就悄悄的溜走了

DJI的无人机,除了手机应用以外,还有一个是蓝牙的手柄,害,我也买了,用不明白了。。。

所以最大的问题就是作为一个小航模,没有一个航模遥控器来控制。

TT在拆下扩展模块的时候,使用的WIFI链路+UDP控制,在加扩展模块下,控制的样子和上面大同小异,不过是扩展和飞机之间通讯是串口:

给DJI Tello加个航模遥控器吧~w5.jpg

官方有张图,很漂亮

那这个项目就是使用普通RC接收机+遥控器来完成TT。

其实实现起来很简单,就两个代码而已,但是我觉得没有意思。要搞明白写咋写出来的。

给DJI Tello加个航模遥控器吧~w6.jpg

你要问我为什么不自己写,那抱歉,我是个菜狗

FlySky的接收机要用一个串口,ESP8266的控制需要用一个串口,必须要用的两个串口,但是通讯程序需要调试,所以还需要一个串口,iBUS还支持信息遥测,所以还可以用一个串口。

而且还要ESP8266要网络支持,所以可以找到这一款硬件,串口+ESP8266的合体。

网上可以买到的就是这个了,但有点贵。。。

其实就单纯的控制来讲,其实一个ESP8266+RC就可以了~

给DJI Tello加个航模遥控器吧~w7.jpg

给DJI Tello加个航模遥控器吧~w8.jpg

WeMOS Mega

给DJI Tello加个航模遥控器吧~w9.jpg

而且上面通过拨码开关,来开启各个芯片之间的连接

给DJI Tello加个航模遥控器吧~w10.jpg

如果有板子的,我也给出Pin图

给DJI Tello加个航模遥控器吧~w11.jpg

那有人想要原理图,我也有,牛逼不?从俄罗斯搞得~

给DJI Tello加个航模遥控器吧~w12.jpg

还不夸我

给DJI Tello加个航模遥控器吧~w13.jpg

给DJI Tello加个航模遥控器吧~w14.jpg

ESP8266有两个串口

2 个 UART 接⼝的数据传输均由硬件实现。数据传输速度可达 115200*40 (4.5 Mbps)。UART0 可以⽤做通信接⼝,⽀持流控。由于 UART1 ⽬前只有数据传输功能,所以⼀般⽤作打印 log。
给DJI Tello加个航模遥控器吧~w15.jpg

这个是编码开关的连接方式

Tello 公开了一个接收命令的 UDP 端口和另一个公开统计信息的端口。ESP8266 模块会先连接到 Tello 建立的WIFI,并发送command消息以稳定通信。

一个通道(遥控器通道)用作起飞和降落的开关。起飞后,使用rc指令连续控制无人机,同时发送所有 4 个通道(左/右、前/后、上/下和偏航)。

这些在源码中都会有体现。

ATmega2560 和 ESP8266 模块之间的通信是通过其中一个串行端口进行的。我选择使用基于文本的通信,只是为了更容易在两个模块之间来回发送数据和调试消息。

给DJI Tello加个航模遥控器吧~w16.jpg

这就是我们的控制方式了

给DJI Tello加个航模遥控器吧~w17.jpg

给DJI Tello加个航模遥控器吧~w18.jpg

我们就要这些说明,不要挑战卡

我是没有接触过网络编程的,这个需要补一个UDP编程。
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/udp-examples.html
这里推荐自带的教程

创建一个WiFiUDP对象。然后指定一个端口来监听传入的数据包。最后,我们需要为传入的数据包设置缓冲区并定义回复消息。

给DJI Tello加个航模遥控器吧~w19.jpg

推荐这个开源的调试软件

给DJI Tello加个航模遥控器吧~w20.jpg

8266中,UDP只有12个函数

函数用法在这里:

uint8_t begin(uint16_t p)uint8_t begin(IPAddress a, uint16_t p)
启动监听某个端口,或者来自某地址发送给某端口的数据;
void stop()
停止监听,释放资源;
intbeginPacket()
准备发送数据包(仅在运行parsePacket()方法且返回值大于0时可用);
intbeginPacket(IPAddress ip, uint16_t port)
准备发送数据包,参数分别为目标IP和目标端口号;
size_t write(uint8_t)size_t write(constuint8_t *buffer, size_t size)
复制数据到发送缓存(同一数据包发送缓存最大1460字节);
intendPacket()
发送数据;
intparsePacket()
获取接收数据信息,如果有数据包可用,则返回队首数据包长度,否则返回0;
intread()
读取首字节数据(仅在运行parsePacket()方法且返回值大于0时可用);
intread(unsignedchar* buffer, size_t len)intread(char* buffer, size_t len)
读取数据(仅在运行parsePacket()方法且返回值大于0时可用);
intpeek()
读取首字节数据,但并不从接收缓存中删除它(仅在运行parsePacket()方法且返回值大于0时可用);
void flush()
清空当前接收缓存(仅在运行parsePacket()方法且返回值大于0时可用);
IPAddress remoteIP()
返回远端地址(仅在运行parsePacket()方法且返回值大于0时可用);
uint16_t remotePort()
返回远端端口号(仅在运行parsePacket()方法且返回值大于0时可用);

因为频繁的使用到串口,这里也说一下串口的使用,ESP8266的串口可以使用特殊优化过的库:
https://github.com/plerup/espsoftwareserial实现了中断服务例程的最佳实践。在接收中断中,不是一次阻塞整个字节—使 CPU 的任何近实时行为无效——只记录电平变化和时间戳。比较耗时的相位检测和字节组装在主代码中完成。除了高比特率,取决于其他正在进行的活动,特别是中断,此软件串行适配器支持全双工接收和发送。SoftwareSerial::enableIntTx(false)在高比特率 (115200bps) 下,可以通过函数调用以阻塞并发全双工接收为代价来改进发送比特时序。与相应的 AVR 库具有相同的功能,但可以同时激活多个实例。支持高达 115200 波特的速度。除了与 AVR SoftwareSerial 类兼容的构造函数和不带参数的更新构造函数外,该begin() 函数还可以处理引脚分配和逻辑反转。它还具有用于字节缓冲区和 ISR 位缓冲区的可选输入缓冲区容量参数。这样,它就可以更好地替代 ESP MCU 上的硬件串行 API。请注意,由于 ESP 总是有其他活动正在进行,因此中断时序会有些不准确。当以高波特率传输大量数据时,这可能会导致不可避免但很少的位错误。该库支持 ESP8266、ESP32、ESP32-S2 和 ESP32-C3 设备。
如果你的硬件串口不够用的话,可以考虑使用IO来模拟UART:

传统的SoftwareSerial 库具有以下已知限制:

1.它不能同时发送和接收数据。2.如果使用多个软件串口,一次只能接收一个数据。在Arduino 1.0的之前,内置的库是上面这个库,但是对中断支持不好,甚至说就是没有支持,后面有大佬重写了SoftSerial:它引入了中断驱动的接收——对本机 SoftwareSerial 所需的轮询进行了显着改进。如果没有中断,程序设计将受到相当大的限制,因为它必须以非常短的时间间隔连续轮询串行端口,这使得它几乎不可能。例如,使用 SoftwareSerial 来接收 GPS 数据并将其解析为可用的形式。当 NMEA 字符到达时,程序正忙于跟上它们,而无暇实际花时间将它们组装成有意义的东西。这就是 AFSoftSerial(和NewSoftSerial的)中断架构的天赐之物。使用中断驱动的 RX,程序在处理先前接收到的数据时会在后台填充其缓冲区。http://arduiniana.org/NewSoftSerial/NewSoftSerial12.zip
这个是库的直接下载位置,可以去读源码

具体的API就不罗列了:

https://blog.csdn.net/poisonchry/article/details/116503393
这篇写的很好了

我们这里还缺一个RC的知识铺垫:

用于 Flysky/Turnigy RC iBUS 协议的 Arduino 库 - 使用硬件 UART 的伺服(接收)和传感器/遥测(发送)。iBUS 协议是 Flysky 开发的一种半双工协议,用于使用一条数字线控制多个舵机和电机。每个伺服通道接收到的值在 1000(十六进制 eE8)和 2000(十六进制 7D0)之间,具有中性子微调设置,这与大多数伺服的脉冲宽度(以微秒为单位)相对应。该协议还可以连接传感器,将遥测信息发送回 RC 收发器。
给DJI Tello加个航模遥控器吧~w21.jpg

TR的遥控器还挺丑的

官网上面早就没有了AFHDS2的协议内容,不过互联网是有记忆的:

给DJI Tello加个航模遥控器吧~w22.jpg

这个是2代的协议

给DJI Tello加个航模遥控器吧~w23.jpg

逻辑分析仪的数据

AFHDS 一代协议(FlySky),至于一代的协议在这里。

官方又放出了富斯AFHDS3 ibus 协议通道数据格式如下:3.3V UART 115200 bauds, 8 bits, 2 stop bits with no parity serial link
给DJI Tello加个航模遥控器吧~w24.jpg

可以读一下

给DJI Tello加个航模遥控器吧~w25.jpg

整个通讯链路的话就是这样

我们需要两份代码,一份处理RC,一份负责遥测以及将RC通道的信息解码到UDP使用WIFI发射出去。

我们先看RC部分:

https://github.com/bmellink/IBusBM
使用这个库来解码

该代码用于与 RC 接收器通信,并将数据从通道数据发送到 ESP8266。它不断地从接收器读取 RC 通道;然后将其序列化为具有格式的字符串:
>channelNumber:value
给DJI Tello加个航模遥控器吧~w26.jpg

这个是序列化的代码

最后通过ESP8266串口发送。它还从串口读取消息。它们可以是调试或数据消息。两种类型的数据消息是电池电量和温度水平。它们都作为遥测传感器发送回 RC 接收器。

给DJI Tello加个航模遥控器吧~w27.jpg

我们建立RC和信息遥测两个对象,以及使用了Mega的4个串口

给DJI Tello加个航模遥控器吧~w28.jpg

就打印信息,可以波特率不高,信息回调也打开了

给DJI Tello加个航模遥控器吧~w29.jpg

可以遥测的数据

给DJI Tello加个航模遥控器吧~w30.jpg

在前面调试的时候开一个串口,将解码出来的数据打印出去,获得的是第几个通道的值是多少。

SerialEvent()函数。函数将在loop()中自动被内部调用。在我们写的代码中如果串口有任何数据(只要不是换行符),那么就将数据加到一个缓存字符串中。在收到换行符时就返回缓存字符串。发送后将会将字符串清空为null。

这个有点回调的感觉,但是又感觉不是:

给DJI Tello加个航模遥控器吧~w31.jpg

三串口是信息回调串口:然后一直读到换行,如果里面有<bat,就通过字符串的方法提取电量,接着降值加载到遥测上面。之后打印一下值在终端,后面的代码都一样的。

接下来的代码用于使用 UDP API 通过端口 8889 向 Tello 发送消息。它基本上使用 4 个命令:command- 稳定通信。takeoff- 起飞。它由频道 5 上的 RC 发射器开关控制。land- 着陆。它也由通道 5 开关控制。rc- 发送每个方向的控制。
给DJI Tello加个航模遥控器吧~w32.jpg

硬件的连接,和IP+控制端口+信息端口

给DJI Tello加个航模遥控器吧~w33.jpg

打印的信息用类来包装

给DJI Tello加个航模遥控器吧~w34.jpg

应该写的够详细了吧

连接WIFI到Tello,并且发送控制命令。

模块有三种模式:

1:STA 模式:ESP8266模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制。

2:AP 模式:ESP8266模块作为热点,实现手机或电脑直接与模块通信,实现局域网无线控制。

3:STA+AP 模式:两种模式的共存模式,即可以通过互联网控制可实现无缝切换,方便操作。

给DJI Tello加个航模遥控器吧~w35.jpg

发送的命令的时候随便打印在终端上面

给DJI Tello加个航模遥控器吧~w36.jpg

和Tello的通讯

给DJI Tello加个航模遥控器吧~w37.jpg

SDK3.0

给DJI Tello加个航模遥控器吧~w38.jpg

SDK2.0

这个代码来处理这个字符串

给DJI Tello加个航模遥控器吧~w39.jpg

这个从UDP 端口 8890 读取统计数据。这些统计数据被序列化为一个字符串,其中包含几个不同的键和值,由“;”分隔。此代码解析此字符串,并选择电池和温度。它从串行接口读取 RC 通道并将统计数据写回。

给DJI Tello加个航模遥控器吧~w40.jpg

这个是自编码的,在从缓冲区取到的字符串插入:/0,末尾有EOF的时候停止,开始插入,不停的插入:;,来分割字符串。

给DJI Tello加个航模遥控器吧~w41.jpg

其实就是键值对拆分,妈的,写Python久了看着这东西还有点害怕

给DJI Tello加个航模遥控器吧~w42.jpg

最后把解码的值装载到Tello的状态类里面

给DJI Tello加个航模遥控器吧~w43.jpg

这个代码是从UDP口取到信息,和上面的代码运行的时候有顺序区别

给DJI Tello加个航模遥控器吧~w44.jpg

上面的数组,就是为了确定状态,这个是工具函数,来处理摇杆的数据

给DJI Tello加个航模遥控器吧~w45.jpg

这个是拨钮开关和三段式开关,控制飞行起落的

给DJI Tello加个航模遥控器吧~w46.jpg

这个就是我们心心念念的RC函数了,写入到cmd,然后UDP发送

给DJI Tello加个航模遥控器吧~w47.jpg

一些前置准备

给DJI Tello加个航模遥控器吧~w48.jpg

这里就是和RC遥控器的纠葛了

把取到的字符串开始拆解:
>channelNumber:value
读到>的时候,开始取出通道后面的值。后面也有一段终端的打印代码。

给DJI Tello加个航模遥控器吧~w49.jpg

这个是快速的打印电池和温度的信息,也可以自己加wifi强度等信息。

给DJI Tello加个航模遥控器吧~w50.jpg

如果要起飞的话,就发送,也会检查降落情况,顺便油门全关。

之后就是发送RC控制了。

不知不觉写了这么多,受益匪浅了,睡觉去了~

视频演示稍后附上。

给DJI Tello加个航模遥控器吧~w51.jpg

小彭同学的摄影技术越来越(๑•̀ㅂ•́)و✧

欢迎领取
https://terra-1-g.djicdn.com/2d4dce68897a46b19fc717f3576b7c6a/Tello%20%E7%BC%96%E7%A8%8B%E7%9B%B8%E5%85%B3/For%20Tello/Tello%20SDK%20Documentation%20EN_1.3_1122.pdfhttps://arduino-esp8266.readthedocs.io/en/latest/libraries.htmlhttps://www.arduino.cc/reference/en/libraries/wifi/https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFihttp://arduiniana.org/libraries/newsoftserial/https://blog.csdn.net/m0_61543203/article/details/126706199https://blog.csdn.net/m0_51220742/article/details/123568721?spm=1001.2014.3001.5501https://blog.csdn.net/m0_51220742/article/details/123791062https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFihttps://github.com/espressif/arduino-esp32/tree/master/libraries/AsyncUDPhttps://packetsender.com/https://forum.arduino.cc/t/mega-wifi-r3-atmega2560-esp8266-8-mb-memoire/446340/12https://www.instructables.com/Arduino-MEGA-2560-With-WiFi-Built-in-ESP8266/https://www.amazon.it/ATmega2560-ESP8266-USB-TTL-NodeMCU-Arduino/dp/B07HML8DZDhttps://github.com/werneckpaiva/telloRChttps://github.com/esp8266/Arduinohttps://terra-1-g.djicdn.com/851d20f7b9f64838a34cd02351370894/RM-TT/RoboMaster%20TT%20Arduino%20IDE%20%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.pdfhttps://dl.djicdn.com/downloads/RoboMaster%20TT/Tello_SDK_3.0_User_Guide_cn.pdfhttps://github.com/tianbot/rmtt_roshttps://www.dji.com/cn/robomaster-tt/downloadshttps://login.squarespace.com/api/1/login/oauth/provider/authorize?client_id=qNgYXXcY8Fa8M&redirect_uri=https%3A%2F%2Fflysky.squarespace.com%2Fauth%2Foauth%2Fconnect%3FdestinationUrl%3Dhttps%253A%252F%252Fflysky.squarespace.com%252Fconfig%252F%253FframeUrl%253D%252Fchinese-blog-1%252F2019%252F9%252F28%252Fafhds3-ibus-&state=1%3A1674458861%3AtrpJciNyjaO3jrl3EHDMTFPuKwVuHAQ08JV%2Fg9QF9tE%3D&overrideLocale=en-US&options=%7B%22isCloseVisible%22%3Afalse%2C%22isCreateAccountViewActive%22%3Afalse%7D
您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

快速回复 返回顶部 返回列表