首先非常感谢安信可送的雷达模组🎉️ 感谢园长❤️
RD03e雷达模组采用的串口协议50ms传输一次数据,这次我采用的是立创的开发板配合模组使用
数据帧AA AA 01 00 00 55 55
上面是串口发送的数据帧我们可以很明显的看到特点所以我们写一个函数来处理这个数据帧
// 检测串口数据帧的函数
void detect_serial_data(uint8_t *data, size_t length) {
// 检查数据长度是否至少为7(帧头+距离+手势+帧尾)
if (length < 7) {
return;
}
// 遍历数据缓冲区,查找数据帧AA AA 01 00 00 55 55
for (size_t i = 0; i <= length - 7; ++i) {
// 检查帧头帧尾
if (data[i] == 0xAA && data[i + 1] == 0xAA && data[i + 5] == 0x55 && data[i + 6] == 0x55) {
// 检查目标
uint8_t goals = data[i + 2];
if (goals == 0x00) {
ESP_LOGI("test", "No goals\n");
gpio_set_level(LED_PIN, 0);//将led引脚配置为低电平
} else if (goals == 0x01) {
ESP_LOGI("test", "Moving goals\n");
gpio_set_level(LED_PIN, 1);//将led引脚配置为高电平
} else if (goals == 0x02) {
ESP_LOGI("test", "Micro Moving goals\n");
}
// 检查距离(小端模式)
uint16_t distance = (data[i + 3] | (data[i + 4] << 8));
ESP_LOGI("test", "distance:%dcm\n", distance);
i = i + 6;
}
}
这段代码定义了一个名为 detect_serial_data
的函数,它用于检测串口数据帧是否满足特定的格式,并根据数据帧中的信息执行相应的操作。以下是对代码段的详细解释:
- 函数定义:
void detect_serial_data(uint8_t *data, size_t length)
该函数接受两个参数:一个指向 uint8_t
类型的指针 data
(表示串口接收到的数据),以及一个 size_t
类型的变量 length
(表示数据的长度)。
2. 数据长度检查:
if (length < 7) {
return;
}
如果接收到的数据长度小于7,则函数直接返回,因为这样的数据长度不足以构成一个完整的数据帧。
3. 遍历数据缓冲区:
for (size_t i = 0; i <= length - 7; ++i) {
这里使用一个 for
循环来遍历数据缓冲区,寻找特定的数据帧。循环的结束条件是 i
达到 length - 7
,以确保在尝试访问 data[i + 6]
时不会超出数据缓冲区的范围。
4. 检查帧头和帧尾:
if (data[i] == 0xAA && data[i + 1] == 0xAA && data[i + 5] == 0x55 && data[i + 6] == 0x55) {
该条件检查当前位置和接下来的位置是否匹配预期的帧头和帧尾值(0xAA 0xAA
作为帧头,0x55 0x55
作为帧尾)。
5. 检查目标(goals):
uint8_t goals = data[i + 2];
if (goals == 0x00) {
// ...
} else if (goals == 0x01) {
// ...
} else if (goals == 0x02) {
// ...
}
从数据帧的第3个字节读取 goals
的值,并根据其值输出不同的日志信息,并设置LED引脚的状态。
6. 检查距离:
uint16_t distance = (data[i + 3] | (data[i + 4] << 8));
ESP_LOGI("test", "distance:%dcm\n", distance);
从数据帧的第4和第5个字节读取距离值(假设为小端模式),并将其组合成一个16位的整数。然后,输出这个距离值。
7. 更新循环索引:
i = i + 6;
由于已经检查并处理了从 i
开始的7个字节,所以将 i
增加6,以便在下次循环迭代时跳过已经处理过的字节。
static void rx_task(void *arg)
{
static const char *RX_TASK_TAG = "RX_TASK";
esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE + 1);
while (1) {
const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 50 / portTICK_PERIOD_MS);
if (rxBytes > 0) {
detect_serial_data(data, rxBytes);
}
}
free(data);
}
void app_main(void)
{
init();
xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL);
// xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 2, NULL);
}
上面这个代码是新建一个rtos任务来将串口数据传到解析函数处理
烧录进去看一下效果
[0;32mI (3125) test: distance:0cm
[0m
[0;32mI (3175) test: No goals
[0m
[0;32mI (3175) test: distance:0cm
[0m
[0;32mI (3225) test: No goals
[0m
[0;32mI (3225) test: distance:0cm
[0m
[0;32mI (3275) test: No goals
[0m
[0;32mI (3275) test: distance:0cm
[0m
[0;32mI (3325) test: Moving goals
[0m
[0;32mI (3325) test: distance:54cm
[0m
[0;32mI (3375) test: Moving goals
[0m
[0;32mI (3375) test: distance:71cm
[0m
[0;32mI (3425) test: Micro Moving goals
[0m
[0;32mI (3425) test: distance:63cm
[0m
[0;32mI (3475) test: Micro Moving goals
串口打印的数据能正常检测到
上灯试试、目前还有点简陋,主要没有外壳、以后看看搞个外壳做个板子
<iframe src="https://player.bilibili.com/player.html?aid=1552106617&bvid=BV1k1421Q7nz&cid=1482036488&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>