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.
Mapping:
- 1 -> gpio pin 6
- 2 -> gpio pin 5
- 3 -> gnd
- 4 -> gpio pin 4
- 5 -> gpio pin 9
- 6 -> gpio pin 3
- 7 -> gpio pin 2
- 8 -> gnd
- 9 -> gpio pin 7
- 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; } } }