GM862 i2c, how to do? - WORKS NOW...

Hi guys,

What of these follow bytes (description bellow) I need to send over IIC readwrite command?

I try the follow “\xD0\x22\x00\x12\x34” but no success. I found some examples using only the address but I think it is not the case.

Thanks in advance.

Daniel

Description:

Space temperature can be read from memory locations 0x12 (hi byte) and 0x13 (low

byte).

To do this a sequence of two I2C frames has to be sent to the sensor: first send a I2C

write frame containing the sensor address, command number and how many bytes to

read, RAM address to read from, and a checksum. Then send a I2C read frame to read

the status, data and checksum. See chapter 2 for details.

In this case 2 bytes starting from address 0x12 should be read. This will give data from

address 0x12 and 0x13, which contains current space temperature. The sensor address

is 0x68 (default factory setting, configurable in EEPROM).

So, the first frame should look like:

Start | 0xD0 | 0x22 | 0x00 | 0x12 | 0x34 | Stop

g. 0xD0 is Sensor address and read/write bit. 0x68 shifted one bit to left and R/W bit is 0 (Write).

h. 0x22 is command number 2 (ReadRAM), and 2 bytes to read

i. Checksum 0x34 is calculated as sum of byte 2, 3 and 4.

The next frame will read the actual data:

Start | 0xD1 | <4 bytes read from sensor> | Stop

j. The 1:st byte from the sensor will contain operation status, where bit 0

tells us if the read command was successfully executed.

k. The 2:nd and 3:rd byte will contain space temp value hi byte and space

temp value low byte.

l. The 4:th byte contains checksum

The I2C protocol requires special switching of the SDA line to indicate a start and stop condition. These are required to signal the slaves they need to pay attention (or stop when sending is finished). Did you take care of that too, or did you just send out those bytes. If those start and stop conditions (there can also a repeated start) are not sent then it won’t work. The slave should also respond by sending an ACK (acknowledged) or NACK (not-acknowledged) bit after every byte received to indicate it received the byte.

I don’t know if Wikipedia has a complete writeup on the I2C protocol, but it does seem to cover the basics:

http://en.wikipedia.org/wiki/I²C

(the square symbol might have corrupted the link, eitherway I suggest you make sure you know or read up on the full I2C protocoll)

Thanks!

The Telit IIC python module takes care of Start and Stop sequences, Ack reception and Bytes answer collection. It also mount the frame to the right address and read/write bit.

Today I figure out how to do, now it works smooth.

The I2C default package is:

START | ADDRESS | W | ACK | DATA | ACK | DATA | ACK | STOP

ACK sent by SLAVE

The sensor used in this project needs more info than memory address to read data. It needs memory type address (RAM/EEPROM), how many bytes to read and a checksum calculated as sum of all data bytes.

All this info must be considered data, take a look to the code.

import IIC
import MOD

I2C_SDA = 3 # GPIO used for SDA pin
I2C_SCL = 4 # GPIO used for SCL pin
I2C_ADDR = 0x68 # myIIC1 address


myIIC1 = IIC.new(I2C_SDA, I2C_SCL, I2C_ADDR)
status = myIIC1.init()

print 'Writing from ADDR = 0x08'

"""
0x22 is command number 2 (ReadRAM), and 2 bytes to read 
0x00 0x08 is the memory address where the information resides
Checksum 0x2A is calculated as sum of byte 2, 3 and 4.
all this 4 bytes are considered data by IIC module.
obs:. use 0 as last argument when the command is to write.
"""
if myIIC1.readwrite('\x22\x00\x08\x2A', 0) == -1:
	print 'Error acknowledged'

"""
The answer to the command is 2 bytes more 1 byte checksum and 1 byte command,
it means readwrite command ask for 4 bytes.
\x21\x02\x03\x26
"""
ret = myIIC1.readwrite('', 4) # Current address read
print ' CURRENT ADDR READ = 0x08, (4)bytes: %s' % ret

I assume you have the Telit Easy Script Python r13 document. I have a GE865 with a TMP102 sensor connected to it. The I2C sensor part of the code is as follow:

import IIC
import SER2

#SER2.send('Initialize GPIO pins\r\n')
I2C_SDA = 7     # GPIO used for SDA pin
I2C_SCL = 6     # GPIO used for SCL pin
I2C_ADDR = 0x48 # TMP_102 address ADD0 pin to ground 0x90>>1
TMP_102 = IIC.new(I2C_SDA, I2C_SCL, I2C_ADDR)
status = TMP_102.init() #initialize I2C device

if (status == 1):
    a = SER2.send('TMP_102 initialization successful.\r\n')
    a = SER2.send('Ready to GO\r\n')                                                          #debug
    a = SER2.send('I2C_SDA:' + str(I2C_SDA) + '\r\n')                                    #debug
    a = SER2.send('I2C_SDC:' + str(I2C_SCL) + '\r\n')                                    #debug
    a = SER2.send('I2C_ADDR:' + str(hex(I2C_ADDR)) + '\r\n')                          #debug

    tmploop = 2
    while (tmploop > 0):
        ret = TMP_102.readwrite('\x00', 2)      # Read
        ret1 = ord(ret[0:1])                    # Assign 1st byte to ret1
        ret2 = ord(ret[1:2]) >> 4               # Assign 2nd byte to ret2 and bitshift right 4
        calc = 288 * ret1 + 18 * ret2 + 5120    # Convert from degC to degF * 160 to use only integers
        #SER2.send(str(calc) + ' calc\r\n')                                                    #debug
        tval = divmod(calc, 160)                # Find whole# and remainder
        t_whole = int(str(tval)[1:str(tval).find(',')])   # Extract whole number as integer
        t_frac = int(str(tval)[str(tval).find(' '):str(tval).find(')')]) # Extract fraction as integer
        t_frac_divmod = divmod( t_frac * 100, 160)  # Calculate fraction as integer with 2 decimal precision * 100 
        t_frac_whole = int(str(t_frac_divmod)[1:str(t_frac_divmod).find(',')]) # Extract fractional portion of temperature
        if (ret == -1): # Check to see if ERROR returned from Read of TMP102
            a = SER2.send('readwrite Error Acknowledged.\r\n')
            tmploop = tmploop -  1
        if (tmploop == 0):
            a = SER2.send('Temperature reading failed\r\n')
            return
        else:  # If no ERROR, 
            #a = SER2.send('Temperature is ' + str(t_whole) + '.' + str(t_frac_whole) + 'F\r\n')
            return (t_whole, t_frac_whole)
if (status == -1):
    a = SER2.send('TMP_102 initialization failed.\r\n')

I get 2 bytes back from device hence the ret1 and ret2 variables. If you don’t care about Farenheit, you do’t need the divmod statements (needed since Telit python doesn’t do floating point numbers). Hope this helps. What type sensor are you using?

Good luck with your project.