Arduino Due HMC5883l

Hello everyone,

this forum has helped me a lot of times without having to post something so this is actually my first post.
My problem: I have an arduino due and I am trying to communicate with HMC5883l through I2C. I have already connected the HMC to my arduino uno and it worked fine so I believe the sensor is ok. When I connected it to arduino due though the values don't change when I rotate the board HMC is mounted on. The HMC is connected to SDA(20) and SCL(21) without any pull-up resistors and I power it with 3.3V.

Here is the code :

#include <Wire.h>

#define adress 0x1E

void setup() {
 Serial.begin(9600);
 delay(10);
 Wire.begin();

 Wire.beginTransmission(adress);
 Wire.write(0x02);
 Wire.write(0x00);
 Wire.endTransmission();

}

void loop() {
 int16_t x,y,z;
  
 Wire.beginTransmission(adress);
 Wire.write(0x03);
 Wire.endTransmission();

 Wire.requestFrom(adress,6);
 if(Wire.available() <= 6){
   
   x = Wire.read() << 8 | Wire.read();
   z = Wire.read() << 8 | Wire.read();
   y = Wire.read() << 8 | Wire.read();
 
 }

 Serial.print("X=");
 Serial.print(x);
 Serial.print(", Y=");
 Serial.print(y);
 Serial.print(", Z=");
 Serial.println(z);
 
 float heading=atan2(x, y)/0.0174532925;
 if(heading < 0) heading+=360;
 heading=360-heading; // N=0/360, E=90, S=180, W=270
 
 Serial.println(heading);  
 delay(500);
}

Any help would be really appreciated!!

How did you connect the grounds ?

Hello ard_newbie.

I connected the ground from arduino to ground of HMC.
Here are the readings I get :

X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00
X=-1, Y=-1, Z=-1
135.00

Shoudn't it be : if(6<=Wire.available()){ .... ?

BTW Edit your post and post your code between code tags

Sorry about that, like I said it's my first post.

Like I said the code works for arduino uno so I don't think there is a problem there. I changed it anyway and the receiving values changed but still remained steady during rotation.

X=30532, Y=2464, Z=-24431
274.61
X=30532, Y=2464, Z=-24431
274.61
X=30532, Y=2464, Z=-24431
274.61
X=30532, Y=2464, Z=-24431
274.61

If you have a long I2C bus, you have ringing on the falling edges.

It appears that the AVRs have 50ns glitch filters and falling edge slew limiters built into the TWI hardware. The ARM Cortex M3 has nothing to filter glitchs.

See this thread, reply 19 for a workaround.
https://forum.arduino.cc/index.php?topic=358428.15

That was really helpful. So the way to do it is to use 200 pF capacitors form SDA and SCL of HMC 5883l to ground?

So, have you done it yet? add the capacitor 200pF. Cause i have an issue just like you

I had the same issue using the HMC5983 magnetometer, (it's the same as the HMC5883L, but with temperature compensation), in conjuction with an Atmel SAMD51 ARM Cortex M4F micro-controller. The falling edges on SAMD51 are particularly harsh. Undershoot and ringing on both the clock and data signals caused the magnetometer to crash with the SCL line held low, effectively hanging the I2C bus.

The same set-up had worked faultlessly with the SAMD21 ARM Cortex M0+ micro-controller, (used on the Arduino Zero).

Rather than adding extra capacitance, (the I2C has a maximum bus capacitance of 400pF), I instead added two 100 Ohm series resistors to the SCL and SDA lines, (in addition to the standard I2C pull-ups at 2.2kOhms). These current limiting resistors reduced the signal slew rate, undershoot and ringing, allowing the I2C bus to operate normally (at 400kHz) oncemore.