#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <U8g2lib.h>
#define SCL 16
#define SDA 17
#define DISP_OLED 1
#define DISP_CONSOLE 1
typedef struct{
// 温度
float temp;
// 加速度
float acce_x;
float acce_y;
float acce_z;
// 姿态
float gyro_x;
float gyro_y;
float gyro_z;
}MPU6050;
MPU6050 mpu6050;
SemaphoreHandle_t xMutexMPU6050 = NULL; // 同步锁
SemaphoreHandle_t xMutexIIC = NULL; // IIC设备同步
Adafruit_MPU6050 mpu; // 声明设备
// 陀螺仪任务
void mpu_task(void* param_t){
if (xSemaphoreTake(xMutexIIC, 1000) == pdPASS) {
mpu.setAccelerometerRange(MPU6050_RANGE_8_G); // 设置重力加速度的测量范围为±8G
mpu.setGyroRange(MPU6050_RANGE_500_DEG); // 设置陀螺仪的测量范围为±500度/秒
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); // 设置滤波器带宽
xSemaphoreGive(xMutexIIC); // 释放同步锁
}
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
for(;;){
// 循环读取更新陀螺仪数据
if (xSemaphoreTake(xMutexIIC, 1000) == pdPASS) {
mpu.getEvent(&accel, &gyro, &temp); // 获取数据
xSemaphoreGive(xMutexIIC); // 释放同步锁
}
if (xSemaphoreTake(xMutexMPU6050, 1000) == pdPASS) {
// printf("获得钥匙,赶紧更新数据...\n");
// 读出温度
mpu6050.temp = temp.temperature;
// 读出加速度
mpu6050.acce_x = accel.acceleration.x / 9.81; // 得到的是重力, / 9.81得到的是牛
mpu6050.acce_y = accel.acceleration.y / 9.81;
mpu6050.acce_z = accel.acceleration.z / 9.81;
// 读出姿态
mpu6050.gyro_x = gyro.gyro.x *180 / PI; // 得到的是弧度,转换为角度
mpu6050.gyro_y = gyro.gyro.y *180 / PI;
mpu6050.gyro_z = gyro.gyro.z *180 / PI;
xSemaphoreGive(xMutexMPU6050); // 释放同步锁
// printf("数据更新完毕,把钥匙还回去了!\n");
}else{
printf("没人没送回钥匙来,我不等了~~\n");
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
#if defined(DISP_CONSOLE) && DISP_CONSOLE == 1
// 打印输出线程
void print_task(void *param_t){
for(;;){
if (xSemaphoreTake(xMutexMPU6050, 1000) == pdPASS) {
printf("-----===== MPU6050 =====-----\n");
printf("Temp : %.2f°C\n",mpu6050.temp);
printf("Gyro-X : %.2f°\n",mpu6050.gyro_x);
printf("Gyro-Y : %.2f°\n",mpu6050.gyro_y);
printf("Gyro-Z : %.2f°\n",mpu6050.gyro_z);
printf("Acce-X : %.2f g\n",mpu6050.acce_x);
printf("Acce-Y : %.2f g\n",mpu6050.acce_y);
printf("Acce-Z : %.2f g\n",mpu6050.acce_z);
printf("==============================\n");
xSemaphoreGive(xMutexMPU6050);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
#endif
#if defined(DISP_OLED) && DISP_OLED == 1
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE);
// OLED显示线程
void led_task(void *param_t){
if (xSemaphoreTake(xMutexIIC, 1000) == pdPASS) {
u8g2.begin();
// u8g2.setFont(u8g2_font_ncenB08_tr); // 设置字体
u8g2.setFont(u8g2_font_7x14_mr);
xSemaphoreGive(xMutexIIC); // 释放同步锁
}
char buf[24]; // 打印缓冲区
for(;;){
u8g2.clearBuffer(); // 清理缓冲区
if (xSemaphoreTake(xMutexMPU6050, 1000) == pdPASS) {
sprintf(buf,"Temp : %.2f°C\n",mpu6050.temp);
u8g2.drawStr(0,10,buf);
sprintf(buf,"GX:%3.2f° AX:%3.2fg\n",mpu6050.gyro_x, mpu6050.acce_x);
u8g2.drawStr(0,25,buf);
sprintf(buf,"GY:%3.2f° AY:%3.2fg\n",mpu6050.gyro_y, mpu6050.acce_y);
u8g2.drawStr(0,40,buf);
sprintf(buf,"GZ:%3.2f° AZ:%3.2fg\n",mpu6050.gyro_z, mpu6050.acce_z);
u8g2.drawStr(0,55,buf);
xSemaphoreGive(xMutexMPU6050);
}
if (xSemaphoreTake(xMutexIIC, 1000) == pdPASS) {
u8g2.sendBuffer(); // 显示内容
xSemaphoreGive(xMutexIIC); // 释放同步锁
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
#endif
void setup() {
Serial.begin(115200);
xMutexMPU6050 = xSemaphoreCreateMutex(); // 创建数据同步锁
xMutexIIC = xSemaphoreCreateMutex(); // 创建IIC同步锁
Wire.begin(SDA, SCL); // 初始化I2C总线
if (mpu.begin()) { // 初始化陀螺仪
Serial.println("MPU6050 初始化成功");
xTaskCreatePinnedToCore(mpu_task, "MPU6050", 1024*4, NULL, 1, NULL, 1);
#if defined(DISP_CONSOLE) && DISP_CONSOLE == 1
xTaskCreate(print_task, "Print", 1024*4, NULL, 1, NULL);
#endif
#if defined(DISP_OLED) && DISP_OLED == 1
xTaskCreatePinnedToCore(led_task, "OLED", 1024*4, NULL, 1, NULL,1);
#endif
} else {
Serial.println("MPU6050 初始化失败");
}
}
void loop() {
delay(10);
}
Loading
esp32-s3-devkitc-1
esp32-s3-devkitc-1
imu1:INT
imu1:AD0
imu1:XCL
imu1:XDA
imu1:SDA
imu1:SCL
imu1:GND
imu1:VCC
Loading
ssd1306
ssd1306