Seven Segment Display With TinyGo On My Arudino Uno

I wrote a TinyGo counter for a 7-segment display with my Uno, and in the process learned about several Go features, like packages and channels!

Seven Segment Display With TinyGo On My Arudino Uno
Photo by Sahand Babali / Unsplash

I wrote a TinyGo counter for a 7-segment display with my Uno, and in the process learned about several Go features, like packages and channels!

First of all, let's see the result:

0:00
/

This is a relatively trivial example: as you can see, this is a counter that only displays the last digit of its decimal value. You can think of this as counting from 0 to 9 and then cycling back to 0.

However, the trick to this is that it's written in TinyGo using goroutines! This means that the display and the counter are asynchronous, and handled separately.

Take a look at the counter's source code:

// Counts an int using goroutines and channels for a 7-segment display
package main

import (
    "example.com/display"
    "time"
)

func main() {
    c := make(chan int64)
    display.InitDisplay()
    go countToChannel(c)
    displayFromChannel(c)
}

func displayFromChannel(c chan int64) () {
    for {
        display.DisplayInt(<- c)
    }
}

func countToChannel(c chan int64) () {
    var currentInt int64 = 0
    for {
        c <- currentInt
        delay(200)
        currentInt = currentInt + 1
    }
}

func delay(t int64) {
    time.Sleep(time.Duration(1000000 * t))
}

The goroutine is seen at "go countToChannel(c)". Both countToChannel and displayFromChannel are infinite loops, one which slowly increments an integer and one which reads from the Go channel to display on the 7-segment display.

You'll notice that the display code is in a separate package, which I import in the counter program. Packaging is always one of the first things to learn about a new language.

The display package's code is thus:

// Uses pins 2 to 8 for a seven-segment display.
// D2: Top right
// D3: Top
// D4: Top left
// D5: Bottom right
// D6: Middle
// D7: Bottom
// D8: Bottom left

package display

import (
    "machine"
)

func InitDisplay() {
    pins := [...]machine.Pin{
        machine.D2,
        machine.D3,
        machine.D4,
        machine.D5,
        machine.D6,
        machine.D7,
        machine.D8,
    }
    for _, singlePin := range pins {
        singlePin.Configure(machine.PinConfig{Mode: machine.PinOutput})
    }
}

func DisplayInt(digit int64) () {
    singleDigit := digit % 10
    switch {
    case singleDigit == 0:
        displayArray([7]bool{true, true, true, true, false, true, true})
    case singleDigit == 1:
        displayArray([7]bool{true, false, false, true, false, false, false})
    case singleDigit == 2:
        displayArray([7]bool{true, true, false, false, true, true, true})
    case singleDigit == 3:
        displayArray([7]bool{true, true, false, true, true, true, false})
    case singleDigit == 4:
        displayArray([7]bool{true, false, true, true, true, false, false})
    case singleDigit == 5:
        displayArray([7]bool{false, true, true, true, true, true, false})
    case singleDigit == 6:
        displayArray([7]bool{false, true, true, true, true, true, true})
    case singleDigit == 7:
        displayArray([7]bool{true, true, false, true, false, false, false})
    case singleDigit == 8:
        displayArray([7]bool{true, true, true, true, true, true, true})
    case singleDigit == 9:
        displayArray([7]bool{true, true, true, true, true, true, false})
    }
}

func displayArray(segments [7]bool) () {
    pins := [...]machine.Pin{
        machine.D2,
        machine.D3,
        machine.D4,
        machine.D5,
        machine.D6,
        machine.D7,
        machine.D8,
    }
    for idx, singlePin := range pins {
        if segments[idx] {
            singlePin.High()
            continue
        }
        singlePin.Low()
    }
}

I used a switch and array to represent the conversion between a digit and the segments of a display. Perhaps another time I'd try a mapping of pins to boolean values, but that seems much more tightly coupled than an array.