Components and supplies
Development Kit Accessory, Jumper Wire Kit
Solderless Breadboard Half Size
Jumper wires (generic)
Solderless Breadboard Full Size
Arduino UNO
Resistor 220 ohm
Tactile Switch, Top Actuated
5 mm LED: Red
Apps and platforms
Arduino IDE
Project description
Code
A sketch to randomly throw two six sided dice, using cascaded 74HC595 serial-parallel input/output
c_cpp
A sketch to randomly throw two six sided dice, using cascaded 74HC595 serial-parallel input/output ICs
1// 2// Ron Bentley, Stafford, UK, December 2021 3// This code is in the public domain and is offered without warranty 4// 5// Rolling the Dice, part 2 of 2 parts 6// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 7// A sketch to use with board games (or any game), where a two dice are required, to 8// throw two six sided dice, using cascaded serial-parallel ICs, eg 74HC595 chips. 9// 10// Method: two electronic dice are 'thrown' to produce a random number of pips each time the 11// wired button switch is pressed. 12// 13// By default, the sketch also drives a heart beat using the LED_BUILTIN LED, normally on pin 13, 14// to show it is running (or not!). To deselect the heart beat set the macro 15// definition for heart beat on/off to false in the heart beat declaration section below, ie 16// #define heart_beat_on false. 17// 18// Note that the circuit design calls for each die to be represented by 7 x LEDs, 19// these being physically arranged to represent each of the faces/sides of a standard 20// die pip layout - 21// 22// Die LED pip layouts: 23// The sketch uses 7 LEDs for each die to represent a partial 3 x 3 square of 24// LEDs (1 x LED = 1 x pip) that allows 1 - 6 pips to be displayed in a standard die pattern, ie 25// 26// 1 pip 0 0, 2 pips 0 0, 3 pips X 0 27// 0 X 0, X 0 X, 0 X 0 28// 0 0, 0 0, 0 X 29// 30// 4 pips X X, 5 pips X X, 6 pips X X 31// 0 0 0, 0 X 0, X 0 X 32// X X, X X, X X 33// 34// These LEDS are connected to serial/parallel I/O ICs connections QB-QH, eg 74HC595, 35// in two separate sets. Note that QA is not used in this implementation. 36// 37// Further reading and interest: 38// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 39// The sketch uses my ez_switch_lib and ez_SIPO8 libraries for managing the switch and SIPO ICs, respectively. 40// In this instance, a button switch wired simply connected without a 10k ohm resistor (INPUT_PULLUP mode). 41// See the Arduino Project Hub links below for more detailed reading: 42// 43// ez_switch_lib: 44// https://create.arduino.cc/projecthub/ronbentley1/a-switch-library-for-arduino-dfbe40?ref=user&ref_id=1455180&offset=8 45// 46// ez_SIPO8_lib: 47// https://create.arduino.cc/projecthub/ronbentley1/command-control-of-multiple-serial-in-parallel-out-ics-3e0b1a?ref=user&ref_id=1455180&offset=7 48// 49// heart_beat monitoring: 50// 51// https://create.arduino.cc/projecthub/ronbentley1/implementing-a-heart-beat-in-your-code-3f3460?ref=user&ref_id=1455180&offset=5 52// 53 54#include <ez_switch_lib.h> 55#include <ez_SIPO8_lib.h> 56 57// 58// Define switch data required for the sketch... 59// 60#define button_switch_pin 12 // digital pin assigned to the switch 61int switch_id; // stores the switch 'token' for the switch following the add_switch call 62 63// 64// Define serial/parallel I/O (SIPO) data required for the sketch... 65// 66#define data_pin 2 67#define latch_pin 3 68#define clock_pin 4 69#define num_SIPOs 2 // 2 x 8 bit SIPO ICs linked in cascade formation 70#define num_SIPO_timers 0 // no SIPO timers used in this example 71int bank_id; // holds the SIPO bank ID given by the create_bank function 72 73// 74// Define heart beat data... 75// 76#define heart_beat_pin LED_BUILTIN // digital pin for heart beat LED 77#define heart_beat_on true // determines if the implementation uses the heartbeat 78long unsigned heart_beat_freq = 1000; // time(milliseconds) of heart beat frequency 79long unsigned heart_beat_on_off_time; // the time the LED is on and off - 1/2 frequency 80long unsigned last_heart_beat_time; // time in milliseconds of last heart beat status change 81bool heart_beat_status = HIGH; // current status of heart beat, start high 82 83// 84// Function handles the heart beat cycle. 85// May be called from anywhere, but at least every main loop cycle. 86// 87void heart_beat() { 88 if (heart_beat_on) { 89 if (millis() - last_heart_beat_time >= heart_beat_on_off_time) { 90 // time to swap status of the heart beat LED and update it 91 last_heart_beat_time = millis(); 92 heart_beat_status = !heart_beat_status; // invert current heart beat status value 93 digitalWrite(heart_beat_pin, heart_beat_status); // update LED with new status 94 } 95 } 96} 97 98// 99// This array is used to define the SIPO outputs that connect to the LEDs 100// that make up each of the die face patterns/layouts. 101// Each element of the array (faces) corresonds to the binary pattern of the 102// pip value thrown (0-5) for each face/side of a die. 103// The SIPO outputs are referenced as QA - QH, with the LSB (0) being QA, etc. 104// See SIPO documentations. 105// Note that QA is not used in this implementation. 106// 107#define num_dice num_SIPOs // because we are using one SIPO IC for each die 108#define faces_per_die 6 109#define die_1 0 110#define die_2 1 111uint8_t pip_patterns[faces_per_die] = { 112 // Die pip patterns, faces 1-6 (array index 0-5) across 7 SIPO connected leds 113 0b00010000, // 1 pip, just the central LED connected to SIPO output QE 114 0b01000100, // 2 pips, each central two outer LEDs connected to SIPO outputs QC and QG 115 0b00111000, // 3 pips, diagonal LEDs connected to SIPO outputs QD, QE and QF 116 0b10101010, // 4 pips, each corner LED connected to SIPO outputs QB, QD, Q5 and QH 117 0b10111010, // 5 pips, all LEDs connected to SIPO outputs QB, QD, QE, Q5 and QH 118 0b11101110 // 6 pips, each outer column of 3 LEDs connected to SIPO outputs QB, QC, QD, QF, QG and QH 119}; 120 121// Create the switch control instance... 122Switches my_switches(1); // define a switch control structure for a single switch 123 124// Create the SIPO control instance for the number of dice defined... 125SIPO8 my_SIPOs(num_dice, num_SIPO_timers); // define a SIPO control structure for the number of dice (SIPO ICs) required 126 127// 128// Clear down the pips/LEDs 129// 130void clear_pips() { 131 my_SIPOs.set_bank(bank_id, LOW); // set all bits in this bank to 0 (off) 132 my_SIPOs.xfer_bank(bank_id, MSBFIRST); // write out the SIPO bank data to the SIPO ICs 133} 134 135// 136// Announces (signals) that a dice throw is about to start 137// 138void announce_throw() { 139#define num_cycles 2 140#define num_patterns 5 141 uint8_t announce_pattern[num_patterns] = {// simple strobe sequence - down and up 142 0b00100010, // outer two top LEDs of a die 143 0b01000100, // outer two middle LEDs of a die 144 0b10001000, // outer two bottom LEDs of a die 145 0b01000100, // outer two middle LEDs of a die 146 0b00100010 // outer two top LEDs of a die 147 }; 148 // Start by clearing down the existing die pips/score 149 clear_pips(); 150 for (uint8_t cycle = 1; cycle <= num_cycles; cycle++) {// do 'num_cycles' cycles 151 // send each face/side strobe pattern to each die with a short delay between each 152 for (uint8_t pattern = 0; pattern < num_patterns; pattern++) { 153 my_SIPOs.set_bank_SIPO(bank_id, die_1, announce_pattern[pattern]); // set first die to this 'pattern' 154 my_SIPOs.set_bank_SIPO(bank_id, die_2, announce_pattern[pattern]); // set second die to this 'pattern' 155 my_SIPOs.xfer_bank(bank_id, MSBFIRST); // transfer (xfer) out the dice bits to the physical cascaded SIPOs 156 delay(50); 157 heart_beat(); // keep pumping the heart beat 158 clear_pips(); 159 } 160 } 161} 162 163// 164// Throw the die 165// 166void throw_dice() { 167 announce_throw(); // 'announce' the throw of the die 168 randomSeed(analogRead(A0) * 31 + 169 analogRead(A1) * 37 + 170 random(1023, 10000)); // keep changing the seed 171 uint8_t die_face; 172 die_face = random(1, 104640) % faces_per_die; // range 0-(faces_per_die-1) 173 my_SIPOs.set_bank_SIPO(bank_id, 174 die_1, // first die in the bank 175 pip_patterns[die_face]); // load first die pip patern for this face 176 die_face = random(1, 104640) % faces_per_die; // range 0-(faces_per_die-1) 177 my_SIPOs.set_bank_SIPO(bank_id, 178 die_2, // second die in the bank 179 pip_patterns[die_face]); // load second die pip pattern for this face 180 my_SIPOs.xfer_bank(bank_id, MSBFIRST); // move dice data to the physical cascaded SIPOs 181} 182 183void setup() { 184 // **** Create a switch - a button switch wired without 185 // **** a 10k ohm resistor (circuit_C2 - INPUT_PULLUP) 186 switch_id = my_switches.add_switch(button_switch, button_switch_pin, circuit_C2); 187 if (switch_id < 0) { 188 // failure to add a switch! 189 exit(0); 190 } 191 // **** Create the SIPO bank of size 192 // **** = number of individual SIPO ICs (num_SIPOs) in the cascaded bank 193 bank_id = my_SIPOs.create_bank(data_pin, clock_pin, latch_pin, num_SIPOs); 194 if (bank_id == create_bank_failure ) { 195 // failure to create a SIPO bank 196 exit(0); 197 } 198 if (heart_beat_on) { 199 // **** Setup heart beat, if selected 200 pinMode(heart_beat_pin, OUTPUT); 201 last_heart_beat_time = millis(); // start of heartbeat timer 202 heart_beat_on_off_time = heart_beat_freq / 2; // LED is on and off at 1/2 frequency time 203 // end of heart beat setup 204 } 205 announce_throw(); // illuminate the LEDs on startup 206} 207 208void loop() { 209 do { 210 heart_beat(); // keep pumping the heart beat timer every cycle 211 if (my_switches.read_switch(switch_id) == switched) { 212 // Switch has been pressed and released, so throw the die... 213 throw_dice(); 214 } 215 } while (true); 216} 217
A sketch to randomly throw two six sided dice, using cascaded 74HC595 serial-parallel input/output
c_cpp
A sketch to randomly throw two six sided dice, using cascaded 74HC595 serial-parallel input/output ICs
1// 2// Ron Bentley, Stafford, UK, December 2021 3// This code is in the public domain and is offered without warranty 4// 5// Rolling the Dice, part 2 of 2 parts 6// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 7// A sketch to use with board games (or any game), where a two dice are required, to 8// throw two six sided dice, using cascaded serial-parallel ICs, eg 74HC595 chips. 9// 10// Method: two electronic dice are 'thrown' to produce a random number of pips each time the 11// wired button switch is pressed. 12// 13// By default, the sketch also drives a heart beat using the LED_BUILTIN LED, normally on pin 13, 14// to show it is running (or not!). To deselect the heart beat set the macro 15// definition for heart beat on/off to false in the heart beat declaration section below, ie 16// #define heart_beat_on false. 17// 18// Note that the circuit design calls for each die to be represented by 7 x LEDs, 19// these being physically arranged to represent each of the faces/sides of a standard 20// die pip layout - 21// 22// Die LED pip layouts: 23// The sketch uses 7 LEDs for each die to represent a partial 3 x 3 square of 24// LEDs (1 x LED = 1 x pip) that allows 1 - 6 pips to be displayed in a standard die pattern, ie 25// 26// 1 pip 0 0, 2 pips 0 0, 3 pips X 0 27// 0 X 0, X 0 X, 0 X 0 28// 0 0, 0 0, 0 X 29// 30// 4 pips X X, 5 pips X X, 6 pips X X 31// 0 0 0, 0 X 0, X 0 X 32// X X, X X, X X 33// 34// These LEDS are connected to serial/parallel I/O ICs connections QB-QH, eg 74HC595, 35// in two separate sets. Note that QA is not used in this implementation. 36// 37// Further reading and interest: 38// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 39// The sketch uses my ez_switch_lib and ez_SIPO8 libraries for managing the switch and SIPO ICs, respectively. 40// In this instance, a button switch wired simply connected without a 10k ohm resistor (INPUT_PULLUP mode). 41// See the Arduino Project Hub links below for more detailed reading: 42// 43// ez_switch_lib: 44// https://create.arduino.cc/projecthub/ronbentley1/a-switch-library-for-arduino-dfbe40?ref=user&ref_id=1455180&offset=8 45// 46// ez_SIPO8_lib: 47// https://create.arduino.cc/projecthub/ronbentley1/command-control-of-multiple-serial-in-parallel-out-ics-3e0b1a?ref=user&ref_id=1455180&offset=7 48// 49// heart_beat monitoring: 50// 51// https://create.arduino.cc/projecthub/ronbentley1/implementing-a-heart-beat-in-your-code-3f3460?ref=user&ref_id=1455180&offset=5 52// 53 54#include <ez_switch_lib.h> 55#include <ez_SIPO8_lib.h> 56 57// 58// Define switch data required for the sketch... 59// 60#define button_switch_pin 12 // digital pin assigned to the switch 61int switch_id; // stores the switch 'token' for the switch following the add_switch call 62 63// 64// Define serial/parallel I/O (SIPO) data required for the sketch... 65// 66#define data_pin 2 67#define latch_pin 3 68#define clock_pin 4 69#define num_SIPOs 2 // 2 x 8 bit SIPO ICs linked in cascade formation 70#define num_SIPO_timers 0 // no SIPO timers used in this example 71int bank_id; // holds the SIPO bank ID given by the create_bank function 72 73// 74// Define heart beat data... 75// 76#define heart_beat_pin LED_BUILTIN // digital pin for heart beat LED 77#define heart_beat_on true // determines if the implementation uses the heartbeat 78long unsigned heart_beat_freq = 1000; // time(milliseconds) of heart beat frequency 79long unsigned heart_beat_on_off_time; // the time the LED is on and off - 1/2 frequency 80long unsigned last_heart_beat_time; // time in milliseconds of last heart beat status change 81bool heart_beat_status = HIGH; // current status of heart beat, start high 82 83// 84// Function handles the heart beat cycle. 85// May be called from anywhere, but at least every main loop cycle. 86// 87void heart_beat() { 88 if (heart_beat_on) { 89 if (millis() - last_heart_beat_time >= heart_beat_on_off_time) { 90 // time to swap status of the heart beat LED and update it 91 last_heart_beat_time = millis(); 92 heart_beat_status = !heart_beat_status; // invert current heart beat status value 93 digitalWrite(heart_beat_pin, heart_beat_status); // update LED with new status 94 } 95 } 96} 97 98// 99// This array is used to define the SIPO outputs that connect to the LEDs 100// that make up each of the die face patterns/layouts. 101// Each element of the array (faces) corresonds to the binary pattern of the 102// pip value thrown (0-5) for each face/side of a die. 103// The SIPO outputs are referenced as QA - QH, with the LSB (0) being QA, etc. 104// See SIPO documentations. 105// Note that QA is not used in this implementation. 106// 107#define num_dice num_SIPOs // because we are using one SIPO IC for each die 108#define faces_per_die 6 109#define die_1 0 110#define die_2 1 111uint8_t pip_patterns[faces_per_die] = { 112 // Die pip patterns, faces 1-6 (array index 0-5) across 7 SIPO connected leds 113 0b00010000, // 1 pip, just the central LED connected to SIPO output QE 114 0b01000100, // 2 pips, each central two outer LEDs connected to SIPO outputs QC and QG 115 0b00111000, // 3 pips, diagonal LEDs connected to SIPO outputs QD, QE and QF 116 0b10101010, // 4 pips, each corner LED connected to SIPO outputs QB, QD, Q5 and QH 117 0b10111010, // 5 pips, all LEDs connected to SIPO outputs QB, QD, QE, Q5 and QH 118 0b11101110 // 6 pips, each outer column of 3 LEDs connected to SIPO outputs QB, QC, QD, QF, QG and QH 119}; 120 121// Create the switch control instance... 122Switches my_switches(1); // define a switch control structure for a single switch 123 124// Create the SIPO control instance for the number of dice defined... 125SIPO8 my_SIPOs(num_dice, num_SIPO_timers); // define a SIPO control structure for the number of dice (SIPO ICs) required 126 127// 128// Clear down the pips/LEDs 129// 130void clear_pips() { 131 my_SIPOs.set_bank(bank_id, LOW); // set all bits in this bank to 0 (off) 132 my_SIPOs.xfer_bank(bank_id, MSBFIRST); // write out the SIPO bank data to the SIPO ICs 133} 134 135// 136// Announces (signals) that a dice throw is about to start 137// 138void announce_throw() { 139#define num_cycles 2 140#define num_patterns 5 141 uint8_t announce_pattern[num_patterns] = {// simple strobe sequence - down and up 142 0b00100010, // outer two top LEDs of a die 143 0b01000100, // outer two middle LEDs of a die 144 0b10001000, // outer two bottom LEDs of a die 145 0b01000100, // outer two middle LEDs of a die 146 0b00100010 // outer two top LEDs of a die 147 }; 148 // Start by clearing down the existing die pips/score 149 clear_pips(); 150 for (uint8_t cycle = 1; cycle <= num_cycles; cycle++) {// do 'num_cycles' cycles 151 // send each face/side strobe pattern to each die with a short delay between each 152 for (uint8_t pattern = 0; pattern < num_patterns; pattern++) { 153 my_SIPOs.set_bank_SIPO(bank_id, die_1, announce_pattern[pattern]); // set first die to this 'pattern' 154 my_SIPOs.set_bank_SIPO(bank_id, die_2, announce_pattern[pattern]); // set second die to this 'pattern' 155 my_SIPOs.xfer_bank(bank_id, MSBFIRST); // transfer (xfer) out the dice bits to the physical cascaded SIPOs 156 delay(50); 157 heart_beat(); // keep pumping the heart beat 158 clear_pips(); 159 } 160 } 161} 162 163// 164// Throw the die 165// 166void throw_dice() { 167 announce_throw(); // 'announce' the throw of the die 168 randomSeed(analogRead(A0) * 31 + 169 analogRead(A1) * 37 + 170 random(1023, 10000)); // keep changing the seed 171 uint8_t die_face; 172 die_face = random(1, 104640) % faces_per_die; // range 0-(faces_per_die-1) 173 my_SIPOs.set_bank_SIPO(bank_id, 174 die_1, // first die in the bank 175 pip_patterns[die_face]); // load first die pip patern for this face 176 die_face = random(1, 104640) % faces_per_die; // range 0-(faces_per_die-1) 177 my_SIPOs.set_bank_SIPO(bank_id, 178 die_2, // second die in the bank 179 pip_patterns[die_face]); // load second die pip pattern for this face 180 my_SIPOs.xfer_bank(bank_id, MSBFIRST); // move dice data to the physical cascaded SIPOs 181} 182 183void setup() { 184 // **** Create a switch - a button switch wired without 185 // **** a 10k ohm resistor (circuit_C2 - INPUT_PULLUP) 186 switch_id = my_switches.add_switch(button_switch, button_switch_pin, circuit_C2); 187 if (switch_id < 0) { 188 // failure to add a switch! 189 exit(0); 190 } 191 // **** Create the SIPO bank of size 192 // **** = number of individual SIPO ICs (num_SIPOs) in the cascaded bank 193 bank_id = my_SIPOs.create_bank(data_pin, clock_pin, latch_pin, num_SIPOs); 194 if (bank_id == create_bank_failure ) { 195 // failure to create a SIPO bank 196 exit(0); 197 } 198 if (heart_beat_on) { 199 // **** Setup heart beat, if selected 200 pinMode(heart_beat_pin, OUTPUT); 201 last_heart_beat_time = millis(); // start of heartbeat timer 202 heart_beat_on_off_time = heart_beat_freq / 2; // LED is on and off at 1/2 frequency time 203 // end of heart beat setup 204 } 205 announce_throw(); // illuminate the LEDs on startup 206} 207 208void loop() { 209 do { 210 heart_beat(); // keep pumping the heart beat timer every cycle 211 if (my_switches.read_switch(switch_id) == switched) { 212 // Switch has been pressed and released, so throw the die... 213 throw_dice(); 214 } 215 } while (true); 216} 217
Downloadable files
Physical 74HC595 ICs, layouts
Physical 74HC595 ICs, layouts
Physical breadboard layouts
Physical breadboard layouts
Breadboard layout with 74HC595 IC and microcontroller connections
Overview of dice breadboard layout and connections to the 74HC595 ICs and to the microcontroller
Breadboard layout with 74HC595 IC and microcontroller connections
Physical design, all parts
Physical design, all parts
74HC595 IC intra/inter connections
Overview of the 74HC595 IC mini breadboard connections in cascade/daisy chain form
74HC595 IC intra/inter connections
Breadboard layout with 74HC595 IC and microcontroller connections
Overview of dice breadboard layout and connections to the 74HC595 ICs and to the microcontroller
Breadboard layout with 74HC595 IC and microcontroller connections
Physical design, all parts
Physical design, all parts
74HC595 IC intra/inter connections
Overview of the 74HC595 IC mini breadboard connections in cascade/daisy chain form
74HC595 IC intra/inter connections
Physical breadboard layouts
Physical breadboard layouts
Physical 74HC595 ICs, layouts
Physical 74HC595 ICs, layouts
Physical microcontroller layouts
Physical microcontroller layouts
Comments
Only logged in users can leave comments
ronbentley1
0 Followers
•0 Projects
Table of contents
Intro
0
0