Page 1 of 1

I2c read mutiple bytes[SOLVED]

Posted: Sat Jul 12, 2014 1:28 pm
by ilpiero
Hi everybody, this is my first post to this forum.

Lately my company (after a suggestion from me ;) ), has bough some Raspberry to be used as cheap interfacing devices.

I have been trying the I2C interface for a day and there are some features that I still cannot get to work.

I need to read more than one byte form a slave WITHOUT sending the cmd/subaddress byte.
So in a single transaction i should see on the scope START|READADDRRES|ACK|BYTE1|ACK|BYTE2|ACK ... BYTEN|ACK|STOP
I seems to me that all of the functions that read more than on byte only work with a cmd/subaddress, am I right?.

Has anyone faced this problem already?

Thanks in advance

Marco

Re: I2c read mutiple bytes

Posted: Mon Jul 14, 2014 7:28 pm
by BAStumm
The "GET TEMPERATURE" command on a thermocouple device I'm using returns 4 bytes.

Code: Select all

  //setup i2c to mod-tc on 0x23
  if((fd = wiringPiI2CSetup(0x23)) < 0) {
    printf("I2CSetup Failed, %i\n", fd);
  }

  // GET_TEMP
  wiringPiI2CWrite(fd, 0x21);
  read(fd, temp, 4);

Re: I2c read mutiple bytes

Posted: Mon Jul 14, 2014 7:39 pm
by joan
The way you communicate with an I2C device depends on the device itself and will be documented in its datasheet.

However, a lot of I2C devices seem to operate in a similar fashion.

Have you a particular device you are testing?

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 10:24 am
by ilpiero
@joan
Maybe i was misunderstood, i have no doubt on how the slave device works (see my first post), i simply cannot find a way to output that sequnce.
The device is a touch screen controller, but id don't think it's availible on the consumer market.

@BAStumm
That seem to be what i'm looking for... is there a way i can use that functions by command line or python script?

Thank you both, guys!

P.S:
So far I got it working using this (terrible :o ) GPIO bitbanging python script :

Code: Select all

import RPi.GPIO as GPIO

#####################
#      SETUP        #
#####################

#set up GPIO using BCM numbering
GPIO.setmode(GPIO.BCM)
# setup dataready GPIO 
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#####################
#     FUNCTIONS     #
#####################

def clk(value):
 if (value):
  GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 else:
  GPIO.setup(22, GPIO.OUT, pull_up_down=GPIO.PUD_UP)
  GPIO.output( 22, False) 
 return

def data(value):
 if (value):
  GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 else:
  GPIO.setup(23, GPIO.OUT, pull_up_down=GPIO.PUD_UP)
  GPIO.output( 23, False) 
 return

def datard():
 return(GPIO.input(23) == 1)
  
def StartBus():
 clk(True)
 data(True)
 data(False)

def StopBus():
 clk(True)
 data(False)
 data(True)

def WriteByte(x):
#bit 0
 clk(False)
 data((x&128 != 0))
 clk(True)
#bit 1
 clk(False)
 data((x&64 != 0))
 clk(True)
#bit 2
 clk(False)
 data((x&32 != 0))
 clk(True)
#bit 3
 clk(False)
 data((x&16 != 0))
 clk(True)
#bit 4
 clk(False)
 data((x&8 != 0))
 clk(True)
#bit 5
 clk(False)
 data((x&4 != 0))
 clk(True)
#bit 6
 clk(False)
 data((x&2 != 0))
 clk(True)
#bit 7
 clk(False)
 data((x&1 != 0))
 clk(True)
#ack
 clk(False)
 data(True)
 clk(True)
 clk(False)    

def ReadByte():
 x=0
 data(True);
#bit 0
 clk(False)
 clk(True)
 if (datard()):
  x=x+128
#bit 1
 clk(False)
 clk(True)
 if (datard()):
  x=x+64
#bit 2
 clk(False)
 clk(True)
 if (datard()):
  x=x+32
#bit 3
 clk(False)
 clk(True)
 if (datard()):
  x=x+16
#bit 4
 clk(False)
 clk(True)
 if (datard()):
  x=x+8
#bit 5
 clk(False)
 clk(True)
 if (datard()):
  x=x+4
#bit 6
 clk(False)
 clk(True)
 if (datard()):
  x=x+2
#bit 7
 clk(False)
 clk(True)
 if (datard()):
  x=x+1
#ack
 clk(False)
 data(False)
 clk(True)
 clk(False)   
 return x
  
 

#####################
#      MAIN         #
#####################

#StartBus()
#WriteByte(0xA1)
#b1=ReadByte()
#b2=ReadByte()
#StopBus()
#print("0x%02X" % b1)
#print("0x%02X" % b2)



Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 10:38 am
by joan
By read address do you mean the device's I2C bus address?

The smbus block read commands including the smbus block I2C read commands always include a register address as well as the device address.

If your device doesn't have any registers or only reads them in a fixed sequence you'll need to use an underlying I2C device command.

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 1:49 pm
by ilpiero
Yes, you got it
My device behaves as described in the fisrt post, there is NO subaddres (or register address)
You perform a read at the i2c bus address ad the device replies you with two bytes: the first one is an ACK, and the second is the number of bytes to read in the subsequential read operation.

Here is an example of a read:

Read 2 bytes from i2c address 0x50
reply:
0xEE (ack)
0x03 (number of bytes to read)

Read 3 bytes from i2c address 0x50
reply:
0xXX (Data # 1)
0xXX (Data # 2)
0xXX (Data # 3)

The single reads must be perfomed each in a monolithic transition, if a stop condition happens the data is lost

Their I2c implementation sucks but i guess is still legal ;)

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 2:08 pm
by joan
I believe you will have to use the underlying device rather than using the smbus layer which is the normal interface.

What language do you want to use?

You can roll your own in C or use a library for C or Python. Not sure about Java.

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 2:24 pm
by ilpiero
I would like to do this in python because this is just a simple code for testing and debugging, it's much more handy than compiling every time, and i dont' care about performance...

What library should i call anyway?

Thanks

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 2:30 pm
by joan
ilpiero wrote:I would like to do this in python because this is just a simple code for testing and debugging, it's much more handy than compiling every time, and i dont' care about performance...

What library should i call anyway?

Thanks
For Python I'd use my own library. I think the other Python modules use smbus exclusively.

pigpio
Python module

Use http://abyz.co.uk/rpi/pigpio/python.htm ... ead_device for raw I2C access.

You can also just open the devices directly from Python but you then need some trickery to get the right ioctl.

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 2:35 pm
by ilpiero
Thank you so much, i'll let you know if it's working!
What is the upper limit of the Count parameter?

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 2:40 pm
by joan
ilpiero wrote:Thank you so much, i'll let you know if it's working!
What is the upper limit of the Count parameter?
Not sure in the current download version (16). In my working version (17) I've changed the maximum socket message size to 8192 bytes. It'll be several thousand bytes at least for version 16.

The smbus calls are limited to a maximum of 32 bytes.

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 4:44 pm
by BAStumm
I don't use Python but I think the python read() function would work the same as the C function.

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 5:00 pm
by joan
BAStumm wrote:I don't use Python but I think the python read() function would work the same as the C function.
You can manipulate the raw device (/dev/i2c-x) in Python using open/read/close. What is not so simple is the IOCTL needed to set the I2C device address. I also remember you have to muck about with buffering options.

Re: I2c read mutiple bytes

Posted: Tue Jul 15, 2014 6:20 pm
by ilpiero
Thanks a lot, your API works flawlessly!