#pragma once #include "driver/i2c_types.h" #include "esp_err.h" #include #include typedef enum : uint8_t { // Internal 8MHz oscillator MPU6050_CLKSEL_INTERNAL_8MHZ_OSC = 0, // PLL with X axis gyroscope reference MPU6050_CLKSEL_PLL_GYRO_X_REF = 1, // PLL with Y axis gyroscope reference MPU6050_CLKSEL_PLL_GYRO_Y_REF = 2, // PLL with Z axis gyroscope reference MPU6050_CLKSEL_PLL_GYRO_Z_REF = 3, // PLL with external 32.768kHz reference MPU6050_CLKSEL_PLL_EXTERNAL_32_768_HZ_REF = 4, // PLL with external 19.2MHz reference MPU6050_CLKSEL_PLL_EXTERNAL_19_200K_HZ_REF = 5, // Stops the clock and keeps the timing generator in reset MPU6050_CLKSEL_PLL_STOP_RESET = 7, } Mpu6050_ClockSource; typedef enum : uint8_t { // ± 250 °/s MPU6050_GYRO_RANGE_250 = 0, // ± 500 °/s MPU6050_GYRO_RANGE_500 = 1, // ± 1000 °/s MPU6050_GYRO_RANGE_1000 = 2, // ± 2000 °/s MPU6050_GYRO_RANGE_2000 = 3, } Mpu6050_GyroRange; typedef enum : uint8_t { // ± 2g MPU6050_ACCEL_RANGE_2 = 0, // ± 4g MPU6050_ACCEL_RANGE_4 = 1, // ± 8g MPU6050_ACCEL_RANGE_8 = 2, // ± 16g MPU6050_ACCEL_RANGE_16 = 3, } Mpu6050_AccelRange; typedef struct { float x; float y; float z; } float3; typedef struct { i2c_master_bus_handle_t i2c_bus; i2c_master_dev_handle_t i2c_dev; Mpu6050_GyroRange gyro_range; Mpu6050_AccelRange accel_range; float3 rotation_bias; float3 accel_bias; } Mpu6050; esp_err_t mpu6050_init(Mpu6050* dev); esp_err_t mpu6050_deinit(Mpu6050* dev); esp_err_t mpu6050_get_rotation(Mpu6050* dev, float3* rotation); esp_err_t mpu6050_get_acceleration(Mpu6050* dev, float3* accel); esp_err_t mpu6050_read_temperature(Mpu6050* dev, float* temperature); esp_err_t mpu6050_set_clock_source(Mpu6050* dev, Mpu6050_ClockSource source); esp_err_t mpu6050_set_gyro_range(Mpu6050* dev, Mpu6050_GyroRange range); esp_err_t mpu6050_set_accel_range(Mpu6050* dev, Mpu6050_AccelRange range); esp_err_t mpu6050_set_sleep_enabled(Mpu6050* dev, bool enabled); #define MPU6050_SAMPLE_RATE_TO_DIV_1KHZ(SAMPLE_RATE) \ ((uint8_t)(1000.0f / (float)(SAMPLE_RATE) - 1.0f)) #define MPU6050_SAMPLE_RATE_TO_DIV_8KHZ(SAMPLE_RATE) \ ((uint8_t)(8000.0f / (float)(SAMPLE_RATE) - 1.0f)) // Sample rate = Gyro output rate / (1 + Sample rate divier) // Optionally use // - `MPU6050_SAMPLE_RATE_TO_DIV_1KHZ()`, if DLPF is enabled // - `MPU6050_SAMPLE_RATE_TO_DIV_8KHZ()`, if DLPF is disabled esp_err_t mpu6050_set_sample_rate_div(Mpu6050* dev, uint8_t div); typedef enum : uint8_t { // Accelerometer: bandwidth = 260Hz, delay = 0.0ms // Gyroscope: bandwidth = 256Hz, delay = 0.98ms // Fs: 8kHz MPU6050_DLPF_0 = 0, // Accelerometer: bandwidth = 184Hz, delay = 2.0ms // Gyroscope: bandwidth = 188Hz, delay = 1.9ms // Fs: 1kHz MPU6050_DLPF_1 = 1, // Accelerometer: bandwidth = 94Hz, delay = 3.0ms // Gyroscope: bandwidth = 98Hz, delay = 2.8ms // Fs: 1kHz MPU6050_DLPF_2 = 2, // Accelerometer: bandwidth = 44Hz, delay = 4.9ms // Gyroscope: bandwidth = 32Hz, delay = 4.8ms // Fs: 1kHz MPU6050_DLPF_3 = 3, // Accelerometer: bandwidth = 21Hz, delay = 8.5ms // Gyroscope: bandwidth = 20Hz, delay = 8.3ms // Fs: 1kHz MPU6050_DLPF_4 = 4, // Accelerometer: bandwidth = 10Hz, delay = 13.8ms // Gyroscope: bandwidth = 10Hz, delay = 13.4ms // Fs: 1kHz MPU6050_DLPF_5 = 5, // Accelerometer: bandwidth = 5Hz, delay = 19.0ms // Gyroscope: bandwidth = 5Hz, delay = 18.6ms // Fs: 1kHz MPU6050_DLPF_6 = 6, } Mpu6050_DLPF; // Digital low pass filter (DLPF) // Note: Sampling rate is dependent on whether DLPF is enabled. esp_err_t mpu6050_set_dlpf(Mpu6050* dev, Mpu6050_DLPF selector); esp_err_t mpu6050_calibrate(Mpu6050* dev, const float3* initial_rotation);