Go Down

Topic: HMC6352 (Read 11 times) previous topic - next topic

Josh

That is very interesting.  I'll be integrating the code you emailed me later tonight and checking it out as well.  I may have had similar issues with other devices in regards to the "ACK" - as some are documented to work this way I believe.  I know when I tried a DS1631 it had cases for no "ACK", and specifically I'm referring to the EEPROM I'm working with right now (the 24LC256) - which in the datasheet (http://www.sparkfun.com/datasheets/IC/24LC256.pdf) says things like this:

Note: The 24XX256 does not generate any Acknowledge bits if an internal programming cycle is in progress.

Also in this same datasheet it says that the final data read would have no ACK, just a stop (bottom of page 11).  So it would seem there are valid conditions for no ACK to be normal.  Not sure if that is your case here or not - just thought I would share some thoughts.

Congratulations on the new Scope!!! I wish I had money for something like that......  :(

I'm excited about your findings and it sounds like your getting very close.

-- Josh

drd

Well, being able to look at the signals with a scope makes all the difference.  I now have Arduino working reliably with the HMC6453 and the DS1307 RTC on the same i2c bus.  There are 3 ways to do it.  One is the interrupt-driven avrlib code ported to Arduino, the second is a software bit-bashing routine I modified so it could deal with the clock-stretching the HMC does, the third is, Wire!  Turns out Wire works fine, you just need to use the right addresses.

Here's a little Wire program to read the HMC6453:

Code: [Select]

#include <Wire.h>

void setup()
{
 Wire.begin();
 Serial.begin(19200);
}

byte val = 0;
byte data[2];
int deg, j, frac;

void loop()
{
 Wire.beginTransmission(0x21);
 Wire.send(0x41);
 Wire.endTransmission();
 delay(70);
 Wire.beginTransmission(0x21);
 Wire.requestFrom(0x21, 2);
 j = 0;
 while(Wire.available())
 {
   char c = Wire.receive();
   data[j] = c;
   j++;
 }
 Wire.endTransmission();
 Serial.print(" heading = ");
 frac = data[0]*256 + data[1];
 deg = frac / 10;
 frac = frac - deg * 10;
 Serial.print(deg);
 Serial.print(".");
 Serial.println(frac);
 delay(5000);
}





I will tidy up the other two and try to make them into libraries.  The software has the advantage of being small and simple, and can use any pins, not just analog 4 and 5, but it is single-master only so far.  The avrlib is nice, and versatile, but not as simple to use as Wire.

Enjoy!

D.

Josh

So if I understand you correctly, you just had the I2C address wrong on the HMC?  Or did introducing a delay, having the "beginTransmission" immediatly followed by the "requestFrom", etc - make any difference.  I'm wondering if you got your 24LC256 working or not as well.  I am fairly certain I have the correct address using the Wire lib, yet I'm not getting it to work.  If you could hook yours up and scope if it does not work - I would really appreciate it.

Congrats on getting your HMC working!

-- Josh

drd

#38
Mar 29, 2007, 12:29 am Last Edit: Mar 29, 2007, 01:01 am by drd Reason: 1
Looks like Wire wants the address in 7-bit form - so the 0x42 from the datasheet turns into 0x21, then Wire sets the R/W bit itself depending on what you ask it to do.  Further back on this thread the scope pictures should have made this obvious, but I didn't get it.  The working example for the DS1307 used an address of 0x68, yet the 1307 datasheet said the address is 0xd0 - hmmm!

The way it works is the most significant 7 bits are the device address, and the LS bit is 0 for write and 1 for read.  Once I saw the signals on the scope it became obvious.  

I haven't wired up the 24LC256 yet, but I think the address Wire wants would be 0x50.  I need to wire mine up again - ran out of breadboards.  We'll get it running - no worries.  Hopefully I'll have something tomorrow.

The 70 ms delay before the  i2c read only needs to be 7 ms.  I made it 70 ms so I could punch a button on my scope to catch the second i2c transaction.

Having a scope turns this from frustrating into great fun!

Josh

:-[

Ok, so I'm stupid.  Your right, it is just the address - 0x50.  Wire only wants the 7 bits....  I can't believe I didnt put that together.  Sometimes having the right tools is what it is all about.  I'm betting all my other devices will work fine now if I get it right.  At least you have some cool code that others can use to do I2C over other pins - that could be a big help for some.

Thanks All!!

-- Josh

Go Up