Maxint R&D / Mbed 2 deprecated mBuino_Dice

Dependencies:   mbed

Fork of mBuino_Dice by Valentin Ivanov

Files at this revision

API Documentation at this revision

Comitter:
maxint
Date:
Mon Sep 08 10:01:38 2014 +0000
Parent:
2:0d311a6cfb96
Child:
4:0c3a1b829d8c
Commit message:
0.1.140908 Added deep sleep mode, explanatory comments, incorporated suggestions, improved randomness

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Sep 01 18:59:39 2014 +0000
+++ b/main.cpp	Mon Sep 08 10:01:38 2014 +0000
@@ -5,9 +5,12 @@
 ** Setup requirements: connect any type of switch between P0.4 and GND.
 ** On mBuino P0.4 is close to GND and the two pitch distance is exactly the same as a mini-switch! 
 **
-** 0.1.140901 Made for mBuino on mbed.org by maxint on 1-sep-2014
+** 0.1.140908 Added deep sleep mode after one iteration of demo or ten seconds of wating, credits: Andy A and Erik Olieman
+**            Added explanatory comments and incorporated suggestion by Erik Olieman
+**            Improved randomness as per suggestion of Andy A
+** 0.1.140901 First version mad for mBuino on mbed.org by maxint on 1-sep-2014
 **
-** Feel free to use this code anyway you want, but please acknowledge my work by mentioning my name.
+** Feel free to use this code anyway you want, but please acknowledge my work by mentioning maxint as creator.
 **
 */
 
@@ -15,10 +18,12 @@
 #include "mbed.h"
 
 DigitalOut LED[] = {(P0_7), (P0_8), (P0_2), (P0_20), (P1_19), (P0_17), (P0_23)};// declare 7 LEDs
-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
-AnalogIn RandomIn = (P0_14); // use the random noise on this analog input to seed the random generator
 
+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
+AnalogIn RandomIn(P0_14); // use the random noise on this analog input to seed the random generator
 
+// Define the LED pattern of each dice number
+// Can be made more compact by using binary values instead of a nested array.
 bool DicePattern[6][7]=
 {
     {0, 0, 0, 1, 0, 0, 0 },
@@ -29,11 +34,35 @@
     {1, 1, 1, 0, 1, 1, 1 }
 };
 
-float delayTime = .05;
+/*
+// 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
+BusOut LEDS(P0_7, P0_8, P0_2, P0_20, P1_19, P0_17, P0_23);
+char byteDice[6]=
+{
+0x08,   // 0B00001000
+0x22,   // 0B00100010
+0x2A,   // 0B00101010
+0x55,   // 0B01010101
+0x5D,   // 0B01011101
+0x77    // 0B01110111
+};
+*/
 
+Timer tWait;    // time used for tickcounts
+
+void myDeepSleep()
+{   // Go into deep sleep to safe power. Use onboard or off-board interrupt triggered button to revive
+    // see http://mbed.org/forum/repo-52552-mBuino_low_power_led_flasher-community/topic/5130/
+    LPC_PMU->PCON = 0x1;
+    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+    LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800;
+    __WFI();
+}
+ 
 
 void SwitchAllLeds(bool fOn)
 {   // switch all leds on or off
+    // 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
     for(int x = 0; x < 7; x++)
     {
         LED[x] = fOn?1:0;   // turn on or off
@@ -49,7 +78,7 @@
 }
 
 void BlinkOneLed(int nLed=0, float flDelayOn=0.2, float flDelayOff=0.2)
-{
+{   // blink just one led once, for the specified time
     LED[nLed] = 1; // turn on
     wait(flDelayOn); // delay
 
@@ -97,9 +126,12 @@
     wait(flDelayOff);
 }
 
-int RollDice(int nRolls=10, int nBlinks=2, float flDelayRoll=0.2)
+int RollDice(int nRolls=10, int nBlinks=2, float flDelayRoll=0.15)
 {   // roll the dice and show the outcome value
     int nDiceValue;
+
+    // improve randomness: seed the random generator with the background noise of an analog input combined with passed time at user triggered moment
+    srand(RandomIn.read_u16()+tWait.read_us());
     
     // first roll the dice
     for(int n=0; n<nRolls; n++)
@@ -112,7 +144,7 @@
     nDiceValue=rand()%6+1;
     for(int n=0; n<nBlinks; n++)
         BlinkDiceLed(nDiceValue, flDelayRoll, 0);
-    BlinkDiceLed(nDiceValue, true);        
+    SwitchDiceLed(nDiceValue, true);        // return while keeping dice led's on
     
     return(nDiceValue);
 }
@@ -130,6 +162,7 @@
     srand(RandomIn.read_u16());     // seed the random generator with the background noise of an analog input
     
     ActionButton.fall(interruptButtonPressed); // using the fall requires the button to be unpressed before the interrupt is triggered again
+    tWait.start();      // start the timer
 }
 
 void loop(void)
@@ -177,27 +210,35 @@
         
         if(!fButtonPressed)
             wait(1);
+            
+        if(!fButtonPressed)
+            myDeepSleep();   // enter deep sleep after one demo iteration
     }
     else
     {   // demo mode is ended, roll the dice upon each button press
         fDemoDone=true;
         fButtonPressed=false;
         
+        unsigned uTickStop=tWait.read_ms()+10000;
         while(!fButtonPressed)
         {   // flash the LEDS to show we wait for a roll call
             SweepAllLeds(true, 0.01);
             SweepAllLeds(false, 0.01);
+
+            if(!fButtonPressed && tWait.read_ms()>uTickStop)
+                myDeepSleep();   // enter deep sleep when waited for more than 10 seconds without button pressed
         }
         fButtonPressed=false;
-
-        Timer tWait;
         
+        // roll the dice and show the outcome while waiting max. 10 seconds
         int nDiceValue=RollDice();
         wait(1);
-        tWait.start();
         fButtonPressed=false;
-        while(!fButtonPressed && tWait.read_ms()<10000)
-            BlinkDiceLed(nDiceValue, 0.2, 0.01);  // hmmmm, something switched off the leds after the wait? Strange, let's just blink them...
+        
+        uTickStop=tWait.read_ms()+10000;
+        while(!fButtonPressed && tWait.read_ms()<uTickStop)
+            //wait(0.1);
+            BlinkDiceLed(nDiceValue, 0.2, 0.01);  // to indicate waiting for a new roll, blink the thrown dice value...
         SwitchAllLeds(false);
     }
 }