ESP-IDF环境下LIS2DW12加速度计转换值偏差10倍问题排查
LIS2DW12加速度计转换值比预期小10倍的排查
我正从Arduino IDE切换到ESP-IDF环境,测试LIS2DW12加速度计。硬件编程相关问题已解决,但转换得到的加速度值比预期小10倍:预期重力加速度约9.81m/s²,实际得到0.98m/s²。该传感器数据为14位值,存储在两个8位寄存器中,我已将量程设为16g,分辨率为13bit(对应8191)。
代码实现
#include <stdio.h> #include "esp_log.h" #include "driver/i2c.h" #include "Arduino.h" #include "string.h" static const char *TAG = "LIS2DW12: "; #define I2C_MASTER_SCL_IO 22 /*!< GPIO number used for I2C master clock */ #define I2C_MASTER_SDA_IO 21 /*!< GPIO number used for I2C master data */ #define I2C_MASTER_NUM 1 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ #define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ #define I2C_MASTER_TIMEOUT_MS 1000 // Sensor Reg #define SENSOR_ADDR 0x19 /*!< Slave address of the MPU9250 sensor */ #define WHO_AM_I_REG_ADDR 0x0F /*!< Register addresses of the "who am I" register */ #define Temp_L 0x0D #define Temp_H 0x0E #define WhoAmI 0x0F #define CTRL1 0x20 #define CTRL2 0x21 #define CTRL3 0x22 #define CTRL4 0x23 #define CTRL5 0x24 #define CTRL6 0x25 #define X_LSB 0x28 #define X_MSB 0x29 #define Y_LSB 0x2A #define Y_MSB 0x2B #define Z_LSB 0x2C #define Z_MSB 0x2D uint16_t X_raw, Y_raw, Z_raw; float X, Y, Z; int ix,iy,iz; void Sensor_data_test(){ byte buf[2]; // read register register_read(Z_LSB, buf, 2); Z_raw = buf[1]<<8 | buf[0]; // buf = MSB <<8 | LSB; // print buffer Serial.println("Sensor Data:"); Serial.print("buf0: ");Serial.print(buf[0]); Serial.println(); Serial.print("buf1: ");Serial.print(buf[1]); Serial.println(); Serial.print("Z uint16_t : ");Serial.print(Z_raw); Serial.println(); // calculate binary and print uint16_t Zh = Z_raw; String hz; while(Zh!=0) { hz=(Zh%2==0 ?"0":"1")+hz; Zh/=2; } Serial.print("Z bin : ");Serial.println(hz); //calculate 2'er complement int k = 0; if(Z_raw & (((uint16_t)0x1) << 15)) //check if binary is negativ { //if negativ, do Z_raw = ~Z_raw; //invert bits Z_raw = Z_raw + 1; //add one bit Z_raw = Z_raw >> 2; //shift 2 spaces to the rigt (caused by Sensor register) k = Z_raw * -1; //save as Integer an reverse sign } else{ //if positiv, do Z_raw = Z_raw >> 2; //shift to spaces to the rigt (caused by Sensor register) k = Z_raw; //save as Integer } if (k){ Serial.print("Z int: ");Serial.print(k); Serial.println(); } //acceleration value ============================================ Z= (float)k *16/8191; // factor 10 needed? Serial.print("Z accel: ");Serial.print(Z); Serial.println(); } void Set_Sensor_Config(){ register_write_byte(CTRL1,0x55); register_write_byte(CTRL2,0x04); register_write_byte(CTRL3,0x00); register_write_byte(CTRL4,0x00); register_write_byte(CTRL5,0x00); register_write_byte(CTRL6,0x34); } void Show_Sensor_Config(){ uint8_t buf[1]; ESP_LOGI(TAG, "LIS12DW Config: "); register_read(CTRL1, buf, 1); ESP_LOGI(TAG, "CTRL1 = %X", buf[0]); register_read(CTRL2, buf, 1); ESP_LOGI(TAG, "CTRL2 = %X", buf[0]); register_read(CTRL3, buf, 1); ESP_LOGI(TAG, "CTRL3 = %X", buf[0]); register_read(CTRL4, buf, 1); ESP_LOGI(TAG, "CTRL4 = %X", buf[0]); register_read(CTRL5, buf, 1); ESP_LOGI(TAG, "CTRL5 = %X", buf[0]); register_read(CTRL6, buf, 1); ESP_LOGI(TAG, "CTRL6 = %X", buf[0]); } extern "C" void app_main() { Serial.begin(115200); ESP_ERROR_CHECK(i2c_master_init()); ESP_LOGI(TAG, "I2C initialized successfully"); Set_Sensor_Config(); Show_Sensor_Config(); Sensor_data_test(); ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM)); ESP_LOGI(TAG, "I2C de-initialized successfully"); }
输出结果
I (336) LIS2DW12: : LIS12DW Config: I (336) LIS2DW12: : CTRL1 = 55 I (337) LIS2DW12: : CTRL2 = 4 I (341) LIS2DW12: : CTRL3 = 0 I (344) LIS2DW12: : CTRL4 = 0 I (348) LIS2DW12: : CTRL5 = 0 I (351) LIS2DW12: : CTRL6 = 34 Sensor Data: buf0: 40 buf1: 248 Z uint16_t : 63528 Z bin : 1111100000101000 Z int: -502 Z accel: -0.98 I (367) LIS2DW12: : I2C de-initialized successfully
疑问:我编写了读取Z轴加速度寄存器并将补码数据转换为[m/s²]值的函数,但结果始终比预期小10倍,请问问题出在哪里?
问题分析与解决
问题出在单位转换环节,你当前的计算仅得到了以g为单位的加速度值,未完成到m/s²的转换。
具体原因:
- 计算式
Z= (float)k *16/8191的结果是以g为单位的加速度,比如输出的-0.98实际是-0.98g。 - 1g对应约
9.81m/s²,因此需要将结果乘以9.81才能得到正确的m/s²单位值。
修正后的计算式:
Z= (float)k *16/8191 *9.81;
验证:
用测试数据计算:-502 *16/8191 ≈ -0.98g,乘以9.81后得到-0.98*9.81≈-9.61m/s²,与预期重力加速度值一致。
额外提示:
你代码注释中提到的“factor 10 needed?”,这个10是g到m/s²的近似转换(9.81≈10),用10会得到接近真实值的结果但存在小误差,建议使用精确的9.81或传感器手册推荐的转换系数。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

