ronbentley1
Published

Six sided die sketch, part 1

A sketch to 'throw' a six sided die using a partial 3 x 3 matrix of LEDs, driven directly from the microcontroller

BeginnerProtip681
Six sided die sketch, part 1

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
or any microcontroller with 10 digital IO ports
×1
5 mm LED: Red
5 mm LED: Red
Use any LEDs of any colour, or a mixture
×7
Resistor 220 ohm
Resistor 220 ohm
×7
Tactile Switch, Top Actuated
Tactile Switch, Top Actuated
Use a two terminal switch as these fit into a breadboard far more easily than the 4 terminal type, which always seen to pop out!
×1
Jumper wires (generic)
Jumper wires (generic)
×8
Development Kit Accessory, Jumper Wire Kit
Development Kit Accessory, Jumper Wire Kit
Use these jumpers (various lengths) to keep the breadboard tidy and LEDs clear of wires connecting the LEDs to the microcontroller
×1
Solderless Breadboard Half Size
Solderless Breadboard Half Size
Half size board is ideal for fitting the layout
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Six side Die, Circuit Diagram

Code

Six side die sketch part 1

C/C++
A sketch that randomly throws a standard six side die.
//
// Ron Bentley, Stafford, UK, December 2021
// This code is in the public domain and is offered without warranty
//
// Rolling the Dice, part 1 of 2 parts
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// A sketch to use with board games (or any game), where a die/dice is/are required, to
// throw a six sided die. However, the sketch may be easily modified to
// work with a poly-sided die, provided your microcontroller has sufficient digital
// ports/pins.
//
// Method: an electronic die is 'thrown' to produce a random number of pips each time the
// wired button switch is pressed.
//
// By default, the sketch also drives a heart beat using the LED_BUITIN LED, normally on pin 13,
// to show it is running (or not!).  To deselect the heart beat set the macro
// definition for heart beat on/off to false in the heart beat declaration section below, ie
// #define heart_beat_on false.
//
// Note that the circuit design calls for 7 x LEDs, these being physically
// arranged to represent each of the faces/sides of a standard die pip layout -
//
// Die LED pip layouts:
// The sketch uses 7 LEDs for each die to represent a partial 3 x 3 square of
// LEDs (1 x LED = 1 x pip) that allows 1 - 6 pips to be displayed in a standard die pattern, ie
//
// 1 pip  0   0, 2 pips 0   0, 3 pips X   0
//        0 X 0,        X 0 X,        0 X 0
//        0   0,        0   0,        0   X
//
// 4 pips X   X, 5 pips X   X, 6 pips X   X
//        0 0 0,        0 X 0,        X 0 X
//        X   X,        X   X,        X   X
//
// However, the design may be easily modified just to work with six LEDs
// with the pip count (throw score) represented by the same number of illuminated LEDs.
//
// Further reading and interest:
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// The sketch uses my ez_switch_lib library for managing the switch, in this
// instance, a button switch wired without a 10k ohm resistor (INPUT_PULLUP mode).
// See the Arduino Project Hub link below:
//
// https://create.arduino.cc/projecthub/ronbentley1/a-switch-library-for-arduino-dfbe40?ref=user&ref_id=1455180&offset=8
//
// See also the Arduino Project Article on including a heartbeat monitor to your sketches:
//
// https://create.arduino.cc/projecthub/ronbentley1/implementing-a-heart-beat-in-your-code-3f3460?ref=user&ref_id=1455180&offset=5
//
// for full expositions and detailed documentations.
//
// In 'Six sided die sketch, part 2 of 2 parts' we add a second die to the mix and also move the design to use
// serial to parellel input/output (SIPOs) ICs in a cascaded fashion.  The structure of the part 2 sketch
// largely remains the same this part 1 sketch. See the link below for part 2:
//
// ***************************************************LINK

#include <ez_switch_lib.h>
//
// define switch data required for the sketch...
//
#define button_switch_pin  9 // digitalpin assigned to the switch
int switch_id;               // stores the switch 'token' for the switch following the add_switch call

//
// Define heart beat data...
//
#define heart_beat_pin   LED_BUILTIN  // digital pin for heart beat LED
#define heart_beat_on    true         // determines if the implementation uses the heartbeat
long unsigned heart_beat_freq = 1000; // time(milliseconds) of heart beat frequency
long unsigned heart_beat_on_off_time; // the time the LED is on and off - 1/2 frequency
long unsigned last_heart_beat_time;   // time in milliseconds of last heart beat status change
bool heart_beat_status = HIGH;        // current status of heart beat, start high

//
// Function handles the heart beat cycle.
// May be called from anywhere, but at least every main loop cycle.
//
void heart_beat() {
  if (heart_beat_on) {
    if (millis() - last_heart_beat_time >= heart_beat_on_off_time) {
      // time to swap status of the heart beat LED and update it
      last_heart_beat_time = millis();
      heart_beat_status    = !heart_beat_status;        // invert current heart beat status value
      digitalWrite(heart_beat_pin, heart_beat_status);  // update LED with new status
    }
  }
}

//
// Die LED pip layouts:
// The sketch uses 7 LEDs for each die to represent a partial 3 x 3 square of
// LEDs (1 x LED = 1 x pip) that allows 1 - 6 pips to be displayed in a standard die pattern, ie
//
// 1 pip  0   0, 2 pips 0   0, 3 pips X   0
//        0 X 0,        X 0 X,        0 X 0
//        0   0,        0   0,        0   X
//
// 4 pips X   X, 5 pips X   X, 6 pips X   X
//        0 0 0,        0 X 0,        X 0 X
//        X   X,        X   X,        X   X
//

#define max_leds  7
int pip_pins[max_leds] = {
  // Digital pins mapping each of 7 LEDs
  2, 3, 4, 5, 6, 7, 8
};

//
// This 2-D array is used to define the LEDs that make up each of the die face
// pip patterns/layouts.  Each row of the array (face) corresonds to the pip value thrown (0-5)
// and holds its corresponding pip LED digital output pin numbers.
//
#define faces_per_die      6
#define max_pips_per_face  6
uint8_t pip_patterns[faces_per_die][max_pips_per_face] = {
  // LEDs that represent die pip patterns, faces/side 1-6 (array index 0-5) across 7 leds
  5, 0, 0, 0, 0, 0, // 1 pip, just the central LED
  3, 7, 0, 0, 0, 0, // 2 pips, each central two outer LEDs
  2, 5, 8, 0, 0, 0, // 3 pips, diagonal LEDs
  2, 4, 6, 8, 0, 0, // 4 pips, each corner LED
  2, 4, 5, 6, 8, 0, // 5 pips, all LEDs
  2, 3, 4, 6, 7, 8, // 6 pips, each outer column of 3 LEDs
};

// Create the switch control instance...
Switches my_switches(1); // define a switch control structure for a single switch

//
// Clear down the pips/LEDs
//
void clear_pips() {
  for (uint8_t led = 0; led < max_leds; led++) {
    digitalWrite(pip_pins[led], LOW);
  }
}
//
// Announces (signals) that a die throw is about to start
//
void announce_throw() {
  uint8_t led;
  // Start by clearing down the existing die pips/score
  clear_pips();
  for (uint8_t cycle = 1; cycle <= 2; cycle++) {// do 2 cycles
    for (uint8_t led = 0; led < max_leds; led++) {
      digitalWrite(pip_pins[led], HIGH);
      digitalWrite(pip_pins[max_leds - led - 1], HIGH);
      delay(60);
      heart_beat(); // keep pumping the heart beat timer whilst doing the announcing the throw
      digitalWrite(pip_pins[led], LOW);
      digitalWrite(pip_pins[max_leds - led - 1], LOW);
      delay(20);
      heart_beat(); // keep pumping the heart beat timer whilst doing the announcing the throw
    }
  }
}

//
// Throw the die
//
void throw_die() {
  announce_throw();   // 'announce' the throw of the die
  randomSeed(analogRead(A0) * 31 +
             analogRead(A1) * 37 +
             random(1023, 10000));                        // keep changing the seed
  uint8_t die_face = (random(1, 104640) % faces_per_die); // range 0-(faces_per_die-1)
  // Now display the pips on the die
  for (uint8_t column = 0; column < max_pips_per_face; column++) {
    uint8_t led = pip_patterns[die_face][column];
    if (led != 0) {
      // A pip LED is defined so illuminate it
      digitalWrite(led, HIGH);
    }
  }
}

void setup() {
  // **** Create a switch - a button switch wired without
  // **** a 10k ohm resistor (circuit_C2 - INPUT_PULLUP.
  // **** The parameters 'button_switch' and 'circuit_C2' are defined by ez_switch_lib.h
  switch_id = my_switches.add_switch(button_switch, button_switch_pin, circuit_C2);
  if (switch_id < 0) {
    // Failure to add a switch!
    exit(0);
  }
  // **** Configure each declared LED and set low (off)
  for (uint8_t led = 0; led < max_leds; led++) {
    pinMode(pip_pins[led],      OUTPUT);
    digitalWrite(pip_pins[led], LOW); // set LED to off
  }
  if (heart_beat_on) {
    // **** Setup heart beat, if selected
    pinMode(heart_beat_pin, OUTPUT);
    last_heart_beat_time   = millis();              // start of heartbeat timer
    heart_beat_on_off_time = heart_beat_freq / 2; // LED is on and off at 1/2 frequency time
    // End of heart beat setup
  }
  announce_throw(); // illuminate the LEDs on startup
}

void loop() {
  do {
    heart_beat(); // keep pumping the heart beat timer every cycle
    if (my_switches.read_switch(switch_id) == switched) {
      // the value 'switched' is defined by ez_switch_lib.h
      // Switch has been pressed and released, so throw the die...
      throw_die();
    }
  } while (true);
}

Credits

ronbentley1

ronbentley1

25 projects • 13 followers

Comments