Compass 0-259 degrees bug

Hi, I found a nice code in order to built a compass with the QMC5883L.

It look good and the calibration is ok but something is missing.

at North I get 0 degrees but just befor north instead of getting 359, 358, 357degrees I get -1, -2, -3 etc. For south it's the same problem. I get 178, 179, but then -179, -178, -177 instead of 180, 181, 182 degrees.

This is the code I found. if someone can help me make the appropriate correction, it would be nice.

// ----------------------------------------------------------------------------------------------//
// Robert's Smorgasbord 2022                                                                     //
// https://robertssmorgasbord.net                                                                //
// https://www.youtube.com/channel/UCGtReyiNPrY4RhyjClLifBA                                      //
// QST QMC5883L 3-Axis Digital Compass and Arduino MCU – The Basics https://youtu.be/xh_KCkds038 //
// ----------------------------------------------------------------------------------------------//

#include <QMC5883LCompass.h>

// Mode Control (MODE)
const byte qmc5883l_mode_stby = 0x00;
const byte qmc5883l_mode_cont = 0x01;
// Output Data Rate (ODR)
const byte qmc5883l_odr_10hz  = 0x00;
const byte qmc5883l_odr_50hz  = 0x04;
const byte qmc5883l_odr_100hz = 0x08;
const byte qmc5883l_odr_200hz = 0x0C;
// Full Scale Range (RNG)
const byte qmc5883l_rng_2g    = 0x00;
const byte qmc5883l_rng_8g    = 0x10;
// Over Sample Ratio (OSR)
const byte qmc5883l_osr_512   = 0x00;
const byte qmc5883l_osr_256   = 0x40;
const byte qmc5883l_osr_128   = 0x80;
const byte qmc5883l_osr_64    = 0xC0;


QMC5883LCompass compass;

void setup()
{
   //Serial.begin(1000000);
   Serial.begin(115200);
   compass.init();
   //compass.setADDR(byte b);
   //compass.setMode(byte mode,          byte odr,           byte rng,        byte osr        );
   //compass.setMode(qmc5883l_mode_cont, qmc5883l_odr_200hz, qmc5883l_rng_8g, qmc5883l_osr_512);
   //compass.setSmoothing(byte steps, bool adv);
   //compass.setCalibration(int x_min, int x_max, int y_min, int y_max, int z_min, int z_max);
   compass.setCalibration(-1100, 2480, -2403, 850, -5015, -1261);
   //compass.setReset();

}

void loop()
{
   int x_value;
   int y_value;
   int z_value;
   int azimuth;  // 0° - 359°
   byte bearing; // 0 - 15 (N, NNE, NE, ENE, E, ...)
   char direction[strlen("NNE") + 1];
   char buffer[strlen("X=-99999 | Y=-99999 | Z=-99999 | A=259° | B=15 | D=NNE") + 1]; 
   
   compass.read(); // Read compass values via I2C

   x_value   = compass.getX();
   y_value   = compass.getY();
   z_value   = compass.getZ();
   azimuth   = compass.getAzimuth(); // Calculated from X and Y value 
   bearing   = compass.getBearing(azimuth);
   
   compass.getDirection(direction, azimuth);
   direction[3] = '\0';

   sprintf(buffer,
           "X=%6d | Y=%6d | Z=%6d | A=%3d° | B=%02hu | %s",
           x_value,
           y_value,
           z_value,
           azimuth,
           bearing,
           direction                                           );
   Serial.println(buffer);

   delay(200);
}

Shouldn't that be 359?

It looks like you could just take the negative values and add 360 to them to get what you want. that's a simple if statement.

:slight_smile: yes 359 sorry. Ok I will try tomorrow to add 360.

Solve

Hi Delta G,

It was so simple, thanks for the tips. It work fine.