i2c gyro code problem

gkowen

New Member
I have tried this code over and over and everything else I can think of. Instead of getting back a temperature value I just get the slave address. Does anyone see a problem with this code? I am just trying to learn i2c. It seems simple. Here is the code.

Code:
'L3G4200D -MEMS motion sensor:ultra-stable three-axis digital output gyroscope
'datasheet at addy below
'http://www.parallax.com/portals/0/downloads/docs/prod/sens/27911-GyroscopeL3G4200DDatasheet.pdf

#picaxe 08m2

;Connections 08M2
;--Pin--Name----Function--------Remark------------------
;  1	  +V	    Supply Voltage  5V 
;  2	  C.5	    Serial In	  Not Used
;  3	  C.4     Out		  Not Used
;  4    C.3     In		  Not Used
;  5    C.2     hi2c SDA	  I2C SDA 
;  6    C.1     hi2c SCL	  I2C SCL 
;  7	  C.0	    Serial Out	  Not Used
;  8    0V      Ground		  0V
;--------------------------------------------------------

Symbol	GyroSlvAddr 	= 0xD3	'From datasheet
Symbol	TempOutReg		= 0x26	'From datasheet
Symbol  	CurrentTemp		= b0		'definition

CurrentTemp				= 0xaa	'init current temp to wierd value
pause 1000						'init time

hi2csetup i2cmaster,GyroSlvAddr,i2cfast,i2cbyte	
							'i2c setup 	Master 08m2
							'		Slave = L3G4200D gyro
							'Datasheet: i2cfast (400khz) ok
							'		byte transfers
									
pause 50						'50ms delay just because

Do
	hi2cin TempOutReg, (CurrentTemp)	'read the Temp Output Register

	pause 1000					'temp updates at 1Hz 

	debug CurrentTemp				'display regs so I can see data

	CurrentTemp = 0				'clear current temp

        'Returns $d3 (GyroSlvAddr) in b0  %1101 0011 
Loop

end
 

PaulRB

Senior Member
Code looks ok to me. Are you sure circuit is correct? I2C lines pulled high with resistors? Data sheet also mentions pulling the CS pin high to enable I2C.

Paul
 

gkowen

New Member
Thanks for the reply Paul. I really appreciate it. The part is actually on a circuit board whose datasheet says the 4.7k pullups are there and that CS is pulled high. I measured voltages with a multimeter and that appears to be true. Iwill try to shorten my leads and cleanup my layout. I doubt that is it because the code doesn't work at i2cslow either. Once I figure out the problem, I will post what I find. Thanks again for your reply.

Greg
 

SAborn

Senior Member
What happens when you remove "TempOutReg" from this line............... hi2cin TempOutReg, (CurrentTemp) .........and not set a location to read from.

How long are your wires, more than a metre / 3 foot?

Perhaps post a link to the data sheet might help.
 

gkowen

New Member
I have the link to the part's data sheet in the top of the code posted above.

http://www.parallax.com/portals/0/downloads/docs/prod/sens/27911-GyroscopeL3G4200DDatasheet.pdf

The wires are about 6 inches. When I took out the TempOutReg, I get the same results which is interesting. Basically all I am trying to do is read a register from the part. It should be straight forward. Something interesting: From my understanding the LSB of the slave address is ignored and changed to a 1 for a read and 0 for a write. If I do a read with the slave addy LSB set to 0, it comes back in the register as a 1. So it seems the code is doing something. Also, if I add in another delay and debug statement after setting b0 to 0. Iget alternating SlaveAdress and 0 in the b0 byte. This says that something is being read into b0 somehow. Otherwise it would stay at 0.

Thanks for the help.

Is there such a thing as a down rev 08m2 part? I have had mine for a while. It is reported as Firmware Revision 4.A, Picaxe 08m2 Firmware Revision A.

Greg
 

hippy

Ex-Staff (retired)
Staff member
Is there such a thing as a down rev 08m2 part? I have had mine for a while. It is reported as Firmware Revision 4.A, Picaxe 08m2 Firmware Revision A.
Version 4.A is the latest 08M2 version.

Getting the slave address back on a read has I recall been symptomatic in some cases of not having the I2C bus wired correctly so double check that and perhaps post a circuit diagram. Particularly check SDA and SCL aren't swapped over. Also how is your SA0 wired?

It may be something else or something related to the particular sensor and its implementation of I2C so it would also be a good idea to see if you can get the 08M2 communicating with an I2C EEPROM and/or other I2C devices.
 

PaulRB

Senior Member
Greg, have you got another I2C device you can connect to the bus, eg. an RTC? If so, try connecting picaxe to that first to test the picaxe and your reading code, for example reading just the minutes. Then re-attach the gyro to the bus and test you can still read the rtc.

Paul
 

SAborn

Senior Member
What do you have the SDO pin tied to...high or low as this effects the slave address.

Did you read this in the data.
The slave address (SAD) associated with the L3G4200D is 110100xb. The SDO pin can be
used to modify the least significant bit (LSb) of the device address. If the SDO pin is
connected to the voltage supply, LSb is ‘1’ (address 1101001b). Otherwise, if the SDO pin is
connected to ground, the LSb value is ‘0’ (address 1101000b). This solution permits the
connection and addressing of two different gyroscopes to the same I2C bus.

So if SDO is high then the slave address is ..... LSb is ‘1’ (address 1101001b). or in your code you would use %11010010
And if SDO is low then the slave address is ..... LSb is ‘0’ (address 1101000b). or in your code you would use %11010000

What address is 0xD3 in binary (hex means little to me)
 

gkowen

New Member
0xD3 in binary is %11010011 which is the same as %11010010 because the PICAXE ignore the least significant bit. SD0 is tied high (verified with voltmeter). I have also tried %11010000 but no good. Your addressing for the temp confuses me. It is 0x26 which is %00100110. I will try your address but wondering where it came from. I really appreciate all the help. I don't have any other i2c device although I have ordered some. I am comparing the read timing/protocol for an i2c eeprom with the gyro and see if I notice anything different.

Greg
 

gkowen

New Member
Here is what the datasheets imply;

i2c eeprom read: Start - Slave Addy-ack -Register addy- ack -Start -Slave Addy- ack -Data byte- noack -STOP
gyro read: Start - Slave Addy-ack -Register addy- ack -REStart-Slave Addy- ack -Data byte- noack -STOP


could the problem be the start/restart difference?
 

SAborn

Senior Member
Your addressing for the temp confuses me. It is 0x26 which is %00100110. I will try your address but wondering where it came from.
Page 27 of the data sheet, "Output register mapping" look down the table and you will see all the addresses listed for each register, although only a 7 bit address is given (Out_Temp = 010 0110) and you must use the full 8 bit address so you just add a "0" to the end (010 01100) for the read/write bit, this bit is actually changed by the picaxe command when you use a read/write instruction so no need to change the last bit to suit R/W.

There is only 7 bits listed as in another column it lists if its a R or W command and the 8th bit is added to suit the command used.

You could try the "Who_Am_I" command and send 000 11110 out as an address and it should return 11010011 back to the picaxe register.
 
Last edited:

gkowen

New Member
Actually in the "Output register mapping" they just omitted the left hand MSB of the address. The Temp Out Register is at 0x26 or %00100110. The problem with the "Who_Am_I" command which is at 0x0f or %00001111 is that it's value is the slave address of the device. I always get the slave address back when I read. This would make it look like it was working. That is why I use the TempOut Register.
 

SAborn

Senior Member
Try this code and see what you get.

Code:
#picaxe 08m2

main:

i2cslave %11010010 ,i2cfast_4,i2cbyte

pause 50

readi2c %01001100,(b0)  'should return Temp reading

readi2c %00011110,(b1)  'should return 11010011

debug

pause 300

goto main
 

SAborn

Senior Member
One after thought that im am not sure which way around the picaxe works, but i think its LSB first and the gyro chip sends data MSB first so you might need to invert the data in program before you view it.

I think you can use the picaxe "REV" command to do this.

Given a little time someone else in better knowledge of this thought will correct or confirm this.
 

PaulRB

Senior Member
Surely the I2C standard specifies which of LSB/MSB first?

Although I could imagine confusion over order of least/most significant BYTE when sending 16 bit values.

Paul

P.S. I suspect REV is an X2 only command.
 

SAborn

Senior Member
Yes you were right with Register addresses with the extra bit is added as bit 7

In order to read multiple bytes, it is necessary to assert the most significant bit of the subaddress
field. In other words, SUB(7) must be equal to 1, while SUB(6-0) represents the
address of the first register to be read.
Surely the I2C standard specifies which of LSB/MSB first?
Yes it do, MSB first, as quoted from the data sheet...............

Data is transferred with the most significant bit (MSb) first.
So the correct code example to what i listed above should be

Code:
#picaxe 08m2

main:

i2cslave %11010010 ,i2cfast_4,i2cbyte

pause 50

readi2c %00100110,(b0)  'should return Temp reading

readi2c %00001111,(b1)  'should return 11010011

debug

pause 300

goto main
 

SAborn

Senior Member
On the last look through the data sheet i did wonder if you need to setup all the configuration for the registers first before a register read can be done.
The data sheet is not clear to me on exact proceedures, its not the best data sheet i have ever read!
 

gkowen

New Member
I have hooked the gyro up to a usb to i2c adapter and can read and write the config regs, read the who am I byte and the temp with no troubles. There must be something strange with the PicAxe i2c. The last thing I am going to try is to totally clean up my layout. Thanks for all the help.

Greg
 

hippy

Ex-Staff (retired)
Staff member
Running SAborn's code from post #18 with SCL and SDA not connected results in the slave address ($D3) being returned on both reads, with SCL and SDA pulled-up but no I2C device the reads both return $FF.

I believe the rationale behind getting the slave address back on a read is that this will be what's been put into the MSSP register to be transmitted at the start of an I2C transaction but, as the I2C bus levels are not seen as correct, it never gets transmitted. The firmware continues somewhat oblivious to this, reads the data in the register which would have been returned but is still the slave address from earlier.

That suggests to me the I2C bus is not correct and it's likely a wiring or circuit issue. Perhaps test with the module disconnected and with SCL and SDA pulled-up to see if that reads $FF as would be expected.
 
Last edited:

gkowen

New Member
Thanks for the idea hippy. I have been working that way. I think I know what is going on, but am still getting data to prove it.
 

gkowen

New Member
The gyro I am using has a strange level shifter on the SCL line. It seemed to limit the SCL high level to 2 volts or so. The picaxe was seeing this as a low SCL which I think I remember being a busy signal or something. Nothing was being written from the picaxe to the I2C bus. I added a 4.7K resistor pullup to the SCL line and everything works. The datasheet for the module says this is not needed. I forgot rule number 3: Don't trust everything the datasheet says. So now I have to figure out what the data means.

Thanks to all who helped me on this process. This forum really has a very helpful attitude and I appreciate it. Have a great day!

Greg
 
this is a late comment. I am working on GYRO L3GD20H. But I appreciated the reminder
of a recommendation to pull up the CO pin on the GYRO. Up to then, my device was resetting and I wasn't getting all
my readings . I still have the job of interpreting all those readings. But thnx to the guy from West Yorkshire, UK !
Larry Keegan, Massachusetts, USA
 
Top