Cyber dice: seven-segment on pins 2 to 8, button on 9, on an Arduino Uno
A common-cathode seven-segment digit with segments a to g on pins 2 to 8 spins through 1 to 6 while the button on pin 9 is held; let go and it stops on a roll. The whole build, an Arduino Uno and 4 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
Teaching? Assign it to your class in one click.
Intermediate About 20 minutes to build and run. Runs in your browser. Free, and no account needed.
The parts retail for about $33. On Mokxi they're free.
What you'll learn
- Driving a seven-segment display from seven pins
- One bit per segment in a byte pattern
- A pull-down resistor on a button
- Random numbers with random()
- Loops that run while a button is held
- Difficulty: Intermediate
- Time: About 20 minutes
- Board: Arduino Uno R3
- Parts: 6
How it works
One seven-segment digit has its segments a to g on pins 2 to 8, with a single 220 ohm resistor on the common leg to ground. A pushbutton joins 5V to pin 9, and a 10k resistor pulls pin 9 to ground when it is not pressed.
While you hold the button, the digit flickers through 1 to 6 every 60 ms. When you let go, random(1, 7) picks the roll, the display shows it and the serial monitor prints it.
Parts list
6 parts, plus the jumper wires. They retail for about $33; on Mokxi they're free.
- 1 × Arduino Uno R3In Starter Kit, Claw Machine Kit, Vending Machine Kit.
- 1 × Full-size breadboard
- 1 × Seven segment display
- 1 × Resistor, 220 ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
- 1 × PushbuttonIn Starter Kit, Christmas Lights Kit, Logic Lab Kit.
- 1 × Resistor, 10k ΩIn Starter Kit, Claw Machine Kit, Halloween Prop Kit.
Kits that can build it
These 8 starter kits have every part in the circuit. Each kit's page lists what else it can build.
Wiring table
Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.
| Part and pin | Connects to |
|---|---|
| Resistor, 220 Ω pin 2 | Arduino Uno R3 pin GND |
| Resistor, 10k Ω pin 1 | Arduino Uno R3 pin GND |
| Pushbutton pin 2a | Arduino Uno R3 pin 9 |
| Seven segment display pin G | Arduino Uno R3 pin 8 |
| Seven segment display pin F | Arduino Uno R3 pin 7 |
| Seven segment display pin E | Arduino Uno R3 pin 6 |
| Seven segment display pin D | Arduino Uno R3 pin 5 |
| Seven segment display pin C | Arduino Uno R3 pin 4 |
| Seven segment display pin B | Arduino Uno R3 pin 3 |
| Seven segment display pin A | Arduino Uno R3 pin 2 |
| Pushbutton pin 1a | Arduino Uno R3 pin 5V |
| Resistor, 220 Ω pin 1 | Seven segment display pin COM1 |
| Resistor, 10k Ω pin 2 | Pushbutton pin 2b |
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Cyber dice: hold the button to roll, let go to see the number.
//
// seven-segment a..g -> pins 2..8 (one 220 ohm on the common leg to GND)
// button: one side -> 5V, the other -> pin 9, and 10k from pin 9 to GND
//
// Each digit is a pattern of seven segments, kept as one byte with a bit per
// segment: bit 0 is a, bit 6 is g. show() lights the segments whose bits are
// set. While the button is held the digit flickers through 1 to 6; on release
// random() picks the roll.
const int SEGMENT_PINS[7] = {2, 3, 4, 5, 6, 7, 8};
const int BUTTON = 9;
const byte DIGITS[7] = {
0b0111111, // 0
0b0000110, // 1
0b1011011, // 2
0b1001111, // 3
0b1100110, // 4
0b1101101, // 5
0b1111101, // 6
};
void show(int n) {
for (int s = 0; s < 7; s++) digitalWrite(SEGMENT_PINS[s], (DIGITS[n] >> s) & 1);
}
void setup() {
for (int s = 0; s < 7; s++) pinMode(SEGMENT_PINS[s], OUTPUT);
pinMode(BUTTON, INPUT);
randomSeed(analogRead(A0));
show(0);
Serial.begin(9600);
Serial.println("Mokxi Uno: hold the button on pin 9 to roll the dice");
}
void loop() {
if (digitalRead(BUTTON) == HIGH) {
int spin = 1;
while (digitalRead(BUTTON) == HIGH) {
show(spin);
spin = spin % 6 + 1;
delay(60);
}
int roll = random(1, 7);
show(roll);
Serial.print("you rolled ");
Serial.println(roll);
}
}
Code walkthrough
The key functions of the sketch, and what each one does.
show sketch.ino
Lights the digit n. It looks up the byte DIGITS[n], then for each of the 7 segments shifts the byte right by s and keeps the lowest bit. That bit turns the segment pin on or off.
void show(int n) {
for (int s = 0; s < 7; s++) digitalWrite(SEGMENT_PINS[s], (DIGITS[n] >> s) & 1);
}setup sketch.ino
Makes the seven segment pins outputs and the button an input. randomSeed(analogRead(A0)) varies the rolls from run to run. It shows 0, opens the serial port and prints instructions.
void setup() {
for (int s = 0; s < 7; s++) pinMode(SEGMENT_PINS[s], OUTPUT);
pinMode(BUTTON, INPUT);
randomSeed(analogRead(A0));
show(0);
Serial.begin(9600);
Serial.println("Mokxi Uno: hold the button on pin 9 to roll the dice");
}loop sketch.ino
When the button reads HIGH, it spins: it shows a number, steps it from 1 to 6 and back to 1, and waits 60 ms, until you release. Then it picks random(1, 7), shows that number and prints it.
void loop() {
if (digitalRead(BUTTON) == HIGH) {
int spin = 1;
while (digitalRead(BUTTON) == HIGH) {
show(spin);
spin = spin % 6 + 1;
delay(60);
}
int roll = random(1, 7);
show(roll);
Serial.print("you rolled ");
Serial.println(roll);
}
}Troubleshooting
The usual mistakes with this circuit, and the fix for each.
- The digit looks wrong or has a missing segment This project
Segments a to g go to pins 2 to 8 in order. Check each wire, and the resistor on the common leg. - It rolls on its own This project
Pin 9 needs the 10k resistor to ground so it does not float. - Segments stay dark, or light when they should be off. Seven segment display
Check whether the display is common cathode or common anode. Common cathode: common pin to GND, drive segments HIGH. Common anode: common pin to VCC, drive segments LOW. - One segment is very bright or the LEDs burn out. Seven segment display
Each segment is an LED, so it needs its own resistor, about 220 ohm to 330 ohm on 5 V. One resistor on the common pin makes brightness change with the number of lit segments. - The LED is dim, burns out, or the pin reads wrong because the resistor value is off. Resistor
Read the color bands again. A 220 ohm to 330 ohm resistor suits a typical LED on 5 V. 10k is a common pull-up or pull-down value. Check with a multimeter if unsure. - A pull-up or pull-down resistor is missing, so the input floats and reads random values. Resistor
Tie the input to 5 V or ground through about 10k. Or use INPUT_PULLUP and wire the switch to ground. - The input reads random HIGH and LOW when the button is not pressed. Pushbutton
A floating pin picks up noise. Add a 10 k pull-down or pull-up resistor, or use INPUT_PULLUP and wire the button between the pin and GND. Then pressed reads LOW. - The button seems always pressed, or never changes. Pushbutton
A 4-leg tactile switch has legs joined in pairs. Place it across the breadboard center gap so the pairs sit on different rows. Wired along one side, the legs are already connected.
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.