目录
前言
安信可新款雷达模组Rd-03D已经上市,该雷达采用一发两收的天线,可以实现目标跟踪,实现对区域内目标测距、测角和测速。本应用示例使用STM32解析Rd-03D的串口数据,将结果通过另一个串口发送给VC-02开发板,实现对当前人数的实时播报。
一、Rd-03D引脚说明
J1引脚说明:
J#PIN# | 名称 | 功能 | 说明 |
---|---|---|---|
J1PIN1 | 5V | 电源输入 | 连接串口转接板5V |
J1PIN2 | GND | 接地 | 连接串口转接板GND |
J1PIN3 | TX | UART_TX | 连接串口转接板RXD |
J1PIN4 | RX | UART_RX | 连接串口转接板TXD |
J1PIN5 | DP | 烧录数据正信号 | 若使用4Pin的连接器,则该引脚未使用 |
J1PIN6 | DM | 烧录数据负信号 | 若使用4Pin的连接器,则该引脚未使用 |
J2引脚说明:
J#PIN# | 名称 | 功能 | 说明 |
---|---|---|---|
J2PIN1 | 5V | 电源输入 | 5V |
J2PIN2 | DM | 烧录数据负信号 | - |
J2PIN3 | DP | 烧录数据正信号 | - |
J2PIN4 | DEBUG | 调试串口TXD | 用于调试固件 |
J2PIN5 | GND | 接地 | - |
J2PIN6 | TX | UART_TXD | 连接串口转接板RXD |
J2PIN7 | RX | UART_RXD | 连接串口转接板TXD |
二、软件设计框架
三、STM32F103C8T6使用CubeMX搭配HAL库配置
打开CubeMX,选择STM32F103C8T6。
选择两个串口,分别是串口1和串口2,PA9为USART1_TX,PA10为USART1_RX,PA2为USART2_TX,PA3为USART_RX。
选择异步通讯,勾选中断,注意:串口1的波特率为256000,串口2波特率为115200。
下面附上时钟配置图:
四、STM32与Rd-03D和VC-02的接线
Rd-03D | STM32 | VC-02 | ||
---|---|---|---|---|
5V | — — | 5V | — — | 5V |
GND | — — | GND | — — | GND |
TX | — — | PA10 | ||
RX | — — | PA9 | ||
PA2 | — — | RX | ||
PA3 | — — | TX |
五、串口数据处理
一、Rd-03D的串口数据
Rd-03D模组通过串口(TTL电平)与外界通信,雷达串口默认波特率为256000,1停止位,无奇偶校验位。雷达输出检测到的目标信息,包括在区域中的x坐标,y坐标,以及目标的速度值。
雷达默认是处于单目标检测模式,需要切换至多目标检测模式。
模式 | 指令 |
---|---|
单目标模式 | FD FC FB FA 02 00 80 00 04 03 02 01 |
多目标模式 | FD FC FB FA 02 00 90 00 04 03 02 01 |
上报是数据帧格式:
帧头部 | 帧内数据 | 帧尾部 |
---|---|---|
AA FF 03 00 | 目标1信息 目标2信息 目标3信息 | 55 CC |
数据示例:AA FF 03 00 0E 03 B1 86 10 00 68 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 CC
红色部分表示目标1的信息,蓝色表示目标2的信息,绿色表示目标3的信息。
本示例只展示有无人,所以只需要判断在对应的数据帧中有没有相应的目标信息即可。
二、VC-02的串口数据
VC-02的串口数据格式是由用户自定义的,开发的平台和资料可以在VC系列模组官网查看
这里附上我自己定义的串口协议和语音指令表格,串口输出均为16进制数,文章结尾附上VC-02固件。
唤醒词 | 命令词 | 回复语 | 串口输出 | 串口输入 |
---|---|---|---|---|
小安小安、你好小安 | - | 我在、你说、有什么可以帮你 | - | - |
- | 有多少人、现在有几人、有人吗 | (根据目标数量回复) | A5 00 00 FF 00 | - |
- | - | 当前没有目标 | - | 5A 00 00 00 00 |
- | - | 当前有一个目标 | - | 5A 00 00 00 01 |
- | - | 当前有两个目标 | - | 5A 00 00 00 02 |
- | - | 当前有三个目标 | - | 5A 00 00 00 03 |
- | 大点声、增大音量 | 音量已增大 | - | - |
- | 小点声、减小音量 | 音量已减小 | - | - |
六、STM32数据处理
这里我是采取设置标志位的方式处理数据。为了防止在雷达数据下发过快时,语音一直重复播报的情况。
uint8_t RX_BUF[64]={
0}; //缓存数组
uint8_t RX_count=0; //计数位
uint8_t RX_temp; //缓存字符
uint8_t Radar_1=0; //目标1标志位
uint8_t Radar_2=0; //目标2标志位
uint8_t Radar_3=0; //目标3标志位
uint8_t Speaker_1=0; //语音播报目标1标志
uint8_t Speaker_2=0; //语音播报目标2标志
uint8_t Speaker_3=0; //语音播报目标3标志
uint8_t Single_Target_Detection_CMD[]={
0xFD,0xFC,0xFB,0xFA,0x02,0x00,0x80,0x00,0x04,0x03,0x02,0x01}; //单目标检测模式指令,该模式下只会检测一个目标
uint8_t Multi_Target_Detection_CMD[]={
0xFD,0xFC,0xFB,0xFA,0x02,0x00,0x90,0x00,0x04,0x03,0x02,0x01}; //多目标检测模式指令,该模式下只会检测多个目标
uint8_t SpeakerCMD_0[5]={
0x5A,0x00,0x00,0x00,0x00}; //无目标播报串口指令
uint8_t SpeakerCMD_1[5]={
0x5A,0x00,0x00,0x00,0x01}; //目标1播报串口指令
uint8_t SpeakerCMD_2[5]={
0x5A,0x00,0x00,0x00,0x02}; //目标2播报串口指令
uint8_t SpeakerCMD_3[5]={
0x5A,0x00,0x00,0x00,0x03}; //目标3播报串口指令
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//回调函数,检测到雷达发送一帧数据时进行处理
{
if(huart == &huart2){
//串口2触发中断
RX_BUF[RX_count++] = RX_temp;//将缓存字符存入缓存数组中
if((RX_BUF[RX_count-1] == 0x00)&&(RX_BUF[RX_count-2] == 0xFF)){
//接收VC串口指令查询当前人数
if((0==Radar_3)&&(0==Radar_2)&&(0==Radar_1)){
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_0,sizeof(SpeakerCMD_0),0xFFFF); //触发无目标语音播报
}
else if(1==Radar_3){
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_3,sizeof(SpeakerCMD_3),0xFFFF); //触发目标3语音播报
}
else if(1==Radar_2){
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_2,sizeof(SpeakerCMD_2),0xFFFF); //触发目标2语音播报
}
else if(1==Radar_1){
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_1,sizeof(SpeakerCMD_1),0xFFFF); //触发目标1语音播报
}
while(HAL_UART_GetState(&huart2)==HAL_UART_STATE_BUSY_TX); //判缓存数组是否发送完毕
memset(RX_BUF,0x00,sizeof(RX_temp));//清空缓存数组
RX_count = 0;//计数位置零
}
HAL_UART_Receive_IT(&huart2,&RX_temp,1);//串口2继续接收数据
}
if(huart == &huart1){
//串口1触发中断
RX_BUF[RX_count++] = RX_temp;//将缓存字符存入缓存数组中
if((RX_BUF[RX_count-1] == 0xCC)&&(RX_BUF[RX_count-2] == 0x55)){
if((1==Radar_1)&&(0==Speaker_1)){
//逻辑判断,触发目标1语音播报
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_1,sizeof(SpeakerCMD_1),0xFFFF);
Speaker_1=1;
}
else if((1==Radar_2)&&(0==Speaker_2)){
//逻辑判断,触发目标2语音播报
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_2,sizeof(SpeakerCMD_2),0xFFFF);
Speaker_2=1;
}
else if((1==Radar_3)&&(0==Speaker_3)){
//逻辑判断,触发目标3语音播报
HAL_UART_Transmit(&huart2,(uint8_t *)&SpeakerCMD_3,sizeof(SpeakerCMD_3),0xFFFF);
Speaker_3=1;
}
else if((0x00==RX_BUF[5])&&(0x00==RX_BUF[14])&&(0x00==RX_BUF[22])) //数据比较,雷达检测到无目标
{
Radar_1=0;
Radar_2=0;
Radar_3=0;
Speaker_1=0;
Speaker_2=0;
Speaker_3=0;
}
else if((0x00!=RX_BUF[5])&&(0x00==RX_BUF[14])&&(0x00==RX_BUF[22])) //数据比较,雷达检测到一个目标
{
Radar_1=1;
Radar_2=0;
Radar_3=0;
Speaker_2=0;
Speaker_3=0;
}
else if((0x00!=RX_BUF[5])&&(0x00!=RX_BUF[14])&&(0x00==RX_BUF[22])) //数据比较,雷达检测到两个目标
{
Radar_1=0;
Radar_2=1;
Radar_3=0;
Speaker_1=0;
Speaker_3=0;
}
else if((0x00!=RX_BUF[5])&&(0x00!=RX_BUF[14])&&(0x00!=RX_BUF[22])) //数据比较,雷达检测到三个目标
{
Radar_1=0;
Radar_2=0;
Radar_3=1;
Speaker_1=0;
Speaker_2=0;
}
// HAL_UART_Transmit(&huart1,(uint8_t *)&RX_BUF,RX_count,0xFFFF);//将缓存数组中的数据从串口发送出去
while(HAL_UART_GetState(&huart2)==HAL_UART_STATE_BUSY_TX);//判缓存数组是否发送完毕
memset(RX_BUF,0x00,sizeof(RX_temp));//清空缓存数组
RX_count = 0;//计数位置零
}
HAL_UART_Receive_IT(&huart1,&RX_temp,1);//串口1继续接收数据
}
}
七、效果演示
八、源码地址和固件
源码地址:https://e.coding.net/axk/stm32_rd-03/STM32_Rd-03D_VC-02.git
联系我们
官方网址: https://www.ai-thinker.com
Docs:https://docs.ai-thinker.com
官方论坛: http://bbs.ai-thinker.com