Ferry Musters / Mbed 2 deprecated Clap_Unit

Dependencies:   mbed

Revision:
1:df9d6f3886f6
Parent:
0:6c254e376969
Child:
2:6b15e2363f00
--- a/main.cpp	Mon Jun 29 13:22:34 2015 +0000
+++ b/main.cpp	Mon Jun 29 21:54:14 2015 +0000
@@ -1,78 +1,149 @@
 //**************************************************//
 // Application to switch a light or other output    //
 // whenever the correct handclapping pattern is     //
-// detected.                                        //
+// detected. An external handclap detection board   //
+// is used (works as a SR-latch).                   //
 //                                                  //
 // Ferry Musters & Thom Grasso - 26/06/2015         //
 // Electrical Engineering - Hogeschool Utrecht      //
 //**************************************************//
 // TODO:
-// Must have:   - Reset timer and measurements after (4sec?) timeout
-// Must have:   - Detect set pattern
+// DONE! Must have:   - Reset timer and measurements after (4sec?) timeout
+// DONE! Must have:   - Detect fixed pattern (2 claps)
+// Must have:   - Detect fixed pattern (3+ claps)
 // Could have:  - Make user defined patterns (learn the device the pattern)
 
 #include "mbed.h"
 
+void BlinkLed(char color, float time);
+
+//-------------------[ Parameters ]------------------
+const int timeout_ms = 1000;
+const int allowedError = 200; //Allowed time difference between clap and set clap pattern
+
+const int clapPattern[] = {0, 500}; //initial clap pattern (in ms)
+
 //-------------------[ Variables ]-------------------
 DigitalOut led_red(LED_RED);
 DigitalOut led_blue(LED_BLUE);
 DigitalOut led_green(LED_GREEN);
+InterruptIn userSwitch(SW3);
 
-DigitalOut boardGnd(D4);
+
+DigitalOut boardGnd(D4); //pins
 DigitalOut boardVcc(D5);
 //InterruptIn boardClap(SW2);
 InterruptIn boardClap(D6);
 DigitalOut boardReset(D7);
 
 Serial output(USBTX, USBRX);
-Timer timer; //overall timer
-int clapTime[100]; //buffer to save clap times
+Timer timer; //global timer
+int clapData[100]; //buffer to save clap times
 int currentClap = 0; //counter to keep track of current clap in buffer
 int printedClap = 0; //counter to keep track of printf'ed claps
 
 
-//-------------------[ Functions ]-------------------
-void clap_detected(void)
+//-------------------[ Interrupts ]-------------------
+void ClapDetected(void) //interrupt function for boardClap pin
 {
-    clapTime[currentClap++] = timer.read_ms(); //save clap time and increment counter
+    clapData[currentClap++] = timer.read_ms(); //save clap time and increment counter
 
-    led_red = 0;    //blink a led to show detected clap
+    led_blue= 0;    //blink a led to show detected clap
     boardReset = 1; //reset the clap detecter board with a reset pulse
     wait(0.1); //wait to show led and also avoid handclap 'bounces'
     boardReset = 0;
-    led_red = 1; //The LED pin is inverted so '1' means LED off
+    led_blue = 1; //The LED pin is inverted so '1' means LED off
+}
+
+void DemoPattern(void)  //interrupt function for userSwitch pin
+{
+    const float demoBlinkLength = 0.05; //led blink length in ms
+    int amountOfClaps = sizeof(clapPattern) / sizeof(clapPattern[0]);
+    wait(0.3);
+    BlinkLed('r', demoBlinkLength); //blink the first clap
+    for(int i = 1; i < amountOfClaps; i++) { //blink the second and next claps
+        float delaytime = (clapPattern[i]-clapPattern[i-1])/1000.0 - demoBlinkLength;
+        output.printf("Blinking clap %d for %.2f second\r\n", i, delaytime);
+        output.printf("clapPattern[i] = %d\r\n", clapPattern[i]);
+        output.printf("clapPattern[i-1] = %d\r\n", clapPattern[i-1]);
+        wait(delaytime);
+        BlinkLed('r', demoBlinkLength);
+    }
+}
+
+//-------------------[ Functions ]-------------------
+void Initialize()
+{
+    timer.start();
+    boardVcc = 1;
+    boardGnd = 0;
+    boardReset = 0;
+    led_red = 1;
+    led_green = 1;
+    led_blue = 1;
+    boardClap.rise(&ClapDetected);
+    userSwitch.rise(&DemoPattern);
 }
 
+void PrintClaps()
+{
+    if(printedClap < currentClap) { //if the last clap isn't printed yet
+        output.printf("* Detected clap %d: %d\r\n", ++printedClap, clapData[printedClap]); //debug the clap
+    }
+}
 
+bool CheckTimeout() //check if clap timeout occurs(when last clap is more then x seconds ago)
+{
+    return ((currentClap > 0) && (timer.read_ms() > (clapData[currentClap-1] + timeout_ms)))
+}
+
+void ResetMeasurement() //reset counters to start new measurement
+{
+    output.printf("--- Timeout. %d claps and took %.2fs in total ---\r\n", currentClap, (clapData[currentClap-1] - clapData[0])/1000.0);
+    currentClap = 0;
+    printedClap = 0;
+}
+
+bool CheckClapPattern() //check if clapped pattern matches
+{
+    //CURRENT VERSION SUPPORTS JUST 2-clap patterns
+    output.printf("Check if %d is equal to %d.\r\n", (sizeof(clapPattern)/sizeof(clapPattern[0])), currentClap);
+
+    if((sizeof(clapPattern)/sizeof(clapPattern[0])) != currentClap) return false; //if nr of claps is not equal return mismatch
+
+    int realClapDelta = clapData[1] - clapData[0]; //measured clap pattern
+    int requiredClapDelta = clapPattern[1] - clapPattern[0]; //set clap pattern
+
+    int maxClapDelta = requiredClapDelta + allowedError;
+    int minClapDelta = requiredClapDelta - allowedError;
+    if((realClapDelta > minClapDelta) && (realClapDelta < maxClapDelta)) return true;
+    else return false;
+}
+
+void BlinkLed(char color, float time) //Blink led ('r', 'g' or 'b') for given time (float in sec)
+{
+    if(color == 'r') led_red = !led_red;
+    if(color == 'g') led_green = !led_green;
+    if(color == 'b') led_blue = !led_blue;
+    wait(time);
+    if(color == 'r') led_red = !led_red;
+    if(color == 'g') led_green = !led_green;
+    if(color == 'b') led_blue = !led_blue;
+}
 
 //-------------------[ Main ]-------------------
 int main()
 {
-    timer.start();
-    boardVcc = 1; boardGnd = 0; boardReset = 0;
-    led_red = 1; led_green = 1; led_blue = 1;
-    boardClap.rise(&clap_detected);
+    Initialize(); //initialize all required components and interrupts
 
     while (true) {
-        if(printedClap < currentClap) { //if the last clap isn't printed yet
-            output.printf("Clap %d: %d\r\n", ++printedClap, clapTime[printedClap]); //debug the clap
-        }
-        if((currentClap > 1) && (timer.read_ms() > (clapTime[currentClap-1] + 5000))) { //reset when timeout (last clap is more then 5 seconds ago)
-            output.printf("Timeout. %d claps were detected over a time of %dms\r\n", (currentClap - 1), (clapTime[currentClap] - clapTime[0]));
-            currentClap = 0;
-            printedClap = 0;
+        PrintClaps(); //update the serial terminal to print all detected claps
 
-            led_blue = 0;    //blink a led
-            wait(0.3);
-            led_blue = 1; //The LED pin is inverted so '1' means LED off
-
+        if( CheckTimeout() ) { // if timeout happened -> clap pattern ended
+            bool clapMatches = CheckClapPattern(); //check if claps match set pattern
+            if(clapMatches) BlinkLed('g', 0.5); //pattern match -> blink green
+            else BlinkLed('r', 0.5); //pattern mismatch -> blink red
+            ResetMeasurement();
         }
-
-        /*led_blue = 1;
-        led_green = 0;
-        wait(0.2);
-        led_blue = 0;
-        led_green = 1;
-        wait(0.2);*/
     }
-}
+}
\ No newline at end of file