HMC5883L reading problem

Hi all,
Recently I met a HMC5883L magnetic compass reading problem. After I connected it with my arduino, I can read output values correctly. but after rotating it sometimes say 15 seconds later, something strange happened. the value shown on the Serial window was either stopped or just continusly shows the same value. First I was wondering maybe it is the Serial.println problem, but later I use the compass to control a servo.
It did the same thing as I described above. The servo rotation is just stopped, no matter how I rotate the sensor.
Could any one help me out.
Thanks.
below is my code

#include <Wire.h>
double res = 0;
void setup()
{
Wire.begin();
Serial.begin(9600);
initHMC5843();
delay(100);
}
void loop()
{
readxyz();
}
void initHMC5843()
{
delay(5);
Wire.beginTransmission(0x1E);// 7 bits address
Wire.send(0x02);
Wire.send(0x00); // continues reading
Wire.endTransmission();
}

void readxyz()
{
Wire.beginTransmission(0x1E);
Wire.send(0x03);
Wire.endTransmission();
delay(5);
Wire.requestFrom(0x1E, 6);
if(6 <= Wire.available())
{
int x,y,z;
x = Wire.receive() << 8;
x |= Wire.receive();
y = Wire.receive() << 8;
y |= Wire.receive();
z = Wire.receive() << 8;
z |= Wire.receive();
if(x>0)
{
res = map(x, 0, 246, 0, 90);
}
else if(x<0)
{
if(x!=0)
{
res = abs(x);
res = map(res,0,255,90,0);
res = 270+res;
}
else
res = 0;
}
Serial.println(res);
}
}

Please use # button for code in the forum editor.

This is a mysterious device as Google cannot find no reference. Do you have a datasheet / URL?
BIng gave some hits at Honeywell space division but the sitesearch gave nothing. Where did you get this compass? Bought an retired spaceshuttle? :slight_smile:

The HMC5883L is a newly updated version for HMC5883, and the replacement for the HMC5843, because HMC5843 will discontinues the production.
Here is the datasheet url:
http://www.cgs-tech.com/pdf/HMC5883L.pdf

1 Like
   Wire.requestFrom(0x1E, 6);
   if(6 <= Wire.available())

You request 6 bytes and immediately test if they are available, if this is not the case the whole if statement is skipped and loop starts over again. This may be a critical piece of timing.

Insert an active waiting loop that test if enough data is available with a max of ~1 second. Code below is not tested...

for (int i=0; i< 1000; i++)
{ 
if ( 6 >= Wire.available()) break;
delay(1);
}