Go GPIO library for Raspberry Pi

GopherBeen playing a bit with Go (-lang) lately, it seems like a fun little language. Very minimalistic and clean, yet quite powerful – you can do so many things with the simple constructs they provide (especially the goroutines, channels and type-system). Sadly, it looks like it’s pretty slow in benchmarks compared to the other natural alternatives – but it’s still early.

animatedAnyway, in an attempt to mix Gophers and Pi, I’ve made a small native GPIO library for Go on the Raspberry Pi (or the bcm2835 chipset in general). Nothing advanced, but it provides the usual suspects: PinMode (Output, Input), Write, Read, PullUp, PullDown, PullOff, etc. It works by memory-mapping the GPIO addresses in /dev/mem, so it will require root.

To use, and blink a little LED (“hello world” of the electronics/microcontroller realm) just do something like:


import (
	"fmt"
	"github.com/stianeikeland/go-rpio"
	"os"
	"time"
)

func main() {
	if err := rpio.Open(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer rpio.Close()

	pin = rpio.Pin(10)
	pin.Output()

	for x := 0; x < 20; x++ {
		pin.Toggle()
		time.Sleep(time.Second)
	}
}

Available over at GitHub.

Would be awesome to add PWM, I2C, SPI, etc.. who knows, maybe one day..

Flocking / Synchronization

There are a few behaviors in nature that seems really advanced, impressive and organic, that actually can be simulated on a computer using only a few simple rules. One of them is flocking – the “formation”-flying of birds or movement of schools of fish. There’s an old algorithm/simulation by Craig Reynolds called Boids (often used in screensavers and even used for modeling the flying bats in batman) that explains this pretty well. Make a few objects that react to their neighborhood according to the following three simple rules:

  • Separation – try to stay at least x units away from all neighbours.
  • Alignment – try to match the average direction of your neighbours.
  • Cohesion – steer towards the center location of your neighbours.

Flocking in paper.js

Click on the image above for a live demo 🙂

Implement the rules and depending on how you weight them you quickly get behavior that looks impressively organic. Was bored the other evening, and my coding fingers are itching since I’ve barely gotten to do any programming at work these last months – the meeting/planning vs programming ratio is through the roof. So I did a quick implementation for shits and giggles. Check it out here: http://goo.gl/eY8KY (or click the image above). I have no idea if it works with all browsers, but works with chrome at least.

There’s also a decent TED talk on the subject:

What’s it going to be used for? Notting really, but might be useful to know if I ever get to chance to program a large army of hunter killer robots with swarm capability.

MSP430 Coffeetimer

The MSP430 is a familty of cheap microcontrollers from Texas Instruments featuring ultra low power usage. TI offers a devkit with everything you need to get started (USB-based development board and 2 microcontrollers from the value line) called the MSP430 Launchpad. The killer – it’s dead cheap – $4.30 for two microcontrollers and the launchpad including shipping (fedex!). You can also probably manage to get a few MCUs for free as samples. TI is probably selling the kit at a loss really trying to get into the hobbyist market, which is primarily dominated by the Arduino (and to a lesser degree Atmel in general and Microchip Pic). I was very impressed by the power usage, a guy managed to run them for 10 weeks as a clock on a couple of capacitors (granted – 10F caps).

Anyway, I have a 1 hour safety timer connected to my coffee maker (one of those devices that tick down and cut the power after one hour). Being a really cheap device from a low cost “wallmart” like shop I guess it was no surprise when it broke. It doesn’t tick down anymore, seems like the motor burned out – it’s mostly mechanical with a disc rotating one revolution and then cut the power by physically hitting a switch. I liked having the extra safety this device provided – and wanted a new one. Figured it was a good chance to learn some MSP430 programming. Turning the coffee maker on and off using a relay would be pretty simple, but I really don’t want to fuck with 220V mains and leave it without supervision (which probably also voids my home insurance).

I have a few radio controlled Nexa power switches (which are CE certified), so I hooked up one of the MSP430 microcontrollers from the launchpad kit to a remote with a few transistors. Programmed the microcontroller to sleep and wait for a interrupt from small push button, on interrupt it turns on the coffee maker (via the remote – connected with two transistors) and starts a timer. The timer blinks a led every now and then before turning off the coffee maker one hour+ later. Put the whole thing in a small ikea plastic container with 2 AA-batteries, which should last severals years if the MSP430 is as power efficient as they say.

There’s a few gotchas when programming the MSP430s, for example the watchdog timer.. The MCU features a watchdog that resets the device after a short time (VERY anoying..), unless you disable the timer – it’s on by default. Other than that it was more or less straight forward. You can either use the supplied eclipse-based code composer from texas instruments (proprietary and windows only) – or the open source msp430-gcc toolchain (runs on both linux and mac).. Code written in the code composer will probably not compile using msp430-gcc, there seems to be different syntax for defining interrupts – and intrinsic functions often have different names and functions depending on which compiler you use. I’ve tried both, the TI software nicely integrates a debugger that can step through lines and instructions in the IDE as they are running on the chip – Spy-Bi-Wire (pretty awesome feature for a $4.30 pricetag). For the open source toolchain you can use mspdebug to open a network port where you can connect using gdb.. providing you with more or less the same features, but it’s way more cumbersome to use gdb than a IDE-integrated debugger.. But then again, I don’t often use a debugger (even for normal software – my method of debugging often involves throwing prints everywhere), so I guess having to not run the proprietary IDE in a virtual machine is worth the loss of the IDE integrated debugger.

Also, setting up the internal timers required reading quite a lot of TI documentation, more so than other microcontrollers I’ve tried. The community using it is also small and there are few libraries available. But anyway, got it running – and now it turns on and off my coffee maker.

In conclusion, I don’t think TI will make that big of an impact on the hobbyist market with this, the alternatives are easier to use, have better documentation, usefull libraries and less cumbersome development tools. But then again – it’s a really cheap way to get started on MCUs.

Posting the coffee timer code as a future reference, maybe some of the boilerplate code can be useful for others as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* Coffetimer (safetytimer)
*
* Activated when button (pin 4) is grounded.
* Connected to a RF - remote control on pin 5 and 6
* via a couple of transistors, controling the
* coffemakers power outlet.
*
* */

#include "msp430g2231.h"

#define LONGDELAY (1000000 / (8*8)) * 4
#define SHORTDELAY (1000000 / (8*8*8))
#define POWERONTIME 4500

const int redLed = BIT0;
const int button = BIT4;
const int powerOn = BIT5;
const int powerOff = BIT6;

volatile int powerActive = 0;
volatile unsigned int onTime = 0;
volatile int blinkState = 0;

unsigned int i, y;

void main(void) {

WDTCTL = WDTPW + WDTHOLD;

P1DIR = ~button; // Button is input, rest output..
P1OUT &= ~(powerOn | powerOff | redLed);

P1REN |= button; // Pull up
P1IES |= button; // High to low interrupt
P1IE |= button; // Interrupt on button..
P1IFG = 0; // Clear INT flag

// Use internal occilator as timer source.. / 8.. /8
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // SMCLK = DCO = 1MHz
BCSCTL2 |= DIVS_3; // Divder / 8 for smclk
TACTL = TASSEL_2 + MC_1 + ID_3 + TACLR; // Timer A, SMCLK src, up mode, divider / 8..

CCTL0 = CCIE; // capture/compare interrupt go!
CCR0 = SHORTDELAY;

__enable_interrupt();

while(1) {
powerActive = 0;
onTime = 0;

// Go to sleep, wait for button
P1IFG = 0;
LPM4;

// Waking up from button push..
// Blink and power on coffemaker..
for (i = 0; i < 4; i++) {
P1OUT ^= redLed | powerOn;
for (y = 0; y < 40; y++)
__delay_cycles(40000);
}
P1OUT &= ~(redLed | powerOn);

powerActive = 2;

LPM1;

// Waking up from timer.. blink and turn off coffeemaker..
for (i = 0; i < 12; i++) {
P1OUT ^= redLed | powerOff;
for (y = 0; y < 40; y++)
__delay_cycles(40000);
}
P1OUT &= ~(redLed | powerOff);

}
}

// Button interrupt
#pragma vector=PORT1_VECTOR
__interrupt void port1_isr(void)
{
if (powerActive == 0) {

// Power on coffeemaker..
powerActive = 1;
LPM4_EXIT;

} else if (powerActive == 2) {

// Power off coffeemaker ahead of time..
onTime = POWERONTIME + 1;
P1OUT &= ~redLed;
powerActive = 0;
LPM1_EXIT;
}

P1IFG = 0;
}

// Timer interrupt, blink twice every few seconds..
#pragma vector=TIMERA0_VECTOR
__interrupt void timera0_isr(void)
{
if (powerActive != 2)
return;

CCR0 = (++blinkState % 4) ? SHORTDELAY : LONGDELAY;

if (blinkState % 2)
P1OUT |= redLed;
else
P1OUT &= ~redLed;

onTime += (blinkState % 4) ? 1 : 4;

// Wake from sleep if coffeemaker has been on long enough
if (onTime > POWERONTIME) {
P1OUT &= ~redLed;
powerActive = 0;
LPM1_EXIT;
}
}