Git Product home page Git Product logo

mecha_qmc5883l's Introduction

Mechasolution QMC5883L Library

한글 설명 바로가기

Arduino Code

There are a few simple rules for using that library. Please read the following summary and apply it to your project

Basic Elements

Required header files (#include ...) and Setup side code.

#include <Wire.h>
#include <MechaQMC5883.h>

void setup(){
  Wire.begin();
}

Object Declaration

The object declaration method. It is used outside the setup statement, and a name such as qmc can be changed to any other name you want.

#include <Wire.h>
#include <MechaQMC5883.h>

MechaQMC5883 qmc;

initialization

QMC5883 Sensor's setting function.

The init function allows you to take advantage of the features of the QMC5883 sensor by default.

void setup(){
    Wire.begin();
    qmc.init();
}

If you want more detailed settings, you can use it as follows.

void setup(){
  Wire.begin();
  qmc.init();
  qmc.setMode(Mode_Standby,ODR_200Hz,RNG_8G,OSR_512);
}

The values ​​used for setMode can take the following values:

Mode : Mode_Standby / Mode_Continuous

ODR : ODR_10Hz / ODR_50Hz / ODR_100Hz / ODR_200Hz
ouput data update rate

RNG : RNG_2G / RNG_8G
magneticfield measurement range

OSR : OSR_512 / OSR_256 / OSR_128 / OSR_64
over sampling rate

Read values

How to read the measured sensor value is as follows.

void loop(){
  int x,y,z;

  qmc.read(&x,&y,&z);
}

and we can get azimuth too.

void loop(){
  int x,y,z;
  int a;
  //float a; //can get float value

  qmc.read(&x,&y,&z,&a);
}

also can claculate azimuth you want

void loop(){
  int x,y,z;
  int a;

  qmc.read(&x,&y,&z);
  a = qmc.azimuth(&y,&x);
}

Basic example

It can be seen as a collection of the contents mentioned above.

#include <Wire.h>
#include <MechaQMC5883.h>

MechaQMC5883 qmc;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  qmc.init();
  //qmc.setMode(Mode_Continuous,ODR_200Hz,RNG_2G,OSR_256);
}

void loop() {
  int x,y,z;
  qmc.read(&x,&y,&z);

  Serial.print("x: ");
  Serial.print(x);
  Serial.print(" y: ");
  Serial.print(y);
  Serial.print(" z: ");
  Serial.print(z);
  Serial.println();
  delay(100);
}

mecha_qmc5883l's People

Contributors

keepworking avatar pierstitus avatar yevgenyhong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mecha_qmc5883l's Issues

Mecha_QMC5883L

This is a great library, but i have a issue, because i use the azimuth and then i wrote an if function which should tell me when i am heading to north but the problem know is the value of azimuth do not reach 0 and i also have two north points , because the value goes from 210 to 180 and then again from 180 to 210 if i rotate the compass and i though the value goes from 0 to 360 if i rotate it once. I am very desperately and thanks in advance

I2C stops working at fast reading (100Hz) solved

With this library I had issues to get a reliable connection to the sensor when I executed MechaQMC5883::read command more than 50 times a second. Even though the Sensor could work up to 200Hz.

When reading the chapter "8.2.4 I2C Read" in the datasheet, i discovered, that for reading the sensor data (x,y,z) there should only be one Stop-Bit sent from the master.
I am assuming, that your library instead is sending two Stop-Bits for one data-reading sequence. As far as I understand the Wire.h library, the Wire.endTransmission(); line is sending a Stop-Bit even though it shouldn't.

After I added a false Wire.endTransmission(false); in the read function, I could achieve a reliable 100Hz connection.

Example sketches don't compile

In each of the example sketches, the line "int x,y,z;" causes an error as all of these are expected to be uint16_t by the function qmc.read

Azimuth works on UNO but fails on ESP8266WiFi

Still debugging, but on UNO I was getting 0-360 reliably, within 2 degrees; however on the ESP8266, I only get 0 - 90 with abrupt jumps between 0, 45, and 90. Basically, I just copied the create, init, and read lines from the UNO code and changed the pins from default on the UNO to SCL_PIN=D3=0 & SDA_PIN=D2=4 for the ESP8266. I assumed the Wire and MechaQMC5883 libraries would handle the details. I initially had some errors in my code, but I assumed they didn't affect the operation once I fixed them. I have not considered pull-up or pull-down resistors at this point nor the differences between the A4 & A5 on the UNO or D2 & D3 on the ESP8266.

compass stop working after couple of minutes

hi I bought GY-271 3.3 volt external compass QMC5883L and it cease to working after couple of minutes and it should reset to start working again , I really appreciated for any hint

Output value in uTesta or uGauss

Hello @keepworking
What values do we get at the library output?

  int x,y,z;
  qmc.read(&x,&y,&z);

  Serial.print("x: ");
  Serial.print(x);
  Serial.print(" y: ");
  Serial.print(y);
  Serial.print(" z: ");
  Serial.print(z);
  Serial.println();
  delay(100);

Judging by the library code, these are raw values without scaling and conversion to units of magnetic field strength.

int MechaQMC5883::read(int* x,int* y,int* z){
   Wire.beginTransmission(address);
   Wire.write(0x00);
   int err = Wire.endTransmission();
   if (err) {return err;}
   Wire.requestFrom(address, 7);
   *x = (int)(int16_t)(Wire.read() | Wire.read() << 8);
   *y = (int)(int16_t)(Wire.read() | Wire.read() << 8);
   *z = (int)(int16_t)(Wire.read() | Wire.read() << 8);
   byte overflow = Wire.read() & 0x02;
   return overflow << 2;
}

But the output is very small values, similar to uTesla.

fail to calibrate QMC5883L module

hi buddy , sorry to pen ticket for my question , but actually I’ve been trying to install Chinese compass QMC5883L (instead of HMC5843 ) to my Arducopter , I ran compos test sketch in the library and notice it didn’t initialize. After tracking the issue I’ve notice init() function do not work correctly because it’s return unsuccessful flag for rest of operation, then I’ve notice there are following parameters which is base on well known HMC5843 compass whereas its not compatible with this Chinese compass

uint16_t expected_x = 715; 
uint16_t expected_yz = 715; 
float gain_multiple = 1.0; 
float calibration[3];

and this is ini() function in the driver lib

bool AP_Compass_QMC5883L::init()
{
    
	int numAttempts = 0, good_count = 0;
    bool success = false;
    
    uint16_t expected_x = 715;
    uint16_t expected_yz = 715;
    float gain_multiple = 1.0;
	
  if (!write_register(ConfigRegB,0x80)) return false; //softReset  must reset first         
  hal.scheduler->delay(10);
       write_register(0x0B, 0x01);//SET/RESET Period
  
    _i2c_sem = hal.i2c->get_semaphore();
    if (!_i2c_sem->take(HAL_SEMAPHORE_BLOCK_FOREVER))  hal.scheduler->panic(PSTR("Failed to get QMC5883L semaphore")); 
    // determine if we are using 5843 or 5883L
    _base_config = BaseReg;
    if (  !write_register(ConfigRegA, Mode_Continuous | ODR_200Hz | Mode_Continuous| RNG_8G | OSR_512 ) 
	//	|| !read_register(ConfigRegA, &_base_config)  
	) 
	{
        _healthy[0] = false;
        _i2c_sem->give();
        return false;
    }
	
    
        product_id = AP_COMPASS_TYPE_QMC5883L;
       
        /*
          note that the HMC5883 datasheet gives the x and y expected
          values as 766 and the z as 713. Experiments have shown the x
          axis is around 766, and the y and z closer to 713.
         */
        expected_x = 766;
        expected_yz  = 713;
        gain_multiple = 660.0 / 1090;  // adjustment for runtime vs calibration gain
    

    calibration[0] = 0;
    calibration[1] = 0;
    calibration[2] = 0;

    while ( success == 0 && numAttempts < 25 && good_count < 5)
    {
        // record number of attempts at initialisation
        numAttempts++;
        // read values from the compass
        hal.scheduler->delay(50);
        if (!read_raw())  continue; // we didn't read valid values     Fill _mag_x _mag_y _mag_z       

        hal.scheduler->delay(10);

        float cal[3];

        //   hal.console->printf_P(PSTR("%d) mag: %d - %d - %d \n"),numAttempts, _mag_x, _mag_y, _mag_z);
        cal[0] = fabsf(expected_x / (float)_mag_x);
        cal[1] = fabsf(expected_yz / (float)_mag_y);
        cal[2] = fabsf(expected_yz / (float)_mag_z);

        //  hal.console->printf_P(PSTR(" cal=%.2f   %.2f   %.2f\n"),numAttempts, cal[0], cal[1], cal[2]);

        // we throw away the first two samples as the compass may still be changing its state from the application of the
        // strap excitation. After that we accept values in a reasonable range
        if (numAttempts > 2 &&
            cal[0] > 0.7f && cal[0] < 1.35f &&
            cal[1] > 0.7f && cal[1] < 1.35f &&
            cal[2] > 0.7f && cal[2] < 1.35f) 
		{
            //  hal.console->printf_P(PSTR("  good\n") );
            good_count++;
            calibration[0] += cal[0];
            calibration[1] += cal[1];
            calibration[2] += cal[2];
        }

#if 0
        /* useful for debugging */
        hal.console->printf_P(PSTR("MagX: %d MagY: %d MagZ: %d\n"), (int)_mag_x, (int)_mag_y, (int)_mag_z);
        hal.console->printf_P(PSTR("CalX: %.2f CalY: %.2f CalZ: %.2f\n"), cal[0], cal[1], cal[2]);
#endif
    }

	//hal.console->printf_P(PSTR("good_count: %d  \n"),good_count);
    if (good_count >= 5)
						{
							/*
							  The use of gain_multiple below is incorrect, as the gain
							  difference between 2.5Ga mode and 1Ga mode is already taken
							  into account by the expected_x and expected_yz values.  We
							  are not going to fix it however as it would mean all
							  APM1/APM2 users redoing their compass calibration. The
							  impact is that the values we report on APM1/APM2 are lower
							  than they should be (by a multiple of about 0.6). This
							  doesn't have any impact other than the learned compass
							  offsets
							 */
							calibration[0] = calibration[0] * gain_multiple / good_count;
							calibration[1] = calibration[1] * gain_multiple / good_count;
							calibration[2] = calibration[2] * gain_multiple / good_count;
							success = true;
						} 
	else
			{
				/* best guess */
				calibration[0] = 1.0;
				calibration[1] = 1.0;
				calibration[2] = 1.0;
			}

    // leave test mode
    if (!re_initialise()) 
	{
        _i2c_sem->give();
        return false;
    }

    _i2c_sem->give();
    _initialised = true;

	// perform an initial read
	_healthy[0] = true;
	read();

#if 0
    hal.console->printf_P(PSTR("CalX: %.2f CalY: %.2f CalZ: %.2f\n"), calibration[0], calibration[1], calibration[2]);
#endif

    return true;//success;
}

so I’ve bypassed it in the way that init() function always return successful flag & calibration[3] array is always equal to 1, then compile and upload the firmware into hardware, but in the end I received compass error that says my compass too bios or fail , I repeated calibration procedure couple of times but the drone didn’t arm so I’m guessing I kinda need to consider calibration into account which is fundamentally need to know correct initial value, unfortunately data sheet didn't be helpful and I don't know how to guess the initial value of expected_x, expected_yz & gain_multiple, so I really appreciated to have your comments about that
full driver lib located here
https://github.com/mkeyno/AP_Compass_QMC5883L/blob/master/AP_Compass_QMC5883L.cpp#L150-L282

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.