Roll an electronic dice on the 4-digit display

Press a button and the 4-digit display spins through numbers before stopping on a random 1 to 6. A second button switches to two dice for board games.
  • Level:Beginner
  • Duration: 50 min
  • Ages 10+
  • Platform: Arduino

Tools for this lesson

Helpful for this build. Open a tool to see tips and more projects that use it.

Roll an electronic dice on the 4-digit display – EEMENTOR STEM™ lesson

Board games need dice, and dice get lost. In this lesson you build an electronic one on the 4-digit 7-segment display from your kit. Press the roll button and the numbers spin faster than your eye can follow, then slow down and stop, just like a real dice tumbling across the table. The second button switches between one dice and two, and the display shows both results and their total.

What you'll learn

  • How a 7-segment display draws numbers from seven small LEDs
  • How multiplexing shows four digits with only twelve pins
  • How to make random numbers with random() and randomSeed()
  • How to slow an animation down step by step

What you need

  • UNO R3 board and USB cable (UNO R3 Starter Kit)
  • 4-digit 7-segment display, common cathode (UNO R3 Starter Kit)
  • 4 resistors, 220 Ω (UNO R3 Starter Kit)
  • 2 push buttons (UNO R3 Starter Kit)
  • Breadboard and jumper wires (UNO R3 Starter Kit)

Make it real: glue the breadboard into a small box lid and cut a window for the display, so the dice sits on the games table like a real gadget.

Wiring

Breadboard wiring diagram: Roll an electronic dice on the 4-digit display
Breadboard view. Check each connection against the wiring table below.
From To
Display segments a, b, c, d, e, f, g, dp UNO pins 2, 3, 4, 5, 6, 7, 8, 9
Display digits D1, D2, D3, D4 220 Ω resistor each, then UNO pins 10, 11, 12, 13
Roll button, one leg UNO pin A0
Mode button, one leg UNO pin A1
Both buttons, the diagonally opposite leg GND

This is the same wiring as the 4-digit stopwatch project, so if you built that, only the sketch changes. Check your display's pin order in its datasheet: most 12-pin displays have digit 1 at the top left.

The sketch

const int SEG_PINS[8] = {2, 3, 4, 5, 6, 7, 8, 9};   // a, b, c, d, e, f, g, dp
const int DIGIT_PINS[4] = {10, 11, 12, 13};         // digits 1 to 4
const int ROLL_PIN = A0;
const int MODE_PIN = A1;

// Segment patterns for 0-9 (bit 0 = a ... bit 6 = g)
const byte NUMBERS[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
const byte BLANK = 0x00, DASH = 0x40;

byte shown[4] = {DASH, DASH, DASH, DASH};
bool twoDice = false;
int dice1 = 0, dice2 = 0;

// Show the four patterns for a few milliseconds each, again and again (multiplexing)
void refresh(unsigned long ms) {
  unsigned long start = millis();
  while (millis() - start < ms) {
    for (int d = 0; d < 4; d++) {
      for (int s = 0; s < 8; s++) digitalWrite(SEG_PINS[s], bitRead(shown[d], s));
      digitalWrite(DIGIT_PINS[d], LOW);      // common cathode: LOW turns the digit on
      delay(2);
      digitalWrite(DIGIT_PINS[d], HIGH);
    }
  }
}

void showDice() {
  if (twoDice) {
    shown[0] = NUMBERS[dice1];
    shown[1] = NUMBERS[dice2];
    int total = dice1 + dice2;
    shown[2] = total >= 10 ? NUMBERS[1] : BLANK;
    shown[3] = NUMBERS[total % 10];
  } else {
    shown[0] = BLANK; shown[1] = BLANK; shown[2] = BLANK;
    shown[3] = NUMBERS[dice1];
  }
}

void roll() {
  int wait = 20;
  while (wait < 260) {                      // spin, slowing down a little each time
    dice1 = random(1, 7);
    dice2 = random(1, 7);
    showDice();
    refresh(wait);
    wait += wait / 6 + 2;
  }
}

void setup() {
  for (int s = 0; s < 8; s++) pinMode(SEG_PINS[s], OUTPUT);
  for (int d = 0; d < 4; d++) {
    pinMode(DIGIT_PINS[d], OUTPUT);
    digitalWrite(DIGIT_PINS[d], HIGH);       // all digits off
  }
  pinMode(ROLL_PIN, INPUT_PULLUP);
  pinMode(MODE_PIN, INPUT_PULLUP);
  randomSeed(analogRead(A5));                // a floating pin gives a different start each time
}

void loop() {
  if (digitalRead(ROLL_PIN) == LOW) {
    randomSeed(micros());                    // the moment you press adds more randomness
    roll();
  }
  if (digitalRead(MODE_PIN) == LOW) {
    twoDice = !twoDice;
    if (dice1 > 0) showDice();
    else for (int d = 0; d < 4; d++) shown[d] = (twoDice || d == 3) ? DASH : BLANK;
    while (digitalRead(MODE_PIN) == LOW) refresh(10);
  }
  refresh(10);
}

How it works

Each digit is eight LEDs: seven segments, called a to g, plus the decimal point. A number is a pattern of segments, stored as one byte: in 0x06, for example, only bits 1 and 2 are set, so only segments b and c light up, which makes a 1.

All four digits share the same eight segment wires, so the sketch switches on one digit at a time, shows its pattern for 2 ms, and moves to the next. That happens 125 times a second, too fast for your eye, so you see all four digits at once. This trick is called multiplexing, and it is why the display has to be refreshed all the time in loop().

random(1, 7) gives a number from 1 to 6. Computers can't really make random numbers, so randomSeed() starts the sequence from something unpredictable: the noise on an unused pin, and the exact microsecond you press the button.

Try this next

  • Add a "cheat" mode that only rolls sixes when you hold both buttons. Then remove it again!
  • Count how often each number comes up in 600 rolls and print the results. Is your dice fair?
  • Make a 1–20 dice for role-playing games.

Troubleshooting

  • Some segments never light: check the eight segment wires against your display's pinout.
  • Numbers look like strange shapes: two segment wires are swapped. Light one segment at a time to find which.
  • The display flickers: something in loop() is waiting too long; keep calling refresh().
  • Nothing lights at all: your display may be common anode. Swap HIGH and LOW for the digit pins and use !bitRead(...) for the segments.

Build it yourself

Everything used in this lesson comes in one kit, with parts tested by our engineers.

UNO R3 Starter Kit | Arduino IDE Compatible | Free Tutorials $56.00

Shop the kit