This library is a fork of Alex Ellis' blinkt_go that I was intending to port to my gpiocdev library, but ended up going off on a bit of a tangent and also using it as a testbed for comparing various GPIO implementations, and incorporating a merge/port of Alex's blinkt_go_examples.
import "github.com/warthog618/blinkt"
// create a blinkt to control the display
bl := blinkt.New()
// set the display brightness
bl.SetBrightness(23)
// write to pixels
bl.SetPixel(0, r, g, b)
...
bl.SetPixel(7, r, g, b)
// show the pixels on the display
bl.Show()
// clear the display
bl.Clear()
bl.Show()
// finish with the display
bl.Close()
The following is a short summary of the Blinkt API.
Create a new Blinkt object using *New":
bl := blinkt.New()
If you no longer need to use the display, or your application is exiting, you should close the display:
bl.Close()
By default the display is cleared when closed. This can be changed with the SetClearOnExit method:
bl.SetClearOnExit(false)
The following methods act on all pixels in the display.
Note that nothing is actually written to the physical display until Show is called.
Set the colour of all pixels at once using SetAll:
bl.SetAll(r, g, b)
Setting the colour does not alter the brightness, which is independent.
Set the brightness of all pixels at once using SetBrightness:
bl.SetBrightness(42)
The brightness value is a percent, so 0-100. By default the display brightness is set to 50.
Turn off all pixels using the Clear method:
bl.Clear()
Update the display with the current pixel states using Show:
bl.Show()
The other methoss only update the pixels in memory - the Show command commits that state to the display.
The Show method performs the update in a separate goroutine using a snapshot of the pixel state, so the main goroutine can immediately begin updating the pixel state while the snapshot is being written to the display.
The Show method will block if the background goroutine is still updating the display with the previous Show.
The following methods apply to an individual pixel.
The pixel parameter which identifies the pixel, and is denoted by p in these snippets, is in the range 0-7.
Turn off the pixel using the ClearPixel method:
bl.ClearPixel(p)
Set the colour of the pixel using SetPixel:
bl.SetPixel(p, r, g, b)
Setting the colour does not alter the brightness, which is independent.
Set the brightness of the pixel using SetPixelBrightness:
bl.SetPixelBrightness(68)
The Blinkt is not safe to call from multiple goroutines, with the exception of the Close method, which is made goroutine safe so it can be called from signal handlers, e.g. when the application is closing down.
The library provides a selection of backends to drive the GPIO, with the selection being performed by a build tag. e.g.
go build -tags blinkt_wiringpi
will build an application using the WiringPi backend.
The default backend is my gpiocdev library, which makes use of the official Linux GPIO interface.
Backend | Build tag | Interface |
---|---|---|
gpiocdev | none (default) | Linux GPIO character device (/dev/gpiochip0) uAPI |
gpio | blinkt_gpio | Raspberry Pi /dev/gpiomem direct access to the BCM hardware |
wiringpi | blinkt_wiringpi | WiringPi cgo wrapper |
sysfs | blinkt_sysfs | deprecated GPIO SYSFS interface |
The examples directory contains a collection of examples that demonstrate the library and display.
These were originally ported from Alex's blinkt_go_examples which are themselves largely ports of some of the Pimoroni examples.
I've ported a few more of those, such as the binary clocks and rainbow.
These are the results from a Raspberry Pi Zero W running Linux v5.10 and built with go1.15.6:
$ go test -test.bench=.*
goos: linux
goarch: arm
pkg: github.com/warthog618/blinkt
BenchmarkShow 106 10547923 ns/op
PASS
ok github.com/warthog618/blinkt 1.683s
A summary of the results for each of the backends:
Backend | ns/op | Shows/sec |
---|---|---|
gpiocdev | 10547923 | 94 |
gpio | 102205 | 9784 |
wiringpi | 3435945 | 291 |
sysfs | 66638981 | 15 |
For comparison the Python/WiringPi implementation can perform around 9 shows/sec on the same platform.
My recommendation is to use the gpiocdev backend unless you have a serious need for speed or very low CPU utilization (and aren't concerned about conflicting with other BCM drivers), in which case the gpio library is a clear winner.
I could only recommend the Python interface for very low bandwidth applications.