Pages: 1 2 [3] 4   Go Down
Author Topic: HMC6352  (Read 10318 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 61
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

My last post was wrong!  I tried the 24LC256 using Wire, and some code from this forum, and it seemed to work, but I realize now it is only because Wire uses the same buffer for put and get, and if I zero the buffer before the read, no data comes back.

This may be because I have my eeprom hooked up wrong, or maybe Wire isn't working in this situation.

Also, I see good ACK from addressing these devices with avrlib hardware and software, but the reads don't get any data.  I think it's worth making i2c work reliably under Arduino, and I'll keep working on it.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
My last post was wrong!  I tried the 24LC256 using Wire, and some code from this forum, and it seemed to work, but I realize now it is only because Wire uses the same buffer for put and get...
I noticed the exact same thing... rather than waiting for a response, my next request just comes back with the last value I transmitted.

Let me know if there is anything I can do to help you test... I have two Arduino NGs, one with an Atmega8 and one with a Atmega168
Logged

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

Hi stuhood - if you want to try out my avrlib code, I can email it to you.  It would be useful to test out i2c master on one Arduino and slave on the other, and be able to log what both are doing.  I can also send you some software bit-bashing code to test the same way - if this could be made to work it would be nice, since any digital pins could be used instead of losing two analog pins.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm having similar issues and willing to help test and refine if someone can send me the code, or point me to where I can download it.

Thanks,
Josh
Logged

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

I just received my new oscilloscope today, and hopefully this will help make sense out of what is happening with i2c.  The first thing I looked at was a little program using the Wire lib to read a DS1307 clock.  This works perfectly, and the SCL and SDA lines do just what one would expect - you can see the ACK on the SDA line.

I will try to figure out how to insert images here, but my first try didn't work.

Next I looked my code that works with the HMC6352.  Strangely enough, after the first i2c transaction, address 0x42 and data 0x41, to request a heading, there was no ACK.  But the code goes on to work perfectly????  I am trying to figure out how to look at the data read, which is 7 ms later - need to learn more about the new scope.  It's a brand-new Tektronix 2012B, and it's wonderful!

I think the fact that the AVRLIB code works is an accident.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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......  smiley-sad

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

-- Josh
Logged

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

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

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!
« Last Edit: March 28, 2007, 06:01:52 pm by drd » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 :-[

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
Logged

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

OK, got the 24lc256 to work fine using Wire.  Here's the code:
Code:
#include <Wire.h>

// Simple read & write to a 24LC256 via the TWI library
// Using the Wire library (created by Nicholas Zambetti)
// http://wiring.org.co/reference/libraries/Wire/index.html
// On the Arduino board, Analog In 4 is SDA, Analog In 5 is SCL
// These correspond to pin 27 (PC4/ADC4/SDA) and pin 28 (PC5/ADC5/SCL) on the Atmega8
// The Wire class handles the TWI transactions, abstracting the nitty-gritty to make
// prototyping easy.


void writestuff(){
  Wire.beginTransmission(0x50);
  Wire.send(0x00);
  Wire.send(0x00);
  // write some data out
  Wire.send(0x00);
  Wire.send(0x01);
  Wire.send(0x02);
  Wire.send(0x03);
  Wire.send(0x04);
  Wire.send(0x05);
  Wire.send("h");
  Wire.send("i");
  Wire.endTransmission();
}

void readstuff(){
  Wire.beginTransmission(0x50);
  Wire.send(0x00);
  Wire.send(0x00);
  Wire.endTransmission();
  Wire.requestFrom(0x50, 10);
  while(Wire.available()){
    Serial.print("  ");
    Serial.print(Wire.receive(), HEX);
  }
  Wire.endTransmission();
}

void setup()

{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(19200);
}

void loop()
{
  Serial.print(" writing ");
  writestuff();
  Serial.println(".");
  Serial.print(" reading ");
  readstuff();
  Serial.println(".");
  Serial.println(" done ");
  delay(250000);
}



Seems like Wire is doing everything perfectly.  I still think it is worth making a software i2c library so you can use other pins - also both software i2c and avrlib i2c are much smaller than including Wire.  I'll keep working on that stuff.
Logged

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

I have software i2c working fine with all devices, and it can use any pins, even analog 4 and 5.  It is only a single-master code, so it is small, and if you need all your analog pins for analog stuff, this is the way to go.

I'm still struggling with making this into a library, so if anyone wants to test this stuff I'm happy to email it to you.  So far I've tested it with HMC6352, DS1307 and 24LC256.  I'm working on DS1631 now.  If anyone is interested in other i2c devices, let me know, (especially if they are cheap!) let me know - I want to get this code working solidly for Arduino before I move on to something else.

The neat thing about software i2c is it will work on any AVR processor, even if they don't have hardware i2c.  Also, the ISR for i2c gets pretty big, and you lose those two A/D pins.  It might be fun to get Arduino to work on the ATtiny85 - I have some and I think it may be do-able.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm up for helping to make software I2C into a library.  Can you email or post your code as it stands?

Thanks,
Josh
Logged

The Netherlands
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Fail faster to succeed sooner!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi drd,

I'd like to test out your software I2C lib.
I just bought an 24LC256 and want to try to get it working on my Arduino Mini.

Could you post it somewhere or mail it to me?

Thanks!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just want to justify on what Drd wrote so it's easier to use it right away. Wiring scheme is included
in the comments to the code. Thanks.

Code:
#include <Wire.h>

// Simple read & write to a 24LC256 via the TWI library
// Using the Wire library (created by Nicholas Zambetti)
// http://wiring.org.co/reference/libraries/Wire/index.html
// On the Arduino board, Analog In 4 is SDA, Analog In 5 is SCL
// These correspond to pin 27 (PC4/ADC4/SDA) and pin 28 (PC5/ADC5/SCL) on the Atmega8
// The Wire class handles the TWI transactions, abstracting the nitty-gritty to make
// prototyping easy.

//      _ _
//  A0-|oU |-Vcc
//  A1-|   |-WP
//  A2-|   |-SCL
// Vss-|   |-SDA
//      ---
//  
//SDA goes to Arduino 4
//SCL goes to Arduino 5
//WP  goes to ground for now. Can be put to Vcc if write protection is needed.
//Vcc goes to arduino Vcc
//Vss goes to arduino ground
//A2, A1, A0 go to ground for now. They can be also put to either ground or Vcc to control up to 8 memory chips (2^3), giving you 2MBit of memory (8*2^15).

char chipAdress=0x50; // Binary 10100000 . Three bits after 1010 (currently 000) are used to specify to what A2, A1, A0 are connected
                      // For example, 10101010 would correspond to chip with A2 put to Vcc, A1 to ground, and A0 to Vcc.
                      // Last bit specifies the opertation - 0 for write, 1 for read. This is controlled for you by the Wire library.


//Writes to the specified address
void writeToRandomPosition(){
  Serial.print("Writing ... ");
  Wire.beginTransmission(chipAdress);
 //Set up the address first
  Wire.send(0x00);  //First  7 bits of the address
  Wire.send(0x00);  //Second 8 bits of the address
  // write some data out - not more then 64 bytes. Otherwise the chip's
  // address counter will roll over and the previously received data will be overwritten.
  Wire.send(0x00);
  Wire.send(0x01);
  Wire.send(0x02);
  Wire.send(0x03);
  Wire.send(0x04);
  Wire.send(0x05);
  Wire.send("h");
  Wire.send("i");
  Wire.endTransmission();
  Serial.println(" Done.");
}


//Reads from the specified address
void readFromSpecificPosition(){
  Serial.print("Reading from the specific address ");
  Wire.beginTransmission(chipAdress);
 //Set up the address first
  Wire.send(0x00);   //First  7 bits of the address
  Wire.send(0x00);   //Second 8 bits of the address
  Wire.endTransmission();
  //Now, let's read some data. The whole memory can be read at once (2^15 bytes)
  Wire.requestFrom(chipAdress, 4);
  while(Wire.available()){
    Serial.print("  ");
    Serial.print(Wire.receive(), HEX);
  }
  Wire.endTransmission();
  Serial.println(".");
}

//Reads starting from the last accessed address
void readAddress(){
  Serial.print("Reading from the the current address: ");
  Wire.requestFrom(chipAdress, 3);
  while(Wire.available()){
    Serial.print("  ");
    Serial.print(Wire.receive(), HEX);
  }
  Wire.endTransmission();
  Serial.println(".");
}


void setup()

{
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(19200);
}

void loop()
{
  
  writestuff();
  readstuff();
  readAddress();
  Serial.println("");
  delay(1000);
}

« Last Edit: July 18, 2007, 10:44:39 am by Maksym » Logged

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