Pages: 1 2 [3]   Go Down
Author Topic: Problems with HMC5843  (Read 3191 times)
0 Members and 1 Guest are viewing this topic.
Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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;
  }
}
Logged

Worcester, MA
Offline Offline
God Member
*****
Karma: 2
Posts: 623
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Worcester, MA
Offline Offline
God Member
*****
Karma: 2
Posts: 623
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Worcester, MA
Offline Offline
God Member
*****
Karma: 2
Posts: 623
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
Logged

I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Worcester, MA
Offline Offline
God Member
*****
Karma: 2
Posts: 623
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

whoops

add this below include

Code:
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
Logged

I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Worcester, MA
Offline Offline
God Member
*****
Karma: 2
Posts: 623
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

I2C GPS Shield

Checkout my Open Source GPS Tracker on Kickstarter

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Singapore
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Torino, Italy
Offline Offline
Sr. Member
****
Karma: 2
Posts: 312
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What a bad luck!
Logged

Pages: 1 2 [3]   Go Up
Jump to: