14 Key poller with debouncing DEMO

Dependencies:   mbed

Committer:
ekelmans
Date:
Sat Jan 07 00:17:15 2012 +0000
Revision:
0:acabda48796c
Child:
1:6ee2362ce0fd
V1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ekelmans 0:acabda48796c 1 /* -----------------------------------------------------------------------
ekelmans 0:acabda48796c 2 14 Key poller and debounce demo by Theo Ekelmans, Version 1.0
ekelmans 0:acabda48796c 3 -----------------------------------------------------------------------
ekelmans 0:acabda48796c 4
ekelmans 0:acabda48796c 5 In this demo, banks A, C and D are push buttons, bank B are toggle switches that have a LED inside
ekelmans 0:acabda48796c 6
ekelmans 0:acabda48796c 7 The timer used for SampleInterval is set to 10 ms (sample time)
ekelmans 0:acabda48796c 8
ekelmans 0:acabda48796c 9 2 * SampleInterval = 20ms for good quality switches, 80ms for high CPU load or really crappy switches :)
ekelmans 0:acabda48796c 10
ekelmans 0:acabda48796c 11 led3 on the MBED
ekelmans 0:acabda48796c 12
ekelmans 0:acabda48796c 13 Config your USB COM port terminal session as a VT100 terminal :)
ekelmans 0:acabda48796c 14
ekelmans 0:acabda48796c 15 Notes:
ekelmans 0:acabda48796c 16 1: The SampleCnt is 32 bit, that means every 2^32 times 10ms SampleInterval it will trigger an overflow
ekelmans 0:acabda48796c 17 on the long vars, thats why @ 4000000000 the TimerOverflowRecover resets all counters.
ekelmans 0:acabda48796c 18 During in that brief moment (2 miliseconds every 25 days or so), the debounce is not reliable ;)
ekelmans 0:acabda48796c 19
ekelmans 0:acabda48796c 20 2: The USB COM port / VT100 terminal session hangs somtimes when you are bashing buttons like a madman,
ekelmans 0:acabda48796c 21 the LCD however is rock solid.
ekelmans 0:acabda48796c 22
ekelmans 0:acabda48796c 23 */
ekelmans 0:acabda48796c 24
ekelmans 0:acabda48796c 25 #include "mbed.h"
ekelmans 0:acabda48796c 26 #include "DigitalIn.h"
ekelmans 0:acabda48796c 27
ekelmans 0:acabda48796c 28 //--- Defines
ekelmans 0:acabda48796c 29 #define ON 1
ekelmans 0:acabda48796c 30 #define OFF 0
ekelmans 0:acabda48796c 31
ekelmans 0:acabda48796c 32 //ASCII commands for the VT100 terminal
ekelmans 0:acabda48796c 33 #define LF 10
ekelmans 0:acabda48796c 34 #define CLS 12
ekelmans 0:acabda48796c 35 #define CR 13
ekelmans 0:acabda48796c 36 #define BS 8
ekelmans 0:acabda48796c 37 #define ESC 27
ekelmans 0:acabda48796c 38
ekelmans 0:acabda48796c 39 //Serial LCD - Matrix Orbital LK204 command codes
ekelmans 0:acabda48796c 40 #define CMD 254
ekelmans 0:acabda48796c 41 #define CurPos 71 //follow up by COL ROW
ekelmans 0:acabda48796c 42
ekelmans 0:acabda48796c 43 Serial lcd(p9, p10); // tx, rx
ekelmans 0:acabda48796c 44
ekelmans 0:acabda48796c 45 //Debounce vars
ekelmans 0:acabda48796c 46 int DebounceThreshold = 3; // 2 * SampleInterval = 20ms for good quality switches, 80ms for high CPU load or really crappy switches :)
ekelmans 0:acabda48796c 47 float SampleInterval = 0.01; // The timer for debouncing interval: 10 ms sample time
ekelmans 0:acabda48796c 48
ekelmans 0:acabda48796c 49 unsigned long PollCount1 = 0;
ekelmans 0:acabda48796c 50 unsigned long PollCount2 = 0;
ekelmans 0:acabda48796c 51 unsigned long KillBeepAt = 0;
ekelmans 0:acabda48796c 52 char strCmd [100] = "";
ekelmans 0:acabda48796c 53
ekelmans 0:acabda48796c 54 //Debounce vars
ekelmans 0:acabda48796c 55 unsigned long SampleCnt = 0;
ekelmans 0:acabda48796c 56 unsigned long DebounceActivationCounter = 0;
ekelmans 0:acabda48796c 57 unsigned long LastSampleA1 = 0;
ekelmans 0:acabda48796c 58 unsigned long LastSampleA2 = 0;
ekelmans 0:acabda48796c 59 unsigned long LastSampleA3 = 0;
ekelmans 0:acabda48796c 60 unsigned long LastSampleA4 = 0;
ekelmans 0:acabda48796c 61 unsigned long LastSampleB1 = 0;
ekelmans 0:acabda48796c 62 unsigned long LastSampleB2 = 0;
ekelmans 0:acabda48796c 63 unsigned long LastSampleB3 = 0;
ekelmans 0:acabda48796c 64 unsigned long LastSampleB4 = 0;
ekelmans 0:acabda48796c 65 unsigned long LastSampleC1 = 0;
ekelmans 0:acabda48796c 66 unsigned long LastSampleC2 = 0;
ekelmans 0:acabda48796c 67 unsigned long LastSampleC3 = 0;
ekelmans 0:acabda48796c 68 unsigned long LastSampleC4 = 0;
ekelmans 0:acabda48796c 69 unsigned long LastSampleD1 = 0;
ekelmans 0:acabda48796c 70 unsigned long LastSampleD2 = 0;
ekelmans 0:acabda48796c 71
ekelmans 0:acabda48796c 72 bool LastButtonA1 = false;
ekelmans 0:acabda48796c 73 bool LastButtonA2 = false;
ekelmans 0:acabda48796c 74 bool LastButtonA3 = false;
ekelmans 0:acabda48796c 75 bool LastButtonA4 = false;
ekelmans 0:acabda48796c 76 bool LastButtonB1 = false;
ekelmans 0:acabda48796c 77 bool LastButtonB2 = false;
ekelmans 0:acabda48796c 78 bool LastButtonB3 = false;
ekelmans 0:acabda48796c 79 bool LastButtonB4 = false;
ekelmans 0:acabda48796c 80 bool LastButtonC1 = false;
ekelmans 0:acabda48796c 81 bool LastButtonC2 = false;
ekelmans 0:acabda48796c 82 bool LastButtonC3 = false;
ekelmans 0:acabda48796c 83 bool LastButtonC4 = false;
ekelmans 0:acabda48796c 84 bool LastButtonD1 = false;
ekelmans 0:acabda48796c 85 bool LastButtonD2 = false;
ekelmans 0:acabda48796c 86
ekelmans 0:acabda48796c 87 // The switch mapping
ekelmans 0:acabda48796c 88 DigitalIn buttonA1(p11);
ekelmans 0:acabda48796c 89 DigitalIn buttonA2(p12);
ekelmans 0:acabda48796c 90 DigitalIn buttonA3(p13);
ekelmans 0:acabda48796c 91 DigitalIn buttonA4(p14);
ekelmans 0:acabda48796c 92 DigitalIn buttonB1(p15);
ekelmans 0:acabda48796c 93 DigitalIn buttonB2(p16);
ekelmans 0:acabda48796c 94 DigitalIn buttonB3(p17);
ekelmans 0:acabda48796c 95 DigitalIn buttonB4(p18);
ekelmans 0:acabda48796c 96 DigitalIn buttonC1(p21);
ekelmans 0:acabda48796c 97 DigitalIn buttonC2(p22);
ekelmans 0:acabda48796c 98 DigitalIn buttonC3(p23);
ekelmans 0:acabda48796c 99 DigitalIn buttonC4(p24);
ekelmans 0:acabda48796c 100 DigitalIn buttonD1(p28);
ekelmans 0:acabda48796c 101 DigitalIn buttonD2(p27);
ekelmans 0:acabda48796c 102
ekelmans 0:acabda48796c 103 //Bank B Leds
ekelmans 0:acabda48796c 104 DigitalOut ledH1(p5);
ekelmans 0:acabda48796c 105 DigitalOut ledH2(p6);
ekelmans 0:acabda48796c 106 DigitalOut ledH3(p7);
ekelmans 0:acabda48796c 107 DigitalOut ledH4(p8);
ekelmans 0:acabda48796c 108
ekelmans 0:acabda48796c 109 //MBED leds
ekelmans 0:acabda48796c 110 DigitalOut led1(LED1);
ekelmans 0:acabda48796c 111 DigitalOut led2(LED2);
ekelmans 0:acabda48796c 112 DigitalOut led3(LED3);
ekelmans 0:acabda48796c 113 DigitalOut led4(LED4);
ekelmans 0:acabda48796c 114
ekelmans 0:acabda48796c 115 //Timer that starts the polling event
ekelmans 0:acabda48796c 116 Ticker DebounceTimer;
ekelmans 0:acabda48796c 117
ekelmans 0:acabda48796c 118 //Beeper port
ekelmans 0:acabda48796c 119 DigitalOut Beep(p29);
ekelmans 0:acabda48796c 120
ekelmans 0:acabda48796c 121 // Config your USB COM port terminal session as a VT100 terminal :)
ekelmans 0:acabda48796c 122 Serial usbUART ( USBTX, USBRX );
ekelmans 0:acabda48796c 123
ekelmans 0:acabda48796c 124 // Kill tha beep....
ekelmans 0:acabda48796c 125 void KillBeep() {Beep = OFF; } // beepTimer.detach();}
ekelmans 0:acabda48796c 126
ekelmans 0:acabda48796c 127
ekelmans 0:acabda48796c 128 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 129 //This is where you put your payload;
ekelmans 0:acabda48796c 130 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 131 void PayLoadPressed(char msg[] ) { lcd.printf("%c%c%c%cA%i%i%i%iB%i%i%i%iC%i%i%i%iD%i%i\r\n@ %ld, %ld bounces\r\nKey + %s @ %ld\r\n ", CMD, CurPos, 1, 1,buttonA1.read(),buttonA2.read(),buttonA3.read(),buttonA4.read(),buttonB1.read(),buttonB2.read(),buttonB3.read(),buttonB4.read(),buttonC1.read(),buttonC2.read(),buttonC3.read(),buttonC4.read(),buttonD1.read(),buttonD2.read(), PollCount2, DebounceActivationCounter, msg, SampleCnt);};
ekelmans 0:acabda48796c 132 void PayLoadRelease(char msg[] ) { lcd.printf("%c%c%c%cA%i%i%i%iB%i%i%i%iC%i%i%i%iD%i%i\r\n@ %ld, %ld bounces\r\nKey - %s @ %ld\r\n ", CMD, CurPos, 1, 1,buttonA1.read(),buttonA2.read(),buttonA3.read(),buttonA4.read(),buttonB1.read(),buttonB2.read(),buttonB3.read(),buttonB4.read(),buttonC1.read(),buttonC2.read(),buttonC3.read(),buttonC4.read(),buttonD1.read(),buttonD2.read(), PollCount2, DebounceActivationCounter, msg, SampleCnt);};
ekelmans 0:acabda48796c 133
ekelmans 0:acabda48796c 134 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 135 //This routine is only needed for the demo and can be removed for runtime
ekelmans 0:acabda48796c 136 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 137 void DeboucnceActive(char msg[], unsigned long l, unsigned long c) {
ekelmans 0:acabda48796c 138 lcd.printf("%c%c%c%cA%i%i%i%iB%i%i%i%iC%i%i%i%iD%i%i\r\n@ %ld, %ld bounces\r\nKey - %s @ %ld\r\n%s bounced %ld x ", CMD, CurPos, 1, 1, buttonA1.read(),buttonA2.read(),buttonA3.read(),buttonA4.read(),buttonB1.read(),buttonB2.read(),buttonB3.read(),buttonB4.read(),buttonC1.read(),buttonC2.read(),buttonC3.read(),buttonC4.read(),buttonD1.read(),buttonD2.read(), PollCount2, DebounceActivationCounter, msg, SampleCnt, msg, (c - l));
ekelmans 0:acabda48796c 139 DebounceActivationCounter ++;
ekelmans 0:acabda48796c 140 led3 = !led3; //Blink on debounce
ekelmans 0:acabda48796c 141 Beep = ON;
ekelmans 0:acabda48796c 142 KillBeepAt = SampleCnt + 50; //Kill Beep in 500 Ms
ekelmans 0:acabda48796c 143 };
ekelmans 0:acabda48796c 144
ekelmans 0:acabda48796c 145 //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 146 // Wait at least <DebounceThreshold> samples Toggle status Payload Save debounce counter Debounce active
ekelmans 0:acabda48796c 147 //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 148 void keyPressedA1 ( void ) {if ((LastSampleA1 + DebounceThreshold) < SampleCnt) {LastButtonA1 = buttonA1; PayLoadPressed("F"); LastSampleA1 = SampleCnt;} else {DeboucnceActive("F", LastSampleA1, SampleCnt);};};
ekelmans 0:acabda48796c 149 void keyReleasedA1( void ) {if ((LastSampleA1 + DebounceThreshold) < SampleCnt) {LastButtonA1 = buttonA1; /*no key up event*/ LastSampleA1 = SampleCnt;} else {/*no key up debounce needed either*/ ;};};
ekelmans 0:acabda48796c 150 void keyPressedA2 ( void ) {if ((LastSampleA2 + DebounceThreshold) < SampleCnt) {LastButtonA2 = buttonA2; PayLoadPressed("G"); LastSampleA2 = SampleCnt;} else {DeboucnceActive("G", LastSampleA2, SampleCnt);};};
ekelmans 0:acabda48796c 151 void keyReleasedA2( void ) {if ((LastSampleA2 + DebounceThreshold) < SampleCnt) {LastButtonA2 = buttonA2; LastSampleA2 = SampleCnt;} else { ;};};
ekelmans 0:acabda48796c 152 void keyPressedA3 ( void ) {if ((LastSampleA3 + DebounceThreshold) < SampleCnt) {LastButtonA3 = buttonA3; PayLoadPressed("H"); LastSampleA3 = SampleCnt;} else {DeboucnceActive("H", LastSampleA3, SampleCnt);};};
ekelmans 0:acabda48796c 153 void keyReleasedA3( void ) {if ((LastSampleA3 + DebounceThreshold) < SampleCnt) {LastButtonA3 = buttonA3; LastSampleA3 = SampleCnt;} else { ;};};
ekelmans 0:acabda48796c 154 void keyPressedA4 ( void ) {if ((LastSampleA4 + DebounceThreshold) < SampleCnt) {LastButtonA4 = buttonA4; PayLoadPressed("I"); LastSampleA4 = SampleCnt;} else {DeboucnceActive("I", LastSampleA4, SampleCnt);};};
ekelmans 0:acabda48796c 155 void keyReleasedA4( void ) {if ((LastSampleA4 + DebounceThreshold) < SampleCnt) {LastButtonA4 = buttonA4; LastSampleA4 = SampleCnt;} else { ;};};
ekelmans 0:acabda48796c 156
ekelmans 0:acabda48796c 157 //Toggle switches need a payload on the pressed and release event, and debouncing on both
ekelmans 0:acabda48796c 158 void keyPressedB1 ( void ) {if ((LastSampleB1 + DebounceThreshold) < SampleCnt) {LastButtonB1 = buttonB1; PayLoadPressed("A"); LastSampleB1 = SampleCnt;} else {DeboucnceActive("A", LastSampleB1, SampleCnt);};};
ekelmans 0:acabda48796c 159 void keyReleasedB1( void ) {if ((LastSampleB1 + DebounceThreshold) < SampleCnt) {LastButtonB1 = buttonB1; PayLoadRelease("a"); LastSampleB1 = SampleCnt;} else {DeboucnceActive("a", LastSampleB1, SampleCnt);};};
ekelmans 0:acabda48796c 160 void keyPressedB2 ( void ) {if ((LastSampleB2 + DebounceThreshold) < SampleCnt) {LastButtonB2 = buttonB2; PayLoadPressed("B"); LastSampleB2 = SampleCnt;} else {DeboucnceActive("B", LastSampleB2, SampleCnt);};};
ekelmans 0:acabda48796c 161 void keyReleasedB2( void ) {if ((LastSampleB2 + DebounceThreshold) < SampleCnt) {LastButtonB2 = buttonB2; PayLoadRelease("b"); LastSampleB2 = SampleCnt;} else {DeboucnceActive("b", LastSampleB2, SampleCnt);};};
ekelmans 0:acabda48796c 162 void keyPressedB3 ( void ) {if ((LastSampleB3 + DebounceThreshold) < SampleCnt) {LastButtonB3 = buttonB3; PayLoadPressed("C"); LastSampleB3 = SampleCnt;} else {DeboucnceActive("C", LastSampleB3, SampleCnt);};};
ekelmans 0:acabda48796c 163 void keyReleasedB3( void ) {if ((LastSampleB3 + DebounceThreshold) < SampleCnt) {LastButtonB3 = buttonB3; PayLoadRelease("c"); LastSampleB3 = SampleCnt;} else {DeboucnceActive("c", LastSampleB3, SampleCnt);};};
ekelmans 0:acabda48796c 164 void keyPressedB4 ( void ) {if ((LastSampleB4 + DebounceThreshold) < SampleCnt) {LastButtonB4 = buttonB4; PayLoadPressed("D"); LastSampleB4 = SampleCnt;} else {DeboucnceActive("D", LastSampleB4, SampleCnt);};};
ekelmans 0:acabda48796c 165 void keyReleasedB4( void ) {if ((LastSampleB4 + DebounceThreshold) < SampleCnt) {LastButtonB4 = buttonB4; PayLoadRelease("d"); LastSampleB4 = SampleCnt;} else {DeboucnceActive("d", LastSampleB4, SampleCnt);};};
ekelmans 0:acabda48796c 166
ekelmans 0:acabda48796c 167 //Push button switches only need a payload and debouncing on the pressed event, and you can ignore the release event (C4 left on for demo purposes)
ekelmans 0:acabda48796c 168 void keyPressedC1 ( void ) {if ((LastSampleC1 + DebounceThreshold) < SampleCnt) {LastButtonC1 = buttonC1; PayLoadPressed("L"); LastSampleC1 = SampleCnt;} else {DeboucnceActive("L", LastSampleC1, SampleCnt);};};
ekelmans 0:acabda48796c 169 void keyReleasedC1( void ) {if ((LastSampleC1 + DebounceThreshold) < SampleCnt) {LastButtonC1 = buttonC1; /*no key up event*/ LastSampleC1 = SampleCnt;} else {/*no key up debounce needed either*/ ;};};
ekelmans 0:acabda48796c 170 void keyPressedC2 ( void ) {if ((LastSampleC2 + DebounceThreshold) < SampleCnt) {LastButtonC2 = buttonC2; PayLoadPressed("M"); LastSampleC2 = SampleCnt;} else {DeboucnceActive("M", LastSampleC2, SampleCnt);};};
ekelmans 0:acabda48796c 171 void keyReleasedC2( void ) {if ((LastSampleC2 + DebounceThreshold) < SampleCnt) {LastButtonC2 = buttonC2; LastSampleC2 = SampleCnt;} else { ;};};
ekelmans 0:acabda48796c 172 void keyPressedC3 ( void ) {if ((LastSampleC3 + DebounceThreshold) < SampleCnt) {LastButtonC3 = buttonC3; PayLoadPressed("N"); LastSampleC3 = SampleCnt;} else {DeboucnceActive("N", LastSampleC3, SampleCnt);};};
ekelmans 0:acabda48796c 173 void keyReleasedC3( void ) {if ((LastSampleC3 + DebounceThreshold) < SampleCnt) {LastButtonC3 = buttonC3; LastSampleC3 = SampleCnt;} else { ;};};
ekelmans 0:acabda48796c 174 void keyPressedC4 ( void ) {if ((LastSampleC4 + DebounceThreshold) < SampleCnt) {LastButtonC4 = buttonC4; PayLoadPressed("O"); LastSampleC4 = SampleCnt;} else {DeboucnceActive("O", LastSampleC4, SampleCnt);};};
ekelmans 0:acabda48796c 175 void keyReleasedC4( void ) {if ((LastSampleC4 + DebounceThreshold) < SampleCnt) {LastButtonC4 = buttonC4; PayLoadRelease("o"); LastSampleC4 = SampleCnt;} else {DeboucnceActive("o", LastSampleC4, SampleCnt);};};
ekelmans 0:acabda48796c 176
ekelmans 0:acabda48796c 177 //Push button switches only need a payload and debouncing on the pressed event, and you can ignore the release event (C4 left on for demo purposes)
ekelmans 0:acabda48796c 178 void keyPressedD1 ( void ) {if ((LastSampleD1 + DebounceThreshold) < SampleCnt) {LastButtonD1 = buttonD1; PayLoadPressed("Q"); LastSampleD1 = SampleCnt;} else {DeboucnceActive("Q", LastSampleD1, SampleCnt);};};
ekelmans 0:acabda48796c 179 void keyReleasedD1( void ) {if ((LastSampleD1 + DebounceThreshold) < SampleCnt) {LastButtonD1 = buttonD1; /*no key up event*/ LastSampleD1 = SampleCnt;} else {/*no key up debounce needed either*/ ;};};
ekelmans 0:acabda48796c 180 void keyPressedD2 ( void ) {if ((LastSampleD2 + DebounceThreshold) < SampleCnt) {LastButtonD2 = buttonD2; PayLoadPressed("P"); LastSampleD2 = SampleCnt;} else {DeboucnceActive("P", LastSampleD2, SampleCnt);};};
ekelmans 0:acabda48796c 181 void keyReleasedD2( void ) {if ((LastSampleD2 + DebounceThreshold) < SampleCnt) {LastButtonD2 = buttonD2; PayLoadRelease("p"); LastSampleD2 = SampleCnt;} else {DeboucnceActive("P", LastSampleD2, SampleCnt);};};
ekelmans 0:acabda48796c 182 //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 183
ekelmans 0:acabda48796c 184
ekelmans 0:acabda48796c 185 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 186 //INIT of the buttons, since toggle switches can be ON at startup
ekelmans 0:acabda48796c 187 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 188 void InitButtons(void) {
ekelmans 0:acabda48796c 189
ekelmans 0:acabda48796c 190 if (buttonA1){LastButtonA1 = true;} else {LastButtonA1 = false;};
ekelmans 0:acabda48796c 191 if (buttonA2){LastButtonA2 = true;} else {LastButtonA2 = false;};
ekelmans 0:acabda48796c 192 if (buttonA3){LastButtonA3 = true;} else {LastButtonA3 = false;};
ekelmans 0:acabda48796c 193 if (buttonA4){LastButtonA4 = true;} else {LastButtonA4 = false;};
ekelmans 0:acabda48796c 194 if (buttonB1){LastButtonB1 = true;} else {LastButtonB1 = false;};
ekelmans 0:acabda48796c 195 if (buttonB2){LastButtonB2 = true;} else {LastButtonB2 = false;};
ekelmans 0:acabda48796c 196 if (buttonB3){LastButtonB3 = true;} else {LastButtonB3 = false;};
ekelmans 0:acabda48796c 197 if (buttonB4){LastButtonB4 = true;} else {LastButtonB4 = false;};
ekelmans 0:acabda48796c 198 if (buttonC1){LastButtonC1 = true;} else {LastButtonC1 = false;};
ekelmans 0:acabda48796c 199 if (buttonC2){LastButtonC2 = true;} else {LastButtonC2 = false;};
ekelmans 0:acabda48796c 200 if (buttonC3){LastButtonC3 = true;} else {LastButtonC3 = false;};
ekelmans 0:acabda48796c 201 if (buttonC4){LastButtonC4 = true;} else {LastButtonC4 = false;};
ekelmans 0:acabda48796c 202 if (buttonD1){LastButtonD1 = true;} else {LastButtonD1 = false;};
ekelmans 0:acabda48796c 203 if (buttonD2){LastButtonD2 = true;} else {LastButtonD2 = false;};
ekelmans 0:acabda48796c 204
ekelmans 0:acabda48796c 205 // Update bank B Leds (Toggle switches)
ekelmans 0:acabda48796c 206 ledH1 = buttonB1.read();
ekelmans 0:acabda48796c 207 ledH2 = buttonB2.read();
ekelmans 0:acabda48796c 208 ledH3 = buttonB3.read();
ekelmans 0:acabda48796c 209 ledH4 = buttonB4.read();
ekelmans 0:acabda48796c 210
ekelmans 0:acabda48796c 211 }
ekelmans 0:acabda48796c 212
ekelmans 0:acabda48796c 213 void TimerOverflowRecover (void) {
ekelmans 0:acabda48796c 214
ekelmans 0:acabda48796c 215 //Reset all counters
ekelmans 0:acabda48796c 216 PollCount2 = 0;
ekelmans 0:acabda48796c 217 PollCount1 = 0;
ekelmans 0:acabda48796c 218 SampleCnt = 0;
ekelmans 0:acabda48796c 219 LastSampleA1 = 0;
ekelmans 0:acabda48796c 220 LastSampleA2 = 0;
ekelmans 0:acabda48796c 221 LastSampleA3 = 0;
ekelmans 0:acabda48796c 222 LastSampleA4 = 0;
ekelmans 0:acabda48796c 223 LastSampleB1 = 0;
ekelmans 0:acabda48796c 224 LastSampleB2 = 0;
ekelmans 0:acabda48796c 225 LastSampleB3 = 0;
ekelmans 0:acabda48796c 226 LastSampleB4 = 0;
ekelmans 0:acabda48796c 227 LastSampleC1 = 0;
ekelmans 0:acabda48796c 228 LastSampleC2 = 0;
ekelmans 0:acabda48796c 229 LastSampleC3 = 0;
ekelmans 0:acabda48796c 230 LastSampleC4 = 0;
ekelmans 0:acabda48796c 231 LastSampleD1 = 0;
ekelmans 0:acabda48796c 232 LastSampleD2 = 0;
ekelmans 0:acabda48796c 233
ekelmans 0:acabda48796c 234 }
ekelmans 0:acabda48796c 235
ekelmans 0:acabda48796c 236 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 237 //The key detection routine
ekelmans 0:acabda48796c 238 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 239 void DebounceTick() {
ekelmans 0:acabda48796c 240
ekelmans 0:acabda48796c 241 // XOR only traps 01 and 10 0->1 = pressed 1->0 = released
ekelmans 0:acabda48796c 242 if (buttonA1 ^ LastButtonA1) {if (buttonA1){keyPressedA1();} else {keyReleasedA1();};};
ekelmans 0:acabda48796c 243 if (buttonA2 ^ LastButtonA2) {if (buttonA2){keyPressedA2();} else {keyReleasedA2();};};
ekelmans 0:acabda48796c 244 if (buttonA3 ^ LastButtonA3) {if (buttonA3){keyPressedA3();} else {keyReleasedA3();};};
ekelmans 0:acabda48796c 245 if (buttonA4 ^ LastButtonA4) {if (buttonA4){keyPressedA4();} else {keyReleasedA4();};};
ekelmans 0:acabda48796c 246 if (buttonB1 ^ LastButtonB1) {if (buttonB1){keyPressedB1();} else {keyReleasedB1();};};
ekelmans 0:acabda48796c 247 if (buttonB2 ^ LastButtonB2) {if (buttonB2){keyPressedB2();} else {keyReleasedB2();};};
ekelmans 0:acabda48796c 248 if (buttonB3 ^ LastButtonB3) {if (buttonB3){keyPressedB3();} else {keyReleasedB3();};};
ekelmans 0:acabda48796c 249 if (buttonB4 ^ LastButtonB4) {if (buttonB4){keyPressedB4();} else {keyReleasedB4();};};
ekelmans 0:acabda48796c 250 if (buttonC1 ^ LastButtonC1) {if (buttonC1){keyPressedC1();} else {keyReleasedC1();};};
ekelmans 0:acabda48796c 251 if (buttonC2 ^ LastButtonC2) {if (buttonC2){keyPressedC2();} else {keyReleasedC2();};};
ekelmans 0:acabda48796c 252 if (buttonC3 ^ LastButtonC3) {if (buttonC3){keyPressedC3();} else {keyReleasedC3();};};
ekelmans 0:acabda48796c 253 if (buttonC4 ^ LastButtonC4) {if (buttonC4){keyPressedC4();} else {keyReleasedC4();};};
ekelmans 0:acabda48796c 254 if (buttonD1 ^ LastButtonD1) {if (buttonD1){keyPressedD1();} else {keyReleasedD1();};};
ekelmans 0:acabda48796c 255 if (buttonD2 ^ LastButtonD2) {if (buttonD2){keyPressedD2();} else {keyReleasedD2();};};
ekelmans 0:acabda48796c 256
ekelmans 0:acabda48796c 257 // Update bank B Leds (Toggle switches)
ekelmans 0:acabda48796c 258 ledH1 = buttonB1.read();
ekelmans 0:acabda48796c 259 ledH2 = buttonB2.read();
ekelmans 0:acabda48796c 260 ledH3 = buttonB3.read();
ekelmans 0:acabda48796c 261 ledH4 = buttonB4.read();
ekelmans 0:acabda48796c 262
ekelmans 0:acabda48796c 263 SampleCnt ++;
ekelmans 0:acabda48796c 264
ekelmans 0:acabda48796c 265 //Kill Beep
ekelmans 0:acabda48796c 266 if (SampleCnt > KillBeepAt) {Beep = OFF;}
ekelmans 0:acabda48796c 267
ekelmans 0:acabda48796c 268 //Overflow protection
ekelmans 0:acabda48796c 269 if (SampleCnt >= 4000000000) {TimerOverflowRecover();};
ekelmans 0:acabda48796c 270 }
ekelmans 0:acabda48796c 271
ekelmans 0:acabda48796c 272
ekelmans 0:acabda48796c 273
ekelmans 0:acabda48796c 274 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 275 // Main loop
ekelmans 0:acabda48796c 276 //-------------------------------------------------------------------------------------------------------
ekelmans 0:acabda48796c 277 int main() {
ekelmans 0:acabda48796c 278
ekelmans 0:acabda48796c 279 //Init Serial LCD
ekelmans 0:acabda48796c 280 lcd.baud(115200);
ekelmans 0:acabda48796c 281 lcd.printf("%c", CLS);
ekelmans 0:acabda48796c 282
ekelmans 0:acabda48796c 283 //Init USB COM port for VT100
ekelmans 0:acabda48796c 284 usbUART.baud(115200);
ekelmans 0:acabda48796c 285
ekelmans 0:acabda48796c 286 //VT100 clear screen (ESC[2J) , move cursor (ESC[1;1H) to Row 1, Col 1
ekelmans 0:acabda48796c 287 usbUART.printf("%c[2J%c[1;1H", ESC , ESC );
ekelmans 0:acabda48796c 288
ekelmans 0:acabda48796c 289 InitButtons();
ekelmans 0:acabda48796c 290
ekelmans 0:acabda48796c 291 // The timer for debouncing interval: 10 ms sample time
ekelmans 0:acabda48796c 292 DebounceTimer.attach(&DebounceTick, SampleInterval);
ekelmans 0:acabda48796c 293
ekelmans 0:acabda48796c 294 //Sound a beep for 500 Ms
ekelmans 0:acabda48796c 295 Beep = ON;
ekelmans 0:acabda48796c 296 KillBeepAt = SampleCnt + 50;
ekelmans 0:acabda48796c 297
ekelmans 0:acabda48796c 298
ekelmans 0:acabda48796c 299 PollCount1 = 0;
ekelmans 0:acabda48796c 300 while (1) {
ekelmans 0:acabda48796c 301
ekelmans 0:acabda48796c 302 PollCount1 ++;
ekelmans 0:acabda48796c 303
ekelmans 0:acabda48796c 304 //Update terminal every 500000'th pass
ekelmans 0:acabda48796c 305 if ( PollCount1 % 500000 == 0 ) {
ekelmans 0:acabda48796c 306
ekelmans 0:acabda48796c 307 PollCount1 = 0;
ekelmans 0:acabda48796c 308 PollCount2 ++;
ekelmans 0:acabda48796c 309
ekelmans 0:acabda48796c 310 //Send to VT100 terminal emulator on the PC USB COM port
ekelmans 0:acabda48796c 311 //And because i think scrolling screens are annoying, i added cursor control codes below
ekelmans 0:acabda48796c 312 //VT100 move cursor (ESC[1;1H) to Row 1, Col 1
ekelmans 0:acabda48796c 313 usbUART.printf("%c[1;1H", ESC );
ekelmans 0:acabda48796c 314 usbUART.printf("A%i%i%i%i ",buttonA1.read(),buttonA2.read(),buttonA3.read(),buttonA4.read());
ekelmans 0:acabda48796c 315 usbUART.printf("B%i%i%i%i ",buttonB1.read(),buttonB2.read(),buttonB3.read(),buttonB4.read());
ekelmans 0:acabda48796c 316 usbUART.printf("C%i%i%i%i ",buttonC1.read(),buttonC2.read(),buttonC3.read(),buttonC4.read());
ekelmans 0:acabda48796c 317 usbUART.printf("D%i%i @ %ld, %ld bounces",buttonD1.read(),buttonD2.read(), PollCount2, DebounceActivationCounter);
ekelmans 0:acabda48796c 318
ekelmans 0:acabda48796c 319 }
ekelmans 0:acabda48796c 320
ekelmans 0:acabda48796c 321 }
ekelmans 0:acabda48796c 322 }