[英]How to read data from MPU6050 using STM32F4
I need to monitorate the acelleration of a object.我需要监控 object 的加速。 I'm using the MPU6050(accelerometer and gyroscope) and the controller STM32F401RBT6.
我正在使用 MPU6050(加速度计和陀螺仪)和 controller STM32F401RBT6。 The code below is the solution that i'm using for this.
下面的代码是我为此使用的解决方案。
#define MPU6050_ADDR 0xD0
#define SMPLRT_DIV_REG 0x19
#define GYRO_CONFIG_REG 0x1B
#define ACCEL_CONFIG_REG 0x1C
#define ACCEL_XOUT_H_REG 0x3B
#define TEMP_OUT_H_REG 0x41
#define GYRO_XOUT_H_REG 0x43
#define PWR_MGMT_1_REG 0x6B
#define WHO_AM_I_REG 0X75
uint16_t Accel_X_RAW,Accel_Y_RAW,Accel_Z_RAW;
uint16_t Ax,Ay,Az;
char buffer[10];
void MPU6050_Init(void)
{
uint8_t check, data;
HAL_I2C_Mem_Read(&hi2c3,MPU6050_ADDR,WHO_AM_I_REG,1,&check,1,100);
if(check == 104)
{
data = 0x07;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,SMPLRT_DIV_REG,1,&data,1,50);
HAL_Delay(50);
data = 0x00;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,ACCEL_CONFIG_REG,1,&data,1,50);
HAL_Delay(50);
data = 0x00;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,GYRO_CONFIG_REG,1,&data,1,50);
HAL_Delay(50);
data = 0;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,PWR_MGMT_1_REG,1,&data,1,50);
HAL_Delay(50);
}
}
void MPU6050_Read_Accel(void)
{
uint8_t recData[6];
for(int i=0;i<6;i++) recData[i] = 0;
HAL_I2C_Mem_Read(&hi2c3,MPU6050_ADDR,ACCEL_XOUT_H_REG,I2C_MEMADD_SIZE_8BIT,recData,6,100);
HAL_Delay(50);
uint16_t dataConvert1,dataConvert2;
dataConvert1 = (uint16_t)(0x0000 | recData[0]) << 8;
dataConvert2 = (uint16_t)(0x0000 | recData[1]);
Accel_X_RAW = dataConvert1 | dataConvert2;
dataConvert1 = (uint16_t)(0x0000 | recData[2]) << 8;
dataConvert2 = (uint16_t)(0x0000 | recData[3]);
Accel_Y_RAW = dataConvert1 | dataConvert2;
dataConvert1 = (uint16_t)(0x0000 | recData[4]) << 8;
dataConvert2 = (uint16_t)(0x0000 | recData[5]);
Accel_Z_RAW = dataConvert1 | dataConvert2;
Ax = (uint16_t)(Accel_X_RAW / 16384);
Ay = (uint16_t)(Accel_Y_RAW / 16384);
Az = (uint16_t)(Accel_Z_RAW / 16384);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C3_Init();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MPU6050_Init();
while (1)
{
MPU6050_Read_Accel();
sprintf(buffer, "%d / ", Accel_X_RAW);
CDC_Transmit_FS((char*)buffer,10);
}
}
I already did it on ATMEL Controler (Arduino) and it worked, but not on STM32.我已经在 ATMEL Controler (Arduino) 上完成了它并且它有效,但不是在 STM32 上。 I am trying to read the value of X Axis and show it using the USB CDC.
我正在尝试读取 X Axis 的值并使用 USB CDC 显示它。 This code sets a value for the `` `Accel_X_RAW```` variable between 0 and 65535. In Arduino, the reference value was 32768 when the object was stopped, but reading with STM32 remains at the maximum value (65535) if don't have movement.
此代码为 ``Accel_X_RAW``` 变量设置一个介于 0 和 65535 之间的值。在 Arduino 中,当 object 停止时,参考值为 32768,但如果不使用 STM32 读取,则保持最大值(65535)没有运动。 I don't know what's wrong with this code, I tried many options, but it still doesn't work.
我不知道这段代码有什么问题,我尝试了很多选项,但它仍然不起作用。 Can you help me please.
你能帮我吗。
According to the MPU6050 datasheet, the 16-bit values for acceleration and gyroscope are returned in the signed 2's complement form (it detects acceleration values in the range +-g).根据 MPU6050 数据表,加速度和陀螺仪的 16 位值以有符号 2 的补码形式返回(它检测 +-g 范围内的加速度值)。 As you are receiving signed data in the unsigned variables, the result is not what you expect.
当您在无符号变量中接收签名数据时,结果不是您所期望的。 Therefore, replace all uint16_t datatypes with int16_t.
因此,将所有 uint16_t 数据类型替换为 int16_t。
The reason why you are getting 65535 value;您获得 65535 值的原因; the hex value of -1 in signed int16_t form is 0xFFFF.
有符号 int16_t 形式的 -1 的十六进制值为 0xFFFF。 However, if you store it in the uint16_t variable, it will be read as 65535. I am assuming that the default acceleration value at rest is -1g.
但是,如果将其存储在 uint16_t 变量中,它将被读取为 65535。我假设 rest 处的默认加速度值为 -1g。
#include <stdlib.h> /* For using memset */
#define MPU6050_ADDR 0xD0
#define SMPLRT_DIV_REG 0x19
#define GYRO_CONFIG_REG 0x1B
#define ACCEL_CONFIG_REG 0x1C
#define ACCEL_XOUT_H_REG 0x3B
#define TEMP_OUT_H_REG 0x41
#define GYRO_XOUT_H_REG 0x43
#define PWR_MGMT_1_REG 0x6B
#define WHO_AM_I_REG 0X75
int16_t Accel_X_RAW,Accel_Y_RAW,Accel_Z_RAW;
int16_t Ax,Ay,Az;
char buffer[10];
void MPU6050_Init(void)
{
uint8_t check, data;
HAL_I2C_Mem_Read(&hi2c3,MPU6050_ADDR,WHO_AM_I_REG,1,&check,1,100);
if(check == 104)
{
data = 0x07;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,SMPLRT_DIV_REG,1,&data,1,50);
HAL_Delay(50);
data = 0x00;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,ACCEL_CONFIG_REG,1,&data,1,50);
HAL_Delay(50);
data = 0x00;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,GYRO_CONFIG_REG,1,&data,1,50);
HAL_Delay(50);
data = 0;
HAL_I2C_Mem_Write(&hi2c3,MPU6050_ADDR,PWR_MGMT_1_REG,1,&data,1,50);
HAL_Delay(50);
}
}
void MPU6050_Read_Accel(void)
{
uint8_t recData[6];
//for(int i=0;i<6;i++) recData[i] = 0;
memset(recData, 0, sizeof(recData));
HAL_I2C_Mem_Read(&hi2c3,MPU6050_ADDR,ACCEL_XOUT_H_REG,I2C_MEMADD_SIZE_8BIT,recData,6,100);
HAL_Delay(50);
Accel_X_RAW = (int16_t)(recData[0] << 8 | recData[1]);
Accel_Y_RAW = (int16_t)(recData[2] << 8 | recData[3]);
Accel_Z_RAW = (int16_t)(recData[4] << 8 | recData[5]);
Ax = (int16_t)(Accel_X_RAW / 16384);
Ay = (int16_t)(Accel_Y_RAW / 16384);
Az = (int16_t)(Accel_Z_RAW / 16384);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C3_Init();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MPU6050_Init();
while (1)
{
MPU6050_Read_Accel();
sprintf(buffer, "%d / ", Accel_X_RAW);
CDC_Transmit_FS((char*)buffer,10);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.