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.
Fork of mBuino_Dice by
main.cpp
00001 /* 00002 ** mBuino_Dice 00003 ** 00004 ** This electronic dice application allows the user to throw an electronic dice by the press of a button 00005 ** Setup requirements: connect any type of switch between P0.4 and GND. 00006 ** On mBuino P0.4 is close to GND and the two pitch distance is exactly the same as a mini-switch! 00007 ** 00008 ** 0.1.140916 Using the Outrageous Circuits mBuino platform instead of LPC11U24 (available now) 00009 ** Renamed LED ports to newly available mBuino LED constants 00010 ** Earlier power down after dice roll, showing by flashes slowing down 00011 ** 0.1.140915 Energy use in power down mode down to 3 uA, credits: Andy A 00012 ** 0.1.140910 Power down after one iteration of demo or ten seconds of wating, credits: Andy A 00013 ** 0.1.140908 Added deep sleep mode after one iteration of demo or ten seconds of wating, credits: Andy A and Erik Olieman 00014 ** Added explanatory comments and incorporated suggestion by Erik Olieman 00015 ** Improved randomness as per suggestion of Andy A 00016 ** 0.1.140901 First version mad for mBuino on mbed.org by maxint on 1-sep-2014 00017 ** 00018 ** Feel free to use this code anyway you want, but please acknowledge my work by mentioning maxint as creator. 00019 ** 00020 */ 00021 00022 00023 #include "mbed.h" 00024 00025 DigitalOut LED[] = {(LED1), (LED2), (LED3), (LED4), (LED5), (LED6), (LED7)};// declare 7 LEDs 00026 00027 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 00028 AnalogIn RandomIn(P0_14); // use the random noise on this analog input to seed the random generator 00029 00030 // Define the LED pattern of each dice number 00031 // Can be made more compact by using binary values instead of a nested array. 00032 bool DicePattern[6][7]= 00033 { 00034 {0, 0, 0, 1, 0, 0, 0 }, 00035 {0, 1, 0, 0, 0, 1, 0 }, 00036 {0, 1, 0, 1, 0, 1, 0 }, 00037 {1, 0, 1, 0, 1, 0, 1 }, 00038 {1, 0, 1, 1, 1, 0, 1 }, 00039 {1, 1, 1, 0, 1, 1, 1 } 00040 }; 00041 00042 /* 00043 // 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 00044 BusOut LEDS(P0_7, P0_8, P0_2, P0_20, P1_19, P0_17, P0_23); 00045 char byteDice[6]= 00046 { 00047 0x08, // 0B00001000 00048 0x22, // 0B00100010 00049 0x2A, // 0B00101010 00050 0x55, // 0B01010101 00051 0x5D, // 0B01011101 00052 0x77 // 0B01110111 00053 }; 00054 */ 00055 00056 Timer tWait; // time used for tickcounts 00057 00058 DigitalIn progMode(P0_3); // need to disable pull-down for minimal power deep sleep 00059 void myPowerDown(uint8_t uMode=0x02) 00060 { // Go into power-down mode (0x2) to safe most power. Use onboard or off-board interrupt triggered button to revive 00061 // See https://mbed.org/forum/electronics/topic/5138/ 00062 // Alternative: Go into deep sleep mode (0x1) to safe less power. Is quicker than power-down. Also revived using onboard button or interrupt. 00063 // See http://mbed.org/forum/repo-52552-mBuino_low_power_led_flasher-community/topic/5130/ 00064 // Power usage (CR3032 battery life): 00065 // Running 13mA (1.5 day) 00066 // Sleep 7mA (3 days) 00067 // Deep-sleep 480uA (43 days) 00068 // Power-down 120uA (170 days) 00069 // Power-down with fix 3uA (years) 00070 progMode.mode(PullNone); // fix the 120uA. see http://mbed.org/forum/electronics/topic/5138/?page=1#comment-25338 00071 00072 LPC_PMU->PCON = uMode; // 0x2 = power down, 0x1 = deep sleep 00073 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 00074 LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800; 00075 __WFI(); 00076 } 00077 00078 void SwitchAllLeds(bool fOn) 00079 { // switch all leds on or off 00080 // 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 00081 for(int x = 0; x < 7; x++) 00082 { 00083 LED[x] = fOn?1:0; // turn on or off 00084 } 00085 } 00086 00087 void BlinkAllLeds(float flDelay=0.2) 00088 { // blink all leds 00089 SwitchAllLeds(true); 00090 wait(flDelay); 00091 SwitchAllLeds(false); 00092 wait(flDelay); 00093 } 00094 00095 void BlinkOneLed(int nLed=0, float flDelayOn=0.2, float flDelayOff=0.2) 00096 { // blink just one led once, for the specified time 00097 LED[nLed] = 1; // turn on 00098 wait(flDelayOn); // delay 00099 00100 LED[nLed] = 0; // turn off 00101 wait(flDelayOff); // delay 00102 } 00103 00104 void SweepSingleLed(bool fLeftToRight=true, float flDelay=0.2) 00105 { // sweep a single led from left to rigth or vise-versa 00106 for(int n=0; n<7; n++) 00107 BlinkOneLed(fLeftToRight?n:6-n, flDelay, 0); 00108 } 00109 00110 void SweepAllLeds(bool fLeftToRight=true, float flDelay=0.1) 00111 { // light all leds up from left to rigth or vise-versa and then switch them of from reverse direction 00112 // leds on, left to right 00113 for(int n=0; n<7; n++) 00114 { 00115 LED[fLeftToRight?n:6-n] = 1; // turn on 00116 wait(flDelay); // delay 00117 } 00118 // leds off, right to left 00119 for(int n=0; n<7; n++) 00120 { 00121 LED[!fLeftToRight?n:6-n] = 0; // turn off 00122 wait(flDelay); // delay 00123 } 00124 } 00125 00126 void SwitchDiceLed(int nNumber, bool fOn=true) 00127 { // switch the leds of a particular dice-number on or off 00128 if(nNumber<1) nNumber=1; 00129 if(nNumber>6) nNumber=6; 00130 00131 for(int n=0; n<7; n++) 00132 if(DicePattern[nNumber-1][n]) 00133 LED[n]=fOn; 00134 } 00135 00136 void BlinkDiceLed(int nNumber, float flDelayOn=0.6, float flDelayOff=0.1) 00137 { // blink a particular dice value 00138 SwitchDiceLed(nNumber, true); 00139 wait(flDelayOn); 00140 SwitchDiceLed(nNumber, false); 00141 wait(flDelayOff); 00142 } 00143 00144 int RollDice(int nRolls=10, int nBlinks=2, float flDelayRoll=0.15) 00145 { // roll the dice and show the outcome value 00146 int nDiceValue; 00147 00148 // improve randomness: seed the random generator with the background noise of an analog input combined with passed time at user triggered moment 00149 srand(RandomIn.read_u16()+tWait.read_us()); 00150 00151 // first roll the dice 00152 for(int n=0; n<nRolls; n++) 00153 { 00154 nDiceValue=rand()%6+1; 00155 BlinkDiceLed(nDiceValue, flDelayRoll, 0); 00156 } 00157 00158 // then show the result 00159 nDiceValue=rand()%6+1; 00160 for(int n=0; n<nBlinks; n++) 00161 BlinkDiceLed(nDiceValue, flDelayRoll, 0); 00162 SwitchDiceLed(nDiceValue, true); // return while keeping dice led's on 00163 00164 return(nDiceValue); 00165 } 00166 00167 bool fButtonPressed=false; // if the button is pressed, mBuino will switch from demo mode to play mode. 00168 bool fDemoDone=false; 00169 00170 void interruptButtonPressed() 00171 { 00172 fButtonPressed=true; 00173 } 00174 00175 void setup(void) 00176 { // perform initialisations 00177 srand(RandomIn.read_u16()); // seed the random generator with the background noise of an analog input 00178 00179 ActionButton.fall(interruptButtonPressed); // using the fall requires the button to be unpressed before the interrupt is triggered again 00180 tWait.start(); // start the timer 00181 } 00182 00183 void loop(void) 00184 { // run forever 00185 if(!fDemoDone && !fButtonPressed) 00186 { // Run an entertaining demo show until button is pressed 00187 // For all parts of the show we check to see if the actionbutton was pressed to stop the show asap 00188 if(!fButtonPressed) 00189 SweepAllLeds(true); 00190 if(!fButtonPressed) 00191 SweepAllLeds(false); 00192 if(!fButtonPressed) 00193 SweepAllLeds(true, 0.05); 00194 if(!fButtonPressed) 00195 SweepAllLeds(false, 0.05); 00196 00197 // show the dice numbers from one to six 00198 for(int n=1; n<=6; n++) 00199 if(!fButtonPressed) 00200 BlinkDiceLed(n); 00201 00202 if(!fButtonPressed) 00203 SweepSingleLed(true, 0.2); 00204 if(!fButtonPressed) 00205 SweepSingleLed(false, 0.1); 00206 00207 // show three random dice throws 00208 for(int n=0; n<3; n++) 00209 { 00210 if(!fButtonPressed) 00211 { 00212 RollDice(); 00213 wait(1); 00214 SwitchAllLeds(false); 00215 } 00216 } 00217 00218 // blink all leds as the same time at increasing and decreasing speeds 00219 for(float flDelay=0.3; flDelay>0; flDelay-=0.05) 00220 if(!fButtonPressed) 00221 BlinkAllLeds(flDelay); 00222 for(float flDelay=0.05; flDelay<0.4; flDelay+=0.05) 00223 if(!fButtonPressed) 00224 BlinkAllLeds(flDelay); 00225 00226 if(!fButtonPressed) 00227 wait(1); 00228 00229 if(!fButtonPressed) 00230 myPowerDown(); // enter dpower-down mode after one demo iteration 00231 } 00232 else 00233 { // demo mode is ended, roll the dice upon each button press 00234 fDemoDone=true; 00235 fButtonPressed=false; 00236 00237 unsigned uTickStop=tWait.read_ms()+10000; 00238 float ftDelay=0.01; 00239 while(!fButtonPressed) 00240 { // flash the LEDS to show we wait for a roll call 00241 SweepAllLeds(true, ftDelay); 00242 SweepAllLeds(false, ftDelay); 00243 00244 if(!fButtonPressed && tWait.read_ms()>uTickStop) 00245 myPowerDown(); // enter power-down mode when waited for more than 10 seconds without button pressed 00246 else 00247 ftDelay=(10-((float)uTickStop-tWait.read_ms())/1000)/100; // make the fast flashes slow down while closer to power down mode 00248 } 00249 fButtonPressed=false; 00250 00251 // roll the dice and show the outcome while waiting max. 10 seconds 00252 int nDiceValue=RollDice(); 00253 wait(1); 00254 fButtonPressed=false; 00255 00256 uTickStop=tWait.read_ms()+10000; 00257 ftDelay=0.01; 00258 while(!fButtonPressed && tWait.read_ms()<uTickStop) 00259 { 00260 BlinkDiceLed(nDiceValue, 0.2, ftDelay); // to indicate waiting for a new roll, flash the thrown dice value... 00261 ftDelay=(10-((float)uTickStop-tWait.read_ms())/1000)/100; // make the fast flashes slow down while closer to power down mode 00262 } 00263 SwitchAllLeds(false); 00264 00265 if(!fButtonPressed) 00266 myPowerDown(); // enter power-down mode when waited for more than 10 seconds without button pressed 00267 } 00268 } 00269 00270 int main() 00271 { // implement Arduino-style setup() and loop() 00272 setup(); 00273 while(true) 00274 loop(); 00275 }
Generated on Fri Jul 22 2022 13:13:16 by 1.7.2