Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@2:6b15e2363f00, 2015-07-03 (annotated)
- Committer:
- Ferryy
- Date:
- Fri Jul 03 09:42:38 2015 +0000
- Revision:
- 2:6b15e2363f00
- Parent:
- 1:df9d6f3886f6
Final Version
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Ferryy | 2:6b15e2363f00 | 1 | //**************************************************// |
| Ferryy | 2:6b15e2363f00 | 2 | // Clap_unit.cpp // |
| Ferryy | 0:6c254e376969 | 3 | //**************************************************// |
| Ferryy | 0:6c254e376969 | 4 | // Application to switch a light or other output // |
| Ferryy | 0:6c254e376969 | 5 | // whenever the correct handclapping pattern is // |
| Ferryy | 1:df9d6f3886f6 | 6 | // detected. An external handclap detection board // |
| Ferryy | 1:df9d6f3886f6 | 7 | // is used (works as a SR-latch). // |
| Ferryy | 2:6b15e2363f00 | 8 | // |
| Ferryy | 2:6b15e2363f00 | 9 | // The programmed pattern can be demonstrated by // |
| Ferryy | 2:6b15e2363f00 | 10 | // using SW3. An clapping pattern can be // |
| Ferryy | 2:6b15e2363f00 | 11 | // programmed by pressing switch SW2. // |
| Ferryy | 0:6c254e376969 | 12 | // // |
| Ferryy | 2:6b15e2363f00 | 13 | // Board: FRDM-K64F (using mbed IDE) // |
| Ferryy | 0:6c254e376969 | 14 | // Ferry Musters & Thom Grasso - 26/06/2015 // |
| Ferryy | 0:6c254e376969 | 15 | // Electrical Engineering - Hogeschool Utrecht // |
| Ferryy | 0:6c254e376969 | 16 | //**************************************************// |
| Ferryy | 2:6b15e2363f00 | 17 | |
| Ferryy | 0:6c254e376969 | 18 | |
| Ferryy | 0:6c254e376969 | 19 | #include "mbed.h" |
| Ferryy | 0:6c254e376969 | 20 | |
| Ferryy | 1:df9d6f3886f6 | 21 | void BlinkLed(char color, float time); |
| Ferryy | 1:df9d6f3886f6 | 22 | |
| Ferryy | 1:df9d6f3886f6 | 23 | //-------------------[ Parameters ]------------------ |
| Ferryy | 2:6b15e2363f00 | 24 | const int timeout_ms = 2000; // |
| Ferryy | 1:df9d6f3886f6 | 25 | const int allowedError = 200; //Allowed time difference between clap and set clap pattern |
| Ferryy | 1:df9d6f3886f6 | 26 | |
| Ferryy | 2:6b15e2363f00 | 27 | int clapPattern[100] = {0, 300, 900}; //initial clap pattern (in ms). Can be changed by user |
| Ferryy | 2:6b15e2363f00 | 28 | int clapPatternSize = 3; //initial clap pattern size (to indicate which portion of the array is used) |
| Ferryy | 0:6c254e376969 | 29 | //-------------------[ Variables ]------------------- |
| Ferryy | 0:6c254e376969 | 30 | DigitalOut led_red(LED_RED); |
| Ferryy | 0:6c254e376969 | 31 | DigitalOut led_blue(LED_BLUE); |
| Ferryy | 0:6c254e376969 | 32 | DigitalOut led_green(LED_GREEN); |
| Ferryy | 2:6b15e2363f00 | 33 | InterruptIn learningSwitch(SW2); |
| Ferryy | 2:6b15e2363f00 | 34 | InterruptIn demoSwitch(SW3); |
| Ferryy | 2:6b15e2363f00 | 35 | |
| Ferryy | 2:6b15e2363f00 | 36 | PwmOut lamp(A5); |
| Ferryy | 0:6c254e376969 | 37 | |
| Ferryy | 1:df9d6f3886f6 | 38 | |
| Ferryy | 1:df9d6f3886f6 | 39 | DigitalOut boardGnd(D4); //pins |
| Ferryy | 0:6c254e376969 | 40 | DigitalOut boardVcc(D5); |
| Ferryy | 0:6c254e376969 | 41 | //InterruptIn boardClap(SW2); |
| Ferryy | 0:6c254e376969 | 42 | InterruptIn boardClap(D6); |
| Ferryy | 0:6c254e376969 | 43 | DigitalOut boardReset(D7); |
| Ferryy | 0:6c254e376969 | 44 | |
| Ferryy | 0:6c254e376969 | 45 | Serial output(USBTX, USBRX); |
| Ferryy | 1:df9d6f3886f6 | 46 | Timer timer; //global timer |
| Ferryy | 1:df9d6f3886f6 | 47 | int clapData[100]; //buffer to save clap times |
| Ferryy | 0:6c254e376969 | 48 | int currentClap = 0; //counter to keep track of current clap in buffer |
| Ferryy | 0:6c254e376969 | 49 | int printedClap = 0; //counter to keep track of printf'ed claps |
| Ferryy | 2:6b15e2363f00 | 50 | bool learning = false; //flag to indicate if the system is learning a new clap pattern |
| Ferryy | 0:6c254e376969 | 51 | |
| Ferryy | 1:df9d6f3886f6 | 52 | //-------------------[ Interrupts ]------------------- |
| Ferryy | 1:df9d6f3886f6 | 53 | void ClapDetected(void) //interrupt function for boardClap pin |
| Ferryy | 0:6c254e376969 | 54 | { |
| Ferryy | 1:df9d6f3886f6 | 55 | clapData[currentClap++] = timer.read_ms(); //save clap time and increment counter |
| Ferryy | 0:6c254e376969 | 56 | boardReset = 1; //reset the clap detecter board with a reset pulse |
| Ferryy | 2:6b15e2363f00 | 57 | BlinkLed('b',0.05); //wait to show led and also avoid handclap 'bounces' |
| Ferryy | 0:6c254e376969 | 58 | boardReset = 0; |
| Ferryy | 1:df9d6f3886f6 | 59 | } |
| Ferryy | 1:df9d6f3886f6 | 60 | |
| Ferryy | 2:6b15e2363f00 | 61 | void DemoPattern(void) //interrupt function for userSwitch pin. Demonstrates |
| Ferryy | 1:df9d6f3886f6 | 62 | { |
| Ferryy | 1:df9d6f3886f6 | 63 | const float demoBlinkLength = 0.05; //led blink length in ms |
| Ferryy | 1:df9d6f3886f6 | 64 | wait(0.3); |
| Ferryy | 1:df9d6f3886f6 | 65 | BlinkLed('r', demoBlinkLength); //blink the first clap |
| Ferryy | 2:6b15e2363f00 | 66 | for(int i = 1; i < clapPatternSize; i++) { //blink the second and next claps |
| Ferryy | 1:df9d6f3886f6 | 67 | float delaytime = (clapPattern[i]-clapPattern[i-1])/1000.0 - demoBlinkLength; |
| Ferryy | 1:df9d6f3886f6 | 68 | output.printf("Blinking clap %d for %.2f second\r\n", i, delaytime); |
| Ferryy | 2:6b15e2363f00 | 69 | //output.printf("clapPattern[i] = %d\r\n", clapPattern[i]); |
| Ferryy | 2:6b15e2363f00 | 70 | //output.printf("clapPattern[i-1] = %d\r\n", clapPattern[i-1]); |
| Ferryy | 1:df9d6f3886f6 | 71 | wait(delaytime); |
| Ferryy | 1:df9d6f3886f6 | 72 | BlinkLed('r', demoBlinkLength); |
| Ferryy | 1:df9d6f3886f6 | 73 | } |
| Ferryy | 1:df9d6f3886f6 | 74 | } |
| Ferryy | 1:df9d6f3886f6 | 75 | |
| Ferryy | 2:6b15e2363f00 | 76 | void StartLearning(void) //when switch is pressed, system goes into learning mode. |
| Ferryy | 2:6b15e2363f00 | 77 | { |
| Ferryy | 2:6b15e2363f00 | 78 | output.printf("--- Starting Learning Mode! Enter clap pattern"); |
| Ferryy | 2:6b15e2363f00 | 79 | led_red = 0; |
| Ferryy | 2:6b15e2363f00 | 80 | learning = true; |
| Ferryy | 2:6b15e2363f00 | 81 | } |
| Ferryy | 2:6b15e2363f00 | 82 | |
| Ferryy | 1:df9d6f3886f6 | 83 | //-------------------[ Functions ]------------------- |
| Ferryy | 1:df9d6f3886f6 | 84 | void Initialize() |
| Ferryy | 1:df9d6f3886f6 | 85 | { |
| Ferryy | 1:df9d6f3886f6 | 86 | timer.start(); |
| Ferryy | 1:df9d6f3886f6 | 87 | boardVcc = 1; |
| Ferryy | 1:df9d6f3886f6 | 88 | boardGnd = 0; |
| Ferryy | 1:df9d6f3886f6 | 89 | boardReset = 0; |
| Ferryy | 1:df9d6f3886f6 | 90 | led_red = 1; |
| Ferryy | 1:df9d6f3886f6 | 91 | led_green = 1; |
| Ferryy | 1:df9d6f3886f6 | 92 | led_blue = 1; |
| Ferryy | 2:6b15e2363f00 | 93 | lamp.period_ms(1); |
| Ferryy | 1:df9d6f3886f6 | 94 | boardClap.rise(&ClapDetected); |
| Ferryy | 2:6b15e2363f00 | 95 | demoSwitch.rise(&DemoPattern); |
| Ferryy | 2:6b15e2363f00 | 96 | learningSwitch.rise(&StartLearning); |
| Ferryy | 0:6c254e376969 | 97 | } |
| Ferryy | 0:6c254e376969 | 98 | |
| Ferryy | 1:df9d6f3886f6 | 99 | void PrintClaps() |
| Ferryy | 1:df9d6f3886f6 | 100 | { |
| Ferryy | 1:df9d6f3886f6 | 101 | if(printedClap < currentClap) { //if the last clap isn't printed yet |
| Ferryy | 1:df9d6f3886f6 | 102 | output.printf("* Detected clap %d: %d\r\n", ++printedClap, clapData[printedClap]); //debug the clap |
| Ferryy | 1:df9d6f3886f6 | 103 | } |
| Ferryy | 1:df9d6f3886f6 | 104 | } |
| Ferryy | 0:6c254e376969 | 105 | |
| Ferryy | 1:df9d6f3886f6 | 106 | bool CheckTimeout() //check if clap timeout occurs(when last clap is more then x seconds ago) |
| Ferryy | 1:df9d6f3886f6 | 107 | { |
| Ferryy | 2:6b15e2363f00 | 108 | return ((currentClap > 0) && (timer.read_ms() > (clapData[currentClap-1] + timeout_ms))); |
| Ferryy | 2:6b15e2363f00 | 109 | } |
| Ferryy | 2:6b15e2363f00 | 110 | |
| Ferryy | 2:6b15e2363f00 | 111 | void SavePattern() |
| Ferryy | 2:6b15e2363f00 | 112 | { |
| Ferryy | 2:6b15e2363f00 | 113 | for(int i = 0; i < currentClap; i++) clapPattern[i] = clapData[i]; //save clapped buffer as new pattern |
| Ferryy | 2:6b15e2363f00 | 114 | clapPatternSize = currentClap; //save pattern size (amount of claps) |
| Ferryy | 2:6b15e2363f00 | 115 | led_red = 1; //turn off red 'recording' LED |
| Ferryy | 2:6b15e2363f00 | 116 | } |
| Ferryy | 2:6b15e2363f00 | 117 | |
| Ferryy | 2:6b15e2363f00 | 118 | bool CheckClapPattern() //check if clapped pattern matches |
| Ferryy | 2:6b15e2363f00 | 119 | { |
| Ferryy | 2:6b15e2363f00 | 120 | if(clapPatternSize != currentClap) return false; //if nr of claps is not equal return mismatch |
| Ferryy | 2:6b15e2363f00 | 121 | |
| Ferryy | 2:6b15e2363f00 | 122 | bool mismatch = false; //variable to keep track if any mismatch is found |
| Ferryy | 2:6b15e2363f00 | 123 | |
| Ferryy | 2:6b15e2363f00 | 124 | for(int i = 1; i < clapPatternSize; i++) { //check for each clap (each time interval between claps |
| Ferryy | 2:6b15e2363f00 | 125 | int realClapDelta = clapData[i] - clapData[i-1]; //measured clap pattern |
| Ferryy | 2:6b15e2363f00 | 126 | int requiredClapDelta = clapPattern[i] - clapPattern[i-1]; //set clap pattern |
| Ferryy | 2:6b15e2363f00 | 127 | |
| Ferryy | 2:6b15e2363f00 | 128 | int maxClapDelta = requiredClapDelta + allowedError; |
| Ferryy | 2:6b15e2363f00 | 129 | int minClapDelta = requiredClapDelta - allowedError; |
| Ferryy | 2:6b15e2363f00 | 130 | |
| Ferryy | 2:6b15e2363f00 | 131 | if((realClapDelta < minClapDelta) || (realClapDelta > maxClapDelta)) { |
| Ferryy | 2:6b15e2363f00 | 132 | mismatch = true; |
| Ferryy | 2:6b15e2363f00 | 133 | break; |
| Ferryy | 2:6b15e2363f00 | 134 | } |
| Ferryy | 2:6b15e2363f00 | 135 | } |
| Ferryy | 2:6b15e2363f00 | 136 | return !mismatch; //return if clap pattern matches (true) or not (false) |
| Ferryy | 1:df9d6f3886f6 | 137 | } |
| Ferryy | 1:df9d6f3886f6 | 138 | |
| Ferryy | 1:df9d6f3886f6 | 139 | void ResetMeasurement() //reset counters to start new measurement |
| Ferryy | 1:df9d6f3886f6 | 140 | { |
| Ferryy | 1:df9d6f3886f6 | 141 | output.printf("--- Timeout. %d claps and took %.2fs in total ---\r\n", currentClap, (clapData[currentClap-1] - clapData[0])/1000.0); |
| Ferryy | 2:6b15e2363f00 | 142 | currentClap = 0; //reset clap counters |
| Ferryy | 1:df9d6f3886f6 | 143 | printedClap = 0; |
| Ferryy | 1:df9d6f3886f6 | 144 | } |
| Ferryy | 1:df9d6f3886f6 | 145 | |
| Ferryy | 2:6b15e2363f00 | 146 | 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) |
| Ferryy | 1:df9d6f3886f6 | 147 | { |
| Ferryy | 2:6b15e2363f00 | 148 | if(color=='r' || color=='w' || color=='y' || color=='p') led_red = 0; |
| Ferryy | 2:6b15e2363f00 | 149 | if(color=='g' || color=='w' || color=='y' || color=='c') led_green = 0; |
| Ferryy | 2:6b15e2363f00 | 150 | if(color=='b' || color=='w' || color=='p' || color=='c') led_blue = 0; |
| Ferryy | 2:6b15e2363f00 | 151 | wait(time); |
| Ferryy | 2:6b15e2363f00 | 152 | if(color=='r' || color=='w' || color=='y' || color=='p') led_red = 1; |
| Ferryy | 2:6b15e2363f00 | 153 | if(color=='g' || color=='w' || color=='y' || color=='c') led_green = 1; |
| Ferryy | 2:6b15e2363f00 | 154 | if(color=='b' || color=='w' || color=='p' || color=='c') led_blue = 1; |
| Ferryy | 1:df9d6f3886f6 | 155 | } |
| Ferryy | 1:df9d6f3886f6 | 156 | |
| Ferryy | 0:6c254e376969 | 157 | |
| Ferryy | 0:6c254e376969 | 158 | //-------------------[ Main ]------------------- |
| Ferryy | 0:6c254e376969 | 159 | int main() |
| Ferryy | 0:6c254e376969 | 160 | { |
| Ferryy | 2:6b15e2363f00 | 161 | Initialize(); //initialize all required components and interrupts(!) |
| Ferryy | 0:6c254e376969 | 162 | |
| Ferryy | 0:6c254e376969 | 163 | while (true) { |
| Ferryy | 1:df9d6f3886f6 | 164 | PrintClaps(); //update the serial terminal to print all detected claps |
| Ferryy | 0:6c254e376969 | 165 | |
| Ferryy | 2:6b15e2363f00 | 166 | if(learning) { //learning state can be enabled by interrupt by switch on devboard |
| Ferryy | 2:6b15e2363f00 | 167 | if( CheckTimeout() ) { // if timeout happened -> clap pattern ended |
| Ferryy | 2:6b15e2363f00 | 168 | SavePattern(); //save clapped pattern as the new reference pattern |
| Ferryy | 2:6b15e2363f00 | 169 | learning = false; //disable learning state |
| Ferryy | 2:6b15e2363f00 | 170 | } |
| Ferryy | 2:6b15e2363f00 | 171 | } else { |
| Ferryy | 1:df9d6f3886f6 | 172 | bool clapMatches = CheckClapPattern(); //check if claps match set pattern |
| Ferryy | 2:6b15e2363f00 | 173 | if(clapMatches) { |
| Ferryy | 2:6b15e2363f00 | 174 | wait(0.2); //give a delay to make UI feel better |
| Ferryy | 2:6b15e2363f00 | 175 | lamp = 1 - lamp; //switch lamp on or off |
| Ferryy | 2:6b15e2363f00 | 176 | BlinkLed('g', 0.5); //pattern match -> blink green |
| Ferryy | 2:6b15e2363f00 | 177 | ResetMeasurement(); |
| Ferryy | 2:6b15e2363f00 | 178 | } else if( CheckTimeout() ) { //give the user some time to enter additional claps, else a timeout will happen. |
| Ferryy | 2:6b15e2363f00 | 179 | BlinkLed('r', 0.5); //pattern mismatch -> blink red |
| Ferryy | 2:6b15e2363f00 | 180 | ResetMeasurement(); |
| Ferryy | 2:6b15e2363f00 | 181 | } |
| Ferryy | 0:6c254e376969 | 182 | } |
| Ferryy | 0:6c254e376969 | 183 | } |
| Ferryy | 1:df9d6f3886f6 | 184 | } |