Also: for Pi day I got a PiBow, PiGlow and PiBrella!
— Aaron Brady (@insom) March 14, 2014
Missed off of that list of presents: this year I got a Bus Pirate from Dangerous Prototypes.
The Bus Pirate is a single PCB diagnostic and development tool that speaks several serial protocols: SPI, I2C, 1-Wire, low-voltage RS232 and it can also perform some non-serial tasks, like reading an ADC or generating PWM signals.
Like many useful tools, it has a bit of a learning curve. There’s wiki pages with lots of information but they are no substitute for just getting your hands dirty and using the thing. In fact, there’s a 3EEPROM Explorer Board for this very reason- it gives someone taking their Bus Pirate out of the box something to poke while they learn the ropes.
I didn’t have one of these, but it turns out that doesn’t matter: enter the PiGlow.
PiGlow provides 18 dimmable LEDs and is designed to be used with a Raspberry Pi. It sits right on the GPIO header of the Pi. It doesn’t use actual GPIO pins though, because the PiGlow is actually based on the SN3218 I2C PWM LED driver.
If you’re following along, you’ll need a few more bits to get up and running. I already had a breadboard-compatible breakout for the Raspberry Pi GPIO header (not exactly a Cobbler, but similar), I needed an IDC10 ribbon and an IDC10 breadboard breakout. If you had a Bus Pirate Cable or even just female-to-male jumper wires, you could probably do without those two.
For the remaining hardware part, it’s just a case of connecting everything up. I moved slowly here: because I’d added in adaptors and ribbons cables (not all of which were keyed to avoid flipping them around) I had to check that the numbering of pins didn’t get messed up from what I expected.
(This pin out diagram from Crockett Engineering was extremely useful for this step)
For example, the first thing I did was put an LED across where I expected the
GND to be on my IDC10 breakout. Once you select a mode on the Bus Pirate, using the
V command turns on the power supply and will light up the LED. This step-by-step testing paid off: the LED did not light, I had the pins all backwards. For my set up, 9 was
3.3V and 10 was
Once that was established, I checked the image on the Dangerous Prototypes site for the
SDA connections (3 and 4, respectively) and I also ran the
5V (pin 8) over to pin 2 on the GPIO breakout.
I2C requires pull up resistors. As the Bus Pirate runs at both
5V, you will need to provide an input to
Vpu on the board. I connected pin 6 on my breakout (
Vpu) to pin 9 (
(You can see my version of the wiring above: I have a lot more wires plugged in. I hooked up all of the
3.3V inputs before I realised which ones were needed and which weren’t. You don’t need to.)
|Raspberry Pi Pins|
(Where 1 is the bottom left pin pictured above, 2 is the top left etc.)
Now, for software. I’m driving this from a Debian Jessie laptop, but as long as you have USB serial port drivers, you could be driving it from anything.
sudo picocom --b 115200 /dev/ttyUSB0 picocom v1.7 port is : /dev/ttyUSB0 flowcontrol : none baudrate is : 115200 parity is : none databits are : 8 escape is : C-a local echo is : no noinit is : no noreset is : no nolock is : no send_cmd is : sz -vv receive_cmd is : rz -vv imap is : omap is : emap is : crcrlf,delbs, Terminal ready
The Bus Pirate boots into high-impedence mode, with the power supply turned off. Let’s select I2C, 100Khz (which is around the speed of the Raspberry Pi’s I2C).
HiZ>m 1. HiZ 2. 1-WIRE 3. UART 4. I2C 5. SPI 6. 2WIRE 7. 3WIRE 8. LCD 9. DIO x. exit(without change) (1)>4 Set speed: 1. ~5KHz 2. ~50KHz 3. ~100KHz 4. ~400KHz
Vpu, so we can safely turn on the PSU and enable the built-in pull-up resistors:
I2C>W Power supplies ON I2C>P Pull-up resistors ON
And search the available I2C address space:
I2C>(1) Searching I2C address space. Found devices at: 0xA8(0x54 W)
This bit confused me for ages. The source code I had read referred to 0x54 as the address, but the Bus Pirate wants to use the raw address for all writes, which is 0xA8. Writing to 0x54 just generates a lot of NACKs.
We want to write 0x0 0x1 to enable output:
I2C>[0xA8 0x0 0x1] I2C START BIT WRITE: 0xA8 ACK WRITE: 0x00 ACK WRITE: 0x01 ACK I2C STOP BIT
And enable all of the LEDs:
I2C>[0xA8 0x13 0xFF] [0xA8 0x14 0xFF] [0xA8 0x15 0xFF] I2C START BIT WRITE: 0xA8 ACK WRITE: 0x13 ACK WRITE: 0xFF ACK I2C STOP BIT I2C START BIT WRITE: 0xA8 ACK WRITE: 0x14 ACK WRITE: 0xFF ACK I2C STOP BIT I2C START BIT WRITE: 0xA8 ACK WRITE: 0x15 ACK WRITE: 0xFF ACK I2C STOP BIT
This picture from Boeeerb’s PiGlow Python library is useful for addressing the LEDs:
Lets turn on a bright white by writing 0x0A 0xFF (LED number, intensity as an 8bit integer). Then we need to write 0x16 0x0 to flush the values.
I2C>[0xA8 0x0A 0xFF] [0xA8 0x16 0x0] I2C START BIT WRITE: 0xA8 ACK WRITE: 0x0A ACK WRITE: 0xFF ACK I2C STOP BIT I2C START BIT WRITE: 0xA8 ACK WRITE: 0x16 ACK WRITE: 0x00 ACK I2C STOP BIT
And our first hint that any of this is really working, the
Hello World of electronics: turning a light on: