esp32-MPU-driver
esp32-MPU-driver copied to clipboard
MPU-9250 Magnetometer example
There is no example of using magnetometer sensor. Also it will be good to see example of getting some data, like roll, pitch, yaw angles
For now the example "mpu_real" computes roll, pitch, and yaw from accel/gyro data fusion. I will be adding a magnetometer example in near future as soon as I can.
I would be interested in this, too. great work btw ;)
Hi. Yes, great work! I got some example lines from your test_mpu.cpp code (at the end of the file) I'm using a MPU9250. Self-test seems to work and I get values for magnetometer x,y,z, but finally when I call to mpu.heading(&mag), I get always 0,0,0 There is any problem with heading function at this moment to get magnetometer values? It's just me? TNX
Hello, I am also trying to get the raw mag data but always end up getting all 3 values as 0. All other functionalities seem to be working as expected. Any pointers about how to debug?
I use SEGGER JLINK for esp-idf debug. Chinese Aliexpress cheap units also work for this (I've used both). If you need a wiring map, let me know.
Magnetometer seems to work from my Raspberry PI command line. Here the bash file I made for my test:
#i2cdump -y -r 0x37-0x37 1 0x68
echo \"MPU9250_ADDR_PWR_MGMT_1\"
i2cget -y 1 0x68 0x6b
i2cset -y 1 0x68 0x6b 0x00
echo "MPU9250_ADDR_INT_PIN_CFG"
i2cget -y 1 0x68 0x37
i2cset -y 1 0x68 0x37 0x0e
echo "MAG MODE: MAG_MODE_POWERDOWN"
i2cset -y 1 0x0c 0x0a 0x0
echo "MAG MODE: MAG_MODE_CONTINUOUS_8HZ"
i2cset -y 1 0x0c 0x0a 0x2
sleep 1
i2cdump -y -r 0x03-0x09 1 0x0c c
i2cdump -y -r 0x03-0x09 1 0x0c c
i2cdump -y -r 0x03-0x09 1 0x0c c
i2cdump -y -r 0x03-0x09 1 0x0c c
`
A different I2C adress is used for the magnetomer => 0x0c
I'm goint to try a dirty solution this weekend using direct access to 0x0c. I will let you know the result.
@rafa400 Thanks a lot for the reply. I am actually interfacing MPU9250 on SPI and I wonder if the issue is arising because of that. Would try to test it on I2C and share the results.
Hi, I was able to get the magnetometer data through SPI. Turns out I wasn't initializing the devices properly. As soon as I started initializing the devices as shown in the mpu_real
example, I started getting the mag values.
hi could you said how you did? im working on the same solution and it will helpfull thks
I tried to get mag data from m5stack. m5stack has MPU9250. This is my code, But mag data is always zero. Do you have some advice??
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#include "I2Cbus.hpp"
#include "MPU.hpp"
#include "mpu/math.hpp"
#include "mpu/types.hpp"
static const char* TAG = "example";
static constexpr gpio_num_t SDA = GPIO_NUM_21;
static constexpr gpio_num_t SCL = GPIO_NUM_22;
static constexpr uint32_t CLOCK_SPEED = 400000; // range from 100 KHz ~ 400Hz
extern "C" void app_main() {
printf("$ MPU Driver Example: MPU-I2C\n");
fflush(stdout);
// Initialize I2C on port 0 using I2Cbus interface
i2c0.begin(SDA, SCL, CLOCK_SPEED);
// Or directly with esp-idf API
/*
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = SDA;
conf.scl_io_num = SCL;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = CLOCK_SPEED;
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0));
*/
MPU_t MPU; // create a default MPU object
MPU.setBus(i2c0); // set bus port, not really needed since default is i2c0
MPU.setAddr(mpud::MPU_I2CADDRESS_AD0_LOW); // set address, default is AD0_LOW
// Great! Let's verify the communication
// (this also check if the connected MPU supports the implementation of chip selected in the component menu)
while (esp_err_t err = MPU.testConnection()) {
ESP_LOGE(TAG, "Failed to connect to the MPU, error=%#X", err);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
ESP_LOGI(TAG, "MPU connection successful!");
// Initialize
ESP_ERROR_CHECK(MPU.initialize()); // initialize the chip and set initial configurations
// Setup with your configurations
// ESP_ERROR_CHECK(MPU.setSampleRate(50)); // set sample rate to 50 Hz
// ESP_ERROR_CHECK(MPU.setGyroFullScale(mpud::GYRO_FS_500DPS));
// ESP_ERROR_CHECK(MPU.setAccelFullScale(mpud::ACCEL_FS_4G));
// Initialize compass
MPU.compassInit();
// Reading sensor data
printf("Reading sensor data:\n");
mpud::raw_axes_t accelRaw; // x, y, z axes as int16
mpud::raw_axes_t gyroRaw; // x, y, z axes as int16
mpud::float_axes_t accelG; // accel axes in (g) gravity format
mpud::float_axes_t gyroDPS; // gyro axes in (DPS) o/s format
while (true) {
// Read
MPU.acceleration(&accelRaw); // fetch raw data from the registers
MPU.rotation(&gyroRaw); // fetch raw data from the registers
// MPU.motion(&accelRaw, &gyroRaw); // read both in one shot
// Convert
accelG = mpud::accelGravity(accelRaw, mpud::ACCEL_FS_4G);
gyroDPS = mpud::gyroDegPerSec(gyroRaw, mpud::GYRO_FS_500DPS);
#if 0
// Debug
printf("accel: [%+6.2f %+6.2f %+6.2f ] (G) \t", accelG.x, accelG.y, accelG.z);
printf("gyro: [%+7.2f %+7.2f %+7.2f ] (o/s)\n", gyroDPS[0], gyroDPS[1], gyroDPS[2]);
#endif
int16_t magx, magy, magz;
MPU.heading(&magx, &magy, &magz);
printf("mag: [%d %d %d ]\n", magx, magy, magz);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
Calling setAuxI2CEnabled(true)
as mentioned in https://github.com/natanaeljr/esp32-MPU-driver/issues/7 seems to work.
For reference, I'm using a 9250 with i2c.
@mahad-ahmed Thank you for replay. I modified as follows, but MAG data of m5stack-gray (MPU9250) become all 0.
esp_err_t MPU::compassInit()
{
#ifdef CONFIG_MPU_I2C
if (MPU_ERR_CHECK(setAuxI2CBypass(true))) return err;
if (MPU_ERR_CHECK(setAuxI2CEnabled(true))) return err;
Currently, the m5stack-gray Geomagnetic Sensor has been changed to BMM150. I will stop further investigation.
hello Sir, spi interface with two 9250 can't get magnetometer reading. any examples would be great.....
Error Log
I (358) example: MPU2 connection successful! E (1358) MPU9250: auxI2CWriteByte()-> Timeout. Aux I2C might've hung. Restart it. E (1358) MPU9250: func:esp_err_t mpud::MPU::compassWriteByte(uint8_t, uint8_t) @ line:1756, expr:"auxI2CWriteByte(COMPASS_I2CADDRESS, regAddr, data)", error:0x107 E (1368) MPU9250: func:esp_err_t mpud::MPU::compassReset() @ line:2079, expr:"compassWriteByte(regs::mag::CONTROL2, 0x1)", error:0x107 E (1378) MPU9250: func:esp_err_t mpud::MPU::compassInit() @ line:1790, expr:"compassReset()", error:0x107 I (1588) MPU9250: Reset! E (2588) MPU9250: auxI2CWriteByte()-> Timeout. Aux I2C might've hung. Restart it. E (2588) MPU9250: func:esp_err_t mpud::MPU::compassWriteByte(uint8_t, uint8_t) @ line:1756, expr:"auxI2CWriteByte(COMPASS_I2CADDRESS, regAddr, data)", error:0x107 E (2598) MPU9250: func:esp_err_t mpud::MPU::compassReset() @ line:2079, expr:"compassWriteByte(regs::mag::CONTROL2, 0x1)", error:0x107 E (2608) MPU9250: func:esp_err_t mpud::MPU::compassInit() @ line:1790, expr:"compassReset()", error:0x107 E (2618) MPU9250: func:esp_err_t mpud::MPU::initialize() @ line:80, expr:"compassInit()", error:0x107 ESP_ERROR_CHECK failed: esp_err_t 0x107 (ESP_ERR_TIMEOUT) at 0x400871d4 0x400871d4: _esp_error_check_failed at /home/suraj/esp/esp-idf/components/esp32/panic.c:726
file: "/home/suraj/jarusWork/MPUdriver/examples/mpu_spi/main/mpu_spi.cpp" line 78 func: void app_main() expression: MPU2.initialize()
ELF file SHA256: a9360acc58f7c6bdf11c341e5bdbbe9cc88c6d9841bdaedf5b74a0f70e5a8cc7
Backtrace: 0x40086c35:0x3ffb5090 0x400871d7:0x3ffb50b0 0x400d2aa1:0x3ffb50d0 0x400d10ce:0x3ffb5150 0x40089171:0x3ffb5170 0x40086c35: invoke_abort at /home