Digital dice with extras
In this project I present the prototyping of a multifunctional digital dice.
Devices & Components
1
Arduino Nano
2
Push button (12x12)
2
Resistor (10K Ω, 0.5W)
1
9V Alkaline battery
1
TM1637 4 digit 7 segment display module
1
9V battery cover with wire
20
Jumper wires (several types of)
1
Electromagnetic buzzer
1
2 position slide switch
1
Breadboard (for testing)
Hardware & Tools
1
Soldering iron (generic)
1
Solder Soldering Wire
1
3D Printer, ABS Filament
Software & Tools
Arduino IDE
Project description
Code
Arduino Code
c
First commit
1/******** INCLUDES ********/ 2#include <TM1637Display.h> 3#include "pitches.h" 4 5 6/******** SET PINS ********/ 7const byte buzzerPin = 10; // BUZZER 8const byte menuButtonPin = 11; // CHANGE MENU BUTTON 9const byte buttonPin = 12; // ROLL | GENERATE | CHANGE BUTTON 10 11/******** TM1637 DISPLAY OBJECT ********/ 12TM1637Display display(8, 9); 13 14/******** SET TM1637 DISPLAY SEGMENTS FOR OPTIONS ********/ 15const byte OFF[] = { 16 0, 0, 0, 0 17}; 18 19const byte MENU[] = { 20 SEG_G, 21 SEG_G, 22 SEG_G, 23 0 24}; 25 26const byte AUTO_EXIT_ON[] = { 27 SEG_A| SEG_F| SEG_G| SEG_E| SEG_D, 28 0, 29 SEG_B| SEG_C, 30 0 31}; 32 33const byte AUTO_EXIT_OFF[] = { 34 SEG_A| SEG_F| SEG_G| SEG_E| SEG_D, 35 0, 36 SEG_A| SEG_F| SEG_B| SEG_E| SEG_C| SEG_D, 37 0 38}; 39 40const byte SOUND_ON[] = { 41 SEG_A| SEG_F| SEG_G| SEG_C| SEG_D, 42 SEG_A| SEG_F| SEG_B| SEG_E| SEG_C| SEG_D, 43 SEG_F| SEG_B| SEG_E| SEG_C| SEG_D, 44 SEG_B| SEG_C 45}; 46 47const byte SOUND_OFF[] = { 48 SEG_A| SEG_F| SEG_G| SEG_C| SEG_D, 49 SEG_A| SEG_F| SEG_B| SEG_E| SEG_C| SEG_D, 50 SEG_F| SEG_B| SEG_E| SEG_C| SEG_D, 51 SEG_G 52}; 53 54/******** FOR BUZZER MELODY ********/ 55int winnerMelody[] = { 56 NOTE_C4, NOTE_E4, NOTE_G4, NOTE_C5 57}; 58 59int winnerMelodyDurations[] = { 60 4, 4, 4, 4 61}; 62 63int loserMelody[] = { 64 NOTE_A3, NOTE_AS3, NOTE_A3 65}; 66 67int loserMelodyDurations[] = { 68 8, 8, 4 69}; 70 71/******** VARIABLES ********/ 72bool buttonState = LOW; 73bool menuButtonState = LOW; 74bool lastButtonState = LOW; 75bool lastMenuButtonState = LOW; 76bool shouldUpdateDisplay = true; 77bool autoExit = 0; 78bool buzzerState = 0; 79byte menuItem = 1; 80short randNumber = 0; 81short DELAY = 3000; 82char lastButton = '-'; 83 84void setup() { 85 pinMode(menuButtonPin, INPUT); 86 pinMode(buttonPin, INPUT); 87 pinMode(buzzerPin, OUTPUT); 88 display.setSegments(OFF); 89 display.setBrightness(6); 90 display.setSegments(MENU); 91 display.showNumberDec(menuItem, false, 1, 3); 92} 93 94/******** LOOP ********/ 95void loop() { 96 // READ BUTTONS STATE 97 buttonState = digitalRead(buttonPin); 98 menuButtonState = digitalRead(menuButtonPin); 99 100 // CHANGE MENU 101 if (menuButtonState == HIGH && lastMenuButtonState == LOW){ 102 lastMenuButtonState = HIGH; 103 shouldUpdateDisplay = true; // NEED TO UPDATE THE DISPLAY 104 menuItem <= 6 ? menuItem += 1 : menuItem = 1; // INCREASE THE VALUE OF THE MENU ITEM 105 shouldUpdateDisplay == true ? setDisplay('M', 0, menuItem) : none(); 106 } 107 108 // AFTER WE PUSHED THE MENU BUTTON 109 if (menuButtonState == LOW && lastMenuButtonState == HIGH){ 110 lastMenuButtonState = LOW; // WE NEED TO CHANGE THE LAST STATE OF THE MENU BUTTON 111 } 112 113 // ENTER CURRENT MENU: ROLLING THE DICE | GENERATE RANDOM NUMBER | CHANGE SETTINGS 114 if (buttonState == HIGH && lastButtonState == LOW){ 115 lastButtonState = HIGH; 116 shouldUpdateDisplay = true; 117 (shouldUpdateDisplay == true) ? menuControl(menuItem) : none(); 118 } 119 120 // AFTER WE PUSHED THE FUNCTION BUTTON (ROLLING | GENERATE | SETTINGS) 121 if (buttonState == LOW && lastButtonState == HIGH){ 122 lastButtonState = LOW; 123 } 124 125 delay(100); 126} 127 128/******** DISPLAY CONTROL ********/ 129void setDisplay(char type, int num, int menuItem){ 130 display.setSegments(OFF); 131 // SHOW THE MENU 132 if (type == 'M'){ 133 display.setSegments(MENU); 134 display.showNumberDec(menuItem, false, 1, 3); 135 } 136 137 // SHOW THE ROLLED | GENERATED NUMBER 138 if (type == 'R'){ 139 display.showNumberDec(num, false, menuItem, 0); 140 } 141 142 // SHOW SOUND SETTING 143 if (type == 'S'){ 144 (buzzerState == 1) ? display.setSegments(SOUND_ON) : display.setSegments(SOUND_OFF); 145 } 146 147 // SHOW AUTO EXIT SETTING 148 if (type == 'E'){ 149 (autoExit == 0) ? display.setSegments(AUTO_EXIT_OFF) : display.setSegments(AUTO_EXIT_ON); 150 } 151 152 // SHOW AUTO EXIT TIME 153 if (type == 'D'){ 154 display.showNumberDec(num); 155 } 156 157 shouldUpdateDisplay = false; 158} 159 160/******** MENU CONTROL ********/ 161void menuControl(int menuItem) { 162 switch (menuItem) { 163 164 // ROLLING A DICE 165 case 1: 166 randNumber = random(1,7); 167 setDisplay('R', randNumber, menuItem); 168 // PLAYING THE WINNER MELODY IF THE ROLLED NUMBER IS 6 AND THE SOUND OPTION IS ON 169 (randNumber == 6 && buzzerState == 1) ? playMelody(winnerMelody, winnerMelodyDurations, sizeof(winnerMelody) / sizeof(winnerMelody[0])) : none(); 170 // PLAYING THE LOSING MELODY IF THE ROLLED NUMBER IS 1 AND THE SOUND OPTION IS ON 171 (randNumber == 1 && buzzerState == 1) ? playMelody(loserMelody, loserMelodyDurations, sizeof(loserMelody) / sizeof(loserMelody[0])) : none(); 172 // IF AUTO EXIT IS ENABLED, DELAY IS ACTIVATED 173 (autoExit == 0) ? none() : delay(DELAY); 174 // IF AUTO EXIT IS ENABLED, YOU WILL BE AUTOMATICALLY TAKEN BACK TO THE MENU 175 (autoExit == 0) ? none() : setDisplay('M', 0, menuItem); 176 return; 177 178 // ROLLING TWO DICE 179 case 2: 180 randNumber = random(2,13); 181 setDisplay('R', randNumber, menuItem); 182 // PLAYING THE WINNER MELODY IF THE ROLLED NUMBER IS 12 AND THE SOUND OPTION IS ON 183 (randNumber == 12 && buzzerState == 1) ? playMelody(winnerMelody, winnerMelodyDurations, sizeof(winnerMelody) / sizeof(winnerMelody[0])) : none(); 184 // PLAYING THE LOSING MELODY IF THE ROLLED NUMBER IS 2 AND THE SOUND OPTION IS ON 185 (randNumber == 2 && buzzerState == 1) ? playMelody(loserMelody, loserMelodyDurations, sizeof(loserMelody) / sizeof(loserMelody[0])) : none(); 186 // IF AUTO EXIT IS ENABLED, DELAY IS ACTIVATED 187 (autoExit == 0) ? none() : delay(DELAY); 188 // IF AUTO EXIT IS ENABLED, YOU WILL BE AUTOMATICALLY TAKEN BACK TO THE MENU 189 (autoExit == 0) ? none() : setDisplay('M', 0, menuItem); 190 return; 191 192 // GENERATE RANDOM NUMBER BETWEEN 100 AND 1000 193 case 3: 194 setDisplay('R', random(100,1000), menuItem); 195 // IF AUTO EXIT IS ENABLED, DELAY IS ACTIVATED 196 (autoExit == 0) ? none() : delay(DELAY); 197 // IF AUTO EXIT IS ENABLED, YOU WILL BE AUTOMATICALLY TAKEN BACK TO THE MENU 198 (autoExit == 0) ? none() : setDisplay('M', 0, menuItem); 199 return; 200 201 // GENERATE RANDOM NUMBER BETWEEN 1 AND 10000 202 case 4: 203 setDisplay('R', random(1,10000), menuItem); 204 // IF AUTO EXIT IS ENABLED, DELAY IS ACTIVATED 205 (autoExit == 0) ? none() : delay(DELAY); 206 // IF AUTO EXIT IS ENABLED, YOU WILL BE AUTOMATICALLY TAKEN BACK TO THE MENU 207 (autoExit == 0) ? none() : setDisplay('M', 0, menuItem); 208 return; 209 210 // SET THE SOUND ON/OFF 211 case 5: 212 (buzzerState == 0) ? buzzerState = 1 : buzzerState = 0; 213 setDisplay('S', 0, 0); 214 delay(3000); 215 setDisplay('M', 0, 1); 216 setDeafultMenuItem(); 217 return; 218 219 // SET THE AUTO EXIT ON/OFF 220 case 6: 221 (autoExit == 0) ? autoExit = 1 : autoExit = 0; 222 setDisplay('E', 0, 0); 223 delay(3000); 224 setDisplay('M', 0, 1); 225 setDeafultMenuItem(); 226 return; 227 228 // SET THE AUTO EXIT TIME BETWEEN 3 SEC AND 9,5 SEC 229 case 7: 230 unsigned long int lastDelayChange = millis(); 231 // SETTINGS WILL BE SAVED WITHOUT PRESSING THE BUTTON FOR 3 SECONDS 232 while(3000 > (millis() - lastDelayChange)){ 233 buttonState = digitalRead(buttonPin); 234 if(buttonState == HIGH ){ 235 lastDelayChange = millis(); 236 (DELAY == 9500) ? DELAY = 3000 : DELAY += 500; 237 setDisplay('D', DELAY, 0); 238 delay(200); 239 } 240 } 241 lastDelayChange = 0; 242 } 243 244 setDeafultMenuItem(); 245 setDisplay('M', 0, 1); // IT IS 1 and not 'menuItem', BECAUSE THE DEFAULT MENU VALUE IS NOT YET SET DUE TO THE FAST RUNNING 246 return; 247} 248 249/******** PLAYING MELODY ********/ 250void playMelody(int melody[], int noteDurations[], int length) { 251 for (int i = 0; i < length; i++) { 252 int noteDuration = 1000 / noteDurations[i]; 253 int pauseBetweenNotes = noteDuration * 1.30; 254 tone(buzzerPin, melody[i], noteDuration); 255 delay(pauseBetweenNotes); 256 noTone(buzzerPin); 257 } 258} 259 260/******** SET THE MENU ITEM FOR DEFAULT (1) ********/ 261void setDeafultMenuItem(){ 262 menuItem = 1; 263} 264 265/******** NOTHING TO DO: FOR TERNARY IF STATEMENT ********/ 266void none(){ 267 return; 268}
Pitches header
c
First commit
1/************************************************* 2 3 * Public Constants 4 5 *************************************************/ 6 7#define NOTE_B0 31 8#define NOTE_C1 33 9#define NOTE_CS1 35 10#define NOTE_D1 37 11#define NOTE_DS1 39 12#define NOTE_E1 41 13#define NOTE_F1 44 14#define NOTE_FS1 46 15#define NOTE_G1 49 16#define NOTE_GS1 52 17#define NOTE_A1 55 18#define NOTE_AS1 58 19#define NOTE_B1 62 20#define NOTE_C2 65 21#define NOTE_CS2 69 22#define NOTE_D2 73 23#define NOTE_DS2 78 24#define NOTE_E2 82 25#define NOTE_F2 87 26#define NOTE_FS2 93 27#define NOTE_G2 98 28#define NOTE_GS2 104 29#define NOTE_A2 110 30#define NOTE_AS2 117 31#define NOTE_B2 123 32#define NOTE_C3 131 33#define NOTE_CS3 139 34#define NOTE_D3 147 35#define NOTE_DS3 156 36#define NOTE_E3 165 37#define NOTE_F3 175 38#define NOTE_FS3 185 39#define NOTE_G3 196 40#define NOTE_GS3 208 41#define NOTE_A3 220 42#define NOTE_AS3 233 43#define NOTE_B3 247 44#define NOTE_C4 262 45#define NOTE_CS4 277 46#define NOTE_D4 294 47#define NOTE_DS4 311 48#define NOTE_E4 330 49#define NOTE_F4 349 50#define NOTE_FS4 370 51#define NOTE_G4 392 52#define NOTE_GS4 415 53#define NOTE_A4 440 54#define NOTE_AS4 466 55#define NOTE_B4 494 56#define NOTE_C5 523 57#define NOTE_CS5 554 58#define NOTE_D5 587 59#define NOTE_DS5 622 60#define NOTE_E5 659 61#define NOTE_F5 698 62#define NOTE_FS5 740 63#define NOTE_G5 784 64#define NOTE_GS5 831 65#define NOTE_A5 880 66#define NOTE_AS5 932 67#define NOTE_B5 988 68#define NOTE_C6 1047 69#define NOTE_CS6 1109 70#define NOTE_D6 1175 71#define NOTE_DS6 1245 72#define NOTE_E6 1319 73#define NOTE_F6 1397 74#define NOTE_FS6 1480 75#define NOTE_G6 1568 76#define NOTE_GS6 1661 77#define NOTE_A6 1760 78#define NOTE_AS6 1865 79#define NOTE_B6 1976 80#define NOTE_C7 2093 81#define NOTE_CS7 2217 82#define NOTE_D7 2349 83#define NOTE_DS7 2489 84#define NOTE_E7 2637 85#define NOTE_F7 2794 86#define NOTE_FS7 2960 87#define NOTE_G7 3136 88#define NOTE_GS7 3322 89#define NOTE_A7 3520 90#define NOTE_AS7 3729 91#define NOTE_B7 3951 92#define NOTE_C8 4186 93#define NOTE_CS8 4435 94#define NOTE_D8 4699 95#define NOTE_DS8 4978
Downloadable files
Digital dice box 3D print
Shapr3D
file.None
Wiring
Fritzing
file.None

Documentation
Arduino Digital Dice github repository
First commit
https://github.com/Kela910512/Arduino-Digital-Dice
Comments
Only logged in users can leave comments