[HH] Seeking help on Programming I2C bus in python on Raspberry Pi

Greg London email at greglondon.com
Wed Nov 14 15:17:47 EST 2012


Hm, I'm doing I2C stuff at the extreme low level.
we make chips that have an I2C interface, and
I have to deal with I2C transactions all the time.

I'm not sure what you're looking for.
If you need to understand I2C, a good intro is here:

http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html

You have 1 master and as many slaves as you want,
and they're all hooked up to the same two pins.

The protocol uses tristates and pullup resistors so that
if a master or slave is not driving the bus, then they
tristate their outputs, and the pullup resistor will pull
the wires high. If anyone wants to drive a signal,
they can ONLY drive the wire LOW. If they want a signal to
go high, they are only supposed to tristate, and allow
the pullup resistor to pull high. This makes it impossible
to get driver contention and smoke your parts.

Two chips pulling to ground at the same time is not a problem.

This is how you can have as many slaves as you want on the same
two wires.

The protocol is fairly simple. The two signals start high
(everyone tristate/no one driving). One signal is considered
the clock, which is always driven by the master. The other
signal is data, which is sometimes driven by the master
and sometimes driven by the slave.

When transfering data bits, the data (SDA) signal is only
allowed to transition when the clock is LOW.

This is because changing data while the clock is high
indicates either a START or STOP signal.
(see the link for waveforms)

>From the all-high or idle condition,
the protocol generates  a "start" symbol
(data goes low while clock is high.)
the master must then bring the clock low.

And then data bits are transferred serially.
clock is low
set data value
clock goes high
wait
clock gose low

repeat for each data bit.

The first 7 bits after a START symbol is the SLAVE address
I2C slave chips usually default to some address, and/or
may have some pins which  will allow you to set some or
all of the address bits for the slave.

You'll have to check the spec of your I2C slave chip to see
how to set the address. If you're using the MCP23017,
the datasheet shows the pinout contains A0, A1, A2, which would
let you have up to 8 of these chips sharing the same two I2C pins.

The next bit is READ/WRITE bit. telling the slave whether
you want to read or write a slave register.

The next bit is an ACK from the slave.
The master chip should tristate the data pin and continue
toggling the clock. The slave will pull the data low to ack.

The next 8 bits is the REGISTER address within the selected slave
that you want to read or write.

Then another ACK bit.

The next 8 bits is the DATA, either the data to write, or the
data read back from the slave.

Then another ACK bit.

Then the MASTER creates a STOP symbol .


So, it looks like this:
(all data driven by master unless otherwise noted)

a write:
START
7 SLAVE ADDRESS
1 READ
1 ACK (from slave)
8 REGISTER ADDRESS
1 ACK (from slave)
8 WRITE DATA
1 ACK (from slave)
STOP

a read:
START
7 SLAVE ADDRESS
1 READ
1 ACK (from slave)
8 REGISTER ADDRESS
1 ACK (from slave)
8 READ DATA (from slave)
1 ACK (from master)
STOP


I don't know the raspberry pi, but I assume someone has an I2C library.
Depending on how the library works, you might set a default slave address
if you only have one slave, to be equal to the address controlled
by the A0, A1, A2 pins on your slave chip.

Or the library might simply require you to pass in the slave address
with every call.  You're library i2c call might look something like this:

i2c(slaveaddress, registeraddress, data);


Then you'll need to figure out what REGISTER address within the slave
will write the LED's. Looking at the spec for the same I2C chip above,
the registers you'll need to program are on page 9, section 1.5
GPIO port. Table 1-3 shows all the register addresses inside the slave.

You'll probably need to program the IODIRA register to all outputs
and then program the data you want on the pins in the OLATn register.

You'll probably want to wrap this into an initialization subroutine
and an assignment subroutine, and have both calls not pass in any
i2c specific stuff. hide the i2c stuff inside the subroutine so you
can use the same application code, even if you change the schematic
to use a different i2c slave chip with a different register map.

if you're doing rows of leds, you might have

initialize_led(rownumber)
set_led(rownumber, data)

or something like that.

And hten you're up and running.

Greg


> Hi Guys, I was recently introduced to this group, so here is my first
> post.
>
> I work/volunteer at the Southend Technology Center in Boston.  We teach
> technology to kids and adults fostering interest in technology for kids
> and
> enabling adults to be more competitive in the workforce.  We were the
> original Fab Lab initiated by MIT, and continue to have a strong
> relationship with MIT.  We have laser cutters, shopbot, broken 3D printer,
> and teach kids to work with arduino.
>
> I manage the computer hardware repair workshop.
>
> So I have taken on a project (over my head) using old computer parts and
> raspberry Pi.  I am trying to build a POV sign that can gather data from
> the net/cloud/remotely.
>
> I have followed this example http://www.skpang.co.uk/blog/archives/454 to
> get LEDs controlled by a raspberry.  But now like to convert this to using
> this http://adafruit.com/products/459 a bi-color 12 bar led (for more
> colors and cleaner product)
>
> I figured out the wiring to get the bar to light up using the same codes
> as
> above.  So I am now ready to control the LED bar, and that is where I am
> stuck...on the python code to control the I2C.  I think my too basic
> knowledge of electronics and programming would be benefited by someones
> help.  This is my immediate challenge to figure out how to program the I2C
> for the LED bar, then eventually, I need to program a python code to POV
> display the messages which i can imaging that it get pretty challenging
> given how to form a character with LED while timing the rotation.
>
> So I am looking for someone who maybe familiar with I2C to offer insight
> and hopefully someone that has time to tinker on this project along with
> me.  I am at the tech center typically in the afternoons till 8PM at 359
> Columbus Ave in the Southend.
>
> So any help through email or in person would be greatly appreciated.
>
> Thanks
>
> Ming
> _______________________________________________
> Hardwarehacking mailing list
> Hardwarehacking at blu.org
> http://lists.blu.org/mailman/listinfo/hardwarehacking
>


-- 





More information about the Hardwarehacking mailing list