一、课程引入
(1)Arduino IDE软件使用
(2)Arduino Hardware库和Arduino RMTT Library的安装
(3)学习机顶全彩LED
(4)学习TOF测距传感器
(5)学习与无人机通讯
二、知识原理讲解
(1)学习机顶全彩LED
机顶全彩LED由64颗红色灯珠以及64颗蓝色灯珠组成,一共128颗灯珠。通过封装好的接口,可以实现对LED 矩阵每颗灯珠的色彩、亮度等控制。
在点阵LED屏控制过程中,我们需要让该屏幕显示我们需要的内容。在嵌入式开发中,除非已有封装好的显示库,否则您通常需要自己编写程序,从最底层控制每个像素每颗LED的亮暗,才能达到显示我们想要的内容的效果。这意味着,即使我们需要显示数字、文字等简单内容,也需要控制每颗LED的亮暗来达到对应效果。幸运的是,您无需亲自实现这个控制过程,只需使用取模软件,将需要显示的内容以简单的图形化方式绘制,即可从取模软件中获得自动生成的点阵数组代码。
打开“点阵取模”文件夹下的matrix.exe,然后随心绘制您所需要的图形。点击
生成代码,即可得到对应的点阵数组。将其复制到您的项目中即可使用。
这里提供一个数字显示库(0-100)用于本项目的显示实验:MyLedFontsLib.h
取模软件生成的代码如图。看起来让人一头雾水?其实它的结构并没有那么复杂。
让我们先来看看点阵LED屏的硬件组成形式。
Talent扩展模块上的点阵屏由64颗红色灯珠以及64颗蓝色灯珠组成,一共128颗灯珠。如图中演示,每个
格子(像素)中安装有一红一蓝两颗贴片LED(虽然他们被封装在同一个贴片元件内)。
基于硬件,我们需要使用一个大小为64(像素数)*2(色彩数)=128的一维数组来表示每个格子中每颗LED 的亮暗情况。
从上图中您可以知道,每个像素的显示需要蓝红两个通道的色值以进行控制。
为了方便理解,我们可以将数据分为64组,每组两个色值。这些数据在大小为128的一维数组中由上至下由左至右排列,分别代表64个像素的LED色值数据。
我们可以总结出一套规律:
2 * n 代表第n个像素中的蓝灯 (n属于 [ 0, 7 ])
2 * n + 1 代表第n个像素中的红灯
(1)学习TOF测距传感器
本模块由红外发射器和接收器组成。
通过比对红外光出射和返回的时间差,也即光的飞行时间( Time of Flight, ToF ),我们使用公式
即可计算得知光的单程行走路程d,也即我们所需要测量的距离。
(3)在Visual Studio 2019上配置Arduino
Visual Studio 的插件「Visual Micro」的安装和使用方法。
Visual Micro 的官网是 Arduino Plugin (new version, simpler & more powerful) ,
在安装完 Visual Studio 和 Arduino IDE 之后,双击下载的 *.vsix 文件就可以完成插件的安装,安装插件时最好关闭 Visual Studio。如果双击无法安装此文件,那么在打开方式中选择 Microsoft Visual Studio Version Selector。
安装插件后,Visual Studio 将多出一个菜单,名为「VISUAL MICRO」。在菜单中可以选择 Arduino 版本、开发板版本以及串口号等参数。
安装成功
三、项目实施步骤
(操作时注意安全,飞手远离桨叶)
项目描述:
要求使用Arduino IDE环境进行编程,实现无人机飞行过程中,通过TOF传感器实时显示无人机机头到墙壁的真实距离。
任务拆解:
(1)打开Arduino IDE
(2)创建项目编程文件,并命名为DistanceFromDrone2Wall_TOF.c
(3)编写程序
(4)编译连接下载程序
(5)起飞无人机观察现象
学生能力基础:
(1)熟悉RMTT Library
(2)会使用LED和TOF测距传感器
(3)C语言基础
流程图:
具体实施步骤如下:
步骤1 配置Arduino环境
步骤2 找到下载好的DistanceFromDrone2Wall_TOF.ino文件
步骤3 找到模块相应的端口,编译下载。
步骤4 可以看到拍照时Tof传感器测出的距离手机的距离大约是3dm即30cm
步骤5 而Tof传感器最大距离约为81dm即约810cm
材料清单
- RoboMaster TT无人机 X1 链接
- 配套拓展模块 X1
演示视频:
项目文件:
#include <RMTT_Libs.h>
#include <Wire.h>
#include "MyLedFontsLib.h"
RMTT_Matrix tt_matrix;
RMTT_TOF tt_sensor;
int range = 0;
void setup()
{
Serial.begin(115200);
Wire.begin(27, 26);
Wire.setClock(100000);
tt_sensor.SetTimeout(500); // 设置单次测量超时时间
if (!tt_sensor.Init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1)
{
}
}
tt_matrix.Init(127); // 初始化点阵
tt_matrix.SetLEDStatus(RMTT_MATRIX_CS, RMTT_MATRIX_SW, RMTT_MATRIX_LED_ON); // 开启点阵LED
matrix_effect_init(255);
}
void loop()
{
range = tt_sensor.ReadRangeSingleMillimeters();
range = range/100; // 将数据单位转换至分米
Serial.println(range);
if (tt_sensor.TimeoutOccurred())
{ // 判断当次测量是否未超时(是否为有效测量)
Serial.print("TIMEOUT");
}
else
{
matrix_effect_set_graph(MyLedFontsMatrix[range]);
delay(15);
}
}
评论