[RESOLVED]Python smbus.read_i2c_block_data


6 posts
by Hove » Wed Sep 18, 2013 9:37 am
Hi,

The MPU6050 has 14 sequential registers 0x3B to 0x48 which can be read, register by register serially to retrieve gyro, accelerometer and temperature information. I've had a ongoing niggle that because this is called from Python this 14 individual reads may not be from the same snapshot in time, leading to occasional dodgy values.

I've just stumbled across smbus.read_i2c_block_data() which returns a byte array of a predefined size (lets call is n bytes long). However, the examples / docs I've seen are not helpful / clear.

My question then is whether this byte array is read (under the covers in the smbus driver) as n bytes sequentially from a single register, or if the code steps from register 0x3B thru' 0x48 filling each read byte into the next part of the array. The examples kinda suggest the latter but they or on the murky side.

Anyone got experience of using read_i2c_data_block() in this way?

Thanks
Last edited by Hove on Thu Sep 19, 2013 9:45 am, edited 1 time in total.
www.pistuffing.co.uk - things to fulfil your Raspberry Pi
User avatar
Posts: 747
Joined: Sun Oct 21, 2012 6:55 pm
Location: Cotswolds, UK
by Hove » Wed Sep 18, 2013 12:08 pm
Or put it another way, is it normal that data is store in fixed bytes of memory 'indexed' by the register ID, such that reading 2 bytes from say register 0x23 returns the data from 0x23 and 0x24. I have the feeling the answer is going to be now, but my knowledge of how registers are implemented is insufficient to make the call myself.
www.pistuffing.co.uk - things to fulfil your Raspberry Pi
User avatar
Posts: 747
Joined: Sun Oct 21, 2012 6:55 pm
Location: Cotswolds, UK
by Hove » Wed Sep 18, 2013 12:21 pm
OK, I'm assuming I have the wrong end of the stick and need to keep my code the way it is now. This is based upon the following link https://www.kernel.org/doc/Documentation/i2c/smbus-protocol defining the kernel i2c API and seems clear that i2c_smbus_read_i2c_block_data() reads a block of data from a single specific register rather than an array of single bytes from a range of sequential registers as I'd hoped. Oh well.

I'm open to being told I've got it wrong though!
www.pistuffing.co.uk - things to fulfil your Raspberry Pi
User avatar
Posts: 747
Joined: Sun Oct 21, 2012 6:55 pm
Location: Cotswolds, UK
by jjackowski » Wed Sep 18, 2013 8:36 pm
As I understand it, the block read and writes usually cause the address to increment as they operate on each word. They aren't very useful otherwise. The datasheet for the component will probably explicitly state if it does this, and if it even supports the block operations.
Posts: 43
Joined: Thu Jan 10, 2013 5:25 am
by Hove » Thu Sep 19, 2013 5:16 am
jjackowski wrote:As I understand it, the block read and writes usually cause the address to increment as they operate on each word. They aren't very useful otherwise. The datasheet for the component will probably explicitly state if it does this, and if it even supports the block operations.


Thanks - that make's it worth my while giving it a go - as you say, but seems a bit pointless reading the same register n times in one 'operation'
www.pistuffing.co.uk - things to fulfil your Raspberry Pi
User avatar
Posts: 747
Joined: Sun Oct 21, 2012 6:55 pm
Location: Cotswolds, UK
by Hove » Thu Sep 19, 2013 9:45 am
I tried it, and it works - if you use smbus.read_i2c_block_data(), it allows you to read the contents of n sequential registers in a single Python call (rather than n calls), and so increase the performance significantly. So now instead of 12 calls to get Accelerometer / Gyro data, I make a single call and then parse the returned array myself - much easier.
www.pistuffing.co.uk - things to fulfil your Raspberry Pi
User avatar
Posts: 747
Joined: Sun Oct 21, 2012 6:55 pm
Location: Cotswolds, UK