GY271 /HMC5883 Compass... weird

Hello all

Just added an I2C GY271 /HMC5883 Compass module to my project.
Just spat out the same value, and movement didn't do anything.

So, loaded the Adafruit demo code (below) and it returned information about the compass.... when it wasn't plugged in?

Did an I2c bus scan and it returned all 5 items on the bus correctly.
So, I removed everything from the I2C bus and ran the compass demo code again.... returned a load of values (list below). How can it do that when the compass isn't there? (in fact, there is nothing on the I2C bus).

Adding the compass makes no difference. The output stays the same.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

void displaySensorDetails(void)
{
  sensor_t sensor;
  mag.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" uT");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" uT");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" uT");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void setup(void) 
{
  Serial.begin(9600);
  Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!mag.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
    while(1);
  }
  
  /* Display some basic information on this sensor */
  displaySensorDetails();
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  mag.getEvent(&event);
 
  /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
  Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print("  ");Serial.println("uT");

  // Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
  // Calculate heading when the magnetometer is level, then correct for signs of axis.
  float heading = atan2(event.magnetic.y, event.magnetic.x);
  
  // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
  // Find yours here: http://www.magnetic-declination.com/
  // Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
  // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
  float declinationAngle = 0.22;
  heading += declinationAngle;
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
   
  // Convert radians to degrees for readability.
  float headingDegrees = heading * 180/M_PI; 
  
  Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
  
  delay(500);
}#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

void displaySensorDetails(void)
{
  sensor_t sensor;
  mag.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" uT");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" uT");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" uT");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void setup(void) 
{
  Serial.begin(9600);
  Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!mag.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
    while(1);
  }
  
  /* Display some basic information on this sensor */
  displaySensorDetails();
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  mag.getEvent(&event);
 
  /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
  Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print("  ");Serial.println("uT");

  // Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
  // Calculate heading when the magnetometer is level, then correct for signs of axis.
  float heading = atan2(event.magnetic.y, event.magnetic.x);
  
  // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
  // Find yours here: http://www.magnetic-declination.com/
  // Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
  // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
  float declinationAngle = 0.22;
  heading += declinationAngle;
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
   
  // Convert radians to degrees for readability.
  float headingDegrees = heading * 180/M_PI; 
  
  Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
  
  delay(500);
}

This code.... with or without the compass connected, spits out:

HMC5883 Magnetometer Test

------------------------------------
Sensor:       HMC5883
Driver Ver:   1
Unique ID:    12345
Max Value:    800.00 uT
Min Value:    -800.00 uT
Resolution:   0.20 uT
------------------------------------

X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61
X: -0.09  Y: -0.09  Z: -0.10  uT
Heading (degrees): 237.61

Should add... running on a Nano. Nothing else connected

OK.... Dud library. The Adafruit basically doesn't work at all. Neither do a couple of others I found.

This DFrobot one appears to work correctly:

/*!
   @file getCompassdata.ino
   @brief Output the compass data
   @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
   @license     The MIT License (MIT)
   @author      [dexian.huang](952838602@qq.com)
   @version  V1.0
   @date  2017-7-3
   @url https://github.com/DFRobot/DFRobot_QMC5883
*/
#include <DFRobot_QMC5883.h>

DFRobot_QMC5883 compass(&Wire, /*I2C addr*/0x0D);

void setup()
{
  Serial.begin(9600);
  while (!compass.begin())
  {
    Serial.println("Could not find a valid 5883 sensor, check wiring!");
    delay(500);
  }

  Serial.println("Initialize HMC5883");

  //Set/get the compass signal gain range, default to be 1.3 Ga
  // compass.setRange(HMC5883L_RANGE_1_3GA);
  // Serial.print("compass range is:");
  // Serial.println(compass.getRange());

  //Set/get measurement mode
  // compass.setMeasurementMode(HMC5883L_CONTINOUS);
  // Serial.print("compass measurement mode is:");
  // Serial.println(compass.getMeasurementMode());

  //Set/get the data collection frequency of the sensor
  // compass.setDataRate(HMC5883L_DATARATE_15HZ);
  // Serial.print("compass data rate is:");
  // Serial.println(compass.getDataRate());

  //Get/get sensor status
  // compass.setSamples(HMC5883L_SAMPLES_8);
  // Serial.print("compass samples is:");
  // Serial.println(compass.getSamples());

  delay(1000);
}
void loop()
{
  /**
     @brief  Set declination angle on your location and fix heading
     @n      You can find your declination on: http://magnetic-declination.com/
     @n      (+) Positive or (-) for negative
     @n      For Bytom / Poland declination angle is 4'26E (positive)
     @n      Formula: (deg + (min / 60.0)) / (180 / PI);
  */
  float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / PI);
  compass.setDeclinationAngle(declinationAngle);
  sVector_t mag = compass.readRaw();
  compass.getHeadingDegrees();
  Serial.print("X:");
  Serial.print(mag.XAxis);
  Serial.print(" Y:");
  Serial.print(mag.YAxis);
  Serial.print(" Z:");
  Serial.println(mag.ZAxis);
  Serial.print("Degress = ");
  Serial.println(mag.HeadingDegress);
  delay(300);
}

Only trouble is, it's a bit heavy. Takes a lot more memory than the Adafruit one.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.