挑战利用RD-03D雷达+ESP12F+ASRPRO语音模块+STM32制作一个小型敌我识别小玩意!

[复制链接]
查看743 | 回复9 | 2024-2-28 15:35:07 | 显示全部楼层 |阅读模式

本帖最后由 我94喜欢丰兄 于 2024-9-20 14:52 编辑

本帖最后由 我94喜欢丰兄 于 2024-2-28 23:56 编辑

本帖最后由 我94喜欢丰兄 于 2024-2-28 15:35 编辑

前言

去年无意间在B站上看到有些大佬利用小米摄像头来结合流浪地球中的MOSS,让MOSS的可以实现视觉跟踪(实际就是小米摄像头的其中一个功能而已),但是跟随的不是很流畅,总体来说还是不错的。所以我就决定自己也做一个。在淘宝买材料的时候,发现安信可新款雷达模组Rd-03D已经上市,该雷达采用一发两收的天线,可以实现目标跟踪,实现对区域内目标测距、测角和测速。感觉这个还不错,就想买回来和摄像头结合一下。让MOSS拥有两个系统,一个是自身的系统,另一个就是以STM32为主控芯片的语音控制系统。

通过利用STM32解析Rd-03D的串口数据,当雷达功能开启的时候,检测人体距离雷达的角度,根据角度来调整X轴移动,实现摄像头跟随的效果。(Y轴的俯仰角的控制现在没有去设计考虑)还有就是关于两个系统之间的切换设计等还未完全搞定,都是边做边想。如果有小伙伴有啥好的建议可以一起评论区讨论。

一:Rd-03D引脚说明

J1引脚说明:

J2引脚说明:

二、硬件构成

RD-03D雷达+STM32最小系统板+ASR-PRO离线语音模块+ESP-12F+步进电机+自制整合电路板等模块

1、原理图

image.png

我想把它放在一张图上,看着有点乱。

2、印制电路板

image.png

3、实物图(不完全体)

image.png

三、软件编写

这里由于用到了ASR-PRO和STM32模块,需要分别利用KEIL和天问编程软件编写,在这里不做详细讲解,小伙伴可以自行下载资料研究。(由于3D打印机不稳定,步进电机模块与外壳结合不足导致整体进度卡在百分之80的完成度,我后续完善后继续给大家分享)

1、kei编程软件编写的雷达数据处理部分

#include "Rd_03D.h"
#include "sys.h"
#include "usart3.h"  
#include "usart.h"
#include "delay.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "led.h"
#include "esp8266.h"
#include "uln2003.h"
#include "timer.h"
#include "lcd.h"
#include "exti.h"
unsigned char Radar_wifi_Data[2];
int rada_num=0;
float radar_num=0;
float  pi,angle;
u8 radar_find=0,Radar_detection_mode=0,Radar_mode=0,Radar_floag=0,target_bearing=1;
u16 T=0,F=0;
int radar_data[9],radar_transfer[9],y;


u8 Single_Target[]={0xFD,0xFC,0xFB,0xFA,0x02,0x00,0x80,0x00,0x04,0x03,0x02,0x01};
u8 many_Target[]={0xFD,0xFC,0xFB,0xFA,0x02,0x00,0x90,0x00,0x04,0x03,0x02,0x01};

void radar_usart3_data(void)
{
    u8 i,j;
    if((USART3_RX_STA&0x8000))
     {
        if(Radar_floag)
         {   
          if(Radar_detection_mode==0)
           {
            if(USART3_RX_BUF[0]==0xAA&&USART3_RX_BUF[11]==0x01)
             {
                    Flashing();
                rada_num=1;
                    if(radar_find==0)
                 {
                  printf("R%dD",rada_num);

                    delay_ms(100);
                    radar_find=1;
                        ESP8266_Send(T_NUM,rada_num);
                        delay_ms(300);
                 }
              for(i=0,j=0;i<3;i++,j++)
                 {
                  radar_data[i]=USART3_RX_BUF[4+i+j]+(USART3_RX_BUF[5+i+j]<<8);
                if(radar_data[i]&0x8000)
                       radar_data[i]=radar_data[i]&0x7fff;
                        else
                         radar_data[i]=-radar_data[i];
                     }
                    radar_num=pow((radar_data[0]*0.001),2)+pow((radar_data[1]*0.001),2);
                    radar_num=sqrt(radar_num);
                  pi=fabs((radar_data[0]*0.001)/(radar_data[1]*0.001));
                    angle=atan(pi);
                    angle=(180/3.14)*angle;
                    if(radar_data[0]<=50&&radar_data[0]>=-50)
                     target_bearing=1; 
                    else if(radar_data[0]>50)
                     target_bearing=2; 
          else 
                     target_bearing=0; 
                    if(pi<0.27)
                    {
                   if(abs(radar_data[0]-radar_transfer[0])<200||abs(radar_data[1]-radar_transfer[1])<200)
                          {
                           T++;

                           if(T==100)
                            {
                   ESP8266_Send(POS,target_bearing);
                             delay_ms(300);
                             ESP8266_Send_float(SPE,radar_data[2]*0.01);
                   delay_ms(300);
                   ESP8266_Send_float(SLDE,radar_num);
                   delay_ms(300); 
                             printf("R-Target locked");
                                 delay_ms(300);
                             printf("RD%dES%dPT%dG",(int)(radar_num*100),radar_data[2],target_bearing);
                         T=0;

                            }
                          }
                        else
                         {
                          if(T)
                              T=0;
                         for(i=0;i<3;i++)
                            radar_transfer[i]=radar_data[i];
                             F++;
                             if(F==5)
                              {
                               printf("R-Target locking failed"); 
                                 F=0;
                              }
                         }              
                        }
                         else
                          {
                             T=0;
                             if(target_bearing==2)
                              {
                                 //if(INF1_C!=0)
                                  //{
                                 X_move_L(5,10);
                                   y++;
                                  //}
                              }
                           else if(target_bearing==0)
                              { 

                               X_move_R(5,10);
                                 y--;
                              }

                          }                 
             }
        else if(USART3_RX_BUF[0]==0xAA&&USART3_RX_BUF[11]==0)
             {
          if(radar_find)
                 {
                        ESP8266_Send(POS,1);
              delay_ms(300);
              ESP8266_Send_float(SPE,0);
              delay_ms(300);
              ESP8266_Send_float(SLDE,0);
              delay_ms(300);
              ESP8266_Send(T_NUM,0);
              delay_ms(300);
                  printf("R-The target has disappeared");
                    radar_find=0;
                        T=0;
                        F=0;
                        Radar_detection_mode=0;
                Radar_mode=0;
                rada_num=0;
            LCD_Radar_clr_Show();
                        y=Yuntai_Follow(y);
                 }  
             }
         }
      else
         {
            if(USART3_RX_BUF[0]==0xAA)
             {
              for(i=0,j=0;i<9;i++,j++)
                 {
                    if(i<3)
                   radar_data[i]=USART3_RX_BUF[4+i+j]+(USART3_RX_BUF[5+i+j]<<8);
                    else if(i<6)
                     radar_data[i]=USART3_RX_BUF[6+i+j]+(USART3_RX_BUF[7+i+j]<<8);
                    else 
                     radar_data[i]=USART3_RX_BUF[8+i+j]+(USART3_RX_BUF[9+i+j]<<8);

                if(radar_data[i]&0x8000)
                 radar_data[i]=radar_data[i]&0x7fff;
                else
                 radar_data[i]=-radar_data[i];
                 }
              if(USART3_RX_BUF[11]==0x01&&USART3_RX_BUF[19]==0&&USART3_RX_BUF[27]==0)
                 rada_num=1;
              else if(USART3_RX_BUF[11]==0x01&&USART3_RX_BUF[19]==0x01&&USART3_RX_BUF[27]==0)
                 rada_num=2;
              else if(USART3_RX_BUF[11]==0x01&&USART3_RX_BUF[19]==0x01&&USART3_RX_BUF[27]==0x01)
                 rada_num=3;
              else
                 rada_num=0;
                    if(Time_1s%5==0)
                     printf("R%dD",rada_num);
             }
         } 
     }
   }
    USART3_RX_STA=0;
}

void Radar_T_F(u8 Radar_RX_DATA)
{
 u8 i;
 if(Radar_RX_DATA==1)
  {
   if(Radar_floag==0)
      {
         LCD_ShowChinese(0,80,"µ¥Ä¿±ê",RED,WHITE,16,0);
         LCD_ShowString(48,80,"-",BLACK,WHITE,16,0);
         LCD_ShowChinese(56,80,"±ê×¼",RED,WHITE,16,0);
         Radar_floag=1;
         Radar_detection_mode=0;
         Radar_mode=0;
         rada_num=0;
         radar_find=0;
         T=0;
     F=0;
         y=0;
     strat_USART3();
       for(i=0;i<12;i++)
          MYUSART3_SendData(Single_Target[i]);
         delay_ms(100);
       printf("Radar successfully turned on"); 
      }
     else  printf("Radar working"); 
  }
 else if(Radar_RX_DATA==0)
 {
  if(Radar_floag)
     {
        LCD_Radar_Off_clr_Show();
        y=X_Y_Rest();
    Radar_floag=0;
        Radar_detection_mode=0;
        Radar_mode=0;
        rada_num=0;
        radar_find=0;
        T=0; 
    F=0;
      end_USART3();
        printf("Radar turned off");
     }
    else printf("Radar OFF"); 
 }
}

void Radar_mode_set(u8 Radar_RX_DATA)
{
 u8 i;
 if(Radar_RX_DATA==1)
  {
     if(Radar_floag==1)
        {
         if(Radar_detection_mode)
          printf("R_Current mode working");
     else
          {
           LCD_ShowString(0,80,"  ",RED,WHITE,16,0);
             LCD_ShowChinese(0,80,"¶à",RED,WHITE,16,0);
           Radar_detection_mode=1;
             for(i=0;i<12;i++)
            MYUSART3_SendData(many_Target[i]);
             printf("R_Multi target mode on");
          }          
        }
     else   printf("");
    }
 else if(Radar_RX_DATA==0)
    {
     if(Radar_floag==1) 
        {
         if(Radar_detection_mode==1)
          {
             LCD_ShowString(0,80,"  ",RED,WHITE,16,0);
           LCD_ShowChinese(0,80,"µ¥",RED,WHITE,16,0);
           Radar_detection_mode=0;
             for(i=0;i<12;i++)
            MYUSART3_SendData(Single_Target[i]);
             printf("R_Single target mode on");
          }
         else   printf("R_Current mode working");         
        }
   else printf("");
        }
}

void Radar_work_mode_set(u8 Radar_RX_DATA)
{
 if(Radar_floag)
  {
   if(Radar_RX_DATA==0)
      {
       if(Radar_mode!=0)
          {
       LCD_ShowString(56,80,"    ",RED,WHITE,16,0);
           LCD_ShowChinese(56,80,"±ê×¼",RED,WHITE,16,0);
           Radar_mode=0;
             printf("R_Standard mode on");
          } 
         else printf("R_Current mode working");
      }
     else if(Radar_RX_DATA==1)
        {
         if(Radar_mode!=1)
          {
             LCD_ShowString(56,80,"    ",RED,WHITE,16,0);
           LCD_ShowChinese(56,80,"Ó¦¼±",RED,WHITE,16,0);
           Radar_mode=1;
             printf("R_Emergency defense mode activated");
          }
         else printf("R_Current mode working");
        }
     else if(Radar_RX_DATA==2)
      {
       if(Radar_mode!=2)
          {
             LCD_ShowString(56,80,"    ",RED,WHITE,16,0);
           LCD_ShowChinese(56,80,"×Ô¶¯",RED,WHITE,16,0);
           Radar_mode=2;
             printf("R_Automatic attack mode enabled");
          }
         else printf("R_Current mode working");
      }
  }
    else printf("");
}

void radar_asr_on_off(void)
{
 if(USART_RX_BUF[0]==0x01)
  {
     Radar_T_F(1);
     delay_ms(300);
     ESP8266_Send(Radar,Radar_floag);
     delay_ms(300);
     ESP8266_Send(TDM,0);
     delay_ms(300);
     ESP8266_Send(ROM,0);
     delay_ms(300);
  }
 else if(USART_RX_BUF[0]==0x04)
  {
     Radar_T_F(0);
     ESP8266_Send(Radar,Radar_floag);
     delay_ms(300);
     ESP8266_Send(TDM,0);
     delay_ms(300);
     ESP8266_Send(ROM,0);
     delay_ms(300);
     ESP8266_Send(POS,1);
     delay_ms(300);
     ESP8266_Send_float(SPE,0);
     delay_ms(300);
     ESP8266_Send_float(SLDE,0);
     delay_ms(300);
     ESP8266_Send(T_NUM,0);
     delay_ms(300);
  }
}

void radar_asr_mode(void)
{

 if(USART_RX_BUF[0]==0x02)
  {
     Radar_mode_set(0);

   ESP8266_Send(TDM,Radar_detection_mode);
  }
 else if(USART_RX_BUF[0]==0x03)
  {
     Radar_mode_set(1);

     ESP8266_Send(TDM,Radar_detection_mode);
  }
    else if(USART_RX_BUF[0]==0x09)
  {
     Radar_work_mode_set(1);

   ESP8266_Send(ROM,Radar_mode);
  }
    else if(USART_RX_BUF[0]==0x0B)
  {
     Radar_work_mode_set(2);

     ESP8266_Send(ROM,Radar_mode);
  }
 else if(USART_RX_BUF[0]==0x0A)
  {
     Radar_work_mode_set(0);

     ESP8266_Send(ROM,Radar_mode);
  }


}


这个是关于雷达处理数据的全部代码,里面掺杂了其他wifi、1.8寸显示等其他综合代码,我嫌麻烦一起复制了,只要看void radar_usart3_data(void)这个函数是雷达处理的主要函数。

由于Rd-03D模组通过串口(TTL电平)与外界通信,雷达串口默认波特率为256000,1停止位,无奇偶校验位。雷达输出检测到的目标信息,包括在区域中的x坐标,y坐标,以及目标的速度值(小端模式)。 上报是数据帧格式:

数据示例: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的信息。

本示例展示解析单目标模式下对角度信息进行解析,所以需对单个目标内的数据进行解析(即目标1),其中单个目标具体包含内容如下:

根据目标X,Y坐标数据帧说明可知,若像上述数据示例,模组将目标1的角度数据转换为相关坐标信息的过程展示如下: 目标1x坐标:OxOE+Ox03256= 782 0-782= -782 mm; 目标1y坐标:OxB1+Ox86256 = 34481 34481-2^15= 1713 mm;

我的数据处理思路就是,通过判断X、Y、速度这三个值来确定是否有人,有人话就实时探测跟踪目标并且实时处理数据。在这里我分了三种情况,目标锁定/目标移动过快丢失/目标消失。

当雷达探测到有人,就开始自动追踪。在摄像头的视野范围内移动,只要连续100次目标X/Y移动的幅度不大于200MM,即锁定成功。如果连续5次移动幅度超过200MM即目标移动过快丢失,锁定失败。

如果超过设定的视野范围就会自动跟随目标移动,最终结果也将是失败或者成功锁定,也可能是目标消失。

如果目标突然移动出最大视野范围左右正负60度,即目标消失。

关于这个X轴跟随后续我会再次更新完善。

四、视频演示(只是其中一部分)

视频地址:【STM32与ESP12F:语音交互,雷达探测,WiFi联网,全程演示!】 https://www.bilibili.com/video/BV1Vc411r7Lv/?share_source=copy_web&vd_source=792fb47d93d5a6322849d58c21c7570f

【MOSS小苔藓:它不是你的尾巴,但它的确是个跟屁虫!】 https://www.bilibili.com/video/BV18Q4y1374C/?share_source=copy_web&vd_source=792fb47d93d5a6322849d58c21c7570f

【震撼来袭!MOSS之第十弹:新电路板换装后开机测试体验!】 https://www.bilibili.com/video/BV1JC4y1Y7PN/?share_source=copy_web&vd_source=792fb47d93d5a6322849d58c21c7570f

五、最后说几句

这只是其中一部分,后续我会持续更新,但是由于事情多,估计更新时间不确定。如果更新我会优先在抖音发布,大家可以关注我的抖音号:5946BNYZD

代码我也会慢慢跟随设计的阶段分享。

2024.9.20更新

一、电路板跟新

image.png

image.png

image.png

image.png

image.png

通过实际测试,稳压模块需要采用直插封装,要不然功率不够。

不过也可以采取只用5V电源,舍弃12V。(这也是现在我准备采用的方式)

测试视频:

回复

使用道具 举报

WT_0213 | 2024-2-28 16:08:42 | 显示全部楼层
活动刚开始,咱就已经结束了吗这效率有点高呀
回复 支持 反对

使用道具 举报

1084504793 | 2024-2-28 16:13:19 | 显示全部楼层
回复

使用道具 举报

爱笑 | 2024-2-28 16:35:37 | 显示全部楼层
不错不错
用心做好保姆工作
回复

使用道具 举报

bzhou830 | 2024-2-28 17:02:51 | 显示全部楼层
这速度,也太快了
选择去发光,而不是被照亮
回复 支持 反对

使用道具 举报

楚华 | 2024-2-28 18:53:32 | 显示全部楼层
厉害了
回复

使用道具 举报

知行合一 | 2024-2-28 19:54:21 | 显示全部楼层
回复

使用道具 举报

noonezero | 2024-2-29 09:09:09 | 显示全部楼层
回复

使用道具 举报

lazy | 2024-2-29 09:18:18 | 显示全部楼层
效率真高
回复

使用道具 举报

方源 | 2024-3-4 10:48:12 | 显示全部楼层
太厉害了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则