Adventures with i2c

In order to design the next version of the flotsam hardware I need to make it cheaper and easier to build. The existing hardware was very cheap in terms of components but expensive in terms of time it took to construct! With this lesson learned and with a commission on the horizon I need to find a simpler and more flexible approach to communication between custom hardware and the Raspberry Pi – mainly one that doesn’t require so many wires.

i2c is a serial communication standard used by all kinds of components from sensors to LCD displays. The Raspberry Pi comes with it built in, as the Linux kernel supports it along with various tools for debugging. I also have some Atmel processors from a previous project and there is quite a bit of example code for them. I thought I would post a little account of my troubleshooting on this for others that follow the same path, as I feel there is a lot of undocumented knowledge surrounding these slightly esoteric electronics.

The basic idea of i2c is that you can pass data between a large number of independent components using only two wires to connect them all. One is for data, the other is for a clock signal used for synchronisation.

Debugging LEDs
Debugging LEDs

I started off with the attiny85 processor, mainly as it was the first one I found, along with this very nice and clear library. I immediately ran into a couple of problems, one was that while it has support for serial communication built in (USI) you have to implement i2c on top of this so your code needs to do a lot more. The second was with only 8 pins the attiny85 is not great for debugging. I enabled i2c on the Raspberry Pi and hooked it up, ran i2cdetect – no joy. After a lot of fiddling around with pull up resistors and changing voltages between 3 and 5v either no devices were detected, or all of them were, all reads returning 0 (presumably logic pulled high for everything) or noise – nothing seemed to make any difference.

After a while (and trying other i2c slave libraries to no avail) I switched to an atmega328 processor using this library which includes a Makefile! One thing that I’ve noticed that would make things much easier for learning this stuff is more complete toolchains in example code including the right #defines and fuse settings for the processor. However this code didn’t work either at first, and my attempts at using debugging LEDs on PORTB didn’t work until I figured out it was conflicting with the UART i/o used in the example code – after figuring out that this wasn’t part of the i2c code I removed it and the Raspberry Pi could at last see the device with i2cdetect. With the addition of some LEDS I could check that bytes being sent were correctly being written to the internal buffer at the correct addresses.

It finally works!
It finally works!

Reading was another matter however. Most of the time i2cget on the Pi failed, and when it did work it only returned 0x65 no matter what the parameters. I’d already read extensively about the Raspberry Pi’s i2c clock stretching bug and applied various fixes which didn’t seem to make any difference. What did the trick was to remove the clock divide on the atmega’s fuses – by default it runs at 8Mhz but slows the instruction cycles to 1Mhz – without that it could keep up with the Pi’s implementation and all reads were successful. I still had to solve the ‘0x65 problem’, and went into the i2c code to try and figure out what was going on (using 8 LEDs to display the i2c status register). It seems like reading single bytes one at a time is done by issuing a TW_ST_DATA_NACK as opposed to TW_ST_DATA_ACK, as it sends a not-acknowledged for the last byte read. This state is not supported by the library, after fiddling around with it a bit I switched over on the Pi’s side to using the python smbus library, and tried using read_i2c_block_data – which reads 32 bytes at a time. The first byte is still 0x65 (101 in decimal, in the photo above) – but the rest are correct, I’ll need to read a bit more on the i2c protocol to figure that one out (and get the attiny working eventually), but at least it’s enough for what I need now.

Handy collection of pinouts
Handy collection of pinouts

Tangible livecoding tests in the wild, and material as type in programming

Last week I took the flotsam tangible livecoding system to my programming tutoring lesson for some first tests with the real experts. To provide some background, we started a while back with Raspberry Pi, messing around with the Minecraft API and python and we’ve recently moved on to laptops and pygame. I arrived with the system set up for the Minecraft building language, and we gave it 10 minutes or so before resuming normal activities – although it did get a bit more use during natural breaks in the lesson. Here’s a recent pic of the weaving l-system setup:

tangibleweaves

First impressions were that it was immediately playful, most of the blocks were eagerly removed and examined before we’d turned the thing on. One problem with this was that the chalk symbols rubbed off very quickly! A similarity with the Scratch programming language was also picked up on fairly soon.

A big issue was getting the connectors the right way round – this is not easy as the blocks are circular with little indication of which way is ‘up’. This could be fixed by altering the shape or cutting a little notch – learning how to manipulate them is part of the point, but right now it’s too difficult. This will also be a big problem in livecoding performance situations.

Using Minecraft, the screen was still a distraction. The connection between what’s happening in the 3D world and with the physical blocks is not obvious enough – even with the LED indicators. Also the mouse and keyboard need to be plugged in so we can move the camera around and see stuff, leading to a few too many things going on. I’m not sure how this can be solved regarding Minecraft, but indicates that a musical approach (with no screen or any other peripherals needed other than speakers) is the way to go.

Overall there is huge potential to think much more about the touch/feel of the blocks. Lots of these problems can be solved by using different shapes for different symbols (removing the need for chalk) with a clear orientation. Using different materials to provide textures and ‘feel’ in order to represent different sounds, or in terms of weaving, using the actual yarn material to represent itself is a huge area to explore.

materials

In the photo above, I’m using thick and thin blue yarn wrapped around the blocks that represent them, and tinfoil for l-system rule symbols (X, Y and Z) – this is a kind of material based type indication. Interestingly the yarn feels very different even though it looks the same in the photo. In use this results in much less checking of the block when you pick them up, as your fingers tell you what they are.

dremelling

Weaving notations

I’ve collected images from our workshops in Leeds and Sheffield as we attempted to understand the intricacies of weaving, particularly ancient looms from antiquity.

A simple visualisation of a loom.

A simple visualisation of a loom

Attempting to understand the relationship between lift plans and heddles.

Attempting to understand the relationship between lift plans and heddles.

The connection between tablet woven bands, whose weft form the warp of the warp-weighted loom.

The connection between tablet woven bands, whose weft form the warp of the main weaving.

A pattern language, turning into binary pattern, then thinking about the types of patterns the weavers of antiquity favoured.

A pattern language, turning into binary pattern, then thinking about the types of patterns the weavers of antiquity favoured.

More tablet/warp weighted calculations, grouping threads by colour.

More tablet/warp weighted calculations, grouping threads by colour.

A professional lift plan, by Leslie Downes.

A professional lift plan, by Leslie Downes.