In Part I of our Go (Golang) discussion, we went over why Go might be a good programming language for embedded systems. It is certainly worth you time to go to their website and explore the information there. There’s an interactive workspace for trying the language on the website.
In this article, we will load Go on to a Jetson and look at a simple software application. The software app displays some numbers on a 7 Segment LED Display connected to the Jetson over I2C. In addition, the app implements a web server which sends Server Side Events (SSE) to any attached web browser so that the web browser mirrors the LED display. Looky here:
Note: This demo has been tested on the Jetson TK1 L4T 21.5 and Jetson TX1 L4T 24.1 (32 bit and 64 bit versions). A Jetson TX1 with 64 bit L4T 24.1 is shown in the demo
First, before powering up the Jetson, let’s wire up the LED Segment Display.
For this project, a Adafruit 0.56″ 4-digit 7-segment Display W/i2c Backpack – Green is wired to a Jetson. The Display is assembled per the Adafruit instructions.
On a Jetson TK1, here’s a wiring combination for I2C Bus 1:
GND J3A1-14 -> LED Backpack (GND)
VCC J3A1-1 -> LED Backpack (VCC – 5V)
SCL J3A1-18 -> LED Backpack (SCL)
SDA J3A1-20 -> LED Backpack (SDA)
For the TK1, here’s another article for using the LED Segment Display.
On a Jetson TX1, here’s a wiring combination for I2C Bus 0 (as shown in the video)
GND J21-6 -> LED Backpack (GND)
VCC J21-2 -> LED Backpack (VCC – 5V)
SDA J21-3 -> LED Backpack (SDA)
SCL J21-5 -> LED Backpack (SCL)
Note that the TX1 also has a I2C Bus 1 interface. See the J21 Pinout Diagram.
Once the board is wired up, turn the Jetson on.
Install the libi2c-dev library. In order to be able inspect the LED Display, you may find it useful to also install the i2c tools:
$ sudo apt-get install libi2c-dev i2c-tools
After installation, in a Terminal execute (0 is the I2C bus in this case):
$ sudo i2cdetect -y -r 0
ubuntu@tegra-ubuntu:~$ sudo i2cdetect -y -r 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — — — — — — — — — — — — —
30: — — — — — — — — — — — — — — — —
40: — — — — — — — — — — — — — — — —
50: — — — — — — — — — — — — — — — —
60: — — — — — — — — — — — — — — — —
70: 70 — — — — — — —
You should see an entry of 0x70, which is the default address of the LED Segment Display. If you have soldered the address pins on the Display you should see the appropriate address.
With the I2C library installed and the display attached, we’re now ready to install Go. The directory ‘gowork’ will be the working directory. You may name it to your liking.
$ sudo apt-get install golang-1.6
$ mkdir -p gowork/src
Next edit bashrc to set the environment variable GOPATH, and have the PATH point to the Go binary.
$ gedit ~/.bashrc
Add the lines:
Now either source bashrc or close the current Terminal and open a new one.
Next, we’re ready to install the goi2c example from the JetsonHacks account on Github. Go understands how to retrieve Github repositories:
$ go get github.com/jetsonhacks/goi2c
You will have to set the I2C bus for the demo, depending on how you wired the LED Display to the Jetson. The line that needs to be changed is located in src/github.com/jetsonhacks/i2cExampleServer/main.go
backpack,err := ledBackpack7Segment.NewLedBackpack7Segment(1, 0x70)
In the repository, the bus is set to 1 (the first parameter). You may need to change it to 0.
Now let’s compile the example:
$ cd gowork/src
$ go install github.com/jetsonhacks/goi2c/i2cExampleServer
At this point, the example, ‘i2cExampleServer’, is in the gowork/bin directory.
For this example, the server requires the folder ‘templates’ to be in the same directory as the demo executable. Copy the templates directory to gowork/bin or create a new folder and copy the demo executable and the templates folder into it.
Before running the server, you may want to open a browser to monitor the display. Open a HTML 5 browser and point it to:
To run the demo, go to the folder in which you have placed the executable, and run the demo with sudo permissions. E.g.
$ sudo ./i2cExampleServer
Once the demo starts, the LED Segment Display will run a demo cycle. The web server sends out web pages to reflect the current LED Display. Type ^C to end the demo.
This Go sample app is not idiomatic Go programming. Instead it is a sketch of some of the functionality that may be useful in an embedded environment. It was also my first attempt at Go programming.
There’s not much to comment about on memory safety, as it’s pretty much invisible to the programmer.
Concurrency is a difficult thing, but Go has a good mechanism for dealing with it. Play with the samples and write some of your own code to get a feel for what it can do for you.
Server side events being pushed out from a server are pretty typical of something that you may want to do from an embedded device. Think of it as a stock ticker pushing data from the device. As expected, the web server part is pretty straightforward. Once you start thinking ‘the Go way’, it’s a simple task to write the server code.
Actually interfacing against a low level device, like the I2C Segment Display, feels to be about the same amount of work as a C program. If no memory allocation happens in the device driver, it’s probably just as easy to wrap an existing C library for use.
The thing compiles fast, I’ll certainly give it that.
Drawbacks? Sure. On Linux there’s really not an agreed upon IDE for Go with a good editor, project management and integrated debugger built-in. This seems to stem from the roots of the language designers who aren’t real believers in such things. This leads to a whole lot of what I call ‘Programming by guessing’.
When a professional programmer starts out in the world, the first thing they realize is that they don’t get to work on their own code. Most are thrown in the deep end of very large programs that have an issue which needs fixing. It’s one thing to work on your own code and fix issues, it’s another thing to be thrown out into the sea on your own. Debuggers and project organizers act as life preservers. It’s rather harsh not to have those available in a modern way, especially when you’re first starting out.
All in all, fairly positive. Certainly for having a server of any type on the device, Go should be a definite candidate. If there’s some particular task which needs concurrency at the CPU level, Go should be on the checklist. Certainly worth kicking the tires.
Visual Studio Code has a really good extension for Go. It checks for syntax errors and such. I think there is even a debugger package that I haven’t tried messing with yet. Unfortunately, there is no native version for ARM, but that being said it does run on both Linux and Windows. I wrote some code for a Raspberry Pi. I did it on a laptop then dropped it into my work folder on the Pi using a FTP program.
The Go code is pretty transportable, which makes it straightforward to port to other systems. Qt Creator on ARM has a Golang syntax checker. Unfortunately the state of debuggers on Golang is abysmal. I find this very strange given the idea that it is for very large systems for collaborative distributed programming developers. Thanks for reading!