差气压计的蓝牙协议

This commit is contained in:
lmx
2025-11-21 17:10:36 +08:00
parent 591e7632d2
commit 91b08dbe47
9 changed files with 146 additions and 49 deletions

View File

@ -3,8 +3,7 @@
*/ */
#include "skiing_tracker.h" #include "skiing_tracker.h"
#include "../sensor/SC7U22.h" #include "../sensor/SC7U22.h"
#include <math.h>
#include <string.h>
#define G_ACCELERATION 9.81f #define G_ACCELERATION 9.81f
#define DEG_TO_RAD (3.14159265f / 180.0f) #define DEG_TO_RAD (3.14159265f / 180.0f)

View File

@ -2,6 +2,10 @@
#define SKIING_TRACKER_H #define SKIING_TRACKER_H
#include "../xtell.h" #include "../xtell.h"
#include <math.h>
#include <string.h>
// 定义滑雪者可能的状态 // 定义滑雪者可能的状态
typedef enum { typedef enum {
STATIC, // 静止或动态稳定0 STATIC, // 静止或动态稳定0
@ -52,16 +56,7 @@ typedef struct {
float acc_world_lpf[3]; // 经过低通滤波后的世界坐标系加速度 float acc_world_lpf[3]; // 经过低通滤波后的世界坐标系加速度
} skiing_tracker_t; } skiing_tracker_t;
//ble发送的数据
typedef struct{ //__attribute__((packed)){ //该结构体取消内存对齐
char sensor_state;
char skiing_state;
int speed_cms; //求出的速度cm/s
int distance_cm; //求出的距离cm
short acc_data[3]; //三轴加速度, g
short gyr_data[3]; //三轴陀螺仪, dps
float angle_data[3]; //欧若拉角
}BLE_send_data_t;
typedef struct{ typedef struct{
int acc_KS[3]; //卡尔曼后LSB转换后的 三轴加速度数据cm/s^2 int acc_KS[3]; //卡尔曼后LSB转换后的 三轴加速度数据cm/s^2

View File

@ -56,8 +56,7 @@ extern void close_process(u16* pid,char* name);
typedef struct { typedef struct {
// -- 六轴 -- // -- 六轴 --
signed short acc_data[3]; signed short SC7U22_data[6];
signed short gyr_data[3];
// -- 磁力计 -- // -- 磁力计 --
uint8_t mmc5603nj_buffer[9]; uint8_t mmc5603nj_buffer[9];
// -- 速度 -- // -- 速度 --
@ -88,7 +87,11 @@ void SC7U22_static_calibration(void){
static signed short combined_raw_data[6]; static signed short combined_raw_data[6];
static int calibration_done = 0; static int calibration_done = 0;
char status = 0; char status = 0;
set_SC7U22_Error_Flag(0); static first_set_flag = 0;
if(first_set_flag == 0){
first_set_flag = 1;
set_SC7U22_Error_Flag(0);
}
SL_SC7U22_RawData_Read(acc_data_buf,gyr_data_buf); SL_SC7U22_RawData_Read(acc_data_buf,gyr_data_buf);
memcpy(&combined_raw_data[0], acc_data_buf, 3 * sizeof(signed short)); memcpy(&combined_raw_data[0], acc_data_buf, 3 * sizeof(signed short));
memcpy(&combined_raw_data[3], gyr_data_buf, 3 * sizeof(signed short)); memcpy(&combined_raw_data[3], gyr_data_buf, 3 * sizeof(signed short));
@ -97,20 +100,21 @@ void SC7U22_static_calibration(void){
if(status == 1){ //校准完成 if(status == 1){ //校准完成
extern u16 SC7U22_calibration_id; extern u16 SC7U22_calibration_id;
extern u8 SC7U22_init; extern u8 SC7U22_init;
first_set_flag = 0;
SC7U22_init = 1; SC7U22_init = 1;
close_process(&SC7U22_calibration_id, "SC7U22_calibration"); close_process(&SC7U22_calibration_id, "SC7U22_calibration");
u8 send2_1[5] = {0xBB,0xBE,0x02,0x00,0x01}; u8 send2_1[5] = {0xBB,0xBE,0x02,0x00,0x01};
send_data_to_ble_client(&send2_1,strlen(send2_1)); send_data_to_ble_client(&send2_1,5);
} }
// if(count > 100){ if(count > 100){
// count = 0; count = 0;
// char log_buffer[100]; char log_buffer[100];
// // snprintf( log_buffer, sizeof(log_buffer),"status:%d\n",status); // snprintf( log_buffer, sizeof(log_buffer),"status:%d\n",status);
// // send_data_to_ble_client(&log_buffer,strlen(log_buffer)); // send_data_to_ble_client(&log_buffer,strlen(log_buffer));
// xlog("status:%d\n", status); xlog("status:%d\n", status);
// xlog("RawData:AX=%d,AY=%d,AZ=%d,GX=%d,GY=%d,GZ=%d\r\n",combined_raw_data[0],combined_raw_data[1],combined_raw_data[2],combined_raw_data[3],combined_raw_data[4],combined_raw_data[5]); xlog("RawData:AX=%d,AY=%d,AZ=%d,GX=%d,GY=%d,GZ=%d\r\n",combined_raw_data[0],combined_raw_data[1],combined_raw_data[2],combined_raw_data[3],combined_raw_data[4],combined_raw_data[5]);
// } }
// count++; count++;
} }
/** /**
@ -143,8 +147,8 @@ void start_collect_fuc(void){
uint16_t speed = sensor_processing_task(acc_data_buf,gyr_data_buf,angle, quaternion_output); uint16_t speed = sensor_processing_task(acc_data_buf,gyr_data_buf,angle, quaternion_output);
// -- 数据包装进结构体 -- // -- 数据包装进结构体 --
memcpy(BLE_send_data_tmp.acc_data, acc_data_buf, 3 * sizeof(signed short)); memcpy(&BLE_send_data_tmp.SC7U22_data[0], acc_data_buf, 3 * sizeof(signed short));
memcpy(BLE_send_data_tmp.gyr_data, gyr_data_buf, 3 * sizeof(signed short)); memcpy(&BLE_send_data_tmp.SC7U22_data[3], gyr_data_buf, 3 * sizeof(signed short));
memcpy(BLE_send_data_tmp.mmc5603nj_buffer, mmc5603nj_buffer, 9); memcpy(BLE_send_data_tmp.mmc5603nj_buffer, mmc5603nj_buffer, 9);
BLE_send_data_tmp.speed_cms = speed; BLE_send_data_tmp.speed_cms = speed;
@ -157,17 +161,83 @@ void start_collect_fuc(void){
} }
/** /**
* @brief ble数据发送 * @brief ble数据发送函数
* *
*/ */
void BLE_send_fuc(void){ void BLE_send_fuc(void){
BLE_send_data_t BLE_send_data_tmp; BLE_send_data_t data_to_send;
if(circle_buffer_is_empty(&BLE_send_buff) == 0){
circle_buffer_read(&BLE_send_buff, &BLE_send_data_tmp); if (circle_buffer_is_empty(&BLE_send_buff) == 0) {
circle_buffer_read(&BLE_send_buff, &data_to_send);
} else {
// 缓冲区为空,直接返回
return;
}
// --- 封装并发送六轴传感器数据 ---
{
// 协议定义: 包头(2) + 长度(1) + 类型(1) + 数据(12) = 16字节
const uint8_t IMU_PACKET_LEN = 16;
const uint8_t IMU_PAYLOAD_LEN = 13; // 类型(1) + 数据(12)
const uint8_t IMU_TYPE = 0x01;
uint8_t imu_packet[IMU_PACKET_LEN];
// 填充包头
imu_packet[0] = 0xBB;
imu_packet[1] = 0xBE;
imu_packet[2] = IMU_PAYLOAD_LEN;
imu_packet[3] = IMU_TYPE;
// 拷贝六轴数据
memcpy(&imu_packet[4], data_to_send.SC7U22_data, sizeof(data_to_send.SC7U22_data));
send_data_to_ble_client(&imu_packet, IMU_PACKET_LEN);
} }
// --- 封装并发送磁力计数据 ---
{
// 协议定义: 包头(2) + 长度(1) + 类型(1) + 数据(9) = 13字节
const uint8_t MAG_PACKET_LEN = 13;
const uint8_t MAG_PAYLOAD_LEN = 10; // 类型(1) + 数据(9)
const uint8_t MAG_TYPE = 0x02;
uint8_t mag_packet[MAG_PACKET_LEN];
// 填充包头
mag_packet[0] = 0xBB;
mag_packet[1] = 0xBE;
mag_packet[2] = MAG_PAYLOAD_LEN;
mag_packet[3] = MAG_TYPE;
// 拷贝磁力计数据
memcpy(&mag_packet[4], data_to_send.mmc5603nj_buffer, sizeof(data_to_send.mmc5603nj_buffer));
// 调用实际的蓝牙发送函数
send_data_to_ble_client(&mag_packet, MAG_PACKET_LEN);
}
// --- 封装并发送速度数据 ---
{
// 协议定义: 包头(2) + 长度(1) + 类型(1) + 数据(2) = 6字节
const uint8_t SPEED_PACKET_LEN = 6;
const uint8_t SPEED_PAYLOAD_LEN = 3; // 类型(1) + 数据(2)
const uint8_t SPEED_TYPE = 0x04;
uint8_t speed_packet[SPEED_PACKET_LEN];
// 填充包头
speed_packet[0] = 0xBB;
speed_packet[1] = 0xBE;
// 填充长度
speed_packet[2] = SPEED_PAYLOAD_LEN;
// 填充类型
speed_packet[3] = SPEED_TYPE;
// 小端模式
speed_packet[4] = (uint8_t)(data_to_send.speed_cms & 0xFF); // 低字节
speed_packet[5] = (uint8_t)((data_to_send.speed_cms >> 8) & 0xFF); // 高字节
send_data_to_ble_client(&speed_packet, SPEED_PACKET_LEN);
}
} }

View File

@ -175,4 +175,23 @@ uint8_t bmp280_read_data(float *temperature, float *pressure) {
*pressure = compensate_pressure(adc_P); *pressure = compensate_pressure(adc_P);
return 0; // 成功 return 0; // 成功
}
/**
* @brief 获取该气压计的原始adc数据
*
* @param adc_P 传出,气压
* @param adc_T 传出,温度
*/
void bmp280_read_originanl_data(int* adc_P, int* adc_T){
uint8_t data[6];
// 一次性读取6个字节的温度和气压原始数据
if (bmp280_read_regs(BMP280_REG_PRESS_MSB, data, 6) != 0) {
return; // 读取失败
}
// 组合原始数据 (20位)
adc_P = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | (((uint32_t)(data[2])) >> 4));
adc_T = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | (((uint32_t)(data[5])) >> 4));
} }

View File

@ -8,11 +8,11 @@
// I2C 从设备地址 // I2C 从设备地址
#if BMP_PULL_UP == 1 //外部接的高 #if BMP_PULL_UP == 1 //外部接的高
#define BMP_IIC_7BIT_ADDRESS 0x77 //7位,外部接高为0x77 #define BMP_IIC_7BIT_ADDRESS 0x76 //7位,外部接高为0x77
#define BMP_IIC_WRITE_ADDRESS (BMP_IIC_7BIT_ADDRESS<<1) //8位地址 #define BMP_IIC_WRITE_ADDRESS (BMP_IIC_7BIT_ADDRESS<<1) //8位地址
#define BMP_IIC_READ_ADDRESS (BMP_IIC_WRITE_ADDRESS | 0x01) #define BMP_IIC_READ_ADDRESS (BMP_IIC_WRITE_ADDRESS | 0x01)
#else #else
#define BMP_IIC_7BIT_ADDRESS 0x76 //7位,外部接低为0x76 #define BMP_IIC_7BIT_ADDRESS 0x77 //7位,外部接低为0x76
#define BMP_IIC_WRITE_ADDRESS (BMP_IIC_7BIT_ADDRESS<<1) //8位地址 #define BMP_IIC_WRITE_ADDRESS (BMP_IIC_7BIT_ADDRESS<<1) //8位地址
#define BMP_IIC_READ_ADDRESS (BMP_IIC_WRITE_ADDRESS | 0x01) #define BMP_IIC_READ_ADDRESS (BMP_IIC_WRITE_ADDRESS | 0x01)
#endif #endif
@ -43,4 +43,12 @@ uint8_t bmp280_init(void);
*/ */
uint8_t bmp280_read_data(float *temperature, float *pressure); uint8_t bmp280_read_data(float *temperature, float *pressure);
/**
* @brief 获取该气压计的原始adc数据
*
* @param adc_P 传出,气压
* @param adc_T 传出,温度
*/
void bmp280_read_originanl_data(int* adc_P, int* adc_T);
#endif // BMP280_DRIVER_H #endif // BMP280_DRIVER_H

View File

@ -32,7 +32,7 @@ int mmc5603nj_init(void) {
// ID // ID
if ( mmc5603nj_get_pid() != 0x10) { if ( mmc5603nj_get_pid() != 0x10) {
printf("MMC5603NJ init failed: wrong Product ID (read: 0x%X)\n", mmc5603nj_get_pid()); printf("MMC5603NJ init failed: wrong Product ID (read: 0x%X)\n", mmc5603nj_get_pid());
return 0; // return 0;
} }
// 软件复位 // 软件复位

View File

@ -25,7 +25,7 @@ Copyright (c) 2022 Silan MEMS. All Rights Reserved.
/***使用前请根据实际IIC地址配置参数***/ /***使用前请根据实际IIC地址配置参数***/
/**SC7U22的IIC 接口地址为 7bits: 0****/ /**SC7U22的IIC 接口地址为 7bits: 0****/
/**SC7U22的IIC 接口地址为 8bits: 1****/ /**SC7U22的IIC 接口地址为 8bits: 1****/
#define SL_SC7U22_IIC_7BITS_8BITS 0 #define SL_SC7U22_IIC_7BITS_8BITS 1
/*****************************************/ /*****************************************/
#if SL_SC7U22_SDO_VDD_GND==0 #if SL_SC7U22_SDO_VDD_GND==0
#define SL_SC7U22_IIC_7BITS_ADDR 0x18 #define SL_SC7U22_IIC_7BITS_ADDR 0x18

View File

@ -1,5 +1,6 @@
#ifndef XTELL_H #ifndef XTELL_H
#define XTELL_H #define XTELL_H
#include "system/includes.h"
// #define KS_BLE 1 // #define KS_BLE 1
#define XTELL_TEST 1 #define XTELL_TEST 1

View File

@ -101,6 +101,7 @@ extern void SC7U22_static_calibration(void);
extern void create_process(u16* pid, const char* name, void *priv, void (*func)(void *priv), u32 msec); extern void create_process(u16* pid, const char* name, void *priv, void (*func)(void *priv), u32 msec);
extern void close_process(u16* pid,char* name); extern void close_process(u16* pid,char* name);
extern void start_collect_fuc(void); extern void start_collect_fuc(void);
extern void BLE_send_fuc(void);
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
/* /*
* 模式状态机, 通过start_app()控制状态切换 * 模式状态机, 通过start_app()控制状态切换
@ -225,51 +226,55 @@ void le_user_app_event_handler(struct sys_event* event){
if (SL_SC7U22_Config() == 0) { if (SL_SC7U22_Config() == 0) {
send2_0[4] = 0x00; //初始化失败 send2_0[4] = 0x00; //初始化失败
SC7U22_init = 0; SC7U22_init = 0;
send_data_to_ble_client(&send2_0,strlen(send2_0)); send_data_to_ble_client(&send2_0,5);
break; return;
} }
create_process(&SC7U22_calibration_id,"SC7U22_calibration",NULL,SC7U22_static_calibration,10); create_process(&SC7U22_calibration_id,"SC7U22_calibration",NULL,SC7U22_static_calibration,10);
}else if(event->u.app.buffer[4] == 0x02){ //地磁 }else if(event->u.app.buffer[4] == 0x02){ //地磁
if(mmc5603nj_init() == 0){ if(mmc5603nj_init() == 0){
MMC5603nj_init = 0; MMC5603nj_init = 0;
break; send2_0[4] = 0x02; //地磁初始化失败
send_data_to_ble_client(&send2_0,5);
return;
} }
MMC5603nj_init = 1; MMC5603nj_init = 1;
send2_0[4] = 0x03; //地磁初始化失败 send2_0[4] = 0x03; //地磁初始化成功
send_data_to_ble_client(&send2_0,strlen(send2_0)); send_data_to_ble_client(&send2_0,5);
} }
break; break;
case 0x01: //数据包类型为:获取指定传感器初始化状态 case 0x01: //数据包类型为:获取指定传感器初始化状态
u8 send2_1[5] = {0xBB,0xBE,0x02,0x01,0x00}; u8 send2_1[5] = {0xBB,0xBE,0x02,0x00,0x00};
if(event->u.app.buffer[4] == 0x01){ //六轴 if(event->u.app.buffer[4] == 0x01){ //六轴
send2_1[4] = SC7U22_init; send2_1[4] = SC7U22_init;
}else if(event->u.app.buffer[4] == 0x02){ //地磁 }else if(event->u.app.buffer[4] == 0x02){ //地磁
send2_1[4] = MMC5603nj_init + 2; send2_1[4] = MMC5603nj_init + 2;
} }
send_data_to_ble_client(&send2_1,strlen(send2_1)); send_data_to_ble_client(&send2_1,5);
break; break;
case 0x02: //开始/停止滑雪计算 case 0x02: //开始/停止滑雪计算
if(event->u.app.buffer[4] == 0x01){ //开始滑雪计算 if(event->u.app.buffer[4] == 0x01){ //开始滑雪计算
if(SC7U22_init == 0 || MMC5603nj_init == 0){ //传感器未进行初始化 if(SC7U22_init == 0 || MMC5603nj_init == 0){ //传感器未进行初始化
u8 send2_2[5] = {0xBB,0xBE,0x02,0x01,0x00}; u8 send2_2[5] = {0xBB,0xBE,0x02,0x00,0x00};
send_data_to_ble_client(&send2_2,strlen(send2_2)); send_data_to_ble_client(&send2_2,5);
send2_2[4] = 0x02; send2_2[4] = 0x02;
send_data_to_ble_client(&send2_2,strlen(send2_2)); send_data_to_ble_client(&send2_2,5);
return; return;
} }
create_process(&start_collect_fuc_id,"start_collect",NULL,start_collect_fuc,10); create_process(&start_collect_fuc_id,"start_collect",NULL,start_collect_fuc,10);
create_process(&BLE_send_fuc_id,"BLE_send_fuc",NULL,BLE_send_fuc,1);
}else if(event->u.app.buffer[4] == 0x02){ //停止滑雪计算 }else if(event->u.app.buffer[4] == 0x02){ //停止滑雪计算
close_process(&start_collect_fuc_id,"start_collect"); close_process(&start_collect_fuc_id,"start_collect");
close_process(&BLE_send_fuc_id,"BLE_send_fuc");
} }
break; break;
} }
} }
} }
break; break;
default: default:
xlog("%d\n",event->type); xlog("%d\n",event->type);
break; break;
} }