Electronic dice application for the mBuino platform. Notes: The mBuino starts in Demo mode. In Demo mode the LEDs are lighted, showing sweeps and demo rolls. Connect a button or tilt-switch between P0.4 and GND. No soldering required! When the switch is triggered mBuino goes into Roll mode. In Roll mode mBuino starts with rapid flickering LEDs. Each subsequent switch trigger will perform a roll of the dice, of which the result is shown for ten seconds unless the switch is triggered for another roll. To preserve power, Power down mode is entered after inactivity in Demo mode or Roll mode. Press any button to revive.

Dependencies:   mbed

Fork of mBuino_Dice by Valentin Ivanov

mBuino_Dice

The hardware: No soldering required

As you can see in the picture gallery below, this is a very simple mBuino project, requiring only one extra component: a switch such as a push button or a tilt switch.

Push button

The push-button I used fits neatly between P0.4 and GND. By just bending the legs flat to the PCB, the button attached sturdy enough to make a usable connection.

Tilt switch

The tilt switch version is much more fun. No pushing, just a shake to roll the dice! In the tilt switch version two short wires were used to connect the switch. The wires were twisted around the legs of the tilt switch without any soldering! By adjusting the horizontal level of the switch you can make the dice react more sensitively to small movement.

For a production version, I would of course make it all a bit more durable by soldering the connections and using hot glue to keep everything in place. But going that route, I would also want to make a nicely fitting box, perhaps use other LEDs in a traditional dice-eye position and add an on-off switch...

Committer:
maxint
Date:
Mon Sep 15 16:35:48 2014 +0000
Revision:
5:e2f89a6f4d6c
Parent:
4:0c3a1b829d8c
Child:
6:e52dbebd7465
Incorporate further energy savings in power down mode. Kudos@AndyA

Who changed what in which revision?

UserRevisionLine numberNew contents of line
maxint 1:38fcbf88615a 1 /*
maxint 1:38fcbf88615a 2 ** mBuino_Dice
maxint 1:38fcbf88615a 3 **
maxint 1:38fcbf88615a 4 ** This electronic dice application allows the user to throw an electronic dice by the press of a button
maxint 1:38fcbf88615a 5 ** Setup requirements: connect any type of switch between P0.4 and GND.
maxint 1:38fcbf88615a 6 ** On mBuino P0.4 is close to GND and the two pitch distance is exactly the same as a mini-switch!
maxint 1:38fcbf88615a 7 **
maxint 4:0c3a1b829d8c 8 ** 0.1.140910 Power down after one iteration of demo or ten seconds of wating, credits: Andy A
maxint 3:52997a5f2fbc 9 ** 0.1.140908 Added deep sleep mode after one iteration of demo or ten seconds of wating, credits: Andy A and Erik Olieman
maxint 3:52997a5f2fbc 10 ** Added explanatory comments and incorporated suggestion by Erik Olieman
maxint 3:52997a5f2fbc 11 ** Improved randomness as per suggestion of Andy A
maxint 3:52997a5f2fbc 12 ** 0.1.140901 First version mad for mBuino on mbed.org by maxint on 1-sep-2014
maxint 1:38fcbf88615a 13 **
maxint 3:52997a5f2fbc 14 ** Feel free to use this code anyway you want, but please acknowledge my work by mentioning maxint as creator.
maxint 1:38fcbf88615a 15 **
maxint 1:38fcbf88615a 16 */
maxint 1:38fcbf88615a 17
maxint 1:38fcbf88615a 18
Architect 0:5d9ccbe9d49d 19 #include "mbed.h"
maxint 1:38fcbf88615a 20
maxint 1:38fcbf88615a 21 DigitalOut LED[] = {(P0_7), (P0_8), (P0_2), (P0_20), (P1_19), (P0_17), (P0_23)};// declare 7 LEDs
maxint 1:38fcbf88615a 22
maxint 3:52997a5f2fbc 23 InterruptIn ActionButton(P0_4); // declare the input for the button (or for other single switch, such as movement switch). On mBuino P0.4 is close to GND
maxint 3:52997a5f2fbc 24 AnalogIn RandomIn(P0_14); // use the random noise on this analog input to seed the random generator
maxint 1:38fcbf88615a 25
maxint 3:52997a5f2fbc 26 // Define the LED pattern of each dice number
maxint 3:52997a5f2fbc 27 // Can be made more compact by using binary values instead of a nested array.
maxint 1:38fcbf88615a 28 bool DicePattern[6][7]=
maxint 1:38fcbf88615a 29 {
maxint 1:38fcbf88615a 30 {0, 0, 0, 1, 0, 0, 0 },
maxint 1:38fcbf88615a 31 {0, 1, 0, 0, 0, 1, 0 },
maxint 1:38fcbf88615a 32 {0, 1, 0, 1, 0, 1, 0 },
maxint 1:38fcbf88615a 33 {1, 0, 1, 0, 1, 0, 1 },
maxint 1:38fcbf88615a 34 {1, 0, 1, 1, 1, 0, 1 },
maxint 1:38fcbf88615a 35 {1, 1, 1, 0, 1, 1, 1 }
maxint 1:38fcbf88615a 36 };
Architect 0:5d9ccbe9d49d 37
maxint 3:52997a5f2fbc 38 /*
maxint 3:52997a5f2fbc 39 // TODO: Suggestion by Erik Olieman: alternatively BusOut can be used to combine all used pins in one bus that can be set using a single write
maxint 3:52997a5f2fbc 40 BusOut LEDS(P0_7, P0_8, P0_2, P0_20, P1_19, P0_17, P0_23);
maxint 3:52997a5f2fbc 41 char byteDice[6]=
maxint 3:52997a5f2fbc 42 {
maxint 3:52997a5f2fbc 43 0x08, // 0B00001000
maxint 3:52997a5f2fbc 44 0x22, // 0B00100010
maxint 3:52997a5f2fbc 45 0x2A, // 0B00101010
maxint 3:52997a5f2fbc 46 0x55, // 0B01010101
maxint 3:52997a5f2fbc 47 0x5D, // 0B01011101
maxint 3:52997a5f2fbc 48 0x77 // 0B01110111
maxint 3:52997a5f2fbc 49 };
maxint 3:52997a5f2fbc 50 */
Architect 0:5d9ccbe9d49d 51
maxint 3:52997a5f2fbc 52 Timer tWait; // time used for tickcounts
maxint 3:52997a5f2fbc 53
maxint 5:e2f89a6f4d6c 54 DigitalIn progMode(P0_3); // need to disable pull-down for minimal power deep sleep
maxint 4:0c3a1b829d8c 55 void myPowerDown(uint8_t uMode=0x02)
maxint 4:0c3a1b829d8c 56 { // Go into power-down mode (0x2) to safe most power. Use onboard or off-board interrupt triggered button to revive
maxint 4:0c3a1b829d8c 57 // See https://mbed.org/forum/electronics/topic/5138/
maxint 4:0c3a1b829d8c 58 // Alternative: Go into deep sleep mode (0x1) to safe less power. Is quicker than power-down. Also revived using onboard button or interrupt.
maxint 4:0c3a1b829d8c 59 // See http://mbed.org/forum/repo-52552-mBuino_low_power_led_flasher-community/topic/5130/
maxint 4:0c3a1b829d8c 60 // Power usage (CR3032 battery life):
maxint 4:0c3a1b829d8c 61 // Running 13mA (1.5 day)
maxint 4:0c3a1b829d8c 62 // Sleep 7mA (3 days)
maxint 4:0c3a1b829d8c 63 // Deep-sleep 480uA (43 days)
maxint 4:0c3a1b829d8c 64 // Power-down 120uA (170 days)
maxint 5:e2f89a6f4d6c 65 // Power-down with fix 3uA (years)
maxint 5:e2f89a6f4d6c 66 progMode.mode(PullNone); // fix the 120uA. see http://mbed.org/forum/electronics/topic/5138/?page=1#comment-25338
maxint 5:e2f89a6f4d6c 67
maxint 4:0c3a1b829d8c 68 LPC_PMU->PCON = uMode; // 0x2 = power down, 0x1 = deep sleep
maxint 3:52997a5f2fbc 69 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
maxint 3:52997a5f2fbc 70 LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800;
maxint 3:52997a5f2fbc 71 __WFI();
maxint 3:52997a5f2fbc 72 }
maxint 1:38fcbf88615a 73
maxint 1:38fcbf88615a 74 void SwitchAllLeds(bool fOn)
maxint 1:38fcbf88615a 75 { // switch all leds on or off
maxint 3:52997a5f2fbc 76 // Suggestion by Erik Olieman: alternatively BusOut can be used to combine all used pins in one bus that can be set using a single write
maxint 1:38fcbf88615a 77 for(int x = 0; x < 7; x++)
maxint 1:38fcbf88615a 78 {
maxint 1:38fcbf88615a 79 LED[x] = fOn?1:0; // turn on or off
maxint 1:38fcbf88615a 80 }
maxint 1:38fcbf88615a 81 }
maxint 1:38fcbf88615a 82
maxint 1:38fcbf88615a 83 void BlinkAllLeds(float flDelay=0.2)
maxint 1:38fcbf88615a 84 { // blink all leds
maxint 1:38fcbf88615a 85 SwitchAllLeds(true);
maxint 1:38fcbf88615a 86 wait(flDelay);
maxint 1:38fcbf88615a 87 SwitchAllLeds(false);
maxint 1:38fcbf88615a 88 wait(flDelay);
maxint 1:38fcbf88615a 89 }
maxint 1:38fcbf88615a 90
maxint 1:38fcbf88615a 91 void BlinkOneLed(int nLed=0, float flDelayOn=0.2, float flDelayOff=0.2)
maxint 3:52997a5f2fbc 92 { // blink just one led once, for the specified time
maxint 1:38fcbf88615a 93 LED[nLed] = 1; // turn on
maxint 1:38fcbf88615a 94 wait(flDelayOn); // delay
maxint 1:38fcbf88615a 95
maxint 1:38fcbf88615a 96 LED[nLed] = 0; // turn off
maxint 1:38fcbf88615a 97 wait(flDelayOff); // delay
maxint 1:38fcbf88615a 98 }
maxint 1:38fcbf88615a 99
maxint 1:38fcbf88615a 100 void SweepSingleLed(bool fLeftToRight=true, float flDelay=0.2)
maxint 1:38fcbf88615a 101 { // sweep a single led from left to rigth or vise-versa
maxint 1:38fcbf88615a 102 for(int n=0; n<7; n++)
maxint 1:38fcbf88615a 103 BlinkOneLed(fLeftToRight?n:6-n, flDelay, 0);
maxint 1:38fcbf88615a 104 }
maxint 1:38fcbf88615a 105
maxint 1:38fcbf88615a 106 void SweepAllLeds(bool fLeftToRight=true, float flDelay=0.1)
maxint 1:38fcbf88615a 107 { // light all leds up from left to rigth or vise-versa and then switch them of from reverse direction
maxint 1:38fcbf88615a 108 // leds on, left to right
maxint 1:38fcbf88615a 109 for(int n=0; n<7; n++)
maxint 1:38fcbf88615a 110 {
maxint 1:38fcbf88615a 111 LED[fLeftToRight?n:6-n] = 1; // turn on
maxint 1:38fcbf88615a 112 wait(flDelay); // delay
maxint 1:38fcbf88615a 113 }
maxint 1:38fcbf88615a 114 // leds off, right to left
maxint 1:38fcbf88615a 115 for(int n=0; n<7; n++)
maxint 1:38fcbf88615a 116 {
maxint 1:38fcbf88615a 117 LED[!fLeftToRight?n:6-n] = 0; // turn off
maxint 1:38fcbf88615a 118 wait(flDelay); // delay
maxint 1:38fcbf88615a 119 }
maxint 1:38fcbf88615a 120 }
maxint 1:38fcbf88615a 121
maxint 1:38fcbf88615a 122 void SwitchDiceLed(int nNumber, bool fOn=true)
maxint 1:38fcbf88615a 123 { // switch the leds of a particular dice-number on or off
maxint 1:38fcbf88615a 124 if(nNumber<1) nNumber=1;
maxint 1:38fcbf88615a 125 if(nNumber>6) nNumber=6;
maxint 1:38fcbf88615a 126
maxint 1:38fcbf88615a 127 for(int n=0; n<7; n++)
maxint 1:38fcbf88615a 128 if(DicePattern[nNumber-1][n])
maxint 1:38fcbf88615a 129 LED[n]=fOn;
maxint 1:38fcbf88615a 130 }
maxint 1:38fcbf88615a 131
maxint 1:38fcbf88615a 132 void BlinkDiceLed(int nNumber, float flDelayOn=0.6, float flDelayOff=0.1)
maxint 1:38fcbf88615a 133 { // blink a particular dice value
maxint 1:38fcbf88615a 134 SwitchDiceLed(nNumber, true);
maxint 1:38fcbf88615a 135 wait(flDelayOn);
maxint 1:38fcbf88615a 136 SwitchDiceLed(nNumber, false);
maxint 1:38fcbf88615a 137 wait(flDelayOff);
maxint 1:38fcbf88615a 138 }
maxint 1:38fcbf88615a 139
maxint 3:52997a5f2fbc 140 int RollDice(int nRolls=10, int nBlinks=2, float flDelayRoll=0.15)
maxint 1:38fcbf88615a 141 { // roll the dice and show the outcome value
maxint 1:38fcbf88615a 142 int nDiceValue;
maxint 3:52997a5f2fbc 143
maxint 3:52997a5f2fbc 144 // improve randomness: seed the random generator with the background noise of an analog input combined with passed time at user triggered moment
maxint 3:52997a5f2fbc 145 srand(RandomIn.read_u16()+tWait.read_us());
maxint 1:38fcbf88615a 146
maxint 1:38fcbf88615a 147 // first roll the dice
maxint 1:38fcbf88615a 148 for(int n=0; n<nRolls; n++)
maxint 1:38fcbf88615a 149 {
maxint 1:38fcbf88615a 150 nDiceValue=rand()%6+1;
maxint 1:38fcbf88615a 151 BlinkDiceLed(nDiceValue, flDelayRoll, 0);
maxint 1:38fcbf88615a 152 }
maxint 1:38fcbf88615a 153
maxint 1:38fcbf88615a 154 // then show the result
maxint 1:38fcbf88615a 155 nDiceValue=rand()%6+1;
maxint 1:38fcbf88615a 156 for(int n=0; n<nBlinks; n++)
maxint 1:38fcbf88615a 157 BlinkDiceLed(nDiceValue, flDelayRoll, 0);
maxint 3:52997a5f2fbc 158 SwitchDiceLed(nDiceValue, true); // return while keeping dice led's on
maxint 1:38fcbf88615a 159
maxint 1:38fcbf88615a 160 return(nDiceValue);
maxint 1:38fcbf88615a 161 }
maxint 1:38fcbf88615a 162
maxint 1:38fcbf88615a 163 bool fButtonPressed=false; // if the button is pressed, mBuino will switch from demo mode to play mode.
maxint 1:38fcbf88615a 164 bool fDemoDone=false;
maxint 1:38fcbf88615a 165
maxint 1:38fcbf88615a 166 void interruptButtonPressed()
maxint 1:38fcbf88615a 167 {
maxint 1:38fcbf88615a 168 fButtonPressed=true;
maxint 1:38fcbf88615a 169 }
maxint 1:38fcbf88615a 170
maxint 1:38fcbf88615a 171 void setup(void)
maxint 1:38fcbf88615a 172 { // perform initialisations
maxint 1:38fcbf88615a 173 srand(RandomIn.read_u16()); // seed the random generator with the background noise of an analog input
maxint 1:38fcbf88615a 174
maxint 2:0d311a6cfb96 175 ActionButton.fall(interruptButtonPressed); // using the fall requires the button to be unpressed before the interrupt is triggered again
maxint 3:52997a5f2fbc 176 tWait.start(); // start the timer
maxint 1:38fcbf88615a 177 }
maxint 1:38fcbf88615a 178
maxint 1:38fcbf88615a 179 void loop(void)
maxint 1:38fcbf88615a 180 { // run forever
maxint 1:38fcbf88615a 181 if(!fDemoDone && !fButtonPressed)
maxint 1:38fcbf88615a 182 { // Run an entertaining demo show until button is pressed
maxint 1:38fcbf88615a 183 // For all parts of the show we check to see if the actionbutton was pressed to stop the show asap
maxint 1:38fcbf88615a 184 if(!fButtonPressed)
maxint 1:38fcbf88615a 185 SweepAllLeds(true);
maxint 1:38fcbf88615a 186 if(!fButtonPressed)
maxint 1:38fcbf88615a 187 SweepAllLeds(false);
maxint 1:38fcbf88615a 188 if(!fButtonPressed)
maxint 1:38fcbf88615a 189 SweepAllLeds(true, 0.05);
maxint 1:38fcbf88615a 190 if(!fButtonPressed)
maxint 1:38fcbf88615a 191 SweepAllLeds(false, 0.05);
maxint 1:38fcbf88615a 192
maxint 1:38fcbf88615a 193 // show the dice numbers from one to six
maxint 1:38fcbf88615a 194 for(int n=1; n<=6; n++)
maxint 1:38fcbf88615a 195 if(!fButtonPressed)
maxint 1:38fcbf88615a 196 BlinkDiceLed(n);
maxint 1:38fcbf88615a 197
maxint 1:38fcbf88615a 198 if(!fButtonPressed)
maxint 1:38fcbf88615a 199 SweepSingleLed(true, 0.2);
maxint 1:38fcbf88615a 200 if(!fButtonPressed)
maxint 1:38fcbf88615a 201 SweepSingleLed(false, 0.1);
maxint 1:38fcbf88615a 202
maxint 1:38fcbf88615a 203 // show three random dice throws
maxint 1:38fcbf88615a 204 for(int n=0; n<3; n++)
maxint 1:38fcbf88615a 205 {
maxint 1:38fcbf88615a 206 if(!fButtonPressed)
maxint 1:38fcbf88615a 207 {
maxint 1:38fcbf88615a 208 RollDice();
maxint 1:38fcbf88615a 209 wait(1);
maxint 1:38fcbf88615a 210 SwitchAllLeds(false);
maxint 1:38fcbf88615a 211 }
maxint 1:38fcbf88615a 212 }
maxint 1:38fcbf88615a 213
maxint 1:38fcbf88615a 214 // blink all leds as the same time at increasing and decreasing speeds
maxint 1:38fcbf88615a 215 for(float flDelay=0.3; flDelay>0; flDelay-=0.05)
maxint 1:38fcbf88615a 216 if(!fButtonPressed)
maxint 1:38fcbf88615a 217 BlinkAllLeds(flDelay);
maxint 1:38fcbf88615a 218 for(float flDelay=0.05; flDelay<0.4; flDelay+=0.05)
maxint 1:38fcbf88615a 219 if(!fButtonPressed)
maxint 1:38fcbf88615a 220 BlinkAllLeds(flDelay);
maxint 1:38fcbf88615a 221
maxint 1:38fcbf88615a 222 if(!fButtonPressed)
maxint 1:38fcbf88615a 223 wait(1);
maxint 3:52997a5f2fbc 224
maxint 3:52997a5f2fbc 225 if(!fButtonPressed)
maxint 4:0c3a1b829d8c 226 myPowerDown(); // enter dpower-down mode after one demo iteration
maxint 1:38fcbf88615a 227 }
maxint 1:38fcbf88615a 228 else
maxint 1:38fcbf88615a 229 { // demo mode is ended, roll the dice upon each button press
maxint 1:38fcbf88615a 230 fDemoDone=true;
maxint 1:38fcbf88615a 231 fButtonPressed=false;
maxint 1:38fcbf88615a 232
maxint 3:52997a5f2fbc 233 unsigned uTickStop=tWait.read_ms()+10000;
maxint 1:38fcbf88615a 234 while(!fButtonPressed)
maxint 1:38fcbf88615a 235 { // flash the LEDS to show we wait for a roll call
maxint 1:38fcbf88615a 236 SweepAllLeds(true, 0.01);
maxint 1:38fcbf88615a 237 SweepAllLeds(false, 0.01);
maxint 3:52997a5f2fbc 238
maxint 3:52997a5f2fbc 239 if(!fButtonPressed && tWait.read_ms()>uTickStop)
maxint 4:0c3a1b829d8c 240 myPowerDown(); // enter power-down mode when waited for more than 10 seconds without button pressed
maxint 1:38fcbf88615a 241 }
maxint 1:38fcbf88615a 242 fButtonPressed=false;
maxint 1:38fcbf88615a 243
maxint 3:52997a5f2fbc 244 // roll the dice and show the outcome while waiting max. 10 seconds
maxint 1:38fcbf88615a 245 int nDiceValue=RollDice();
maxint 1:38fcbf88615a 246 wait(1);
maxint 1:38fcbf88615a 247 fButtonPressed=false;
maxint 3:52997a5f2fbc 248
maxint 3:52997a5f2fbc 249 uTickStop=tWait.read_ms()+10000;
maxint 3:52997a5f2fbc 250 while(!fButtonPressed && tWait.read_ms()<uTickStop)
maxint 3:52997a5f2fbc 251 //wait(0.1);
maxint 3:52997a5f2fbc 252 BlinkDiceLed(nDiceValue, 0.2, 0.01); // to indicate waiting for a new roll, blink the thrown dice value...
maxint 1:38fcbf88615a 253 SwitchAllLeds(false);
maxint 1:38fcbf88615a 254 }
maxint 1:38fcbf88615a 255 }
Architect 0:5d9ccbe9d49d 256
Architect 0:5d9ccbe9d49d 257 int main()
maxint 1:38fcbf88615a 258 { // implement Arduino-style setup() and loop()
maxint 1:38fcbf88615a 259 setup();
maxint 1:38fcbf88615a 260 while(true)
maxint 1:38fcbf88615a 261 loop();
Architect 0:5d9ccbe9d49d 262 }