Go Down

Topic: Problems with HMC5843 (Read 5131 times) previous topic - next topic

Crappinni

Hello,

Thanks for replying! I'll try all that in a bit and report the results!

Currently I'm only using Sparkfun's test code (they sent it to me previously) but I've also tried other sketches like the HMC5843 driver so I guess it isn't a problem with the code.

Bo Xuan

Crappinni

Fabio: I've tried communicating with and without pullups and both don't work. I've used pullups of various values so I doubt that's the problem too.

wayneft: I used 2 AA batteries which gave 3.07V to power the HMC5843 breakout and tried both with and without the logic shifter, and with and without setting it to IDLE mode. None of these work (no communication at all).

I swapped back to using the 3.3V regulator, and this time I tried with and without setting it to IDLE mode, and it doesn't work as well.

Using the code Sparkfun sent me, all I can get with the serial monitor is "setting up HMC". It seems to me it gets stuck during the Wire.send() (perhaps waiting for ACK). So maybe I can't even get far enough to tell it to be in IDLE mode.

Here's the original code Sparkfun sent me. I sent 0x02 to the Mode register to try and set it to IDLE mode.

Code: [Select]
// Demonstration sketch for HMC5843 3-axis magnetometer (SparkFun SEN-09371)
// Mike Grusin, SparkFun Electronics, 8/20/2010

// i2c bus connections:
// connect SDA to analog 4
// connect SCL to analog 5

// power sensor with 3.3V from Arduino
// connect 5K-10K pullup resistors to SCA and SDL to 3.3V

#include <Wire.h>


void setup()
{
 Wire.begin();        // set up i2c bus
 Serial.begin(9600);  // set up serial port

 delay(10);           // wait for HMC to boot up
 setup_HMC5843();     // initialize HMC
}


void loop()
{
 read_HMC5843();      // get all magnetometer results, loop
 delay(1000);
}


void setup_HMC5843()
{
 byte result;

 Serial.print("setting up HMC\n");
 
 Wire.beginTransmission(0x1E);      // i2c address (use 7-bit address, wire library will modify for read/write)
 Wire.send(0x02);                   // register to write (0x02 = mode register, see datasheet)
 Wire.send(0x00);                   // write value to register (0.5Hz output rate, normal measurement configuration. See datasheet)
 result = Wire.endTransmission();

 printstatus(result);
}


void read_HMC5843()
{
 int x,y,z;
 byte xmsb,xlsb,ymsb,ylsb,zmsb,zlsb;
 byte result;
 
 Serial.print("ask for readings\n");
 
 Wire.beginTransmission(0x1E);      // i2c address (use 7-bit address, wire library will modify for read/write)
 Wire.send(0x03);                   // register to read (0x03 = first result register, see datasheet)
 result = Wire.endTransmission();
 printstatus(result);

 Wire.requestFrom(0x1E, 6);         // read next six registers (0x03 to 0x08, see datasheet)
 x = Wire.available();              // make sure read was successful
 Serial.print(x, DEC); Serial.print(" bytes available\n");
 if (x == 6)
 {
   xmsb = Wire.receive();    // read out six bytes = three readings (x,y,z)
   xlsb = Wire.receive();    // each reading is split into two bytes (msb, lsb)
   ymsb = Wire.receive();    // msb = most-significant byte ("high byte")
   ylsb = Wire.receive();    // lsb = least-significant byte ("low byte")
   zmsb = Wire.receive();
   zlsb = Wire.receive();
   
   x = word(xmsb,xlsb);      // combine bytes to get readings
   y = word(ymsb,ylsb);      // result = msb*256 + lsb
   z = word(zmsb,zlsb);
   
   Serial.print("X "); Serial.println(x, DEC);
   Serial.print("Y "); Serial.println(y, DEC);
   Serial.print("Z "); Serial.println(z, DEC);
 }
}


void printstatus(byte result)    // Wire.endTransmission can tell you if an i2c transaction was successful or not
{
 Serial.print("I2C status: ");
 Serial.print(result, DEC);
 switch (result)
 {
   case 0:
     Serial.print(", success!\n");
     break;
   case 1:
     Serial.print(", data too long to fit in transmit buffer\n");
     break;
   case 2:
     Serial.print(", received NACK on transmit of address\n");
     break;
   case 3:
     Serial.print(", received NACK on transmit of data\n");
     break;
   case 4:
     Serial.print(", other error\n");
     break;
 }
}

wayneft

Quote
Using the code Sparkfun sent me, all I can get with the serial monitor is "setting up HMC"


Is it only printing out once or is it printing out over and over again?

There's no reason why it should freeze at this point in the code.  If it's continually printing that statement then your Arduino is resetting itself.

Are you using a Duem. or Uno?
I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Crappinni

I'm using an Uno. It only prints once.

If I'm correct, the Wire library doesn't have an I2C timeout, meaning it's possible for a device to be stuck forever waiting for an ACK, or if a device is not working properly and holding the SCL low, the master will be waiting forever.

I guess those are possible reasons for it to be stuck at that stage.

Bo Xuan

wayneft

Unless you have access to an oscilloscope to look at the signals, I'm out of ideas.  The only thing I can tell you is I looked at one of your previous pictures and and you had the compass wired directly to the UNO with a couple of pullup resistor tied to 3.3 volts.  If I were you I would continue to use the logic level converter because keep in mind the Arduino has internal pullup resistors pulled to 5volts so you're effectively tying 2 different voltage sources together (probably not a good idea).

Let us know if you find anything else.
I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Crappinni

Thanks! I'll try to get access to an oscilloscope if necessary. Do you have any suggestions as to what I should be looking out for using the oscilloscope besides the start, stop and ACK signals?

However, I'm not very sure how I can transmit these signals distinctively. The Wire library seems to use a different sequence and the current state of my own TWI functions is rather pathetic..

Bo Xuan

wayneft

Here's one more thing to try:

First add these two lines to the Sparkfun code after Wire.begin() which should disable the internal pullups:
Code: [Select]

cbi(PORTC,5);
cbi(PORTC,4);


Next wire up the Sparkfun converter but don't connect the HV line to 5volts just leave it floating (doing this takes the 10K pullup resistor to 5volts out of the picture). Since most people seem to recommend a 4.7K resistor as a pullup put 10K ohm resistors on the 3.3v side of the lines.  The reason for this is the sparkfun pcb already has a 10K pullup so two in parallel takes you 5K.

Give it a try and see if it works.
I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Crappinni

wayneft, I just tried that but I get an error compiling the code because "cbi was not declared in this scope". I have no experience using this function.. Do I have to declare or include something beforehand?

Bo Xuan

wayneft

whoops

add this below include

Code: [Select]
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Crappinni

wayneft, I manage to the #define for cbi and just copied it in. At first it didn't work but after I connected the 5V on the HV side, there was communication!

It still isn't stable and freezes after a while but this is a huge improvement! Thanks!

Do you know what caused this problem?

Bo Xuan

wayneft

Quote
Do you know what caused this problem?


No I don't sorry.

I'm surprised it didn't work better with the HV disconnected?  Oh well the only thing I can tell you is to try and hook up a scope and look at the I2C signals to make sure they look OK.  Who knows maybe you'll have to play around with different values of pull up resistors.
I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Crappinni

Sure thanks! I'll test it more first. Currently I only can get communication 25% of the time. And it freezes within a few seconds. Also the ACK status is 0 (supposedly meaning success), the number of bytes available fluctuates and sometimes the readings simply don't appear.

Bo Xuan

Crappinni

Ok just now it was 25%. Now it's more like 1%. Using different pullups doesn't help. Even reverting back to the setup where I got some communication couldn't save it.

I haven't gotten any communication since the previous post. Most mysterious. Seems like another case of hit and run...

Bo Xuan

Crappinni

Hello people,

I received my third HMC5843 (second replacement) and it's working happily. It does seem I defeated the odds and received two faulty ones consecutively!

Thanks for all the help!

Bo Xuan


Go Up