hideakitai / MPU9250

Arduino library for MPU9250 Nine-Axis (Gyro + Accelerometer + Compass) MEMS MotionTracking™ Device
MIT License
277 stars 91 forks source link

Make a compass that works on a sailboat. #43

Closed froussel closed 3 years ago

froussel commented 3 years ago

I foolishly thought that the value of the yaw was the direction of magnetic north ... But when I turn the sensor by 90 ° the value does not vary by 90 °

How can I get there?

froussel commented 3 years ago

I use an mpu9250, an esp8266 and an oled screen

`

include

include

include

include

include "MPU9250.h"

define SCREEN_WIDTH 128

define SCREEN_HEIGHT 64

define OLED_MOSI 13 // D7 --> D1 N.C. MISO : D6 GPIO 12

define OLED_CLK 14 // D5 --> D0

define OLED_CS 15 // D8 --> CS

define OLED_DC 2 // D4 --> DC Quelconque

define OLED_RESET 16 // D0 --> RES Quelconque

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); MPU9250 mpu;

void setup() { Serial.begin(115200); Serial.println("\nmpu&7pins\n"); if(!display.begin(SSD1306_SWITCHCAPVCC)) { Serial.println(F("SSD1306 allocation failed")); for(;;); } display.clearDisplay(); display.display(); display.setTextColor(SSD1306_WHITE); Wire.begin(); // Wire.begin(4,5) sda=D2=4 scl=D1=5
if (!mpu.setup(0x68)) { while (1) { Serial.println("MPU Pb de connection");delay(5000); } } display.setTextSize(2); display.println(F("Box a plat")); display.display(); mpu.verbose(true); delay(2000); mpu.calibrateAccelGyro(); display.clearDisplay(); display.setCursor(32,20); display.println(F("Faire")); display.setCursor(32,50); display.println(F("des 8")); display.display(); delay(2000); mpu.calibrateMag(); print_calibration(); mpu.verbose(false);
display.clearDisplay(); delay(1000); }

void loop() { if (mpu.update()) { static uint32_t prev_ms = millis(); if (millis() > prev_ms + 25) { TextDisplay(); prev_ms = millis(); } } }

void TextDisplay() { display.clearDisplay(); display.setTextSize(3); display.setTextColor(SSD1306_WHITE); display.setCursor(20,0); display.print(mpu.getYaw(), 0); display.setTextSize(2); display.setCursor(0,48); display.print(mpu.getPitch(), 0); display.setCursor(64,48); display.print(mpu.getRoll(), 0); display.display(); }

void print_calibration() { Serial.println("< calibration parameters >"); Serial.println("accel bias [g]: "); Serial.print(mpu.getAccBiasX() 1000.f / (float)MPU9250::CALIB_ACCEL_SENSITIVITY); Serial.print(", "); Serial.print(mpu.getAccBiasY() 1000.f / (float)MPU9250::CALIB_ACCEL_SENSITIVITY); Serial.print(", "); Serial.print(mpu.getAccBiasZ() * 1000.f / (float)MPU9250::CALIB_ACCEL_SENSITIVITY); Serial.println(); Serial.println("gyro bias [deg/s]: "); Serial.print(mpu.getGyroBiasX() / (float)MPU9250::CALIB_GYRO_SENSITIVITY); Serial.print(", "); Serial.print(mpu.getGyroBiasY() / (float)MPU9250::CALIB_GYRO_SENSITIVITY); Serial.print(", "); Serial.print(mpu.getGyroBiasZ() / (float)MPU9250::CALIB_GYRO_SENSITIVITY); Serial.println(); Serial.println("mag bias [mG]: "); Serial.print(mpu.getMagBiasX()); Serial.print(", "); Serial.print(mpu.getMagBiasY()); Serial.print(", "); Serial.print(mpu.getMagBiasZ()); Serial.println(); Serial.println("mag scale []: "); Serial.print(mpu.getMagScaleX()); Serial.print(", "); Serial.print(mpu.getMagScaleY()); Serial.print(", "); Serial.print(mpu.getMagScaleZ()); Serial.println(); }

`

vollukas commented 3 years ago

I think that you must do your own calculations to determine if you are looking North etc... Yaw value always returns to the initial number. Is your Yaw value starting at 0 or do you also have some offset like me so it always returns for example to number -81? (just curious, I'm also new with this module)

From what I saw in discussions about this module, nobody will probably give you a simple solution and they seem to be a bit annoyed when someone new doesn't know all the basics. Also, many people made their own projects like this without this exact library and they for example manually write to registers or they used different module with different library...

There are some videos that might help: https://www.youtube.com/watch?v=u6IqVa11UAM https://www.youtube.com/watch?v=k6ccH8QYGK8 https://www.youtube.com/watch?v=vPGChdmfKl0

I wish you luck, I will be playing with the magnetometer myself in the future as I don't necessarily need it for my current project.

froussel commented 3 years ago

What I want to get is the same as https://github.com/visakhanc/eCompass but with Arduino IDE and an mpu9250 which contains the equivalent of an HMC5883L and an MPU6050

Strictly speaking, if I don't know how to have a roll value varying around 0 ° it is not too serious I only have to return the sensor but it is the yall value that I do not understand and how get the magnetic heading

vollukas commented 3 years ago

That's what I was talking about lol. I plan on implementing the same functionality that you want in my drone in the future after I finish my school project with it.

The way I understand it now (I am also new to this) is that there is a magnetometer function that will return your max value if you are heading to true North and min value if you are heading South. You need to write your own algorithm using the "Yaw" value that is telling you how much your device rotated in which direction and somehow compare it to the value from the magnetometer if you are heading north... but you will have to search more about that.

After I learn more, I may help you if you don't mind waiting for a while.

froussel commented 3 years ago
    float an = -a[0];                //
    float ae = +a[1];                //
    float ad = +a[2];                //

With this modification of mpu9250.h I have surprising results The value of yaw changes when I turn the sensor but when I stop the rotation the value changes continuously until it stabilizes .... Surprising result for me. To find a position with maximum and minimum value : the maximum area is wide

froussel commented 3 years ago

I returned the sensor and I use with the "simple.ino" program The yaw value varies from 43 to 95 which normally should correspond to South and North. I could consider a translation between 180 and 360 ° but the trouble is that if when roll changes yaw remains stable, however, changing the pitch has a huge influence on yaw which around the north will vary between 89 and 110 without changing the orientation of the sensor around z

froussel commented 3 years ago

Not arriving at satisfactory results in terms of yaw with this library, I looked elsewhere to advance a bit. I found quaternion_compass_new_v8.ino https://www.instructables.com/Quaternion-Compass/ https://content.instructables.com/ORIG/FVP/R2B4/K7ETG7ZS/FVPR2B4K7ETG7ZS.ino which by just changing the address of the internal led and commenting on the lcd display with a magnetic declination of Paris compiles without problem with an esp8266. By doing task 0: calibration then display Pitch and roll: ok and I get heading values varying between 190 and 240 for a fairly slow flat rotation. I wonder if my magnetic sensor is not defective ... With Chinese product everything is possible ... In France we say "buy Chinese, buy twice" ;-)

hideakitai commented 3 years ago

@froussel @vollukas This issue will be fixed by https://github.com/hideakitai/MPU9250/tree/bugfix_obromious. Please confirm if it works.

froussel commented 3 years ago

Yes, It is good, my sensor was defective, with a new sensor it's correct . Thanks