本实验基于灵动MM32F0020实现测距dToF模块,基于MM32F0040实现WS2812B,并通过AT指令将距离值转换为灯带亮的个数,实现“灯随物动”的效果。
整个工程设计框架如下图所示:
一、简介
1.dToF ( direct time-of-flight ) ,测量发射光和反射光之间的飞行时间并根据光速直接估计目标物体的深度。dToF测距模块硬件外观如下图所示:
dToF测距模块主要特点:
- 串口 IO 电压 3.3 V
- 供电电压 3.3 V
- 串口波特率默认 9600 bps,可调范围为 2000 bps - 2000000 bps
2. WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源。每个元件为一个像素点,像素点内部包含智能数字接口,数据锁存信号整形放大驱动电路,高精度的内部振荡器和12 V高压可编程定电流控制部分,有效保证了像素点的光的颜色一致性。
二、实验环境
1.硬件资源:MM32F0040开发板,MM32F0020开发板,1m灯带,杜邦线若干
2.软件资源:KEIL MDK 软件,Tera Term 终端软件用于监控程序
三、实验资源
1.MM32F0020硬件资源图:
2.MM32F0020硬件尺寸:3.AT 指令集
在键盘输入需要的指令,如“AT”,串口将接收后打印“OK”,其余可用AT指令如表1所示:
序列
|
指令名称
|
指令说明
|
1
|
AT
|
测试模块是否正常通信
|
2
|
AT+RST
|
复位模块
|
3
|
AT+BAUDRATE
|
查询串口波特率
|
4
|
AT+BAUDRATE
|
设置串口波特率
|
4
|
AT+D
|
读取一次距离值
|
5
|
AT+START
|
开始连续传输距离值
|
6
|
AT+STOP
|
停止传输距离值
|
AT+START 指令发送完成并接收“OK”后,模块将会连续以定长帧的形式回传测距值AT+STOP 指令发送完成并接收“OK”后,模块将停止回传测距值
4.电路图
- MM32F0020电路原理图
- MM32F0040电路原理图
四、实验流程
本样例基于MM32F0040开发板和dToF测距模块,实现“灯随物动”。通过串口UART2获取测距模块的数据,串口发送和接收的对应引脚如下表所示:
序号
|
引脚名称
|
复用功能
|
1
|
PD4
|
UART2_TX
|
2
|
PD6
|
UART2_RX
|
获取距离的AT指令为“AT+D?”,并将其转换为灯带亮的个数,从而实现“手止灯止”的效果。
整个模块特点:
•IC控制电路与RGB点光源共用一个电源
•测距模块供电电压3.3 V,串口IO电压3.3 V
•测距模块的串口波特率默认9600 bps,可调范围为2000 bps - 2000000 bps
•测距模块测量范围可精确到4m
•WS2812B驱动RGB灯珠电压为3.5 V~5.5 V
•WS2812B控制信号选择SPI+DMA
•WS2812B光的颜色高度一致,性价比高
Notice芯片MM32F0040正常工作电压在2.0 V~5.5 V都可以,如果接的灯珠较多整体电流功耗就会比较大,需要外接一个5 V的电源适配器给整个系统供电
AT 指令获取距离:
<font face="Arial">extern const ws2812_if_t ws2812_if;
ws2812_t ws2812;
uint32_t led_on_cnt = 0u;
char str_cmd_get_distance[] = "AT+D?\r\n";
char str_cmd_rst[] = "AT+RST\r\n";</font>
uint32_t get_distance 获取距离:
<font face="Arial">uint32_t get_distance(void){
uint8_t uart_buf[APP_UART_BUF_SIZE] = {0u};
uint32_t dis = 0;
for (uint32_t i = 0u; i < sizeof(str_cmd_get_distance) - 1u; i++){
uart_putc(str_cmd_get_distance[i], APP_TIME_OUT);}
for (uint32_t i = 0u; i < 15u; i++){
uart_buf[i] = uart_getc(APP_TIME_OUT);}
dis = strtol((char *)uart_buf + 3, NULL, 16);
if (dis > 65518){
dis -= 65518;}
else{
dis = 0;}
printf("dis = %d, %s\r\n", dis, uart_buf);
return dis;}</font>
led_on_cnt 灯带亮的数量:
int main(void)
{
BOARD_Init();
//printf("ws2812 & dtof\r\n");
ws2812_init(&ws2812, (ws2812_if_t*)&ws2812_if);
ws2812_set_fx(&ws2812, led_fx);
// ws2812_refresh(&ws2812);
for (uint32_t i = 0u; i < sizeof(str_cmd_rst) - 1u; i++){
uart_putc(str_cmd_rst[i], APP_TIME_OUT);}
while (1){
led_on_cnt = get_distance();
ws2812_refresh(&ws2812);}}
uint32_t led_fx(uint32_t led_index){
if (led_index < led_on_cnt){
return 0x000F00;}
else{
return 0x0F0000;}}
---------------------
作者:春娇霹雳娃
链接:https://bbs.21ic.com/icview-3308826-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。