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;
}
}
}