acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
Stopwatch.ino (5413B)
1 /* 2 * A demo app that calculates the ammount of time taken by the 3 * AceButton::check() method. It acts like a stopwatch, supporting the following 4 * operations: 5 * 6 * - press: start the stopwatch 7 * - press: stop the stopwatch, printing out the result 8 * - long press: reset the stopwatch, allowing press to start the process again 9 * 10 * Each 'long press' alternates between enableAllEvents() and disableAllEvents() 11 * so that we can compare the timing of check() when all events are off (except 12 * Pressed and Released) and when all events are on. 13 */ 14 15 #include <AceButton.h> 16 17 using namespace ace_button; 18 19 // The pin number attached to the button. 20 const uint8_t BUTTON_PIN = 2; 21 22 // Create one button. 23 AceButton button; 24 25 // counters to determine the duration of a single call to AceButton::check() 26 uint16_t innerLoopCounter = 0; 27 uint16_t outerLoopCounter = 0; 28 unsigned long startMillis = 0; 29 unsigned long stopMillis = 0; 30 31 // states of the stopwatch 32 const uint8_t STOPWATCH_INIT = 0; 33 const uint8_t STOPWATCH_STARTED = 1; 34 const uint8_t STOPWATCH_STOPPED = 2; 35 36 // implements a finite state machine (FSM) 37 uint8_t stopwatchState = STOPWATCH_INIT; 38 39 bool allEventsEnabled = false; 40 41 void handleEvent(AceButton*, uint8_t, uint8_t); 42 43 void setup() { 44 delay(1000); // some boards reboot twice 45 Serial.begin(115200); 46 while (! Serial); // Wait until Serial is ready - Leonardo/Micro 47 Serial.println(F("setup(): begin")); 48 49 // Button uses the built-in pull up register. 50 pinMode(BUTTON_PIN, INPUT_PULLUP); 51 button.init(BUTTON_PIN); 52 53 // Configure the ButtonConfig with the event handler and enable LongPress. 54 // SupressAfterLongPress is optional since we don't do anything if we get it. 55 ButtonConfig* buttonConfig = button.getButtonConfig(); 56 buttonConfig->setEventHandler(handleEvent); 57 buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); 58 buttonConfig->setLongPressDelay(2000); 59 60 Serial.println(F("setup(): stopwatch ready")); 61 } 62 63 void loop() { 64 // We split the loop into an inner loop and an outer loop. The inner loop 65 // allows us to measure the speed of button.check() without the overhead of 66 // the outer loop. However, we must allow the outer loop() method to return 67 // periodically to allow the microcontroller to its own stuff. This is 68 // especially true on an ESP8266 board, where a Watch Dog Timer will 69 // soft-reset the board if loop() doesn't return every few seconds. 70 do { 71 // button.check() Should be called every 20ms or faster for the default 72 // debouncing time of ~50ms. 73 button.check(); 74 75 // increment loop counter 76 if (stopwatchState == STOPWATCH_STARTED) { 77 innerLoopCounter++; 78 } 79 } while (innerLoopCounter); 80 81 // Each time the innerLoopCounter rolls over (65536), increment the outer loop 82 // counter, and return from loop(), to prevent WDT errors on ESP8266. 83 outerLoopCounter++; 84 } 85 86 // The event handler for the button. 87 void handleEvent(AceButton* /* button */, uint8_t eventType, 88 uint8_t /* buttonState */) { 89 unsigned long now = millis(); 90 switch (eventType) { 91 case AceButton::kEventPressed: 92 if (stopwatchState == STOPWATCH_INIT) { 93 94 // enable or disable higher level events, to get different performance 95 // numbers 96 if (allEventsEnabled) { 97 enableAllEvents(); 98 } else { 99 disableAllEvents(); 100 } 101 102 Serial.println(F("handleEvent(): stopwatch started")); 103 startMillis = now; 104 innerLoopCounter = 0; 105 outerLoopCounter = 0; 106 stopwatchState = STOPWATCH_STARTED; 107 } else if (stopwatchState == STOPWATCH_STARTED) { 108 stopMillis = now; 109 stopwatchState = STOPWATCH_STOPPED; 110 unsigned long duration = stopMillis - startMillis; 111 uint32_t loopCounter = ((uint32_t) outerLoopCounter << 16) + 112 innerLoopCounter; 113 float microsPerLoop = duration * 1000.0f / loopCounter; 114 115 // reenable all events after stopping 116 enableAllEvents(); 117 118 Serial.println(F("handleEvent(): stopwatch stopped")); 119 Serial.print(F("handleEvent(): duration (ms): ")); 120 Serial.print(duration); 121 Serial.print(F("; loopCount: ")); 122 Serial.print(loopCounter); 123 Serial.print(F("; micros/loop: ")); 124 Serial.println(microsPerLoop); 125 126 // Setting 0 allows the loop() function to return periodically. 127 innerLoopCounter = 0; 128 } 129 break; 130 case AceButton::kEventLongPressed: 131 if (stopwatchState == STOPWATCH_STOPPED) { 132 stopwatchState = STOPWATCH_INIT; 133 Serial.println(F("handleEvent(): stopwatch reset")); 134 allEventsEnabled = !allEventsEnabled; 135 } 136 break; 137 } 138 } 139 140 void enableAllEvents() { 141 Serial.println(F("enabling high level events")); 142 button.getButtonConfig()->setFeature(ButtonConfig::kFeatureClick); 143 button.getButtonConfig()->setFeature(ButtonConfig::kFeatureDoubleClick); 144 button.getButtonConfig()->setFeature(ButtonConfig::kFeatureLongPress); 145 button.getButtonConfig()->setFeature(ButtonConfig::kFeatureRepeatPress); 146 } 147 148 void disableAllEvents() { 149 Serial.println(F("disabling high level events")); 150 button.getButtonConfig()->clearFeature(ButtonConfig::kFeatureClick); 151 button.getButtonConfig()->clearFeature(ButtonConfig::kFeatureDoubleClick); 152 button.getButtonConfig()->clearFeature(ButtonConfig::kFeatureLongPress); 153 button.getButtonConfig()->clearFeature(ButtonConfig::kFeatureRepeatPress); 154 }