模块资料
当活动开始的时候就看模块的相关资料了,不过刚开始也没太在意,所以从RD-03系列从头开始看。不过后来才发现RD-03系列的产品有很多,本次活动涉及的产品是RD-03E。所以我赶紧去看03E的相关产品。产品的资料有很多,不过感觉有些文件的内容有些重复,上位机软件的各个参数可能是因为涉及到内部逻辑所以没有详细说明。模块资料链接:Rd-03 系列模组 | 安信可科技 (ai-thinker.com)
模块应用场景
首先官方给的应用场景是智能马桶(手势识别模式),这在上位机当中也是有体现的,在此就不多说了。其次是本次活动要求的是应用在智能灯控上,有感应开关灯、距离改变光照模式等。除了智能家居外,该模块也可以应用在智慧城市和工业控制领域等。
上位机使用体验
在拿到模块后,想必大家都会先用官方的例程或软件体验一下。我也简单的用上位机连接模块看了一下。首先安信可给的模块是没有损坏的,在质量把控方面上安信可确实做得很好,至今也没发现有质量问题。
刚开始时数据波动比较大,波动范围有20CM,也不知道大家是否会关注用户手册中写的探测范围0.3~2.2M。这可能是数据处理不是那么好吧。上位机软件距离显示曲线如下图
但是我又用串口软件进行测试发现数据是50ms发一次,这让我再次怀疑控制芯片处理数据的能力,不过看论坛上的文章和群消息后好像官方也在进行调整。但是我觉得在官方给出新的驱动前可能还有其他的解决方法。于是再次盯住这些杂乱无章的曲线,然后自己在前面不停的微动,这种场景是真的挺搞笑的,但是也没办法,研发就是这样。看了一段时间后,发现问题可能出现在模块发送数据的间隔时间非常短,50ms就发一次。我们一般是一个处理芯片会接很多的模块,对某一个模块接收的数据也不会这么频繁,反正是我没遇见过。所以就想着我1S接收一次是不是就会避免了。在上位机软件中也无意发现有上报周期这一选项,于是就把这个参数改成1000及1S后,发现数据波形确实变平了,但是好像数据波动还是有,不过没有之前那么大了。之前看距离数据时也是发现数一直在跳变,很难看清数值是多少。现在是可以看清的。
修改上报周期后的结果如下图。
不过我对此还是不够满意,所以就把数值改成5000及5S,发现效果和1S的差不多。所以我在后续的程序是采用1S接收一次数据并进行处理。也不知道大家是否注意到这一点,在此将我注意到的点分享给大家。
除了注意到时间间隔外,还注意到一点是在采集到的数据波形有一段时间是0。对此我也开始不断地测试在何种情况下会导致数据是0。后来发现有两种情况会有这种现象。第一种是你超出他的探测范围,这一点我确实没有注意到,因为之前看到的的范围是0.3M~2.2M,也没想到没人的情况下探测距离是多少;第二种是当探测的物体没有晃动或移动,简单来说就是站在那里一动不动就会接收到距离是0的情况,这让我猜到模块的采集数据的方式应该是检测磁场的变化,也就是有物体切割磁感线,模块就会有数据,具体的就没有深究了。
作品功能描述
因为要求作品是与灯有关的,但是我身边也没有与灯相关的模块。而是准备了一个其他的模块,这个在下次的文章中展现给大家。不过好在M61板子上有三个灯,所以就简单的模拟上位机灯泡的显示效果了。代码实现起来非常简单,就是1S采集一下模块的数据,然后判断数据在哪个阶段就亮哪个灯。为了拍摄效果,所以就没把数据选的那么大。
首先是Rd-03E串口数据处理代码,代码如下
void RD03E_GetGestDataPoll()
{
unsigned char i = 0;
unsigned char DistTemp = 0;
bflb_uart_get(pstUARTHandle, au8UartReceData, RD03E_GEST_DATA_MAX_LEN);
printf("RD03E Receive Data is:");
for (i = 0; i < RD03E_GEST_DATA_MAX_LEN; i++)
{
printf("%X ",au8UartReceData[i]);
}
printf("rn");
for (i = 0; i < RD03E_GEST_DATA_MAX_LEN; i++)
{
if (RD03E_GEST_DATA_HEAD_MARK == au8UartReceData[i])
{
/* 找到数据帧开头标志0xAA */
break;
}
}
if ((i < (RD03E_GEST_DATA_MAX_LEN - RD03E_GEST_DATA_LEN -1))
&& (RD03E_GEST_DATA_TAIL_MARK == au8UartReceData[i + RD03E_GEST_DATA_LEN + 1]))
{
/* 找到数据帧 */
DistTemp = au8UartReceData[i + 1] | ((unsigned int)au8UartReceData[i + 2] << 8);
stGestData.GestDist = DistTemp;
stGestData.Gest = au8UartReceData[i + RD03E_GEST_DATA_LEN];
}
}
串口一次性接收10个字节的数据,测试发现若接收5个字节的数据的话,后面会出现解析不到数据帧的开头。这也是为了后面1S采集一次数据的适配。接收到数据后会先找帧开头标志0xAA,找到后便判断后面的第4个字节是否为帧结束标志0x55。若是则将中间的3个数据解析出来,分别为手势识别模式中的距离和手势数据。这样可以防止数据解析有误。
主函数主要是获取串口数据,然后进行处理,逻辑比较简单,所以不再详细讲解。代码如下
int main(void)
{
GestData *RD03EGestDataTemp = {0};
board_init(); /* 板卡初始化 */
LED_Init(); /* 板卡LED引脚I/O初始化 */
UART_Init(); /* RD03E串口初始化 */
while(1)
{
/* 获取RD03E数据 */
RD03EGestDataTemp = RD03E_ReadGestData();
if (RD03EGestDataTemp->Gest != RD03EGestData.Gest)
{
RD03EGestData.Gest = RD03EGestDataTemp->Gest;
/* 检测到有手势变化 */
if (RD03EGestData.Gest)
{
if (LEDSwitch)
{
LEDSwitch = 0;
/* 关闭全部灯 */
LED_SetSta(LED_STA_OFF, GREE_LED_PIN);
LED_SetSta(LED_STA_OFF, RED_LED_PIN);
LED_SetSta(LED_STA_OFF, BLUE_LED_PIN);
}
else
{
LEDSwitch = 1;
}
}
}
if (LEDSwitch == 1)
{
/* 当灯是开的状态再检测距离数据是否发生变化 */
if (RD03EGestDataTemp->GestDist != RD03EGestData.GestDist)
{
RD03EGestData.GestDist = RD03EGestDataTemp->GestDist;
/* 先关全部的灯,再亮其中的一个 */
LED_SetSta(LED_STA_OFF, GREE_LED_PIN);
LED_SetSta(LED_STA_OFF, RED_LED_PIN);
LED_SetSta(LED_STA_OFF, BLUE_LED_PIN);
if (RD03EGestData.GestDist < 50)
{
printf("Dist:%d Green LED ONrn",RD03EGestData.GestDist);
LED_SetSta(LED_STA_ON, GREE_LED_PIN);
}
else if (RD03EGestData.GestDist < 100)
{
printf("Dist:%d Red LED ONrn",RD03EGestData.GestDist);
LED_SetSta(LED_STA_ON, RED_LED_PIN);
}
else
{
printf("Dist:%d Blue LED ONrn",RD03EGestData.GestDist);
LED_SetSta(LED_STA_ON, BLUE_LED_PIN);
}
}
}
/* RD03E轮询不断更新数据 */
RD03E_GetGestDataPoll();
/* 设置1秒已更新,否则灯跳变比较大 */
bflb_mtimer_delay_ms(1000);
}
}
作品展示及工程文件请点击原贴查看:https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=44476&highlight=%E3%80%90%E9%9B%B7%E8%BE%BE%E7%81%AF%E6%8E%A7%E3%80%91%E5%AE%89%E4%BF%A1%E5%8F%AF%2BRd-03E%2B%2B%E7%81%AF%2B%2B%2BAi-M61&_dsign=31a6d697
作品展示
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !