natanaeljr / esp32-MPU-driver

ESP32 full library for all MPU6000 MPU6050 MPU6500 MPU9150 MPU9250 with SPI and I2C support and more.
MIT License
246 stars 67 forks source link

MPU-9250 Magnetometer example #3

Open ghost opened 6 years ago

ghost commented 6 years ago

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

natanaeljr commented 6 years ago

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.

juri117 commented 6 years ago

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

rafa400 commented 5 years ago

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

amoghskulkarni commented 5 years ago

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?

rafa400 commented 5 years ago

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.

amoghskulkarni commented 5 years ago

@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 commented 5 years ago

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.

danylook commented 5 years ago

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

nopnop2002 commented 5 years ago

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);
    }
}
mahad-ahmed commented 5 years ago

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.

nopnop2002 commented 5 years ago

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

jarusRnD commented 4 years ago

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