Files
433_STM32/docs/协议refer.md

344 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 蓝牙协议
```
/********************小程序 发数据到 BL**************************************/
===========================================================
BE BB 02 00 XX
----- -- -- --
| | | |
| | | 指定传感器进行初始化01--六轴02--地磁03--气压计
| | 进行传感器的初始化/校准
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 01 XX
----- -- -- --
| | | |
| | | 01--左脚02--右脚
| | 设置传感器采集的是哪只脚
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 02 XX
----- -- -- --
| | | |
| | | 01表示读六轴状态02表示读地磁状态03表示读气压计状态
| | 读取传感器的状态
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 03 XX
----- -- -- --
| | | |
| | | 01--开始02--停止
| | 采集数据并计算开始与停止
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 04 01
----- -- -- --
| | | |
| | | 获取电量
| | 获取电量
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 05 XX
----- -- -- --
| | | |
| | | 01:100Hz02:200Hz03:400Hz
| | 设置传感器采集频率
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 06 XX
----- -- -- --
| | | |
| | | 00:禁用地磁01:使能地磁
| | 地磁使能指令
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 02 07 XX
----- -- -- --
| | | |
| | | 00:禁用气压计01:使能气压计
| | 气压计使能指令
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 01 09
----- -- --
| | |
| | 开启地磁测试进程
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 01 0A
----- -- --
| | |
| | 关闭地磁测试进程
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 01 0B
----- -- --
| | |
| | 获取固件版本
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 01 0C
----- -- --
| | |
| | 获取rfid/uid
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
BE BB 01 FF 扫描检测传感器
----- -- --
| | |
| | 扫描检测传感器
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示小程序发数据到蓝牙板子
===============================================================
/********************BL 发数据到小程序**************************************/
============================================================
BB BE 02 00 XX
----- -- -- --
| | | |
| | | 10六轴未初始化11六轴初始化成功20地磁未初始化21地磁初始化成功30气压计未初始化31气压计初始化成功
| | 返回传感器的初始化状态
| 表示后面的数据长度
包头BE表示小程序BB表示BL表示蓝牙板子发数据到小程序
### 地磁校准流程
地磁传感器需要校准,发送 BLE 命令后进行"画八字"校准,校准数据会保存到 VM 中,掉电后再次上电会自动加载。
**发送命令:**
```
BE BB 02 00 02 // 启动地磁校准
```
**BLE 反馈消息:**
| 消息 | 含义 | 说明 |
|------|------|------|
| BB BE 02 00 20 | 地磁初始化失败 | 传感器通信异常 |
| BB BE 02 00 21 | 地磁初始化成功 | 传感器正常,即将进入校准状态 |
| BB BE 02 00 22 | 提示开始校准 | 用户可以开始画八字 |
| BB BE 02 00 23 | 校准中 | 循环发送,正在采集数据 |
| BB BE 02 00 24 | 校准错误 | 数据范围不足,需重新画八字 |
| BB BE 02 00 25 | 校准完成 | 校准成功,数据已保存到 VM |
**校准成功后的行为:**
- 校准数据offset_x, offset_y, offset_z保存到 VMCFG_MAG_CALIBRATION
- 再次上电自动从 VM 加载校准数据,无需重复校准
BB BE XX 00 XX.......
----- -- -- --
| | | |
| | | 16组传感器数据。每一组30字节
| | 数据包下标0-255
| 左/右脚数据
包头BE表示小程序BB表示BL表示蓝牙板子发数据到小程序
```
# 蓝牙助手设置
连接后要先将蓝牙的MTU设置为最大一般最大是512左右
![image-20251205204926475](image-20251205204926475.png)
![image-20251205204943926](image-20251205204943926.png)
![image-20251205205027729](image-20251205205027729.png)
右边的调试助手可以查看传输速率。
# 数据采集
先后发送:初始化三个传感器
- BE BB 02 00 01
- 六轴初始化
- 返回BB BE 02 00 11表示初始化成功
- BE BB 02 00 02
- 地磁初始化等到返回BB BE 02 00 21表示初始化成功
- BE BB 02 00 03
- 气压计初始化等到返回BB BE 02 00 31表示初始化成功
设定数据来源:
- 发送BE BB 02 01 XX
- 01左脚
- 02右脚
- 返回数据BB BE 06 05 XX
- 41 -- 已设置为左脚42 -- 已设置为右脚
开始采集,传感器通过蓝牙发送数据
- 发送BE BB 02 03 01
- 如果返回BB BE 02 00 00说明有传感器没初始化成功可以发BE BB 02 02 XX 查看传感器初始化状态
一次完整的数据接收类似如下:
```c
BE BB XX XX 后面每30字节为一组传感器数据,一个16
一次蓝牙发送共计484字节
第一个xx:左右脚标志,41左脚,42右脚
第二个xx:数据包下标,0-255,每到255就会重置为0
```
停止采集:
- BE BB 02 03 02
# 获取电量
发送BE BB 02 04 01
- 返回的是百分比的电量值,如:
- 0x57
- 转为十进制为87当前还剩87%的电量
# 开启地磁测试进程
发送BE BB 01 09
- 返回地磁三轴 X Y Z数据每轴4字节的float类型。
- BB BE 0D 09 XX XX XX XX XX XX XX XX XX XX XX XX
# 获取固件版本
发送BE BB 01 0B
返回: BB BE 03 0B XX XX
最后两字节就是版本号
# 获取设备ID/RFID
发送BE BB 01 0C
返回: BB BE 05 0C XX XX XX XX
最后四字节位就是RFID小端模式
# 扫描检测传感器
发送BE BB 01 FF
返回: 0xBB, 0xBE, 0x07, 0xFF, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX
最后6字节位对应扫描到的6个传感器目前实际最多只有3个。
# 采集速率修改
设置为100Hz
- BE BB 02 05 01
设置200Hz
- BE BB 02 05 02
设置400Hz
- BE BB 02 05 03
# 数据解析
```c
//data蓝牙拿到的数据484字节长度
void data_log(uint8_t* data){
// 检查数据包头部
if (data[0] != 0xBE || data[1] != 0xBB) {
printf("Error: Invalid data packet header.\n");
return;
}
//左右脚
uint8_t package_foot = data[2];
// 解析包索引
uint8_t package_index = data[3];
printf("--- Parsing Data Packet Index: %d ---\n", package_index);
uint8_t* p = &data[4]; // 指向数据负载的起始位置
// 循环解析16组数据
for (int i = 0; i < MPU_FIFO_LEN; i++) {
// 1. 解析六轴传感器数据 (12 bytes)
int16_t imu_raw[6];
for (int j = 0; j < 6; j++) {
// 小端模式: 低字节在前, 高字节在后
imu_raw[j] = (int16_t)(((uint16_t)p[1] << 8) | (uint16_t)p[0]);
p += 2;
}
float acc_g[3];
float gyr_dps[3];
acc_g[0] = (float)imu_raw[0] / 2048.0f;
acc_g[1] = (float)imu_raw[1] / 2048.0f;
acc_g[2] = (float)imu_raw[2] / 2048.0f;
gyr_dps[0] = (float)imu_raw[3] * 0.061f;
gyr_dps[1] = (float)imu_raw[4] * 0.061f;
gyr_dps[2] = (float)imu_raw[5] * 0.061f;
// 2. 解析地磁传感器数据 (12 bytes)
int32_t mag_raw[3];
for (int j = 0; j < 3; j++) {
// 小端模式
mag_raw[j] = (int32_t)(((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[0]);
p += 4;
}
float mag_gauss[3];
mag_gauss[0] = (float)mag_raw[0] / 1000.0f;
mag_gauss[1] = (float)mag_raw[1] / 1000.0f;
mag_gauss[2] = (float)mag_raw[2] / 1000.0f;
// 3. 解析温度数据 (2 bytes)
int16_t temp_raw = (int16_t)(((uint16_t)p[1] << 8) | (uint16_t)p[0]);
p += 2;
float temperature = (float)temp_raw / 1000.0f;
// 4. 解析气压数据 (4 bytes)
uint32_t press_raw = (uint32_t)(((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[0]);
p += 4;
float pressure = (float)press_raw / 1000.0f;
// 打印解析后的数据
if(i % 8 == 0){
printf("Package[%d]:====================\n", i);
printf(" ACC(g): x=%.3f, y=%.3f, z=%.3f\n", acc_g[0], acc_g[1], acc_g[2]);
printf(" GYR(dps):x=%.3f, y=%.3f, z=%.3f\n", gyr_dps[0], gyr_dps[1], gyr_dps[2]);
printf(" MAG(Gs): x=%.3f, y=%.3f, z=%.3f\n", mag_gauss[0], mag_gauss[1], mag_gauss[2]);
printf(" TEMP(C): %.3f, PRESS(Pa): %.3f\n", temperature, pressure);
}
}
printf("--- End of Packet ---\n\n");
}
```