golang on the raspberry pi

Some months back I wrote about receiving a new pair of Raspberry Pi 3 Model B+ cards. These are the latest, with better wireless and a slight bump in processor speeds to 1.2GHz. There were a number of little changes that made the B+ a much better little computer to work on directly. And thus, I started to really dig into programming on the machine and manipulating its hardware ports, first in C++, and later in Go.

I’ve been tempted by Go for a while now, in part because of its tool chain, and in part because it’s a clean version of C, if you will. I’m doing my best to write clean idiomatic Go code, and getting pretty close, but finding that old coding C-isms keep creeping into my code. It’s hard to forget a language you’ve been writing in since the early 1980s; Lifeboat C on an IBM PC XT.

But I believe I’m making good progress. First of all, I’ve moved over entirely to Raspbian as my Linux distribution of choice. After moving back and forth several times between Arch Linux for ARM and Raspbian, I’m now over in the Raspbian camp permanently. The Raspbian graphical desktop is lightweight and very fast, and the version of Chromium that now ships is quite the little performer. The version shipping with the latest version of Raspian: Version 65.0.3325.181 (Official Build) Built on Raspbian , running on Raspbian 9.4 (32-bit).

As far as a development environment is concerned, I have VIM installed and configured to do a decent job of writing Go code.

And to make things even easier I’m using Gobot (https://gobot.io/) which makes writing code to work with hardware on the GPIO pins or on the I2C buss a snap.

Here is a simple application I wrote in Go 1.10.2.

package mainimport ("fmt""os""os/signal""syscall""gobot.io/x/gobot/platforms/raspi")func main() {// Hook the various system abort calls for us to use or ignore as we// see fit. In particular hook SIGINT, or CTRL+C for below.//signal_chan := make(chan os.Signal, 1)signal.Notify(signal_chan,syscall.SIGHUP,syscall.SIGINT,syscall.SIGTERM,syscall.SIGQUIT)// We want to capture CTRL+C to first clear the display and then exit.// We don't want to leave the display lit on an abort.//go func() {for {signal := <-signal_chanswitch signal {case syscall.SIGINT:// CTRL+Cfmt.Println()os.Exit(0)default:}}}()// Go find an I2C buss and open it.//adapter := raspi.NewAdaptor()adapter.Connect()bus := adapter.GetDefaultBus()// Now iterate across all I2C device addresses.// If we successfully read a byte from an address,// then we have detected a device. Print out the// hex address of that device.//for i := 0 ; i < 128 ; i++ {if device, err := adapter.GetConnection(i, bus) ; err == nil {if _, err := device.ReadByte() ; err == nil {fmt.Printf( " Found device at 0x%x / %d on I2C bus %d\n", i, i, bus)}}}}

The purpose of this simple utility is to find the active I2C bus and then to find the active devices on that bus. This is meant to be far simpler than i2cdetect, the utility that is available to Raspbian via its repository. You just type ‘detect’ at the shell command line, it it will produce output similar to this:

 Found device at 0x20 / 32 on I2C bus 1 Found device at 0x70 / 112 on I2C bus 1 Found device at 0x71 / 113 on I2C bus 1

In this example detect found three devices on I2C bus 1 at addresses x020, 0x70, and 0x71. That’s because I have an MCP23017 port expander at 0x20, and a pair of Adafruit FeatherWing four character alphanumeric displays (https://www.adafruit.com/product/3130) at 0x70 and 0x71. Unlike i2cdetect, I don’t have to tell it the I2C buss to use, nor give it a ‘y’ on the command line. It detects the bus, and then detects the devices on that bus. Great for when I want to just know if the devices I plugged in are available or not.