After triple checking the schematics and design files and ordering 80 PCBs (50 sensors and 30 i2c boards) there was an anxious wait for them to arrive and do some initial tests to find out if there were any mistakes. We now have enough boards to make two new pattern matrix devices, one 4X4 and one 5X5 – the plan is to evaluate the design and refine it for future builds.
The picture below shows the first test boards populated and plugged it into the Pi – it’s much neater than the lego and breadboard prototype! The good news is that it seems to work so far, the only problem I’ve had is with the hall effect sensors, the pads are a tiny bit too close together for my skills. After a couple of tricky situations fixed with a de-soldering pump, I think I’ve come up with a strategy that works. I can bend the outer pins away from each other and solder the central pin first – then bend them back to finish the outer ones and being very careful not to bridge the pads.
The blue jumpers on the square i2c boards allow you to program the device channel that the two expanders use – these could alternatively be hard soldered, but it’s good to have the option to reuse the parts or reconfigure a pattern matrix so we can add different sensors etc.
For reference, the KiCad 3D viewer models look pretty close.
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.
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.
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.
More background on this project here. This is the finished Raspberry Pi interface board, most of the circuitry here is an LED driver to light up one of the 32 programming blocks as they are being scanned, or in any pattern required depending on the needs of the particular programming language in use. The small IC is an old 74LS02 NOR gate I’m misusing as a NOT gate (which I couldn’t find in my supplies). I hard wired one of the gate’s inputs to ground so the other one gets inverted. I need this in order to switch between the two 16 way multiplexers to get 32 outputs, by alternating their enable pins.
This time I remembered to include decoupling capacitors (thanks to Julian). Here is the completed wiring for the block input plugs, with everything connected up. I’m new to this scale of building, so really pretty happy it seems to be working:
The same thing, the right way up with a single programming block plugged in, and the Raspberry Pi in the foreground. The first time it’s starting to look like something:
I’m also starting to document the project, as it will be released as open source hardware, here’s an unfinished schematic. This is attempting to be complete, but it’s not really as complex as it looks – I’ll work on a block diagram that makes it easier to describe: