Giter Site home page Giter Site logo

qmc5883l's People

Contributors

dthain 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  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

qmc5883l's Issues

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 readRaw() 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 sent one Stop-Bit 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.

ATTiny85 compile issue

Hi,

Firstly,thanks for this library :) I wanted to use your library in a project but found it wouldnt compile for the ATtny85. Below is the error message. Is there anyway I can fix this?
Thanks for your time
Dave

Arduino: 1.8.5 (Mac OS X), Board: "ATtiny25/45/85, Disabled, CPU, ATtiny85, 8 MHz (internal), EEPROM retained, B.O.D. Disabled"
/Users/daveandrew/Documents/Arduino/libraries/QMC5883L-master/QMC5883L.cpp: In member function 'void QMC5883L::init()':
/Users/daveandrew/Documents/Arduino/libraries/QMC5883L-master/QMC5883L.cpp:149:6: error: 'TWCR' was not declared in this scope
if(TWCR==0) Wire.begin();
^
exit status 1
Error compiling for board ATtiny25/45/85.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Calibration

Hi, thanks for sharing your code, very inspiring.
However, you may consider allowing to stop auto-calibration at some point. When you now point even a magnetic screwdriver at the sensor, the range becomes useless until you switch everything off (or perhaps only Soft Reset). Potential security hazard ;)

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

90° only

I only can detect 90° and no data between, can you help how to solve that? :/ i am stuck there, and this is only lib that works.

sensor is not responding

hi there,
i used your library but the only thing i got was the message,
"turn the sensor in all directions for calibration"
and when i turned nothing happened
could you please help me with the issue???

License?

What's the License of this library?

Don't while(1) in loop()

A small fix for the compass demo:

void loop()
{
    while(1) {
        ...

The while(1) isn't necessary and blocks other background processing. The loop function will be called repeatedly.

Example

HI,

Just to let you know that you should have #include <Wire.h> in the example now that you took it out in cpp for ATtiny85 compatibility. Else you get a wire not declared verify error.
Thanks again
Dave

Wrong example in the library.

sorry to have bothered you but your example in the code is kinda wrong
it is

#include <Serial.h>

QMC5883L compass;

void init()
{
	compass.init();
	compass.setSamplingRate(50);

	Serial.println("QMC5883L Compass Demo");
	Serial.println("Turn compass in all directions to calibrate....");
}

void loop()
{
	while(1) {
		int heading = compass.readHeading();
		if(heading==0) {
			/* Still calibrating, so measure but don't print */
		} else {
			Serial.println(heading);
		}
	}
}

and it should be

#include <QMC5883L.h>
//#include <Serial.h>

QMC5883L compass;

void setup()
{      Serial.begin(9600);
	compass.init();
	compass.setSamplingRate(50);

	Serial.println("QMC5883L Compass Demo");
	Serial.println("Turn compass in all directions to calibrate....");
}

void loop()
{
	while(1) {
		int heading = compass.readHeading();
		if(heading==0) {
			/* Still calibrating, so measure but don't print */
		} else {
			Serial.println(heading);
		}
	}
}

thanks for the code, by the way, keep up the good work

P.S
in the readme, you use an example of calling the function compass.setOverampling(ovl);
and after looking through your code I think it is compass.setOversampling(ovl);

readHeading returns 1

readHeading is returning 1 allways! and you don't have pass by reference so just return heading; mybe? xD

and Wire.begin(sda, scl); call is missing? (for me, for nodemcu) so mybe adding this?

and include arduino.h is needed for atan2 to work (for me again). BTW thanks ALOTE! for code 👍

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

This function will never return an Angle.

I don't know if this is your code error or what, this function never returns an Angle.

int QMC5883L::readHeading()
{
  int16_t x, y, z, t;

  if(!readRaw(&x,&y,&z,&t)) return 0;

  /* Update the observed boundaries of the measurements */

  if(x<xlow) xlow = x;
  if(x>xhigh) xhigh = x;
  if(y<ylow) ylow = y;
  if(y>yhigh) yhigh = y;

  /* Bail out if not enough data is available. */
  
  if( xlow==xhigh || ylow==yhigh ) return 0;

  /* Recenter the measurement by subtracting the average */

  x -= (xhigh+xlow)/2;
  y -= (yhigh+ylow)/2;

  /* Rescale the measurement to the range observed. */
  
  float fx = (float)x/(xhigh-xlow);
  float fy = (float)y/(yhigh-ylow);

  int heading = 180.0*atan2(fy,fx)/M_PI;
  if(heading<=0) heading += 360;
  
  return 1;
}

Random Crashes??

Hello,

I am unsure why this is happening, but the example seems to crash at random times and hang the Arduino. This is repeatable on both the QMC588L's I have. Any idea why?

-Will

How to calculate Yaw by accelerometer data Fusion?

int QMC5883L::readHeading()
{
  int16_t x, y, z, t;

  if(!readRaw(&x,&y,&z,&t)) return 0;

  /* Update the observed boundaries of the measurements */

  if(x<xlow) xlow = x;
  if(x>xhigh) xhigh = x;
  if(y<ylow) ylow = y;
  if(y>yhigh) yhigh = y;

  /* Bail out if not enough data is available. */
  
  if( xlow==xhigh || ylow==yhigh ) return 0;

  /* Recenter the measurement by subtracting the average */

  x -= (xhigh+xlow)/2;
  y -= (yhigh+ylow)/2;

  /* Rescale the measurement to the range observed. */
  
  float fx = (float)x/(xhigh-xlow);
  float fy = (float)y/(yhigh-ylow);

  int heading = 180.0*atan2(fy,fx)/M_PI;
  if(heading<=0) heading += 360;
  
  return heading;
}

Missing Wire.begin()

The example code in examples/compass/compass.ino won't run as is because Wire.begin() isn't called.

It's easily solved with:

#include <Wire.h>

Setup() {
Wire.begin()
...

However, ideally QMC5883L.cpp would initialize Wire iff it has not been so the Wire usage is fully encapsulated.

M_PI Deprecated

This is my first post so please understand improper terms. When I compile my program it fails on M_PI which is buried inside of your library line 200. The little research I did indicates that this has been deprecated in the AVR math library. I am using Arduino 1.6.11 Compiler.
Thanks
Doug
An eager hobbyist

float fx = (float)x/(xhigh-xlow);
float fy = (float)y/(yhigh-ylow);
int heading = 180.0*atan2(fy,fx)/M_PI;
if(heading<=0) heading += 360;

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.