【CEM5861G-M11毫米波雷达】stm32oled串口数据解析再点个灯
分享作者:kkun
作者昵称:玉书前.
评测品牌:萤火工场
评测型号:CEM5861G-M11
发布时间:2025-09-09 16:51:04
0
前言
屏幕的驱动是用的江科大的一个驱动啊,这边事先做一个说明,然后将串口数据做一个解析,也没什么难度。还有就是这一款雷达似乎对距离的检测不是特别准。
开源口碑分享内容

一、介绍

       CEM5816G-M11 是一款高灵敏度24GHz毫米波FMCW人体存在检测雷达模块。区别于传统雷达通过检测人体移动的大幅度动作或者微小幅度的肢体动作来判断人体存在,本模块主要特点是在传统人体感应雷达的功能基础上,同时具备检测人体呼吸等微小幅度的运动,来判断人体存在的功能。

1、电气特性(25℃)

参数最小典型最大单位测试条件
供电电压3.655.5V 
电流 22 mA平均功耗@5V
 62 mA峰值电流@5V
发射等效空间辐射功率 5 dBm 
发射天线半功率方向角 110 水平
 110 垂直
接收天线半功率方向角 110 水平
 110 垂直
功能裸板3米挂高测试,存在半径0-3米可调,移动半径0-5米可调

2、雷达输出格式

 HeadPacket LenFunc codeCMDDataSum
接收55A5000E038100Data[0]~Data[9]:检测到目标的 信息SUM
Data段格式说明
设置/接 收DatafO]目标ID号:8位无符号整型
Data[l]目标状态:8位无符号整型;0:无目标,1:表示移动,2: 表示存在
Data[2]Data [3]距离:16位无符号整型,单位:cm
Data[4]Data[5]速度:16位有符号整型,单位:cm/s
Data[6]万位角度:8位有符号整型,单位:度
Data[7]俯仰角度:8位有符号整型,单位:度
Data[8]Data [9]信号强度:16位无符号整型

3、接口信息

序号功能备注
1OUT有人输出高电平3.3V,无人输出低电平0V
2UART-TX3. 3V串口发送
3UART-RX3. 3V串口接收
4GND
5VCC供电3.6V-5. 5V

这里是几个主要的内容,具体的内容可以去附件的萤火工场 CEM5861G-M11  24GHz毫米波雷达模块规格书 中查看

二、上位机


关于上位机,官方好像有一个上位机可以用,也有几个博主自己做了上位机,使用起来更方便这边不过多赘述,这边使用 作者:Mr_Fang

制作的https://cem.babyfang.cn/ 做上位机演示

ps:距离不是很准

三、硬件部分

开发板使用经典stm32f103c8t6开发板,0.96寸oled屏幕,发光二极管,CEM5861G-M11毫米波雷达

pb8---------屏幕scl

pb9---------屏幕sda

pa9----------雷达2口

pa10---------雷达3口

pa7-----------led正极

ps:雷达电源记得3.6v-5.5v别用单片机的3.3v


四、软件部分

1、屏幕部分

使用江科大的0.96oled驱动

2、串口部分

// 串口中断服务函数

void USART1_IRQHandler(void) {

   uint8_t rx_data;

   // 保存中断状态

   uint16_t usart_it_status = USART_GetITStatus(USART1, USART_IT_RXNE);

   uint16_t usart_flag_status = USART_GetFlagStatus(USART1, USART_FLAG_ORE);


   // 处理接收非空中断

   if (usart_it_status != RESET) {

       rx_data = USART_ReceiveData(USART1);

       

       // 缓冲区未满时存储数据

       if (uart_rx_len < MAX_BUFFER_LEN) {

           uart_rx_buffer[uart_rx_len++] = rx_data;

           last_receive_time = GetTickMs();

           frame_received = 0;

       } else {

           // 缓冲区满时设置溢出标志(可根据需求添加溢出处理)

           frame_received = 1;

           // 可选:记录溢出事件用于调试

           // overflow_count++;

       }

       

       USART_ClearITPendingBit(USART1, USART_IT_RXNE);

   }


   // 处理接收溢出错误

   if (usart_flag_status != RESET) {

       // 读取数据寄存器清除溢出标志

       (void)USART_ReceiveData(USART1);

       USART_ClearFlag(USART1, USART_FLAG_ORE);

   }


   // 其他可能的错误处理(如奇偶校验错、帧错误等)

   if (USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET) {

       USART_ClearFlag(USART1, USART_FLAG_PE);

   }

   if (USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET) {

       USART_ClearFlag(USART1, USART_FLAG_FE);

   }

}


使用简单的串口中断服务程序即可,缓冲区大小使用16即可

3、数据解析部分

// 解析传感器数据帧

void ParseSensorData(uint8_t *rx_buffer) {

   // 帧头校验

   if (rx_buffer[0] == 0x55 && rx_buffer[1] == 0xA5 &&

       rx_buffer[2] == 0x00 && rx_buffer[3] == 0x0E) {

       

       uint8_t raw_status = rx_buffer[8];

       uint8_t target_id = rx_buffer[7];

       uint8_t target_status = raw_status;  // 使用原始值

       uint16_t distance = (rx_buffer[9] << 8) | rx_buffer[10];

       uint16_t signal_strength = (rx_buffer[15] << 8) | rx_buffer[16];


       char display_str[OLED_LINE_MAX_CHARS * OLED_ROWS];

       memset(display_str, 0, sizeof(display_str));


       // 状态解析

       char *status_str;

       switch (target_status) {

           case 0:

               status_str = "no people";

               break;

           case 1:

               status_str = "mov";

               break;

           case 2:

               status_str = "presence";

               break;

           default:

               // 显示未知状态的原始值,方便调试

               sprintf(display_str, "unknown(%d)", target_status);

               status_str = display_str;

               break;

       }


       // 格式化要显示的字符串内容

       sprintf(display_str, "ID: %d                status: %s          range: %d cm         strength: %d",

               target_id, status_str, distance, signal_strength);


       char lines[OLED_ROWS][OLED_LINE_MAX_CHARS + 1];

       uint8_t line_count = SplitStringToLines(display_str, lines);


       ClearAllDataRows();  // 先清屏再显示新数据

       for (uint8_t i = 0; i < line_count; i++) {

           OLED_ShowString(0, 8 + (i * FONT_HEIGHT), lines[i], OLED_6X8);

       }

       OLED_Update();

   }

}

根据雷达输出格式对数据进行处理例如:

串口接收信息:55 A5 00 0E 03 81 00 00 01 00 5E 00 00 00 00 01 78 64
目标ID:第8 byte 0x00
运动状态:第9 byte 0x01,检测到运动目标
目标距离:第10~11 bytes 0x00 0x5E, 转换成十进制为94
目标信号强度:第16~17 bytes 0x01 0x78, 转换成十进制为376
校验和:第18 byte
综上:检测到运动目标,目标距离为0.94米,信号强度为376。


其中速度,方位角,俯仰角该传感器都是不支持的

4、效果-具体效果可以到b站链接观看


五、完结

除了插针用的2mm的不常用,距离误差比较大之外,这个雷达还是挺好用的。

博主比较萌新大佬多多指点

完整项目文件可以私聊博主b站账号

全部评论
暂无评论
0/144