Problem in Adafruit HMC5883L mega sensor code

Hey,

I have bought GY-271 Magnetometer sensor and connected it to my arduino uno board.
I used the adafruit HMC5883l library! here

When I run my code , it just displays the Sensor information and not the values

Using print statements and backpropagating this what i found

  • In the megasenosr example code , problem was with getEvent(), function control never returned from that function
void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; // never returned from this fun
  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");

[/li]

  • going back and looking at getEvent(), i found that the fun read() never returned the control
bool Adafruit_HMC5883_Unified::getEvent(sensors_event_t *event) {
  /* Clear the event */
  memset(event, 0, sizeof(sensors_event_t));

  /* Read new data */
Serial.println("going to Read data...");

  read();//never returned from here
Serial.println("Read data...");
  
  event->version   = sizeof(sensors_event_t);
  event->sensor_id = _sensorID;
  event->type      = SENSOR_TYPE_MAGNETIC_FIELD;
  event->timestamp = 0;
  event->magnetic.x = _magData.x / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
  event->magnetic.y = _magData.y / _hmc5883_Gauss_LSB_XY * SENSORS_GAUSS_TO_MICROTESLA;
  event->magnetic.z = _magData.z / _hmc5883_Gauss_LSB_Z * SENSORS_GAUSS_TO_MICROTESLA;
  
  return true;
}

[/li]

  • going bak to read function, I found that function never escaped out of “while(Wire.available() < 6);”
void Adafruit_HMC5883_Unified::read()
{
  // Read the magnetometer
Serial.println("Reading data 1 ...");

  Wire.beginTransmission((byte)HMC5883_ADDRESS_MAG);
Serial.println("Read data 2...");

  #if ARDUINO >= 100
    Wire.write(HMC5883_REGISTER_MAG_OUT_X_H_M);
Serial.println("Read data 3...");

  #else
    Wire.send(HMC5883_REGISTER_MAG_OUT_X_H_M);
Serial.println("Read data4...");

  #endif
  Wire.endTransmission();
Serial.println("Read data 5...");

  Wire.requestFrom((byte)HMC5883_ADDRESS_MAG, (byte)6);
Serial.println("Read data 6...");

  
  // Wait around until enough data is available
  while(Wire.available() < 6); // never rerturned from here


Serial.println("Read data  7...");


  // Note high before low (different than accel)  
[/code[/li]
[/list]

When i removed the while loop , my code started working but then the values remained constant even when i keep changing the position of my sensor

Seems like it would have been a lot safer for them to add a timeout on that code and then return an error code.

I'd check your connections on the sensor.

I cross checked my connection thousands of times now, And I am sure it's correctly connected!

But still, have no idea why the loop goes into infinite and why am I not getting correct values

Here’s an issue report about that while statement not being necessary:
https://github.com/adafruit/Adafruit_HMC5883_Unified/issues/1

Here’s someone proposing adding the timeout I had mentioned:
https://github.com/adafruit/Adafruit_HMC5883_Unified/pull/4

Hey ! Thanks for replying.

I am someone who is new to this hardware world but have lot of programming experience

Going through those links that you shared, what I understood is (Correct me if I'm wrong)

-> its line if we ignore the while() statement

->I removed the while statement but I get constant values only

->wanted to make sure that does begin() actually checks if my sensor is working or not?

It would be great if you could brief it up and suggest e the changes that should be made to the code

bool Adafruit_HMC5883_Unified::begin()
{
  // Enable I2C
  Wire.begin();

  // Enable the magnetometer
  write8(HMC5883_ADDRESS_MAG, HMC5883_REGISTER_MAG_MR_REG_M, 0x00);
  
  // Set the gain to a known level
  setMagGain(HMC5883_MAGGAIN_1_3);

  return true;
}

The begin() changes were actually unrelated to the addition of a timeout so I don't know why the person submitting that pull request pulled in that commit. It actually came from this pull request:

However, in this case since it sounds like you are interested in both those changes it works out well since you can just download and install grossadamm's fork of the repository and replace your installation of the library with his. Here's the download:
https://github.com/grossadamm/Adafruit_HMC5883_Unified/archive/master.zip
Note that you need to first remove your previous installation of the stock Adafruit library before installing the modified library. If you need instructions for doing that let me know.

I haven't looked at it closely, but if I understand correctly the solution of adding a timeout to the offending while statement offers a bit more debugging information than the alternative of removing the statement altogether since it will return false after the timeout. Of course this adds overhead to the code but in your situation where things are not working that's not the primary consideration.

Hey,
Thank you so much for replying!

I did exactly as it you told and then compiled and uploaded the code

Now, when I run the code, I get a message on monitor saying that " no HMC5883l detected".

I am pretty sure that my connections are right, so should I conclude that there is a problem with my sensor?

Moreover, I have GY-271 Hmc5883l, there are GY-273 one available too, si the code same for both these sensors?

Is Honeywell sensor same as this GY-271?

I don't have any experience with the sensor or that library but it certainly seems likely. If you got the sensor from Adafruit I know their customer service is pretty good so they might just send you a replacement if you contact them with the details.