分享

DJI TT无人机 microPython编程指南

 云深无际 2022-01-04

我这里还是希望dji可以把这个mpy的一些源码放出来,因为我觉得是无关紧要的东西,然后去学习一下。而不是这样盲目的去猜。

使用前用Mind+烧录mpy的固件

编程环境,推荐这个,Mind+太重了

一开始的进入,主要就是开启了GC

当你引入RMTT的库,这里就会引入大量的东西

里面大量的IS31FL3733是什么?研究一下:

https://pdf1.alldatasheetcn.com/datasheet-pdf/view/862170/ISSI/IS31FL3733.html

数据手册

IS31FL373x矩阵LED驱动器系列集成了许多先进的功能,如可配置的矩阵(行/列)结构,预编程照明效果功能,独立的LED控制寄存器,独立的LED开路/短路故障检测,以及设备级联同步,所有这些都可以通过快速1Mhz IIC兼容总线接口访问。每个LED都有自己相应的控制和故障状态寄存器,以提供单独的LED照明效果、去重影和故障报告,以增强整体系统性能和可靠性。LED矩阵结构通常会经历一种“鬼影效应”,即由于LED阵列矩阵中的剩余电荷,LED会保持微弱的状态。IS31FL373x系列消除了这种剩余电荷,从而消除了鬼影效果。此外,LED在不知情的情况下,可能会因为LED打开或短路而无法打开。IS31FL373x系列检测失败的LED条件,将其存储在开短寄存器中,并生成一个中断来通知系统失败的LED在数组中的位置。


TT内部的点阵屏幕的控制是使用的一个开源的库,位置在下面:

https://github.com/zhongkunyu/is31fl3733

这个芯片就是光秃秃的一副死样子

3733应该是对上的

如果你导入了RMTT的所有的库,那么这些是一并导入的

Tab会补全

此时

https://docs.micropython.org/en/latest/esp32/quickref.html#uart-serial-bus

ESP32 具有三个硬件 UART:UART0、UART1 和 UART2。

这是mpy默认的ESP32 串口引脚

我们这样的写法初始化一个端口

这些低级的API都是可以使用的

关于低级的API也是可用的,芯片温度

我这里明明看见了

我这里写几个函数,模拟一下ls,cat,rm:

def cat(filename, ln=True): try: with open(filename, "r") as file: count = 0
for line in file: count += 1
print("{}\t{}".format(count if ln else "", line), end="") except Exception as e:    print(str(e))

cat

def ls(folder):  print("listing...")

ls

def rm(filename):  print("removing...")

删除

但就是不出现文件的名字,emmmm,得不到文件了

你写完东西,保存就放到TT里面了

from machine import Pin, PWMfrom machine import *from RMTTLib import *led = RMTTLedCtrl()led.normal(0, 0, 255)

这是让灯buling buling

led.normal(0, 0, 255)led.normal(255, 255, 255)led.start()led.breath(1, 0, 0, 255)led.start()led.blink(1, 255, 0, 0, 0, 255, 0)led.start()led.blink(1, 255, 255, 255, 255, 255, 255)led.stop()

这是关于这个RGB灯的方法

arduino这边是开源的

选择三个通道

然后就是ESP32的这个灯的方法

具体的实现方法在这里

还有,还有

串口0就是USB链接这里

上面的宏打开以后,这里会打印LEDC的成功消息

插一句,这里是引脚的定义

他是控制每一个灯,然后合起来的效果就不一样了

我觉得吧,要是真真正正的用TT玩些什么东西,Arduino还是靠谱的。

我们的这个点阵屏幕也可以控制:

这里是打印一个符号

效果

matrix.normal( '0000000000rrrr0000r00r0000r00r0000r00r000rr0rr000rr0rr0000000000')matrix.static_char('A', 'r')matrix.static_graph(256, 'r')matrix.start()matrix.moveable_graph( 'u', 1, '0000000000rrrr0000r00r0000r00r0000r00r000rr0rr000rr0rr0000000000')matrix.start()matrix.moveable_char('u', 1, 'HELLO', 'r')matrix.stop()

这个由于很细粒度的API,DJI也没有给出,这里可能需要自己摸索一下

行数列数,奇怪不是8x8

引脚, I2C的配置

下面就是对这个芯片寄存器的包装了,不看了。

这个LED的状态的时候

这里就使用了RTOS,资源的加锁

资源的解锁

下面所有的写法,都是先加锁,处理完,解锁

这个芯片也可以设置驱动模式,在这.

ABM的名字叫呼吸驱动模式(俺也不明白是什么)

这里呢,还有一个是点阵的效果,又封装了效果的文件

几种效果

更全的在这里

字符串的移动 

模式封装

ESP32 使用的是FreeRTOS,我不熟悉,所以去学学看。

https://www.freertos.org/index.html

官网的地址

我们编写的 Arduino 代码是跑在FreeRTOS系统上的,并非裸奔。例如 loop()函数是通过创建一个优先级为1的任务来运行此函数。

信了吗?

关于任务的创建什么的:

C:\Users\yunswj\Desktop\TT\mpython\tools\sdk\include\freertos\freertos\FreeRTOSConfig.h

高优先级任务必须延迟一定时间,给低优先级任务留出执行时间,否则低优先级任务永远处于挂起状态,会导致系统复位。

创建任务句柄

void vTaskFunction(void *pvParameters){ for(;;) { vTaskDelay(1000); }}

任务函数这样定义。

这个是我们TT的任务(并不是。。。)

顺便看看定义

这是任务

任务的具体实现在最下面,参数是:

void matrix_effect_init(uint8_t bright);

这里给的

//删除任务句柄为 xHandle1 的任务vTaskDelete(xHandle1);

删除任务句柄

//删除调用此句的任务自身vTaskDelete(NULL);

不指定任务句柄

接下来就去研究这个FreeRTOS了,真不错。

我上面是测试通过的方法。

大家可能对于上面花里胡哨的东西不敢兴趣,那可以看看关于控制协议的问题

因为Arduino就是这个串口配置

so,这里也是这样的配置方法

可以调用一些方法,出错是因为人家要参数

void getTelloStatus(uint32_t timeout);

看C++的实现

这个迟早会见到,我以前的文章,详细的解释过

串口使用的1,串口0是连接电脑,串口1是通过USB到TT

发送这块明白了,看下回复

这里用Python模拟一下,就是把前缀去除了

源码实现

back是个String

如果这个back不不等于这个串,就执行下面的

而且这里自己写了一个字符串的分割函数

Split(String &body, String data[], int len, char separator)

看参数,要分割的串,以及一个数组,长度,分割符号

Split(back, data, 21, ';');
String data[21];

这个21 的数组要放一些东西

要分割这些东西

在此

自己看去吧。

mpry是所谓的挑战卡

C++中的方法:

这些

Tab,自己补全,参数类型和返回类型看C++ 的源码

这个功能也是实现的

源码在此

protocol.startUntilControl()protocol.sendTelloCtrlMsg("motoron")protocol.sendTelloCtrlMsg("motoroff")protocol.sendTelloCtrlMsg("takeoff")protocol.sendTelloCtrlMsg("throwfly")protocol.sendTelloCtrlMsg("land")protocol.sendTelloCtrlMsg("emergency")protocol.sendTelloCtrlMsg("up "+str(int(50)))protocol.sendTelloCtrlMsg("left "+str(int(50)))protocol.sendTelloCtrlMsg("cw "+str(int(90)))protocol.sendTelloCtrlMsg("flip f")protocol.sendTelloCtrlMsg("go "+str(int(50))+" " + str(int(50))+" "+str(int(0))+" "+str(int(100)))protocol.sendTelloCtrlMsg("stop")protocol.sendTelloCtrlMsg("curve "+str(int(20))+" "+str(int(20))+" "+str( int(0))+" "+str(int(40))+" "+str(int(60))+" "+str(int(0))+" "+str(int(10)))protocol.sendTelloCtrlMsg("mon")protocol.sendTelloCtrlMsg("mdirection 0")protocol.sendTelloCtrlMsg( "go "+str(int(50))+" "+str(int(50))+" "+str(int(80))+" "+str(int(50))+" "+"m-1")protocol.sendTelloCtrlMsg("curve "+str(int(20))+" "+str(int(20))+" "+str(int(80)) + " "+str(int(40))+" "+str(int(60))+" "+str(int(80))+" "+str(int(60))+" "+"m-1")protocol.sendTelloCtrlMsg("jump "+str(int(100))+" "+str(int(0))+" " + str(int(80))+" "+str(int(50))+" "+str(int(0))+" "+"m-1"+" "+"m-1")protocol.sendTelloCtrlMsg("setyaw "+str(0)+" "+"m-1")protocol.getTelloStatus(1000)protocol.sendTelloCtrlMsg("speed "+str(int(50)))

这是所有的协议方法

后面介绍一个最重要的方法:

uart1.write("[TELLO] rc "+str(int(50))+" "+str(int(50)) + " "+str(int(50))+" "+str(int(50)))

rc命令

https://docs.micropython.org/en/latest/library/machine.UART.html?highlight=uart#machine.UART

文档位置。

UART对象的作用就像一个stream对象和读写使用标准流方法完成:

uart.read(10) # read 10 characters, returns a bytes objectuart.read() # read all available charactersuart.readline() # read a lineuart.readinto(buf) # read and store into the given bufferuart.write('abc') # write the 3 characters

直接写就好。

UART.write(buff)

将字节缓冲区写入总线。

返回值:写入或None超时的字节数

除去上面的这些,一些普通的单片机的引脚这些也是可以实现。

from machine import Pin, PWMfrom machine import *pwm13 = PWM(Pin(13))p13 = Pin(13, Pin.OUT)pwm13.duty(200)p13.value(1)

我这里写了一点使用的代码。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多