UP | HOME

Arduino zig: seven segment display

seven segment display is a form of electronic display device for displaying decimal numerals, the following picture shows how to build it up.

schematic.webp

Mapping:

  1. 1 -> gpio pin 6
  2. 2 -> gpio pin 5
  3. 3 -> gnd
  4. 4 -> gpio pin 4
  5. 5 -> gpio pin 9
  6. 6 -> gpio pin 3
  7. 7 -> gpio pin 2
  8. 8 -> gnd
  9. 9 -> gpio pin 7
  10. 10 -> gpio pin 8

1. Setup

const arduino = @import("arduino");
const gpio = arduino.gpio;

pub const panic = arduino.start.panicLogUart;

pub fn main() void {
    arduino.uart.init(arduino.cpu.CPU_FREQ, 115200);
    // ...
}

2. Set pin to output mode

Since you will use pin 2 to 9, you need to set them to output mode.

pub fn main() void {
    // ...
    comptime var pin = 2;
    inline while (pin <= 9) : (pin += 1) {
        gpio.setMode(pin, .output);
    }
}

3. Main loop

In main loop, loop simply count from 9 to 0, and again.

pub fn main() void {
    // ...
    var count: usize = 9;
    while (count >= 0) : (count -= 1) {
        evenSegWrite(count);
        arduino.cpu.delayMilliseconds(500);
        if (count == 0) {
            count = 9;
        }
    }
}

The problem is evenSegWrite, one can simply use evenSegWrite(9) to display 9 by seven-segment display, what magic here?

4. evenSegWrite

The idea is encoding a map from digit to pin state

const seven_seg_digits = [_][7]PinState{
    [_]PinState{ .high, .high, .high, .high, .high, .high, .low }, // = 0
    [_]PinState{ .low, .high, .high, .low, .low, .low, .low }, // = 1
    [_]PinState{ .high, .high, .low, .high, .high, .low, .high }, // = 2
    [_]PinState{ .high, .high, .high, .high, .low, .low, .high }, // = 3
    [_]PinState{ .low, .high, .high, .low, .low, .high, .high }, // = 4
    [_]PinState{ .high, .low, .high, .high, .low, .high, .high }, // = 5
    [_]PinState{ .high, .low, .high, .high, .high, .high, .high }, // = 6
    [_]PinState{ .high, .high, .high, .low, .low, .low, .low }, // = 7
    [_]PinState{ .high, .high, .high, .high, .high, .high, .high }, // = 8
    [_]PinState{ .high, .high, .high, .low, .low, .high, .high }, // = 9
};

fn evenSegWrite(digit: usize) void {
    comptime var pin = 2;
    comptime var seg = 0;
    inline while (seg < 7) : (seg += 1) {
        gpio.setPin(pin, seven_seg_digits[digit][seg]);
        pin += 1;
    }
}

5. All code

const arduino = @import("arduino");
const gpio = arduino.gpio;
const PinState = gpio.PinState;

// Necessary, and has the side effect of pulling in the needed _start method
pub const panic = arduino.start.panicLogUart;

const seven_seg_digits = [_][7]PinState{
    [_]PinState{ .high, .high, .high, .high, .high, .high, .low }, // = 0
    [_]PinState{ .low, .high, .high, .low, .low, .low, .low }, // = 1
    [_]PinState{ .high, .high, .low, .high, .high, .low, .high }, // = 2
    [_]PinState{ .high, .high, .high, .high, .low, .low, .high }, // = 3
    [_]PinState{ .low, .high, .high, .low, .low, .high, .high }, // = 4
    [_]PinState{ .high, .low, .high, .high, .low, .high, .high }, // = 5
    [_]PinState{ .high, .low, .high, .high, .high, .high, .high }, // = 6
    [_]PinState{ .high, .high, .high, .low, .low, .low, .low }, // = 7
    [_]PinState{ .high, .high, .high, .high, .high, .high, .high }, // = 8
    [_]PinState{ .high, .high, .high, .low, .low, .high, .high }, // = 9
};

fn evenSegWrite(digit: usize) void {
    comptime var pin = 2;
    comptime var seg = 0;
    inline while (seg < 7) : (seg += 1) {
        gpio.setPin(pin, seven_seg_digits[digit][seg]);
        pin += 1;
    }
}

pub fn main() void {
    arduino.uart.init(arduino.cpu.CPU_FREQ, 115200);

    comptime var pin = 2;
    inline while (pin <= 9) : (pin += 1) {
        gpio.setMode(pin, .output);
    }

    var count: usize = 9;
    while (count >= 0) : (count -= 1) {
        evenSegWrite(count);
        arduino.cpu.delayMilliseconds(500);
        if (count == 0) {
            count = 9;
        }
    }
}
Date: 2022-01-10 Mon 00:00
Author: Lîm Tsú-thuàn