36 |
37 |
38 |
--------------------------------------------------------------------------------
/examples/AutoBenchmark/Makefile:
--------------------------------------------------------------------------------
1 | # See https://github.com/bxparks/EpoxyDuino for documentation about using
2 | # EpoxyDuino to compile and run AUnit tests natively on Linux or MacOS.
3 |
4 | APP_NAME := AutoBenchmark
5 | ARDUINO_LIBS := EpoxyMockDigitalWriteFast AceCommon AceButton
6 | MORE_CLEAN := more_clean
7 | include ../../../EpoxyDuino/EpoxyDuino.mk
8 |
9 | .PHONY: benchmarks
10 |
11 | AUNITER_DIR := ../../../AUniter/tools
12 |
13 | TARGETS := nano.txt micro.txt samd21.txt stm32.txt samd51.txt \
14 | esp8266.txt esp32.txt
15 |
16 | README.md: generate_readme.py generate_table.awk $(TARGETS)
17 | ./generate_readme.py > $@
18 |
19 | benchmarks: $(TARGETS)
20 |
21 | # The USB/ACM ports can change dynamically. Make sure that the microcontroller
22 | # is on the correct port before using these Make targets.
23 | nano.txt:
24 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END nano:USB0
25 |
26 | micro.txt:
27 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END micro:ACM0
28 |
29 | samd21.txt:
30 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END xiao:ACM0
31 |
32 | stm32.txt:
33 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END stm32:ACM0
34 |
35 | # ItsyBitsy M4 appears on /dev/ttyACM0 when powered on, then disappears after
36 | # flashing, and reappears on /dev/ttyACM1. Specifying the ports as "ACM*" tells
37 | # auniter.sh to use any port satisfying the glob pattern.
38 | samd51.txt:
39 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END 'itsym4:ACM*'
40 |
41 | esp8266.txt:
42 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END nodemcu:USB0
43 |
44 | esp32.txt:
45 | $(AUNITER_DIR)/auniter.sh --cli upmon -o $@ --eof END esp32:USB0
46 |
47 | more_clean:
48 | echo "Use 'make clean_benchmarks' to remove *.txt files"
49 |
50 | clean_benchmarks:
51 | rm -f $(TARGETS)
52 |
--------------------------------------------------------------------------------
/src/ace_button/IEventHandler.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #ifndef ACE_BUTTON_IEVENT_HANDLER_H
26 | #define ACE_BUTTON_IEVENT_HANDLER_H
27 |
28 | #include
29 |
30 | namespace ace_button {
31 |
32 | class AceButton;
33 |
34 | /**
35 | * Interface of the class that will handle the button event. Users can create an
36 | * implementation subclass and register the event handler object using
37 | * ButtonConfig::setIEventHandler().
38 | */
39 | class IEventHandler {
40 | public:
41 | /** Handle the button event. */
42 | virtual void handleEvent(AceButton* button, uint8_t eventType,
43 | uint8_t buttonState) = 0;
44 | };
45 |
46 | }
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/docs/html/classace__button_1_1ButtonConfig__inherit__graph.map:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/docs/html/inherit_graph_1.map:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/docs/html/search/all_c.js:
--------------------------------------------------------------------------------
1 | var searchData=
2 | [
3 | ['setbuttonconfig_71',['setButtonConfig',['../classace__button_1_1AceButton.html#a04b7e1d44e41481d2c36501262e35a04',1,'ace_button::AceButton']]],
4 | ['setclickdelay_72',['setClickDelay',['../classace__button_1_1ButtonConfig.html#aef65e12128997c46bc2754a988b98f14',1,'ace_button::ButtonConfig']]],
5 | ['setdebouncedelay_73',['setDebounceDelay',['../classace__button_1_1ButtonConfig.html#a9860d2c8a6ab33d40ea126b02d168cab',1,'ace_button::ButtonConfig']]],
6 | ['setdoubleclickdelay_74',['setDoubleClickDelay',['../classace__button_1_1ButtonConfig.html#a367a809017e1d633a5cf6b117981d579',1,'ace_button::ButtonConfig']]],
7 | ['seteventhandler_75',['setEventHandler',['../classace__button_1_1AceButton.html#a7769fa58769bc4cf0a0ea9c68072d4de',1,'ace_button::AceButton::setEventHandler()'],['../classace__button_1_1ButtonConfig.html#af916ea5ae0194afeac3a6fd6e25a13d1',1,'ace_button::ButtonConfig::setEventHandler(EventHandler eventHandler)']]],
8 | ['setfeature_76',['setFeature',['../classace__button_1_1ButtonConfig.html#adf3a103f188bb8e669c77ab852553e9a',1,'ace_button::ButtonConfig']]],
9 | ['setheartbeatinterval_77',['setHeartBeatInterval',['../classace__button_1_1ButtonConfig.html#a0c21a9b859c82c78581b340f2de864d5',1,'ace_button::ButtonConfig']]],
10 | ['setieventhandler_78',['setIEventHandler',['../classace__button_1_1ButtonConfig.html#a6fda9545052a13d64b383d11ceea5806',1,'ace_button::ButtonConfig']]],
11 | ['setlongpressdelay_79',['setLongPressDelay',['../classace__button_1_1ButtonConfig.html#a7d90d39aeddacb5abc9d8741611d7c4a',1,'ace_button::ButtonConfig']]],
12 | ['setrepeatpressdelay_80',['setRepeatPressDelay',['../classace__button_1_1ButtonConfig.html#af813c969eddd884e9fa83b334a59a0a5',1,'ace_button::ButtonConfig']]],
13 | ['setrepeatpressinterval_81',['setRepeatPressInterval',['../classace__button_1_1ButtonConfig.html#aa1b1217e0042512fc8d9b6544536aed3',1,'ace_button::ButtonConfig']]]
14 | ];
15 |
--------------------------------------------------------------------------------
/src/ace_button/fast/ButtonConfigFast1.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2021 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #ifndef ACE_BUTTON_BUTTON_CONFIG_FAST1_H
26 | #define ACE_BUTTON_BUTTON_CONFIG_FAST1_H
27 |
28 | #include "../ButtonConfig.h"
29 |
30 | namespace ace_button {
31 |
32 | /**
33 | * An implementation of ButtonConfig that uses digitalReadFast() instead of
34 | * digitalRead() to support 1 button. The primary motivation for using
35 | * digitalReadFast() in this library is the reduction of flash memory, not the
36 | * improvement in performance.
37 | *
38 | * @tparam T_PIN0 physical pin used by button 0
39 | */
40 | template
41 | class ButtonConfigFast1 : public ButtonConfig {
42 | public:
43 | int readButton(uint8_t /*pin*/) override {
44 | return digitalReadFast(T_PIN0);
45 | }
46 | };
47 |
48 | }
49 | #endif
50 |
--------------------------------------------------------------------------------
/docs/html/search/functions_a.js:
--------------------------------------------------------------------------------
1 | var searchData=
2 | [
3 | ['setbuttonconfig_129',['setButtonConfig',['../classace__button_1_1AceButton.html#a04b7e1d44e41481d2c36501262e35a04',1,'ace_button::AceButton']]],
4 | ['setclickdelay_130',['setClickDelay',['../classace__button_1_1ButtonConfig.html#aef65e12128997c46bc2754a988b98f14',1,'ace_button::ButtonConfig']]],
5 | ['setdebouncedelay_131',['setDebounceDelay',['../classace__button_1_1ButtonConfig.html#a9860d2c8a6ab33d40ea126b02d168cab',1,'ace_button::ButtonConfig']]],
6 | ['setdoubleclickdelay_132',['setDoubleClickDelay',['../classace__button_1_1ButtonConfig.html#a367a809017e1d633a5cf6b117981d579',1,'ace_button::ButtonConfig']]],
7 | ['seteventhandler_133',['setEventHandler',['../classace__button_1_1AceButton.html#a7769fa58769bc4cf0a0ea9c68072d4de',1,'ace_button::AceButton::setEventHandler()'],['../classace__button_1_1ButtonConfig.html#af916ea5ae0194afeac3a6fd6e25a13d1',1,'ace_button::ButtonConfig::setEventHandler(EventHandler eventHandler)']]],
8 | ['setfeature_134',['setFeature',['../classace__button_1_1ButtonConfig.html#adf3a103f188bb8e669c77ab852553e9a',1,'ace_button::ButtonConfig']]],
9 | ['setheartbeatinterval_135',['setHeartBeatInterval',['../classace__button_1_1ButtonConfig.html#a0c21a9b859c82c78581b340f2de864d5',1,'ace_button::ButtonConfig']]],
10 | ['setieventhandler_136',['setIEventHandler',['../classace__button_1_1ButtonConfig.html#a6fda9545052a13d64b383d11ceea5806',1,'ace_button::ButtonConfig']]],
11 | ['setlongpressdelay_137',['setLongPressDelay',['../classace__button_1_1ButtonConfig.html#a7d90d39aeddacb5abc9d8741611d7c4a',1,'ace_button::ButtonConfig']]],
12 | ['setrepeatpressdelay_138',['setRepeatPressDelay',['../classace__button_1_1ButtonConfig.html#af813c969eddd884e9fa83b334a59a0a5',1,'ace_button::ButtonConfig']]],
13 | ['setrepeatpressinterval_139',['setRepeatPressInterval',['../classace__button_1_1ButtonConfig.html#aa1b1217e0042512fc8d9b6544536aed3',1,'ace_button::ButtonConfig']]]
14 | ];
15 |
--------------------------------------------------------------------------------
/examples/MemoryBenchmark/generate_table.awk:
--------------------------------------------------------------------------------
1 | #!/usr/bin/gawk -f
2 | #
3 | # Usage: generate_table.sh < ${board}.txt
4 | #
5 | # Takes the file generated by collect.sh and generates an ASCII
6 | # table that can be inserted into the README.md.
7 |
8 | BEGIN {
9 | labels[0] = "Baseline"
10 | labels[1] = "Baseline+pinMode+digitalRead"
11 | labels[2] = "ButtonConfig"
12 | labels[3] = "ButtonConfigFast1"
13 | labels[4] = "ButtonConfigFast2"
14 | labels[5] = "ButtonConfigFast3"
15 | labels[6] = "Encoded4To2ButtonConfig"
16 | labels[7] = "Encoded8To3ButtonConfig"
17 | labels[8] = "EncodedButtonConfig"
18 | labels[9] = "LadderButtonConfig"
19 | record_index = 0
20 | }
21 | {
22 | u[record_index]["flash"] = $2
23 | u[record_index]["ram"] = $4
24 | record_index++
25 | }
26 | END {
27 | NUM_ENTRIES = record_index
28 |
29 | base_flash = u[0]["flash"]
30 | base_ram = u[0]["ram"]
31 | for (i = 0; i < NUM_ENTRIES; i++) {
32 | if (u[i]["flash"] != "-1") {
33 | u[i]["d_flash"] = u[i]["flash"] - base_flash
34 | u[i]["d_ram"] = u[i]["ram"] - base_ram
35 | } else {
36 | u[i]["d_flash"] = -1
37 | u[i]["d_ram"] = -1
38 | }
39 | }
40 |
41 | printf("+--------------------------------------------------------------+\n")
42 | printf("| functionality | flash/ ram | delta |\n")
43 | for (i = 0; i < NUM_ENTRIES; i++) {
44 | if (u[i]["flash"] == "-1") continue
45 |
46 | name = labels[i]
47 | if (name ~ /^Baseline$/ \
48 | || name ~ /^ButtonConfig$/ \
49 | || name ~ /^Encoded4To2ButtonConfig$/ \
50 | || name ~ /^LadderButtonConfig$/) {
51 | printf(\
52 | "|---------------------------------+--------------+-------------|\n")
53 | }
54 | printf("| %-31s | %6d/%5d | %5d/%5d |\n",
55 | name, u[i]["flash"], u[i]["ram"], u[i]["d_flash"], u[i]["d_ram"])
56 | }
57 | printf("+--------------------------------------------------------------+\n")
58 | }
59 |
--------------------------------------------------------------------------------
/src/AceButton.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2018 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | /**
26 | * @mainpage AceButton Library
27 | *
28 | * This is the Doxygen documentation for the
29 | * AceButton Library.
30 | *
31 | * Click on the "Classes" menu above to see the list of classes.
32 | *
33 | * Click on the "Files" menu above to see the list of header files.
34 | */
35 |
36 | #ifndef ACE_BUTTON_H
37 | #define ACE_BUTTON_H
38 |
39 | #include "ace_button/IEventHandler.h"
40 | #include "ace_button/ButtonConfig.h"
41 | #include "ace_button/Encoded8To3ButtonConfig.h"
42 | #include "ace_button/Encoded4To2ButtonConfig.h"
43 | #include "ace_button/EncodedButtonConfig.h"
44 | #include "ace_button/LadderButtonConfig.h"
45 | #include "ace_button/AceButton.h"
46 |
47 | // Version format: xxyyzz == "xx.yy.zz"
48 | #define ACE_BUTTON_VERSION 11001
49 | #define ACE_BUTTON_VERSION_STRING "1.10.1"
50 |
51 | #endif
52 |
--------------------------------------------------------------------------------
/examples/AutoBenchmark/generate_table.awk:
--------------------------------------------------------------------------------
1 | #!/usr/bin/gawk -f
2 | #
3 | # Usage: generate_table.awk < ${board}.txt
4 | #
5 | # Takes the *.txt file generated by AutoBenchmark.ino and generates an ASCII
6 | # table that can be inserted into the README.md. Collects both sizeof()
7 | # information as well as CPU benchmarks.
8 |
9 | BEGIN {
10 | # Set to 1 when 'SIZEOF' is detected
11 | collect_sizeof = 0
12 |
13 | # Set to 1 when 'BENCHMARKS' is detected
14 | collect_benchmarks = 0
15 | }
16 |
17 | /^SIZEOF/ {
18 | collect_sizeof = 1
19 | collect_benchmarks = 0
20 | sizeof_index = 0
21 | next
22 | }
23 |
24 | /^BENCHMARKS/ {
25 | collect_sizeof = 0
26 | collect_benchmarks = 1
27 | benchmark_index = 0
28 | next
29 | }
30 |
31 | !/^END/ {
32 | if (collect_sizeof) {
33 | s[sizeof_index] = $0
34 | sizeof_index++
35 | }
36 | if (collect_benchmarks) {
37 | u[benchmark_index]["name"] = $1
38 | u[benchmark_index]["min"] = $2
39 | u[benchmark_index]["avg"] = $3
40 | u[benchmark_index]["max"] = $4
41 | u[benchmark_index]["samples"] = $5
42 | benchmark_index++
43 | }
44 | }
45 |
46 | END {
47 | TOTAL_BENCHMARKS = benchmark_index
48 | TOTAL_SIZEOF = sizeof_index
49 |
50 | printf("Sizes of Objects:\n")
51 | for (i = 0; i < TOTAL_SIZEOF; i++) {
52 | print s[i]
53 | }
54 |
55 | print ""
56 | print "CPU:"
57 |
58 | printf("+---------------------------+-------------+---------+\n")
59 | printf("| Button Event | min/avg/max | samples |\n")
60 | printf("|---------------------------+-------------+---------|\n")
61 | for (i = 0; i < TOTAL_BENCHMARKS; i++) {
62 | name = u[i]["name"]
63 | if (name ~ /^ButtonConfigFast1/ \
64 | || name ~ /^Encoded4To2ButtonConfig$/) {
65 | printf("|---------------------------+-------------+---------|\n")
66 | }
67 | printf("| %-25s | %3d/%3d/%3d | %7d |\n",
68 | u[i]["name"], u[i]["min"], u[i]["avg"], u[i]["max"], u[i]["samples"])
69 | }
70 | printf("+---------------------------+-------------+---------+\n")
71 | }
72 |
--------------------------------------------------------------------------------
/src/ace_button/fast/ButtonConfigFast2.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2021 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #ifndef ACE_BUTTON_BUTTON_CONFIG_FAST2_H
26 | #define ACE_BUTTON_BUTTON_CONFIG_FAST2_H
27 |
28 | #include "../ButtonConfig.h"
29 |
30 | namespace ace_button {
31 |
32 | /**
33 | * An implementation of ButtonConfig that uses digitalReadFast() instead of
34 | * digitalRead() to support 2 buttons. The primary motivation for using
35 | * digitalReadFast() in this library is the reduction of flash memory, not the
36 | * improvement in performance.
37 | *
38 | * @tparam T_PIN0 physical pin used by button 0
39 | * @tparam T_PIN1 physical pin used by button 1
40 | */
41 | template
42 | class ButtonConfigFast2 : public ButtonConfig {
43 | public:
44 | int readButton(uint8_t pin) override {
45 | // Using nested if-else statements instead of switch saves 2 bytes of
46 | // flash on an AVR. Not worth it.
47 | switch (pin) {
48 | case 0:
49 | return digitalReadFast(T_PIN0);
50 | break;
51 | case 1:
52 | return digitalReadFast(T_PIN1);
53 | break;
54 | default:
55 | return 0;
56 | break;
57 | }
58 | }
59 | };
60 |
61 | }
62 | #endif
63 |
--------------------------------------------------------------------------------
/src/ace_button/fast/ButtonConfigFast3.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2021 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #ifndef ACE_BUTTON_BUTTON_CONFIG_FAST3_H
26 | #define ACE_BUTTON_BUTTON_CONFIG_FAST3_H
27 |
28 | #include "../ButtonConfig.h"
29 |
30 | namespace ace_button {
31 |
32 | /**
33 | * An implementation of ButtonConfig that uses digitalReadFast() instead of
34 | * digitalRead() to support 3 buttons. The primary motivation for using
35 | * digitalReadFast() in this library is the reduction of flash memory, not the
36 | * improvement in performance.
37 | *
38 | * @tparam T_PIN0 physical pin used by button 0
39 | * @tparam T_PIN1 physical pin used by button 1
40 | * @tparam T_PIN2 physical pin used by button 2
41 | */
42 | template
43 | class ButtonConfigFast3 : public ButtonConfig {
44 | public:
45 | int readButton(uint8_t pin) override {
46 | switch (pin) {
47 | case 0:
48 | return digitalReadFast(T_PIN0);
49 | break;
50 | case 1:
51 | return digitalReadFast(T_PIN1);
52 | break;
53 | case 2:
54 | return digitalReadFast(T_PIN2);
55 | break;
56 | default:
57 | return 0;
58 | break;
59 | }
60 | }
61 | };
62 |
63 | }
64 | #endif
65 |
--------------------------------------------------------------------------------
/examples/LadderButtons/README.md:
--------------------------------------------------------------------------------
1 | # Resistor Ladder Buttons
2 |
3 | The `LadderButtons.ino` is a sample code for `LadderButtonConfig` which
4 | supports multiple buttons on a single analog pin. The buttons are distinguished
5 | by using a resistor ladder that sets the voltage to different values. The
6 | voltage can be read using the `analogRead()` function.
7 |
8 | This program demonstrates 4 buttons using 4 resistors:
9 |
10 | * 1 x SparkFun Pro Micro (clone)
11 | * 4 x push buttons
12 | * 1 x 4.7 kohm resistor
13 | * 2 x 10 kohm resistor
14 | * 1 x 47k kohm resistor
15 |
16 | See [Resistor Ladder](../../docs/resistor_ladder) for documentation on
17 | how to use the `LadderButtonConfig` class.
18 |
19 | ## Circuit and Breadboard
20 |
21 | 
22 |
23 | The circuit above shows a 220 Ohm current-limiting resistor on Button 0. I was
24 | lazy and did not use it for this breadboard:
25 |
26 | 
27 |
28 | ## Sample Output
29 |
30 | ### `MODE_READ_BUTTONS`
31 |
32 | When `LadderButtons.ino` is compiled with:
33 | ```C++
34 | #define MODE MODE_READ_BUTTONS
35 | ```
36 | it reads 4 buttons connected to the `A0` analog pin.
37 |
38 | The sample output shows where each button was Pressed then Released. Blank lines
39 | were added for readability:
40 |
41 | ```
42 | handleEvent(): virtualPin: 0; eventType: Pressed; buttonState: 0
43 | handleEvent(): virtualPin: 0; eventType: Released; buttonState: 1
44 |
45 | handleEvent(): virtualPin: 1; eventType: Pressed; buttonState: 0
46 | handleEvent(): virtualPin: 1; eventType: Released; buttonState: 1
47 |
48 | handleEvent(): virtualPin: 2; eventType: Pressed; buttonState: 0
49 | handleEvent(): virtualPin: 2; eventType: Released; buttonState: 1
50 |
51 | handleEvent(): virtualPin: 3; eventType: Pressed; buttonState: 0
52 | handleEvent(): virtualPin: 3; eventType: Released; buttonState: 1
53 | ```
54 |
55 | ### `MODE_CALIBRATE`
56 |
57 | When the program is compiled with
58 |
59 | ```C++
60 | #define MODE MODE_CALIBRATE
61 | ```
62 |
63 | the values of `analogRead()` is printed as fast as possible. It will look
64 | something like:
65 |
66 | ```
67 | 1023
68 | 1023
69 | 1023
70 | 1023
71 | ...
72 | 23
73 | 24
74 | 23
75 | 23
76 | 23
77 | ...
78 | 332
79 | 333
80 | 332
81 | 333
82 | 333
83 | ...
84 | 513
85 | 514
86 | 514
87 | 515
88 | 514
89 | 514
90 | ...
91 | 842
92 | 843
93 | 843
94 | 842
95 | 843
96 | ...
97 | ```
98 |
--------------------------------------------------------------------------------
/examples/ClickVersusDoubleClickUsingBoth/ClickVersusDoubleClickUsingBoth.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * A demo that combines the techniques of ClickVersusDoubleClickUsingReleased
3 | * and ClickVersusDoubleClickUsingSuppression by using both event types to
4 | * trigger a "Clicked". I think this is the best of both worlds. If someone does
5 | * a simple Press/Release, the Release gets triggered. If someone does a quick
6 | * click, then a Click gets triggers (after a delay to wait for the potential
7 | * DoubleClick).
8 | *
9 | * See Also:
10 | * examples/ClickVersusDoubleClickUsingReleased/
11 | * examples/ClickVersusDoubleClickUsingSuppression/
12 | */
13 |
14 | #include
15 | using namespace ace_button;
16 |
17 | // The pin number attached to the button.
18 | const int BUTTON_PIN = 2;
19 |
20 | #ifdef ESP32
21 | // Different ESP32 boards use different pins
22 | const int LED_PIN = 2;
23 | #else
24 | const int LED_PIN = LED_BUILTIN;
25 | #endif
26 |
27 | // LED states. Some microcontrollers wire their built-in LED the reverse.
28 | const int LED_ON = HIGH;
29 | const int LED_OFF = LOW;
30 |
31 | // One button wired to the pin at BUTTON_PIN. Automatically uses the default
32 | // ButtonConfig. The alternative is to call the AceButton::init() method in
33 | // setup() below.
34 | AceButton button(BUTTON_PIN);
35 |
36 | // Forward reference to prevent Arduino compiler becoming confused.
37 | void handleEvent(AceButton*, uint8_t, uint8_t);
38 |
39 | void setup() {
40 | // initialize built-in LED as an output
41 | pinMode(LED_PIN, OUTPUT);
42 |
43 | // Button uses the built-in pull up register.
44 | pinMode(BUTTON_PIN, INPUT_PULLUP);
45 |
46 | ButtonConfig* buttonConfig = button.getButtonConfig();
47 | buttonConfig->setEventHandler(handleEvent);
48 | buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
49 | buttonConfig->setFeature(
50 | ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
51 | buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);
52 | buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterDoubleClick);
53 | }
54 |
55 | void loop() {
56 | // Should be called every 4-5ms or faster, for the default debouncing time
57 | // of ~20ms.
58 | button.check();
59 | }
60 |
61 | // The event handler for the button.
62 | void handleEvent(AceButton* /* button */, uint8_t eventType,
63 | uint8_t /* buttonState */) {
64 | switch (eventType) {
65 | case AceButton::kEventClicked:
66 | case AceButton::kEventReleased:
67 | digitalWrite(LED_PIN, LED_ON);
68 | break;
69 | case AceButton::kEventDoubleClicked:
70 | digitalWrite(LED_PIN, LED_OFF);
71 | break;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/docs/html/search/mag_sel.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
75 |
--------------------------------------------------------------------------------
/examples/Encoded16To4Buttons/README.md:
--------------------------------------------------------------------------------
1 | # Binary Encoded 16-to-4 Buttons
2 |
3 | The `Encoded16To4Buttons.ino` is a sample code for `EncodedButtonConfig`
4 | (which is a generalization of `Encoded4To2ButtonConfig` and
5 | `Encoded8To3ButtonConfig`) to show how it can be used to handle
6 | 15 buttons with 4 pins. These classes are described in detail in
7 | [BinaryEncoding](../../docs/binary_encoding/README.md).
8 |
9 | This program demonstrates 16-to-4 encoding to support 15 buttons using 4 pins
10 | using:
11 |
12 | * 2 x [74LS148](https://www.ti.com/product/SN74LS148) 8-line to 3-line
13 | priority encoder
14 | * 1 x [74LS08](https://www.ti.com/lit/ds/symlink/sn54ls08.pdf) quad 2-input AND
15 | gate
16 | * 1 x SparkFun Pro Micro (clone)
17 | * 4 x push buttons
18 |
19 | A partial schematic is:
20 |
21 | 
22 |
23 | Here is the breadboard that implements this circuit, but with only pins 1, 7, 8,
24 | and 15 for demonstration purposes:
25 |
26 | 
27 |
28 | ## Sample Output
29 |
30 | The sample output looks where each button was Pressed then Released, then was
31 | Pressed/Released quickly to generate a Clicked event. Blank lines were added for
32 | readability:
33 |
34 | ```
35 | handleEvent(): virtualPin: 1; eventType: Pressed; buttonState: 0
36 | handleEvent(): virtualPin: 1; eventType: Released; buttonState: 1
37 |
38 | handleEvent(): virtualPin: 7; eventType: Pressed; buttonState: 0
39 | handleEvent(): virtualPin: 7; eventType: Released; buttonState: 1
40 |
41 | handleEvent(): virtualPin: 8; eventType: Pressed; buttonState: 0
42 | handleEvent(): virtualPin: 8; eventType: Released; buttonState: 1
43 |
44 | handleEvent(): virtualPin: 15; eventType: Pressed; buttonState: 0
45 | handleEvent(): virtualPin: 15; eventType: Released; buttonState: 1
46 |
47 | handleEvent(): virtualPin: 1; eventType: Pressed; buttonState: 0
48 | handleEvent(): virtualPin: 1; eventType: Clicked; buttonState: 1
49 | handleEvent(): virtualPin: 1; eventType: Released; buttonState: 1
50 |
51 | handleEvent(): virtualPin: 7; eventType: Pressed; buttonState: 0
52 | handleEvent(): virtualPin: 7; eventType: Clicked; buttonState: 1
53 | handleEvent(): virtualPin: 7; eventType: Released; buttonState: 1
54 |
55 | handleEvent(): virtualPin: 8; eventType: Pressed; buttonState: 0
56 | handleEvent(): virtualPin: 8; eventType: Clicked; buttonState: 1
57 | handleEvent(): virtualPin: 8; eventType: Released; buttonState: 1
58 |
59 | handleEvent(): virtualPin: 15; eventType: Pressed; buttonState: 0
60 | handleEvent(): virtualPin: 15; eventType: Clicked; buttonState: 1
61 | handleEvent(): virtualPin: 15; eventType: Released; buttonState: 1
62 | ```
63 |
--------------------------------------------------------------------------------
/src/ace_button/EncodedButtonConfig.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2020 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #include "EncodedButtonConfig.h"
26 | #include "AceButton.h"
27 |
28 | namespace ace_button {
29 |
30 | EncodedButtonConfig::EncodedButtonConfig(
31 | uint8_t numPins, const uint8_t pins[], uint8_t numButtons,
32 | AceButton* const buttons[], uint8_t defaultReleasedState):
33 | mNumPins(numPins),
34 | mNumButtons(numButtons),
35 | mPressedState(defaultReleasedState ^ 0x1),
36 | mPins(pins),
37 | mButtons(buttons) {
38 | for (uint8_t i = 0; i < mNumButtons; i++) {
39 | AceButton* button = mButtons[i];
40 | button->setButtonConfig(this);
41 | }
42 | }
43 |
44 | int EncodedButtonConfig::readButton(uint8_t pin) {
45 | uint8_t virtualPin = getVirtualPin();
46 | return (virtualPin == pin) ? mPressedState : (mPressedState ^ 0x1);
47 | }
48 |
49 | void EncodedButtonConfig::checkButtons() const {
50 | uint8_t virtualPin = getVirtualPin();
51 | for (uint8_t i = 0; i < mNumButtons; i++) {
52 | AceButton* button = mButtons[i];
53 | if (button == nullptr) continue;
54 |
55 | // For each button, call checkState() to allow it to figure out which
56 | // state it should move it.
57 | uint8_t buttonPin = button->getPin();
58 | uint8_t buttonState = (buttonPin == virtualPin)
59 | ? mPressedState : (mPressedState ^ 0x1);
60 | button->checkState(buttonState);
61 | }
62 | }
63 |
64 | uint8_t EncodedButtonConfig::getVirtualPin() const {
65 | uint8_t virtualPin = 0;
66 | for (uint8_t i = 0; i < mNumPins; i++) {
67 | uint8_t pin = mPins[i];
68 | int s = digitalRead(pin);
69 | virtualPin |= (s == mPressedState) << i;
70 | }
71 | return virtualPin;
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/ace_button/testing/TestableButtonConfig.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2018 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #ifndef ACE_BUTTON_TESTABLE_BUTTON_CONFIG_H
26 | #define ACE_BUTTON_TESTABLE_BUTTON_CONFIG_H
27 |
28 | #include "../ButtonConfig.h"
29 |
30 | namespace ace_button {
31 | namespace testing {
32 |
33 | /**
34 | * A subclass of ButtonConfig which overrides getClock() and readButton() so
35 | * that their values can be controlled manually. This is intended to be used for
36 | * unit testing.
37 | */
38 | class TestableButtonConfig: public ButtonConfig {
39 | public:
40 | TestableButtonConfig():
41 | mMillis(0),
42 | mButtonState(HIGH) {}
43 |
44 | /**
45 | * Initialize to its pristine state. This method is needed because AUnit
46 | * does not create a new instance of the Test class for each test case, so
47 | * we have to reuse objects between test cases, so we need a way to
48 | * reinitialize this object to its pristine state just after construction.
49 | */
50 | void init() {
51 | resetFeatures();
52 | mMillis = 0;
53 | mButtonState = HIGH;
54 | }
55 |
56 | unsigned long getClock() override { return mMillis; }
57 |
58 | int readButton(uint8_t /* pin */) override { return mButtonState; }
59 |
60 | /** Set the time of the fake clock. */
61 | void setClock(unsigned long millis) { mMillis = millis; }
62 |
63 | /** Set the state of the fake physical button. */
64 | void setButtonState(int buttonState) { mButtonState = buttonState; }
65 |
66 | private:
67 | // Disable copy-constructor and assignment operator
68 | TestableButtonConfig(const TestableButtonConfig&) = delete;
69 | TestableButtonConfig& operator=(const TestableButtonConfig&) = delete;
70 |
71 | unsigned long mMillis;
72 | int mButtonState;
73 | };
74 |
75 | }
76 | }
77 | #endif
78 |
--------------------------------------------------------------------------------
/examples/ClickVersusDoubleClickUsingSuppression/ClickVersusDoubleClickUsingSuppression.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * A demo that uses kFeatureSuppressClickBeforeDoubleClick to distinguish a
3 | * Clicked event from a DoubleClicked event. Click turns on the LED. A
4 | * DoubleClick turns off the LED.
5 | *
6 | * The only way to suppress the Clicked "after" a DoubleClicked is to postpone
7 | * the sending of the Clicked event until getDoubleClickDelay() time after the
8 | * Clicked. At that time, we can tell if a DoubleClicked has occurred or not.
9 | * But this means that every Clicked event is delayed by (kClickDelay +
10 | * kDoubleClickDelay + 2 * kDebounceDelay) which is 700 ms using the default
11 | * values, and you'll notice this delay in the LED turning on.
12 | *
13 | * The other side-effect is that if a user doesn't input a clean Click (which
14 | * results in a normal Press/Release sequence), then nothing happens to the LED.
15 | * Depending on the application, this may or may not be the desirable result.
16 |
17 | * See Also:
18 | * examples/ClickVersusDoubleClickUsingReleased/
19 | * - uses the Released event instead of the Clicked event
20 | */
21 |
22 | #include
23 | using namespace ace_button;
24 |
25 | // The pin number attached to the button.
26 | const int BUTTON_PIN = 2;
27 |
28 | #ifdef ESP32
29 | // Different ESP32 boards use different pins
30 | const int LED_PIN = 2;
31 | #else
32 | const int LED_PIN = LED_BUILTIN;
33 | #endif
34 |
35 | // LED states. Some microcontrollers wire their built-in LED the reverse.
36 | const int LED_ON = HIGH;
37 | const int LED_OFF = LOW;
38 |
39 | // One button wired to the pin at BUTTON_PIN. Automatically uses the default
40 | // ButtonConfig. The alternative is to call the AceButton::init() method in
41 | // setup() below.
42 | AceButton button(BUTTON_PIN);
43 |
44 | // Forward reference to prevent Arduino compiler becoming confused.
45 | void handleEvent(AceButton*, uint8_t, uint8_t);
46 |
47 | void setup() {
48 | // initialize built-in LED as an output
49 | pinMode(LED_PIN, OUTPUT);
50 |
51 | // Button uses the built-in pull up register.
52 | pinMode(BUTTON_PIN, INPUT_PULLUP);
53 |
54 | ButtonConfig* buttonConfig = button.getButtonConfig();
55 | buttonConfig->setEventHandler(handleEvent);
56 | buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
57 | buttonConfig->setFeature(
58 | ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
59 | }
60 |
61 | void loop() {
62 | // Should be called every 4-5ms or faster, for the default debouncing time
63 | // of ~20ms.
64 | button.check();
65 | }
66 |
67 | // The event handler for the button.
68 | void handleEvent(AceButton* /* button */, uint8_t eventType,
69 | uint8_t /* buttonState */) {
70 | switch (eventType) {
71 | case AceButton::kEventClicked:
72 | digitalWrite(LED_PIN, LED_ON);
73 | break;
74 | case AceButton::kEventDoubleClicked:
75 | digitalWrite(LED_PIN, LED_OFF);
76 | break;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/docs/html/search/all_6.js:
--------------------------------------------------------------------------------
1 | var searchData=
2 | [
3 | ['getbuttonconfig_17',['getButtonConfig',['../classace__button_1_1AceButton.html#a7d309d463b50a59a202067a7228149f0',1,'ace_button::AceButton']]],
4 | ['getclickdelay_18',['getClickDelay',['../classace__button_1_1ButtonConfig.html#a2a39fcc939e2dce12f2ddbf803747a6e',1,'ace_button::ButtonConfig']]],
5 | ['getclock_19',['getClock',['../classace__button_1_1ButtonConfig.html#a440271e22d5e7e161cdcb3b73f092111',1,'ace_button::ButtonConfig']]],
6 | ['getdebouncedelay_20',['getDebounceDelay',['../classace__button_1_1ButtonConfig.html#a2866cf111973f8b1bf4ae0e7df17b6dd',1,'ace_button::ButtonConfig']]],
7 | ['getdefaultreleasedstate_21',['getDefaultReleasedState',['../classace__button_1_1AceButton.html#a5c253900d6d6c0035095a322ee7f9aa1',1,'ace_button::AceButton']]],
8 | ['getdoubleclickdelay_22',['getDoubleClickDelay',['../classace__button_1_1ButtonConfig.html#a0098549db5df3c730f64f4235845a5a5',1,'ace_button::ButtonConfig']]],
9 | ['geteventhandler_23',['getEventHandler',['../classace__button_1_1ButtonConfig.html#a06b1f78f5f1f03bc9af51af3345cc22c',1,'ace_button::ButtonConfig']]],
10 | ['getheartbeatinterval_24',['getHeartBeatInterval',['../classace__button_1_1ButtonConfig.html#afd90e97a98826ca8e47933aecb8b2d08',1,'ace_button::ButtonConfig']]],
11 | ['getid_25',['getId',['../classace__button_1_1AceButton.html#a244a2ea3166f2d886ccd94a44286b835',1,'ace_button::AceButton']]],
12 | ['getlastbuttonstate_26',['getLastButtonState',['../classace__button_1_1AceButton.html#abb9c10c1fc6df01fae071ccfcb906935',1,'ace_button::AceButton']]],
13 | ['getlongpressdelay_27',['getLongPressDelay',['../classace__button_1_1ButtonConfig.html#a3ded707bd12aaf7bbcb14e431ec77e15',1,'ace_button::ButtonConfig']]],
14 | ['getnobuttonpin_28',['getNoButtonPin',['../classace__button_1_1EncodedButtonConfig.html#aba96c8f8d55666fb413195407ec5770a',1,'ace_button::EncodedButtonConfig::getNoButtonPin()'],['../classace__button_1_1LadderButtonConfig.html#a1840f50aa3c070c5f0dc7957884c0643',1,'ace_button::LadderButtonConfig::getNoButtonPin()']]],
15 | ['getpin_29',['getPin',['../classace__button_1_1AceButton.html#ab33671acf4de4912b1f00fad28246ae0',1,'ace_button::AceButton']]],
16 | ['getrepeatpressdelay_30',['getRepeatPressDelay',['../classace__button_1_1ButtonConfig.html#aeca9329775d17a06433c9588fca28695',1,'ace_button::ButtonConfig']]],
17 | ['getrepeatpressinterval_31',['getRepeatPressInterval',['../classace__button_1_1ButtonConfig.html#a5c5d86932a98f71030422ef367b57a25',1,'ace_button::ButtonConfig']]],
18 | ['getsystembuttonconfig_32',['getSystemButtonConfig',['../classace__button_1_1ButtonConfig.html#a585353712d2c76d91c10e67102cb614d',1,'ace_button::ButtonConfig']]],
19 | ['getvirtualpin_33',['getVirtualPin',['../classace__button_1_1EncodedButtonConfig.html#ae92e77f9b6e8f5a18cc4f0cf17406724',1,'ace_button::EncodedButtonConfig::getVirtualPin()'],['../classace__button_1_1LadderButtonConfig.html#aac2d59d472aadad37efa9a9c5509dc71',1,'ace_button::LadderButtonConfig::getVirtualPin()']]]
20 | ];
21 |
--------------------------------------------------------------------------------
/docs/html/search/functions_5.js:
--------------------------------------------------------------------------------
1 | var searchData=
2 | [
3 | ['getbuttonconfig_104',['getButtonConfig',['../classace__button_1_1AceButton.html#a7d309d463b50a59a202067a7228149f0',1,'ace_button::AceButton']]],
4 | ['getclickdelay_105',['getClickDelay',['../classace__button_1_1ButtonConfig.html#a2a39fcc939e2dce12f2ddbf803747a6e',1,'ace_button::ButtonConfig']]],
5 | ['getclock_106',['getClock',['../classace__button_1_1ButtonConfig.html#a440271e22d5e7e161cdcb3b73f092111',1,'ace_button::ButtonConfig']]],
6 | ['getdebouncedelay_107',['getDebounceDelay',['../classace__button_1_1ButtonConfig.html#a2866cf111973f8b1bf4ae0e7df17b6dd',1,'ace_button::ButtonConfig']]],
7 | ['getdefaultreleasedstate_108',['getDefaultReleasedState',['../classace__button_1_1AceButton.html#a5c253900d6d6c0035095a322ee7f9aa1',1,'ace_button::AceButton']]],
8 | ['getdoubleclickdelay_109',['getDoubleClickDelay',['../classace__button_1_1ButtonConfig.html#a0098549db5df3c730f64f4235845a5a5',1,'ace_button::ButtonConfig']]],
9 | ['geteventhandler_110',['getEventHandler',['../classace__button_1_1ButtonConfig.html#a06b1f78f5f1f03bc9af51af3345cc22c',1,'ace_button::ButtonConfig']]],
10 | ['getheartbeatinterval_111',['getHeartBeatInterval',['../classace__button_1_1ButtonConfig.html#afd90e97a98826ca8e47933aecb8b2d08',1,'ace_button::ButtonConfig']]],
11 | ['getid_112',['getId',['../classace__button_1_1AceButton.html#a244a2ea3166f2d886ccd94a44286b835',1,'ace_button::AceButton']]],
12 | ['getlastbuttonstate_113',['getLastButtonState',['../classace__button_1_1AceButton.html#abb9c10c1fc6df01fae071ccfcb906935',1,'ace_button::AceButton']]],
13 | ['getlongpressdelay_114',['getLongPressDelay',['../classace__button_1_1ButtonConfig.html#a3ded707bd12aaf7bbcb14e431ec77e15',1,'ace_button::ButtonConfig']]],
14 | ['getnobuttonpin_115',['getNoButtonPin',['../classace__button_1_1EncodedButtonConfig.html#aba96c8f8d55666fb413195407ec5770a',1,'ace_button::EncodedButtonConfig::getNoButtonPin()'],['../classace__button_1_1LadderButtonConfig.html#a1840f50aa3c070c5f0dc7957884c0643',1,'ace_button::LadderButtonConfig::getNoButtonPin()']]],
15 | ['getpin_116',['getPin',['../classace__button_1_1AceButton.html#ab33671acf4de4912b1f00fad28246ae0',1,'ace_button::AceButton']]],
16 | ['getrepeatpressdelay_117',['getRepeatPressDelay',['../classace__button_1_1ButtonConfig.html#aeca9329775d17a06433c9588fca28695',1,'ace_button::ButtonConfig']]],
17 | ['getrepeatpressinterval_118',['getRepeatPressInterval',['../classace__button_1_1ButtonConfig.html#a5c5d86932a98f71030422ef367b57a25',1,'ace_button::ButtonConfig']]],
18 | ['getsystembuttonconfig_119',['getSystemButtonConfig',['../classace__button_1_1ButtonConfig.html#a585353712d2c76d91c10e67102cb614d',1,'ace_button::ButtonConfig']]],
19 | ['getvirtualpin_120',['getVirtualPin',['../classace__button_1_1EncodedButtonConfig.html#ae92e77f9b6e8f5a18cc4f0cf17406724',1,'ace_button::EncodedButtonConfig::getVirtualPin()'],['../classace__button_1_1LadderButtonConfig.html#aac2d59d472aadad37efa9a9c5509dc71',1,'ace_button::LadderButtonConfig::getVirtualPin()']]]
20 | ];
21 |
--------------------------------------------------------------------------------
/examples/ClickVersusDoubleClickUsingReleased/ClickVersusDoubleClickUsingReleased.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * A demo that distinguishes a "Clicked" from a DoubleClicked by using a
3 | * Released event instead of a Clicked. Released turns on the LED. A DoubleClick
4 | * turns off the LED.
5 | *
6 | * Normally, AceButton cannot separate a Clicked from a DoubleClicked because
7 | * the Clicked event will always trigger if a DoubleClicked occurs. We cannot
8 | * suppress the first Clicked because it has already occurred by the time the
9 | * DoubleClicked occurs, and the first Clicked cannot predict the future.
10 | *
11 | * This version uses a Released event instead of a Clicked to turn the LED on,
12 | * while suppressing the Released after a DoubleClicked, and we ignore the
13 | * Clicked event that we can't suppress. The disadvantage of this version is
14 | * that if a user accidentally makes a normal Clicked event (a rapid
15 | * Pressed/Released), nothing happens to the LED. Depending on the application,
16 | * this may or may not be the desirable result.
17 | *
18 | * See Also:
19 | * examples/ClickVersusDoubleClickUsingSuppression/
20 | * - uses the kFeatureSuppressClickBeforeDoubleClick
21 | */
22 |
23 | #include
24 | using namespace ace_button;
25 |
26 | // The pin number attached to the button.
27 | const int BUTTON_PIN = 2;
28 |
29 | #ifdef ESP32
30 | // Different ESP32 boards use different pins
31 | const int LED_PIN = 2;
32 | #else
33 | const int LED_PIN = LED_BUILTIN;
34 | #endif
35 |
36 | // LED states. Some microcontrollers wire their built-in LED the reverse.
37 | const int LED_ON = HIGH;
38 | const int LED_OFF = LOW;
39 |
40 | // One button wired to the pin at BUTTON_PIN. Automatically uses the default
41 | // ButtonConfig. The alternative is to call the AceButton::init() method in
42 | // setup() below.
43 | AceButton button(BUTTON_PIN);
44 |
45 | // Forward reference to prevent Arduino compiler becoming confused.
46 | void handleEvent(AceButton*, uint8_t, uint8_t);
47 |
48 | void setup() {
49 | // initialize built-in LED as an output
50 | pinMode(LED_PIN, OUTPUT);
51 |
52 | // Button uses the built-in pull up register.
53 | pinMode(BUTTON_PIN, INPUT_PULLUP);
54 |
55 | ButtonConfig* buttonConfig = button.getButtonConfig();
56 | buttonConfig->setEventHandler(handleEvent);
57 | buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
58 | buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);
59 | buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterDoubleClick);
60 | }
61 |
62 | void loop() {
63 | // Should be called every 4-5ms or faster, for the default debouncing time
64 | // of ~20ms.
65 | button.check();
66 | }
67 |
68 | // The event handler for the button.
69 | void handleEvent(AceButton* /* button */, uint8_t eventType,
70 | uint8_t /* buttonState */) {
71 | switch (eventType) {
72 | case AceButton::kEventReleased:
73 | digitalWrite(LED_PIN, LED_ON);
74 | break;
75 | case AceButton::kEventDoubleClicked:
76 | digitalWrite(LED_PIN, LED_OFF);
77 | break;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/tests/Jenkinsfile:
--------------------------------------------------------------------------------
1 | // See https://github.com/bxparks/AUniter/tree/develop/jenkins for
2 | // a description of AUniter integration with Jenkins.
3 | //
4 | // The following variables are used:
5 | //
6 | // * AUNITER_ARDUINO_BINARY - defined in the Jenkins system configuration
7 | // * WORKSPACE - automatically filled in by Jenkins
8 | // * BOARDS - defined in the "This project is parameterized" section of the
9 | // Jenkins Pipeline configuration
10 | // * BADGE_BUCKET - defined in "This project is parameterized" section.
11 | //
12 | pipeline {
13 | agent { label 'master' }
14 | stages {
15 | stage('Setup') {
16 | steps {
17 | dir('AUniter') {
18 | git url: 'https://github.com/bxparks/AUniter',
19 | branch: 'develop'
20 | }
21 | dir('libraries/AUnit') {
22 | git url: 'https://github.com/bxparks/AUnit',
23 | branch: 'develop'
24 | }
25 | dir('libraries/CapacitiveSensor') {
26 | git url:
27 | 'https://github.com/PaulStoffregen/CapacitiveSensor',
28 | branch: 'master'
29 | }
30 | }
31 | }
32 | stage('Verify Examples') {
33 | steps {
34 | sh "AUniter/tools/auniter.sh \
35 | --config libraries/AceButton/tests/auniter.ini \
36 | verify \
37 | --sketchbook $WORKSPACE \
38 | $BOARDS \
39 | \$(find libraries/AceButton/examples -type d \
40 | -mindepth 1 -maxdepth 2)"
41 | }
42 | }
43 | stage('Verify Tests') {
44 | steps {
45 | sh "AUniter/tools/auniter.sh \
46 | --config libraries/AceButton/tests/auniter.ini \
47 | verify \
48 | --sketchbook $WORKSPACE \
49 | $BOARDS \
50 | libraries/AceButton/tests/*Test"
51 | }
52 | }
53 | stage('Test') {
54 | steps {
55 | sh "AUniter/tools/auniter.sh \
56 | --config libraries/AceButton/tests/auniter.ini \
57 | test \
58 | --skip_missing_port \
59 | --sketchbook $WORKSPACE \
60 | $BOARDS \
61 | libraries/AceButton/tests/*Test"
62 | }
63 | }
64 | }
65 | post {
66 | failure {
67 | script {
68 | if (env.BADGE_BUCKET?.trim()) {
69 | sh "AUniter/BadgeService/set-badge-status.sh \
70 | $BADGE_BUCKET AceButton FAILED"
71 | }
72 | }
73 | }
74 | success {
75 | script {
76 | if (env.BADGE_BUCKET?.trim()) {
77 | sh "AUniter/BadgeService/set-badge-status.sh \
78 | $BADGE_BUCKET AceButton PASSED"
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/examples/SingleButtonUsingIEventHandler/SingleButtonUsingIEventHandler.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * A demo of a single AceButton which handles events using the IEventHandler
3 | * object, instead of the EventHandler function. Similar to SingleButton.ino.
4 | */
5 |
6 | #include
7 | using namespace ace_button;
8 |
9 | // The pin number attached to the button.
10 | const int BUTTON_PIN = 2;
11 |
12 | #ifdef ESP32
13 | // Different ESP32 boards use different pins
14 | const int LED_PIN = 2;
15 | #else
16 | const int LED_PIN = LED_BUILTIN;
17 | #endif
18 |
19 | // LED states. Some microcontrollers wire their built-in LED the reverse.
20 | const int LED_ON = HIGH;
21 | const int LED_OFF = LOW;
22 |
23 | // One button wired to the pin at BUTTON_PIN. Automatically uses the default
24 | // ButtonConfig. The alternative is to call the AceButton::init() method in
25 | // setup() below.
26 | AceButton button(BUTTON_PIN);
27 |
28 | // An object that handles the event.
29 | class ButtonHandler: public IEventHandler {
30 | public:
31 | void handleEvent(AceButton* /* button */, uint8_t eventType,
32 | uint8_t buttonState) override {
33 |
34 | // Print out a message for all events.
35 | Serial.print(F("handleEvent(): eventType: "));
36 | Serial.print(AceButton::eventName(eventType));
37 | Serial.print(F("; buttonState: "));
38 | Serial.println(buttonState);
39 |
40 | // Control the LED only for the Pressed and Released events.
41 | // Notice that if the MCU is rebooted while the button is pressed down, no
42 | // event is triggered and the LED remains off.
43 | switch (eventType) {
44 | case AceButton::kEventPressed:
45 | digitalWrite(LED_PIN, LED_ON);
46 | break;
47 | case AceButton::kEventReleased:
48 | digitalWrite(LED_PIN, LED_OFF);
49 | break;
50 | }
51 | }
52 | };
53 |
54 | ButtonHandler handleEvent;
55 |
56 | void setup() {
57 | delay(1000); // some microcontrollers reboot twice
58 | Serial.begin(115200);
59 | while (! Serial); // Wait until Serial is ready - Leonardo/Micro
60 | Serial.println(F("setup(): begin"));
61 |
62 | // initialize built-in LED as an output
63 | pinMode(LED_PIN, OUTPUT);
64 |
65 | // Button uses the built-in pull up register.
66 | pinMode(BUTTON_PIN, INPUT_PULLUP);
67 |
68 | // Configure the ButtonConfig with the event handler, and enable all higher
69 | // level events.
70 | ButtonConfig* buttonConfig = button.getButtonConfig();
71 | buttonConfig->setIEventHandler(&handleEvent);
72 | buttonConfig->setFeature(ButtonConfig::kFeatureClick);
73 | buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
74 | buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
75 | buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
76 |
77 | // Check if the button was pressed while booting
78 | if (button.isPressedRaw()) {
79 | Serial.println(F("setup(): button was pressed while booting"));
80 | }
81 |
82 | Serial.println(F("setup(): ready"));
83 | }
84 |
85 | void loop() {
86 | // Should be called every 4-5ms or faster, for the default debouncing time
87 | // of ~20ms.
88 | button.check();
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/examples/Encoded4To2Buttons/Encoded4To2Buttons.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * A demo of Encoded4To2ButtonConfig to detect 3 buttons using 2 pins using
3 | * binary encoding.
4 | */
5 |
6 | #include
7 | using namespace ace_button;
8 |
9 | #ifdef ESP32
10 | // Different ESP32 boards use different pins
11 | static const int LED_PIN = 2;
12 | #else
13 | static const int LED_PIN = LED_BUILTIN;
14 | #endif
15 |
16 | // LED states. Some microcontrollers wire their built-in LED the reverse.
17 | static const int LED_ON = HIGH;
18 | static const int LED_OFF = LOW;
19 |
20 | // Physical pins
21 | static const uint8_t BUTTON_PIN0 = 2;
22 | static const uint8_t BUTTON_PIN1 = 3;
23 |
24 | // Each button is assigned to the virtual pin number (1-3) which comes from the
25 | // binary bit patterns of the 2 actual pins. Button b0 on virtual pin 0 cannot
26 | // be used because it is used to represent "no button pressed".
27 | Encoded4To2ButtonConfig buttonConfig(BUTTON_PIN0, BUTTON_PIN1);
28 | AceButton b1(&buttonConfig, 1);
29 | AceButton b2(&buttonConfig, 2);
30 | AceButton b3(&buttonConfig, 3);
31 |
32 | // Forward reference to prevent Arduino compiler becoming confused.
33 | void handleEvent(AceButton*, uint8_t, uint8_t);
34 |
35 | void setup() {
36 | delay(1000); // some microcontrollers reboot twice
37 | Serial.begin(115200);
38 | while (! Serial); // Wait until Serial is ready - Leonardo/Micro
39 | Serial.println(F("setup(): begin"));
40 |
41 | // Initialize built-in LED as an output.
42 | pinMode(LED_PIN, OUTPUT);
43 |
44 | // Pins use the built-in pull up register.
45 | pinMode(BUTTON_PIN0, INPUT_PULLUP);
46 | pinMode(BUTTON_PIN1, INPUT_PULLUP);
47 |
48 | // Configure the ButtonConfig with the event handler, and enable all higher
49 | // level events.
50 | buttonConfig.setEventHandler(handleEvent);
51 | buttonConfig.setFeature(ButtonConfig::kFeatureClick);
52 | buttonConfig.setFeature(ButtonConfig::kFeatureDoubleClick);
53 | buttonConfig.setFeature(ButtonConfig::kFeatureLongPress);
54 | buttonConfig.setFeature(ButtonConfig::kFeatureRepeatPress);
55 |
56 | Serial.println(F("setup(): ready"));
57 | }
58 |
59 | void loop() {
60 | // Should be called every 4-5ms or faster, for the default debouncing time
61 | // of ~20ms.
62 | b1.check();
63 | b2.check();
64 | b3.check();
65 | }
66 |
67 | // The event handler for the buttons.
68 | void handleEvent(AceButton* button, uint8_t eventType, uint8_t buttonState) {
69 |
70 | // Print out a message for all events.
71 | Serial.print(F("handleEvent(): "));
72 | Serial.print(F("virtualPin: "));
73 | Serial.print(button->getPin());
74 | Serial.print(F("; eventType: "));
75 | Serial.print(AceButton::eventName(eventType));
76 | Serial.print(F("; buttonState: "));
77 | Serial.println(buttonState);
78 |
79 | // Control the LED only for the Pressed and Released events.
80 | // Notice that if the MCU is rebooted while the button is pressed down, no
81 | // event is triggered and the LED remains off.
82 | switch (eventType) {
83 | case AceButton::kEventPressed:
84 | digitalWrite(LED_PIN, LED_ON);
85 | break;
86 | case AceButton::kEventReleased:
87 | digitalWrite(LED_PIN, LED_OFF);
88 | break;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/docs/html/menudata.js:
--------------------------------------------------------------------------------
1 | /*
2 | @licstart The following is the entire license notice for the JavaScript code in this file.
3 |
4 | The MIT License (MIT)
5 |
6 | Copyright (C) 1997-2020 by Dimitri van Heesch
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
9 | and associated documentation files (the "Software"), to deal in the Software without restriction,
10 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
11 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all copies or
15 | substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
18 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
23 | @licend The above is the entire license notice for the JavaScript code in this file
24 | */
25 | var menudata={children:[
26 | {text:"Main Page",url:"index.html"},
27 | {text:"Classes",url:"annotated.html",children:[
28 | {text:"Class List",url:"annotated.html"},
29 | {text:"Class Index",url:"classes.html"},
30 | {text:"Class Hierarchy",url:"inherits.html"},
31 | {text:"Class Members",url:"functions.html",children:[
32 | {text:"All",url:"functions.html",children:[
33 | {text:"a",url:"functions.html#index_a"},
34 | {text:"b",url:"functions.html#index_b"},
35 | {text:"c",url:"functions.html#index_c"},
36 | {text:"d",url:"functions.html#index_d"},
37 | {text:"e",url:"functions.html#index_e"},
38 | {text:"f",url:"functions.html#index_f"},
39 | {text:"g",url:"functions.html#index_g"},
40 | {text:"h",url:"functions.html#index_h"},
41 | {text:"i",url:"functions.html#index_i"},
42 | {text:"k",url:"functions.html#index_k"},
43 | {text:"l",url:"functions.html#index_l"},
44 | {text:"r",url:"functions.html#index_r"},
45 | {text:"s",url:"functions.html#index_s"},
46 | {text:"~",url:"functions.html#index__7E"}]},
47 | {text:"Functions",url:"functions_func.html",children:[
48 | {text:"a",url:"functions_func.html#index_a"},
49 | {text:"b",url:"functions_func.html#index_b"},
50 | {text:"c",url:"functions_func.html#index_c"},
51 | {text:"d",url:"functions_func.html#index_d"},
52 | {text:"e",url:"functions_func.html#index_e"},
53 | {text:"g",url:"functions_func.html#index_g"},
54 | {text:"h",url:"functions_func.html#index_h"},
55 | {text:"i",url:"functions_func.html#index_i"},
56 | {text:"l",url:"functions_func.html#index_l"},
57 | {text:"r",url:"functions_func.html#index_r"},
58 | {text:"s",url:"functions_func.html#index_s"},
59 | {text:"~",url:"functions_func.html#index__7E"}]},
60 | {text:"Variables",url:"functions_vars.html"},
61 | {text:"Typedefs",url:"functions_type.html"}]}]},
62 | {text:"Files",url:"files.html",children:[
63 | {text:"File List",url:"files.html"}]}]}
64 |
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map for AceButton library
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | AceButton KEYWORD1
10 | EventHandler KEYWORD1
11 | IEventHandler KEYWORD1
12 | ButtonConfig KEYWORD1
13 | Encoded4To2ButtonConfig KEYWORD1
14 | Encoded8To3ButtonConfig KEYWORD1
15 | EncodedButtonConfig KEYWORD1
16 | LadderButtonConfig KEYWORD1
17 |
18 | #######################################
19 | # Methods and Functions (KEYWORD2)
20 | #######################################
21 |
22 | # public methods from AceButton.h
23 | init KEYWORD2
24 | getButtonConfig KEYWORD2
25 | setButtonConfig KEYWORD2
26 | setEventHandler KEYWORD2
27 | getPin KEYWORD2
28 | getId KEYWORD2
29 | getDefaultReleasedState KEYWORD2
30 | getLastButtonState KEYWORD2
31 | check KEYWORD2
32 | checkState KEYWORD2
33 | isReleased KEYWORD2
34 | isPressedRaw KEYWORD2
35 |
36 | # methods from ButtonConfig.h
37 | getDebounceDelay KEYWORD2
38 | getClickDelay KEYWORD2
39 | getDoubleClickDelay KEYWORD2
40 | getLongPressDelay KEYWORD2
41 | getRepeatPressDelay KEYWORD2
42 | getRepeatPressInterval KEYWORD2
43 | getClock KEYWORD2
44 | readButton KEYWORD2
45 | #
46 | isFeature KEYWORD2
47 | setFeature KEYWORD2
48 | clearFeature KEYWORD2
49 | resetFeatures KEYWORD2
50 | #
51 | getEventHandler KEYWORD2
52 | setEventHandler KEYWORD2
53 | setIEventHandler KEYWORD2
54 | getSystemButtonConfig KEYWORD2
55 | #
56 | setDebounceDelay KEYWORD2
57 | setClickDelay KEYWORD2
58 | setDoubleClickDelay KEYWORD2
59 | setLongPressDelay KEYWORD2
60 | setRepeatPressDelay KEYWORD2
61 | setRepeatPressInterval KEYWORD2
62 |
63 | # methods from EncodedButtonConfig
64 | checkButtons KEYWORD2
65 | getVirtualPin KEYWORD2
66 | getNoButtonPin KEYWORD2
67 |
68 | # methods from LadderButtonConfig
69 | checkButtons KEYWORD2
70 | getVirtualPin KEYWORD2
71 | getNoButtonPin KEYWORD2
72 |
73 | #######################################
74 | # Instances (KEYWORD2)
75 | #######################################
76 |
77 | #######################################
78 | # Constants (LITERAL1)
79 | #######################################
80 |
81 | # public constants from AceButton.h
82 | kEventPressed LITERAL1
83 | kEventReleased LITERAL1
84 | kEventClicked LITERAL1
85 | kEventDoubleClicked LITERAL1
86 | kEventLongPressed LITERAL1
87 | kEventRepeatPressed LITERAL1
88 | kEventLongReleased LITERAL1
89 | kButtonStateUnknown LITERAL1
90 |
91 | # public constants from ButtonConfig.h
92 | kDebounceDelay LITERAL1
93 | kClickDelay LITERAL1
94 | kDoubleClickDelay LITERAL1
95 | kLongPressDelay LITERAL1
96 | kRepeatPressDelay LITERAL1
97 | kRepeatPressInterval LITERAL1
98 | #
99 | kFeatureClick LITERAL1
100 | kFeatureDoubleClick LITERAL1
101 | kFeatureLongPress LITERAL1
102 | kFeatureRepeatPress LITERAL1
103 | kFeatureSuppressAfterClick LITERAL1
104 | kFeatureSuppressAfterDoubleClick LITERAL1
105 | kFeatureSuppressAfterLongPress LITERAL1
106 | kFeatureSuppressAfterRepeatPress LITERAL1
107 | kFeatureSuppressClickBeforeDoubleClick LITERAL1
108 | kFeatureSuppressAll LITERAL1
109 | kInternalFeatureIEventHandler LITERAL1
110 |
--------------------------------------------------------------------------------
/src/ace_button/testing/TestableEncodedButtonConfig.h:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2018 Brian T. Park
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #ifndef ACE_BUTTON_TESTABLE_ENCODED_BUTTON_CONFIG_H
26 | #define ACE_BUTTON_TESTABLE_ENCODED_BUTTON_CONFIG_H
27 |
28 | #include "../EncodedButtonConfig.h"
29 |
30 | namespace ace_button {
31 | namespace testing {
32 |
33 | /**
34 | * A subclass of EncodedButtonConfig which overrides getClock() and
35 | * getVirtualPin() so that their values can be controlled manually. This is
36 | * intended to be used for unit testing.
37 | */
38 | class TestableEncodedButtonConfig: public EncodedButtonConfig {
39 | public:
40 | TestableEncodedButtonConfig(uint8_t numPins, uint8_t const pins[],
41 | uint8_t numButtons, AceButton* const buttons[],
42 | uint8_t defaultReleasedState = HIGH):
43 | EncodedButtonConfig(numPins, pins, numButtons, buttons,
44 | defaultReleasedState),
45 | mMillis(0),
46 | mVirtualPin(0) {}
47 |
48 | /**
49 | * Initialize to its pristine state. This method is needed because AUnit
50 | * does not create a new instance of the Test class for each test case, so
51 | * we have to reuse objects between test cases, so we need a way to
52 | * reinitialize this object to its pristine state just after construction.
53 | */
54 | void init() {
55 | resetFeatures();
56 | mMillis = 0;
57 | mVirtualPin = 0;
58 | }
59 |
60 | unsigned long getClock() override { return mMillis; }
61 |
62 | uint8_t getVirtualPin() const override { return mVirtualPin; }
63 |
64 | /** Set the time of the fake clock. */
65 | void setClock(unsigned long millis) { mMillis = millis; }
66 |
67 | /** Set the virtual pin number. 0 means "no button pressed". */
68 | void setVirtualPin(uint8_t pin) { mVirtualPin = pin; }
69 |
70 | private:
71 | // Disable copy-constructor and assignment operator
72 | TestableEncodedButtonConfig(const TestableEncodedButtonConfig&) = delete;
73 | TestableEncodedButtonConfig& operator=(const TestableEncodedButtonConfig&)
74 | = delete;
75 |
76 | unsigned long mMillis;
77 | uint8_t mVirtualPin;
78 | };
79 |
80 | }
81 | }
82 | #endif
83 |
--------------------------------------------------------------------------------
/tests/IEventHandlerTest/IEventHandlerTest.ino:
--------------------------------------------------------------------------------
1 | #line 2 "IEventHandlerTest.ino"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | using namespace aunit;
10 | using namespace ace_button;
11 | using namespace ace_button::testing;
12 |
13 | // --------------------------------------------------------------------------
14 |
15 | class EventHandlerClass: public IEventHandler {
16 | public:
17 | EventHandlerClass(EventTracker* eventTracker):
18 | eventTracker_(eventTracker) {}
19 |
20 | void handleEvent(AceButton* button, uint8_t eventType,
21 | uint8_t buttonState) override {
22 | eventTracker_->addEvent(button->getPin(), eventType, buttonState);
23 | }
24 |
25 | private:
26 | EventTracker* eventTracker_;
27 | };
28 |
29 | TestableButtonConfig testableConfig;
30 | AceButton button(&testableConfig);
31 | EventTracker eventTracker;
32 | HelperForButtonConfig helper(&testableConfig, &button, &eventTracker);
33 | EventHandlerClass eventHandler(&eventTracker);
34 |
35 | const uint8_t PIN = 13;
36 | const uint8_t BUTTON_ID = 1;
37 |
38 | void setup() {
39 | #if ! defined(EPOXY_DUINO)
40 | delay(1000); // wait to prevent garbage on SERIAL_PORT_MONITOR
41 | #endif
42 |
43 | SERIAL_PORT_MONITOR.begin(115200);
44 | while (!SERIAL_PORT_MONITOR); // wait until ready - Leonardo/Micro only
45 |
46 | testableConfig.setIEventHandler(&eventHandler);
47 | }
48 |
49 | void loop() {
50 | TestRunner::run();
51 | }
52 |
53 | // --------------------------------------------------------------------------
54 | // Test IEventHandler
55 | // --------------------------------------------------------------------------
56 |
57 | test(press_and_release_pullup) {
58 | const uint8_t DEFAULT_RELEASED_STATE = HIGH;
59 | uint8_t expected;
60 |
61 | // reset the button
62 | helper.init(PIN, DEFAULT_RELEASED_STATE, BUTTON_ID);
63 |
64 | // initial button state
65 | helper.releaseButton(0);
66 | assertEqual(0, eventTracker.getNumEvents());
67 |
68 | // must wait until the initial debouncing
69 | helper.releaseButton(50);
70 | assertEqual(0, eventTracker.getNumEvents());
71 |
72 | // button pressed, but must wait to debounce
73 | helper.pressButton(100);
74 | assertEqual(0, eventTracker.getNumEvents());
75 |
76 | // still in debouncing period, so no event yet
77 | helper.releaseButton(110);
78 | assertEqual(0, eventTracker.getNumEvents());
79 |
80 | // after more than 50 ms, we should get an event
81 | helper.pressButton(190);
82 | assertEqual(1, eventTracker.getNumEvents());
83 | expected = AceButton::kEventPressed;
84 | assertEqual(expected, eventTracker.getRecord(0).getEventType());
85 | assertEqual(LOW, eventTracker.getRecord(0).getButtonState());
86 |
87 | // release the button
88 | helper.releaseButton(1000);
89 | assertEqual(0, eventTracker.getNumEvents());
90 |
91 | // wait more than 50 ms
92 | helper.releaseButton(1060);
93 | assertEqual(1, eventTracker.getNumEvents());
94 | expected = AceButton::kEventReleased;
95 | assertEqual(expected, eventTracker.getRecord(0).getEventType());
96 | assertEqual(HIGH, eventTracker.getRecord(0).getButtonState());
97 | }
98 |
--------------------------------------------------------------------------------
/examples/SingleButtonPullDown/SingleButtonPullDown.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * A demo of a simple AceButton used to handle the events from one button.
3 | * Pretty much the same as SingleButton.ino example but the button is wired with
4 | * an external pull-down resistor, instead of using the built-in pull-up
5 | * resistor.
6 | */
7 |
8 | #include
9 | #include
10 | using namespace ace_button;
11 |
12 | // The pin number attached to the button.
13 | const int BUTTON_PIN = 7;
14 |
15 | #ifdef ESP32
16 | // Different ESP32 boards use different pins
17 | const int LED_PIN = 2;
18 | #else
19 | const int LED_PIN = LED_BUILTIN;
20 | #endif
21 |
22 | // LED states. Some microcontrollers wire their built-in LED the reverse.
23 | const int LED_ON = HIGH;
24 | const int LED_OFF = LOW;
25 |
26 | // Automatically uses the default ButtonConfig. We will configure this later
27 | // using AceButton::init() method in setup() below.
28 | AceButton button;
29 |
30 | // Forward reference to prevent Arduino compiler becoming confused.
31 | void handleEvent(AceButton*, uint8_t, uint8_t);
32 |
33 | void setup() {
34 | delay(1000); // some microcontrollers reboot twice
35 | Serial.begin(115200);
36 | while (! Serial); // Wait until Serial is ready - Leonardo/Micro
37 | Serial.println(F("setup(): begin"));
38 |
39 | // initialize built-in LED as an output
40 | pinMode(LED_PIN, OUTPUT);
41 |
42 | // Button uses an external 10k resistor.
43 | pinMode(BUTTON_PIN, INPUT);
44 |
45 | // We use the AceButton::init() method here instead of using the constructor
46 | // to show an alternative. Using init() allows the configuration of the
47 | // hardware pin and the button to be placed closer to each other.
48 | button.init(BUTTON_PIN, LOW);
49 |
50 | // Configure the ButtonConfig with the event handler, and enable the LongPress
51 | // and RepeatPress events which are turned off by default.
52 | ButtonConfig* buttonConfig = button.getButtonConfig();
53 | buttonConfig->setEventHandler(handleEvent);
54 | buttonConfig->setFeature(ButtonConfig::kFeatureClick);
55 | buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
56 | buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
57 | buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
58 |
59 | Serial.println(F("setup(): ready"));
60 | }
61 |
62 | void loop() {
63 | // Should be called every 4-5ms or faster, for the default debouncing time
64 | // of ~20ms.
65 | button.check();
66 | }
67 |
68 | // The event handler for the button.
69 | void handleEvent(AceButton* /* button */, uint8_t eventType,
70 | uint8_t buttonState) {
71 |
72 | // Print out a message for all events.
73 | Serial.print(F("handleEvent(): eventType: "));
74 | Serial.print(AceButton::eventName(eventType));
75 | Serial.print(F("; buttonState: "));
76 | Serial.println(buttonState);
77 |
78 | // Control the LED only for the Pressed and Released events.
79 | // Notice that if the MCU is rebooted while the button is pressed down, no
80 | // event is triggered and the LED remains off.
81 | switch (eventType) {
82 | case AceButton::kEventReleased:
83 | digitalWrite(LED_PIN, LED_ON);
84 | break;
85 | case AceButton::kEventPressed:
86 | digitalWrite(LED_PIN, LED_OFF);
87 | break;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------