Python i2c write_bus_data usage

Hugo Rune picture Hugo Rune · Nov 25, 2013 · Viewed 7.7k times · Source

8I have a number of 4 digit seven segment displays that I am trying to control using Beaglebone Black (running Ubuntu) and i2c.

The SSD's are Byvac BV4614's and the full datasheet is available here.

I have wired up the circuit correctly using pins P9_19 and P9_20 on the Beaglebone. I have included pullup resistors and am using a i2c logic converter for added safety.

I have verified the device using i2cdetect (it's 0x31 which is correct) and the device powers up nicely and enters it's i2c mode.

However I do not understand how to read or write data to the device using Python SMBbus. The SSD manual says

The format used by this device consists of a command, this is a number, followed by other bytes depending on that command. The method of writing to the device using the I2C protocol follows a consistent format, typically: Where S-Addr is the start condition followed by the device address (0x62). Command is one of the commands given in the table. Data is one or more bytes and Stop is the stop condition.

(on 7-bit addressing the device is at 0x31 which is what I'm using).

So if for example I wanted to get the SSD to display a number on digit 1 the manual says I have to do

Command 5 - Name: Send number to digit - Format:<S-addr><5><digit><byte><Stop>

My question is, how do I write that command using Python? I think i'm looking for something like this

import smbus
b = smbus.SMBus(1)
b.write_byte_data(0x31, 0x35, 0x30, 0x38)

which I'd like to mean "send command 5 (0x35) to device 0x31, digit 0 (0x30) and display the number 8 (0x38)" but wrrite_byte_data does not accept that number of arguments. I have also tried using write_i2c_block_data() which looks more hopeful but again I cannot work out how to use the functions correctly.

I feel that I am facing a BCK problem here but any help would be appreciated.

edit Ok, I have tried

b.write_block_data(0x31, 5, [8, 0x38] )

which makes the number 8 appear on digit 3

b.write_block_data(0x31, 5, [2] )

makes 2 appear on digit 2. I've not yet worked out how to place anything on digit 1 or 4 yet.

b.write_block_data(0x31, 4, [44]) # just entering random stuff now

increases the brightness and then makes the SSD unresponsive.

So I'm getting closer,

edit and SOLVED

In the end it was ridiculously easy.

b.write_i2c_block_data(0x31, 5, [0, 8]) # write number 8 to digit 0
b.write_i2c_block_data(0x31, 5, [4, 5]) # write number 5 to digit 4 etc etc

According to http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2 the function write_block_data is not very good.

write_block_data(int addr,char cmd,long vals[])

Write up to 32 bytes to a device. This function adds an initial byte indicating the length of the vals array before the valls array. Use write_i2c_block_data instead!

Answer

Hugo Rune picture Hugo Rune · Nov 25, 2013
b.write_i2c_block_data(0x31, 5, [0, 8]) # write number 8 to digit 0
b.write_i2c_block_data(0x31, 5, [4, 5]) # write number 5 to digit 4 etc etc

Solved the issue for me! All other commands in the spec now function as intended!

The page at http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2 informed me that the function I was using was not ideal.