Ferry Musters / Mbed 2 deprecated Clap_Unit

Dependencies:   mbed

Revision:
2:6b15e2363f00
Parent:
1:df9d6f3886f6
--- a/main.cpp	Mon Jun 29 21:54:14 2015 +0000
+++ b/main.cpp	Fri Jul 03 09:42:38 2015 +0000
@@ -1,33 +1,39 @@
+//**************************************************//
+//                   Clap_unit.cpp                  //
 //**************************************************//
 // Application to switch a light or other output    //
 // whenever the correct handclapping pattern is     //
 // detected. An external handclap detection board   //
 // is used (works as a SR-latch).                   //
+//
+// The programmed pattern can be demonstrated by    //
+// using SW3. An clapping pattern can be            //
+// programmed by pressing switch SW2.               //
 //                                                  //
+// Board: FRDM-K64F (using mbed IDE)                //
 // Ferry Musters & Thom Grasso - 26/06/2015         //
 // Electrical Engineering - Hogeschool Utrecht      //
 //**************************************************//
-// TODO:
-// 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 timeout_ms = 2000; //
 const int allowedError = 200; //Allowed time difference between clap and set clap pattern
 
-const int clapPattern[] = {0, 500}; //initial clap pattern (in ms)
-
+int clapPattern[100] = {0, 300, 900}; //initial clap pattern (in ms). Can be changed by user
+int clapPatternSize = 3; //initial clap pattern size (to indicate which portion of the array is used)
 //-------------------[ Variables ]-------------------
 DigitalOut led_red(LED_RED);
 DigitalOut led_blue(LED_BLUE);
 DigitalOut led_green(LED_GREEN);
-InterruptIn userSwitch(SW3);
+InterruptIn learningSwitch(SW2);
+InterruptIn demoSwitch(SW3);
+
+PwmOut lamp(A5);
 
 
 DigitalOut boardGnd(D4); //pins
@@ -41,36 +47,39 @@
 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
-
+bool learning = false; //flag to indicate if the system is learning a new clap pattern
 
 //-------------------[ Interrupts ]-------------------
 void ClapDetected(void) //interrupt function for boardClap pin
 {
     clapData[currentClap++] = timer.read_ms(); //save clap time and increment counter
-
-    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'
+    BlinkLed('b',0.05); //wait to show led and also avoid handclap 'bounces'
     boardReset = 0;
-    led_blue = 1; //The LED pin is inverted so '1' means LED off
 }
 
-void DemoPattern(void)  //interrupt function for userSwitch pin
+void DemoPattern(void)  //interrupt function for userSwitch pin. Demonstrates
 {
     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
+    for(int i = 1; i < clapPatternSize; 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]);
+        //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);
     }
 }
 
+void StartLearning(void) //when switch is pressed, system goes into learning mode.
+{
+    output.printf("--- Starting Learning Mode! Enter clap pattern");
+    led_red = 0;
+    learning = true;
+}
+
 //-------------------[ Functions ]-------------------
 void Initialize()
 {
@@ -81,8 +90,10 @@
     led_red = 1;
     led_green = 1;
     led_blue = 1;
+    lamp.period_ms(1);
     boardClap.rise(&ClapDetected);
-    userSwitch.rise(&DemoPattern);
+    demoSwitch.rise(&DemoPattern);
+    learningSwitch.rise(&StartLearning);
 }
 
 void PrintClaps()
@@ -94,56 +105,80 @@
 
 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)))
+    return ((currentClap > 0) && (timer.read_ms() > (clapData[currentClap-1] + timeout_ms)));
+}
+
+void SavePattern()
+{
+    for(int i = 0; i < currentClap; i++) clapPattern[i] = clapData[i]; //save clapped buffer as new pattern
+    clapPatternSize = currentClap; //save pattern size (amount of claps)   
+    led_red = 1; //turn off red 'recording' LED
+}
+
+bool CheckClapPattern() //check if clapped pattern matches
+{
+    if(clapPatternSize != currentClap) return false; //if nr of claps is not equal return mismatch
+
+    bool mismatch = false; //variable to keep track if any mismatch is found
+    
+    for(int i = 1; i < clapPatternSize; i++) { //check for each clap (each time interval between claps
+        int realClapDelta = clapData[i] - clapData[i-1]; //measured clap pattern
+        int requiredClapDelta = clapPattern[i] - clapPattern[i-1]; //set clap pattern
+
+        int maxClapDelta = requiredClapDelta + allowedError;
+        int minClapDelta = requiredClapDelta - allowedError;
+
+        if((realClapDelta < minClapDelta) || (realClapDelta > maxClapDelta)) {
+            mismatch = true;
+            break;
+        }
+    }
+    return !mismatch; //return if clap pattern matches (true) or not (false)
 }
 
 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;
+    currentClap = 0; //reset clap counters
     printedClap = 0;
 }
 
-bool CheckClapPattern() //check if clapped pattern matches
+void BlinkLed(char color, float time) //Blink led ('r', 'g' or 'b'. 'p'urple, 'y'ellow, 'c'yan or 'w'hite) for given time (float in sec)
 {
-    //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;
+    if(color=='r' || color=='w' || color=='y' || color=='p') led_red = 0;
+    if(color=='g' || color=='w' || color=='y' || color=='c') led_green = 0;
+    if(color=='b' || color=='w' || color=='p' || color=='c') led_blue = 0;
+    wait(time);
+    if(color=='r' || color=='w' || color=='y' || color=='p') led_red = 1;
+    if(color=='g' || color=='w' || color=='y' || color=='c') led_green = 1;
+    if(color=='b' || color=='w' || color=='p' || color=='c') led_blue = 1;
 }
 
-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()
 {
-    Initialize(); //initialize all required components and interrupts
+    Initialize(); //initialize all required components and interrupts(!)
 
     while (true) {
         PrintClaps(); //update the serial terminal to print all detected claps
 
-        if( CheckTimeout() ) { // if timeout happened -> clap pattern ended
+        if(learning) { //learning state can be enabled by interrupt by switch on devboard
+            if( CheckTimeout() ) { // if timeout happened -> clap pattern ended
+                SavePattern(); //save clapped pattern as the new reference pattern
+                learning = false; //disable learning state
+            }
+        } else {
             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();
+            if(clapMatches) {
+                wait(0.2); //give a delay to make UI feel better
+                lamp = 1 - lamp; //switch lamp on or off
+                BlinkLed('g', 0.5); //pattern match -> blink green
+                ResetMeasurement();
+            } else if( CheckTimeout() ) { //give the user some time to enter additional claps, else a timeout will happen.
+                BlinkLed('r', 0.5); //pattern mismatch -> blink red
+                ResetMeasurement();
+            }
         }
     }
 }
\ No newline at end of file