Update example to support LilyGo LoRa series
This commit is contained in:
parent
617f77cca4
commit
4afcbe6ec6
276 changed files with 44743 additions and 767 deletions
218
libdeps/AceButton/examples/AutoBenchmark/AutoBenchmark.ino
Normal file
218
libdeps/AceButton/examples/AutoBenchmark/AutoBenchmark.ino
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* A program that prints out the time (min/avg/max) taken by the
|
||||
* AceButton::check() method.
|
||||
*/
|
||||
|
||||
#include <AceButton.h>
|
||||
#include "ProfilingButtonConfig.h"
|
||||
using namespace ace_button;
|
||||
|
||||
// The pin number attached to the button.
|
||||
const int BUTTON_PIN = 2;
|
||||
|
||||
ProfilingButtonConfig buttonConfig;
|
||||
|
||||
// One button wired using the ProfilingButtonConfig.
|
||||
AceButton button(&buttonConfig);
|
||||
|
||||
const unsigned long STATS_PRINT_INTERVAL = 2000;
|
||||
unsigned long lastStatsPrintedTime;
|
||||
TimingStats stats;
|
||||
|
||||
const uint8_t LOOP_MODE_START = 0;
|
||||
const uint8_t LOOP_MODE_IDLE = 1;
|
||||
const uint8_t LOOP_MODE_PRESS_RELEASE = 2;
|
||||
const uint8_t LOOP_MODE_CLICK = 3;
|
||||
const uint8_t LOOP_MODE_DOUBLE_CLICK = 4;
|
||||
const uint8_t LOOP_MODE_LONG_PRESS = 5;
|
||||
const uint8_t LOOP_MODE_END = 6;
|
||||
uint8_t loopMode;
|
||||
uint8_t loopEventType;
|
||||
|
||||
void handleEvent(AceButton*, uint8_t, uint8_t);
|
||||
|
||||
void setup() {
|
||||
delay(1000); // some microcontrollers reboot twice
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // for Leonardo/Micro
|
||||
Serial.println(F("setup(): begin"));
|
||||
|
||||
// Button uses the built-in pull up register.
|
||||
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
||||
button.init(BUTTON_PIN);
|
||||
|
||||
// Configure the ButtonConfig with the event handler, and enable all higher
|
||||
// level events.
|
||||
buttonConfig.setEventHandler(handleEvent);
|
||||
buttonConfig.setFeature(ButtonConfig::kFeatureClick);
|
||||
buttonConfig.setFeature(ButtonConfig::kFeatureDoubleClick);
|
||||
buttonConfig.setFeature(ButtonConfig::kFeatureLongPress);
|
||||
buttonConfig.setFeature(ButtonConfig::kFeatureRepeatPress);
|
||||
buttonConfig.setFeature(ButtonConfig::kFeatureSuppressAll);
|
||||
buttonConfig.setTimingStats(&stats);
|
||||
|
||||
lastStatsPrintedTime = millis();
|
||||
loopMode = LOOP_MODE_START;
|
||||
loopEventType = AceButton::kEventPressed;
|
||||
|
||||
Serial.println(F("setup(): end"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(1); // Decrease sampling frequency to about 1000 Hz
|
||||
button.check();
|
||||
|
||||
switch (loopMode) {
|
||||
case LOOP_MODE_START:
|
||||
loopStart();
|
||||
break;
|
||||
case LOOP_MODE_IDLE:
|
||||
loopIdle();
|
||||
break;
|
||||
case LOOP_MODE_PRESS_RELEASE:
|
||||
loopPressRelease();
|
||||
break;
|
||||
case LOOP_MODE_CLICK:
|
||||
loopClick();
|
||||
break;
|
||||
case LOOP_MODE_DOUBLE_CLICK:
|
||||
loopDoubleClick();
|
||||
break;
|
||||
case LOOP_MODE_LONG_PRESS:
|
||||
loopLongPress();
|
||||
break;
|
||||
case LOOP_MODE_END:
|
||||
loopEnd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void loopStart() {
|
||||
static unsigned long start = millis();
|
||||
|
||||
// Wait one iteration for things to cool down.
|
||||
if (millis() - start > STATS_PRINT_INTERVAL) {
|
||||
Serial.println(F("------------------------+-------------+---------+"));
|
||||
Serial.println(F("button event | min/avg/max | samples |"));
|
||||
Serial.println(F("------------------------+-------------+---------+"));
|
||||
nextMode();
|
||||
}
|
||||
}
|
||||
|
||||
void loopEnd() {
|
||||
Serial.println(F("------------------------+-------------+---------+"));
|
||||
nextMode();
|
||||
}
|
||||
|
||||
void loopIdle() {
|
||||
static unsigned long start = millis();
|
||||
|
||||
if (millis() - start > STATS_PRINT_INTERVAL) {
|
||||
Serial.print(F("idle | "));
|
||||
printStats();
|
||||
Serial.println(F(" |"));
|
||||
nextMode();
|
||||
}
|
||||
}
|
||||
|
||||
void loopPressRelease() {
|
||||
static unsigned long start = millis();
|
||||
|
||||
unsigned long now = millis();
|
||||
unsigned long elapsed = now - start;
|
||||
if (100 <= elapsed && elapsed < 1000) buttonConfig.setButtonState(LOW);
|
||||
if (1000 <= elapsed) buttonConfig.setButtonState(HIGH);
|
||||
|
||||
if (millis() - start > STATS_PRINT_INTERVAL) {
|
||||
if (loopEventType == AceButton::kEventReleased) {
|
||||
Serial.print(F("press/release | "));
|
||||
printStats();
|
||||
Serial.println(F(" |"));
|
||||
}
|
||||
nextMode();
|
||||
}
|
||||
}
|
||||
|
||||
void loopClick() {
|
||||
static unsigned long start = millis();
|
||||
|
||||
unsigned long now = millis();
|
||||
unsigned long elapsed = now - start;
|
||||
if (100 <= elapsed && elapsed < 200) buttonConfig.setButtonState(LOW);
|
||||
if (200 <= elapsed) buttonConfig.setButtonState(HIGH);
|
||||
|
||||
if (millis() - start > STATS_PRINT_INTERVAL) {
|
||||
if (loopEventType == AceButton::kEventClicked) {
|
||||
Serial.print(F("click | "));
|
||||
printStats();
|
||||
Serial.println(F(" |"));
|
||||
}
|
||||
nextMode();
|
||||
}
|
||||
}
|
||||
|
||||
void loopDoubleClick() {
|
||||
static unsigned long start = millis();
|
||||
|
||||
unsigned long now = millis();
|
||||
unsigned long elapsed = now - start;
|
||||
if (100 <= elapsed && elapsed < 200) buttonConfig.setButtonState(LOW);
|
||||
if (200 <= elapsed && elapsed < 300) buttonConfig.setButtonState(HIGH);
|
||||
if (300 <= elapsed && elapsed < 400) buttonConfig.setButtonState(LOW);
|
||||
if (400 <= elapsed) buttonConfig.setButtonState(HIGH);
|
||||
|
||||
if (millis() - start > STATS_PRINT_INTERVAL) {
|
||||
if (loopEventType == AceButton::kEventDoubleClicked) {
|
||||
Serial.print(F("double click | "));
|
||||
printStats();
|
||||
Serial.println(F(" |"));
|
||||
}
|
||||
nextMode();
|
||||
}
|
||||
}
|
||||
|
||||
void loopLongPress() {
|
||||
static unsigned long start = millis();
|
||||
|
||||
unsigned long now = millis();
|
||||
unsigned long elapsed = now - start;
|
||||
if (100 <= elapsed) buttonConfig.setButtonState(LOW);
|
||||
|
||||
if (millis() - start > STATS_PRINT_INTERVAL) {
|
||||
if (loopEventType == AceButton::kEventRepeatPressed) {
|
||||
Serial.print(F("long press/repeat press | "));
|
||||
printStats();
|
||||
Serial.println(F(" |"));
|
||||
}
|
||||
nextMode();
|
||||
}
|
||||
}
|
||||
|
||||
void nextMode() {
|
||||
stats.reset();
|
||||
buttonConfig.setButtonState(HIGH);
|
||||
loopMode++;
|
||||
}
|
||||
|
||||
void printStats() {
|
||||
printInt(stats.getMin());
|
||||
Serial.print('/');
|
||||
printInt(stats.getAvg());
|
||||
Serial.print('/');
|
||||
printInt(stats.getMax());
|
||||
Serial.print(F(" | "));
|
||||
printInt(stats.getCount());
|
||||
}
|
||||
|
||||
// print integer within 3 characters, padded on left with spaces
|
||||
void printInt(uint16_t i) {
|
||||
if (i < 100) Serial.print(' ');
|
||||
if (i < 10) Serial.print(' ');
|
||||
Serial.print(i);
|
||||
}
|
||||
|
||||
// An empty event handler.
|
||||
void handleEvent(AceButton* /* button */, uint8_t eventType,
|
||||
uint8_t /* buttonState */) {
|
||||
loopEventType = eventType;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef PROFILING_BUTTON_CONFIG_H
|
||||
#define PROFILING_BUTTON_CONFIG_H
|
||||
|
||||
#include <Arduino.h> // LOW, HIGH
|
||||
#include <ButtonConfig.h>
|
||||
|
||||
namespace ace_button {
|
||||
|
||||
/**
|
||||
* A subclass of ButtonConfig which overrides readButton() so that the
|
||||
* AutoBenchmark sketch can inject button clicks into the AceButton::check()
|
||||
* loop, which we can use to collect timing stats.
|
||||
*/
|
||||
class ProfilingButtonConfig: public ButtonConfig {
|
||||
public:
|
||||
ProfilingButtonConfig():
|
||||
mButtonState(HIGH) {}
|
||||
|
||||
void init() override {
|
||||
ButtonConfig::init();
|
||||
mButtonState = HIGH;
|
||||
}
|
||||
|
||||
int readButton(uint8_t /* pin */) override { return mButtonState; }
|
||||
|
||||
/** Set the state of the fake physical button. */
|
||||
void setButtonState(int buttonState) { mButtonState = buttonState; }
|
||||
|
||||
private:
|
||||
// Disable copy-constructor and assignment operator
|
||||
ProfilingButtonConfig(const ProfilingButtonConfig&) = delete;
|
||||
ProfilingButtonConfig& operator=(const ProfilingButtonConfig&) = delete;
|
||||
|
||||
int mButtonState;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
111
libdeps/AceButton/examples/AutoBenchmark/README.md
Normal file
111
libdeps/AceButton/examples/AutoBenchmark/README.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# AutoBenchmark
|
||||
|
||||
This sketch measures the amount of time consumed by the `AceButton::check()`
|
||||
method when processing various button events. It uses a special
|
||||
`ProfilingButtonConfig` object that allows the program to inject button events
|
||||
into the library. The profiling numbers come from activating the `TimingStats`
|
||||
object that has been instrumented into the `AceButton::check()` method.
|
||||
|
||||
Note that `ProfilingButtonConfig` class generates synthetic button events,
|
||||
bypassing the actual `digitalRead()` function. The `digitalRead()` function on
|
||||
an Arduino AVR platform (UNO, Nano, etc) is
|
||||
[known to be slow](https://forum.arduino.cc/index.php?topic=337578)
|
||||
which will add to the timing values in actual usage.
|
||||
The [digitalWriteFast library](https://github.com/NicksonYap/digitalWriteFast)
|
||||
might be an alternative if speed is critical.
|
||||
|
||||
## Benchmark Results
|
||||
|
||||
In all of the tests, the **min** time for the "idle" case is larger than any of
|
||||
the other button events. This is because when a button event occurs, the
|
||||
`AceButton::checkDebounced()` method returns immediately until the debouncing
|
||||
time is over which brings down the minimum time. No debouncing is done in the
|
||||
"idle" case so the minimum code path takes more CPU cycles.
|
||||
|
||||
All times are in microseconds. The "samples" column is the number of
|
||||
`TimingStats::update()` calls that were made.
|
||||
|
||||
### Arduino Nano
|
||||
|
||||
* 16MHz ATmega328P
|
||||
|
||||
```
|
||||
------------------------+-------------+---------+
|
||||
button event | min/avg/max | samples |
|
||||
------------------------+-------------+---------+
|
||||
idle | 12/ 13/ 20 | 1934 |
|
||||
press/release | 8/ 14/ 20 | 1925 |
|
||||
click | 8/ 14/ 24 | 1925 |
|
||||
double click | 8/ 13/ 24 | 1925 |
|
||||
long press/repeat press | 8/ 15/ 24 | 1927 |
|
||||
------------------------+-------------+---------+
|
||||
```
|
||||
|
||||
### Arduino Pro Micro
|
||||
|
||||
* 16MHz ATmega32U4
|
||||
|
||||
```
|
||||
------------------------+-------------+---------+
|
||||
button event | min/avg/max | samples |
|
||||
------------------------+-------------+---------+
|
||||
idle | 12/ 13/ 24 | 1935 |
|
||||
press/release | 8/ 14/ 24 | 1928 |
|
||||
click | 8/ 13/ 24 | 1928 |
|
||||
double click | 8/ 13/ 24 | 1926 |
|
||||
long press/repeat press | 8/ 15/ 28 | 1928 |
|
||||
------------------------+-------------+---------+
|
||||
```
|
||||
|
||||
### Teensy 3.2
|
||||
|
||||
* 96 MHz ARM Cortex-M4
|
||||
|
||||
```
|
||||
------------------------+-------------+---------+
|
||||
button event | min/avg/max | samples |
|
||||
------------------------+-------------+---------+
|
||||
idle | 3/ 3/ 5 | 1985 |
|
||||
press/release | 1/ 3/ 6 | 1983 |
|
||||
click | 1/ 3/ 6 | 1984 |
|
||||
double click | 1/ 3/ 6 | 1984 |
|
||||
long press/repeat press | 1/ 3/ 6 | 1983 |
|
||||
------------------------+-------------+---------+
|
||||
```
|
||||
|
||||
### NodeMCU 1.0 clone
|
||||
|
||||
* 80MHz ESP8266
|
||||
|
||||
```
|
||||
------------------------+-------------+---------+
|
||||
button event | min/avg/max | samples |
|
||||
------------------------+-------------+---------+
|
||||
idle | 7/ 8/ 24 | 1922 |
|
||||
press/release | 6/ 8/ 53 | 1919 |
|
||||
click | 6/ 8/ 50 | 1920 |
|
||||
double click | 6/ 8/ 67 | 1910 |
|
||||
long press/repeat press | 6/ 9/ 60 | 1894 |
|
||||
------------------------+-------------+---------+
|
||||
```
|
||||
|
||||
The large **max** times for "double click" and "long press" seem to be
|
||||
reproducible. I have not researched this but my speculation is that the system
|
||||
WiFi code interrupts the `AceButton::check()` method right when the "double
|
||||
click" and "long press" samples are taken, causing the extra latency.
|
||||
|
||||
### ESP32-01 Dev Board
|
||||
|
||||
* 240 MHz Tensilica LX6
|
||||
|
||||
```
|
||||
------------------------+-------------+---------+
|
||||
button event | min/avg/max | samples |
|
||||
------------------------+-------------+---------+
|
||||
idle | 3/ 3/ 3 | 2002 |
|
||||
press/release | 2/ 2/ 8 | 2002 |
|
||||
click | 2/ 2/ 7 | 2002 |
|
||||
double click | 2/ 2/ 4 | 2002 |
|
||||
long press/repeat press | 2/ 2/ 4 | 2002 |
|
||||
------------------------+-------------+---------+
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue