Stap 4: Korte onderscheiden van lange persen
Veel apparaten met weinig controles (bijv. digitale horloges) pack meerdere functies per knop.
Het is erg handig, besparen kostbare volume, maar moet verstandig worden gebruikt, anders wordt het apparaat kan unintuitive te gebruiken.
Korte onderscheiden van lange persen is over het meten van de lengte van de pols.
De gebeurtenis wordt niet langer uitgezonden op de knop te drukken, maar op los te laten. Dit kan invloed hebben op het gevoel van alertheid. Maar tot niet-causale apparaten kunnen worden gekocht, wij niet voorspellen de duur en moeten daarom verder gaan zo.
Dit is een gecombineerde evenement en staat behandeling: we detecteren de verandering van staat (een gebeurtenis), en de duur dat de resulterende staat is blijvend.
Programmering
Dus moeten we voeren een andere globale variabele (button_pressed_counter). Merk ook op dat de gebeurtenis geen meer een Boole-waarde heeft (gebeurtenis aanwezig of niet, zoals in de vorige stap), maar drie staten. Ze worden gedefinieerd door een enumeratie. (Ik had problemen definiëren een enum-type; Arduino-specifieke kwestie? Dus gebruikte ik enum om constanten definiëren).
De eerste afbeelding van deze stap tonen een lange druk en een korte druk timing, met een lange druk op drempel van 3 bemonstering periodes (dat is veel te kort, maar geschikt is voor de tekening).
De tweede foto toont de uitgang voor seriële voor een lange druk op gevolgd door twee korte persen.
Pro/Cons
Mooi verbetert de functionaliteit van de knop (als verstandig gebruikt, om te verzekeren van de goede usability). Maar de code begint te groeien, en krijgen vervuild door globale variabelen... De volgende stap toont de OO-variant, gemaakt voor schalen.
Code
––––––––––8<––––––––––
#define BUTTON_PIN 2 // Button #define LONGPRESS_LEN 25 // Min nr of loops for a long press #define DELAY 20 // Delay per loop in ms enum { EV_NONE=0, EV_SHORTPRESS, EV_LONGPRESS }; boolean button_was_pressed; // previous state int button_pressed_counter; // press running duration void setup() { pinMode(BUTTON_PIN, INPUT); digitalWrite(BUTTON_PIN, HIGH); // pull-up Serial.begin(9600); button_was_pressed = false; button_pressed_counter = 0; } int handle_button() { int event; int button_now_pressed = !digitalRead(BUTTON_PIN); // pin low -> pressed if (!button_now_pressed && button_was_pressed) { if (button_pressed_counter < LONGPRESS_LEN) event = EV_SHORTPRESS; else event = EV_LONGPRESS; } else event = EV_NONE; if (button_now_pressed) ++button_pressed_counter; else button_pressed_counter = 0; button_was_pressed = button_now_pressed; return event; } void loop() { // handle button boolean event = handle_button(); // do other things switch (event) { case EV_NONE: Serial.print("."); break; case EV_SHORTPRESS: Serial.print("S"); break; case EV_LONGPRESS: Serial.print("L"); break; } // add newline sometimes static int counter = 0; if ((++counter & 0x3f) == 0) Serial.println(); delay(DELAY); }
––––––––––>8––––––––––