esp32-MPU-driver icon indicating copy to clipboard operation
esp32-MPU-driver copied to clipboard

MPU-9250 Magnetometer example

Open ghost opened this issue 6 years ago • 12 comments

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

ghost avatar Apr 02 '18 09:04 ghost

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.

natanaeljr avatar Apr 02 '18 11:04 natanaeljr

I would be interested in this, too. great work btw ;)

juri117 avatar May 10 '18 09:05 juri117

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

rafa400 avatar May 01 '19 18:05 rafa400

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?

amoghskulkarni avatar May 07 '19 06:05 amoghskulkarni

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 avatar May 07 '19 12:05 rafa400

@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.

amoghskulkarni avatar May 07 '19 17:05 amoghskulkarni

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.

amoghskulkarni avatar May 21 '19 06:05 amoghskulkarni

hi could you said how you did? im working on the same solution and it will helpfull thks

danylook avatar Jun 06 '19 13:06 danylook

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);
    }
}

nopnop2002 avatar Jun 28 '19 05:06 nopnop2002

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 avatar Oct 24 '19 15:10 mahad-ahmed

@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.

nopnop2002 avatar Oct 25 '19 22:10 nopnop2002

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

jarusRnD avatar Apr 14 '20 14:04 jarusRnD