chipKIT® Development Platform

Inspired by Arduino™

Problem communicate between Uno and Compass using I2C

Created Tue, 20 Nov 2012 21:33:20 +0000 by PICedh


PICedh

Tue, 20 Nov 2012 21:33:20 +0000

hello,

I have connected the Compass CMPS03 to my chipkit Uno using I2C (SDA,SCL) but I have a error 3: data NACK when the PIC send the register number I wish to read. I use the Wire lib as follow:

Wire.begin(CMPS03_ADDRESS); Wire.beginTransmission(CMPS03_ADDRESS); Wire.send(0); // use register 0 int ret = Wire.endTransmission();

the value returned by ret = 3 (data NACK) instead of 0 (successs)

Do you have any idea why the slave nack the data ?

Do you know an other lib, I see that wire lib is not very efficient because it wait for interruption: while (wait && TW_IDLE != TW_STATUS) { asm volatile("nop"); }

Thanks


les1943

Tue, 20 Nov 2012 23:37:06 +0000

wire.begin(CMPS03) starts the I2C master driver your CMPS03 is the slave device address try just wire.begin();


PICedh

Wed, 21 Nov 2012 08:01:12 +0000

Before I tryed just wire.begin() but I got the error 2 : nack adress

The fact to add the slave address calling wire.begin force the call of the function twi_slaveInit which seems good because it initialises ptwi->ixAdd.reg = address.

/*

  • Function twi_slaveInit
  • Desc sets slave address
  • Input none
  • Output none */ void twi_setAddress(uint8_t address) { // set twi slave address ptwi->ixAdd.reg = address;

}

anyway I don't see the impact regarding my data nack error


les1943

Wed, 21 Nov 2012 09:51:21 +0000

Two questions , what is the compass device address and what address do you code in the uno ? in HEX !


PICedh

Wed, 21 Nov 2012 12:20:30 +0000

the compass adress on 7-bit is 0x60 (1100000) this is also the value ( 0x60) I code in the Uno


les1943

Wed, 21 Nov 2012 14:25:59 +0000

The 7 bit address is the clue here , working with I2C EEPROM with the address found in the data sheet Ax 'H where x is the hard wired low address bits A0-A2 ( ignore bit 0) however in UNO I had to address 5x 'H (shifted right 1) also with other I2C devices , MCP23008 expander as 4E'H became 27'H it hangs on the way the address is merged with the R/W bit in UNO. so try 30'H for your compass.


PICedh

Wed, 21 Nov 2012 15:52:39 +0000

yes I known this issue with the adress shifted and it is explained in the Compas doc attached


les1943

Wed, 21 Nov 2012 16:49:52 +0000

So it was already shifted.... 8-)
basic stuff check ...

just the two I2C ports ?

straps JP6 JP8 on uno

2k2 pullups ?

common gnd ?

have you tried

Wire.requestFrom(CMPS03,1);
if(!Wire.available()){}
result = Wire.receive(); Wire.endTransmission();


PICedh

Wed, 21 Nov 2012 19:33:20 +0000

YES just the two I2C ports SDA, clock

YES straps JP6 JP8 on uno

10K pullups on SDA and clock

YES common gnd

I have tried your example, Wire.available returns false


les1943

Wed, 21 Nov 2012 19:42:54 +0000

Hi , pullups for standard I2C speeds should be around 1k2 , 10k may be too high I use 2k2

edit after deep thought

expecting result to be byte or int , i guess false is 00 ..

but it does return something ! is the problem in the requests you are making to compass

datasheet " like eeprom protocol" you normally send address and a location then read device.

compass a 5v are device pullups to 5v or 3v3


PICedh

Wed, 21 Nov 2012 20:00:23 +0000

I will change the resistor to see if it is better Compass uses 5V During the test, I get between 0 and 4.5 V on the clock pin and a constant 3.7 V on the data pin


les1943

Wed, 21 Nov 2012 20:06:10 +0000

Waiting for my iron to warm up !

These calls are what works for my eeprom ( Its not my code, not that good !) but did work first time ,

///////////////////////////////////////////////////////////////// byte WireEepromReadByte(int EEprom, unsigned int theMemoryAddress) { byte theByteArray[sizeof(byte)]; WireEepromRead(EEprom, theMemoryAddress, sizeof(byte), theByteArray); return (byte)(((theByteArray[0] << 0))); } /////////////////////////////////////////////////////////////////////////////// int WireEepromReadInt(int EEprom, unsigned int theMemoryAddress) { byte theByteArray[sizeof(int)]; WireEepromRead(EEprom, theMemoryAddress, sizeof(int), theByteArray); return (int)(((theByteArray[0] << 8)) | (int)((theByteArray[1] << 0))); }


PICedh

Wed, 21 Nov 2012 20:55:02 +0000

I have replaced resitors by 1K, same problem... :( :( :(


PICedh

Wed, 21 Nov 2012 21:27:35 +0000

Yep it's works now ! The weld was bad !

Thanks again :D :D :D


les1943

Wed, 21 Nov 2012 22:13:40 +0000

Your welding it !!! :D

Never had so much fun