Skip to content

Commit 6b7d8bb

Browse files
committed
added selection between active-low/active-high
1 parent 9781bf1 commit 6b7d8bb

File tree

7 files changed

+173
-113
lines changed

7 files changed

+173
-113
lines changed

README.md

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,40 @@
11
## Bugtton
22
Fast button debounce library for ATmega328P. Uses registers instead of digitalRead.
3+
Library tries to minimize any excess cycle time when buttons are unpressed.
4+
Individual Active-Low and Active-High.
5+
6+
### Updates
7+
v1.0.5 you can set individual pins active-low (positive number), or active-high (negative number).
8+
9+
If you have ideas, hit me message or make an issue.
310

411
### Usage In nutshell
5-
Compact to use.
612
```
713
#include <Bugtton.h>
8-
const uint8_t buttonCount = 5;
9-
const uint8_t buttonPins[buttonCount] = {2,3,4,5,6};
10-
Bugtton buttons(buttonCount, buttonPins, INPUT_PULLUP, 25);
11-
--
14+
15+
const uint8_t buttonCount = 6;
16+
const uint8_t buttonPins[buttonCount] = {2,3,4,-5,6,7,14}; // pin5 with pull down resistor
17+
Bugtton buttons(buttonCount, buttonPins, 25);
18+
19+
void setup() {
20+
Serial.begin(57600);
21+
delay(500);
22+
}
23+
1224
void loop() {
13-
buttons.update();
14-
15-
if (buttons.fell(0)) //B0 down and debounced
16-
if (buttons.heldUntil(1,3000)) //B1 has been pressed 3 seconds
17-
--
25+
buttons.update();
26+
27+
// Testing buttons
28+
if (buttons.fell(0)) // Button0 pressed, execute once
29+
if (buttons.heldUntil(1,2000)) // Button1 down 2s, execute once
30+
if (buttons.intervalTick(2,1000)) // Button2 down, execute once every 1s
31+
}
1832
```
1933

2034
### Usable functions
2135
Function|Notes
2236
:--------|:--------
23-
**`Bugtton(buttonCount, *pinArray, mode, debounceTime)`**|*Creates button handler*<br>
37+
**`Bugtton(buttonCount, *pinArray, debounceTime)`**<br>|*Creates button handler*<br>
2438
**`void setMode(pin, mode)`**<br>|*If you need to set individual pins as INPUT and INPUT_PULLUP*
2539
**`void debounceTime(time)`**<br>|*If you need to test different debounce times*
2640
**`void update()`**<br>|*One update to rule them all*
@@ -31,11 +45,9 @@ Function|Notes
3145
**`bool held(button_i)`**<br>|*Is button_i pressed?*
3246
**`bool heldUntil(button_i, time)`**<br>|*Returns true ONCE when button_i have been pressed x time*
3347
**`bool upUntil(button_i, time)`**<br>|*Returns true ONCE when button_i have been unpressed x time*
34-
**`bool intervalTick(button_i, time)`**|*Returns true ONCE every set interval while button_i pressed*
35-
36-
I use long press functionality alot in my codes, so I wanted to add suitable functions for it. Feel free to suggest new ideas.
48+
**`bool intervalTick(button_i, time)`**<br>|*Returns true ONCE every set interval while button_i pressed*
3749

38-
### Why this library was made
50+
### Why another button library?
3951
Idea was to make fast button library when nothing is pressed so it would affect to the cycle time as little as possible.
4052

4153
Doesn't matter if you have 1 or 18 buttons, update() takes between 3100-3250 microseconds per 1000 update on unpressed buttons -> 3us per loop

examples/Functions/Functions.ino

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Functions example using Bugtton - button debounce library.
2+
// Created by Sami Kaukasalo / sakabug, July 20, 2021.
3+
4+
#include <Bugtton.h>
5+
6+
// Button count and button pin array
7+
// Default is Active-Low with pinMode INPUT_PULLUP
8+
// Negative pin number is Active-High with pinMode INPUT
9+
const uint8_t buttonCount = 6;
10+
const uint8_t buttonPins[buttonCount] = {2,-3,4,5,6,7}; // pin 3 on pull down resistor
11+
Bugtton buttons(buttonCount, buttonPins, 100);
12+
13+
void setup() {
14+
Serial.begin(57600);
15+
delay(500);
16+
buttons.debounceTime(25); // Changing debounce time
17+
buttons.setMode(7, INPUT); // Setting pinMode INPUT for pull down resistor
18+
}
19+
20+
void loop() {
21+
buttons.update();
22+
// Print every fell/rose
23+
for (uint8_t i=0; i<buttonCount; i++){
24+
if (buttons.fell(i)) {
25+
Serial.print("B");
26+
Serial.print(i);
27+
Serial.println(" fell");
28+
}
29+
if (buttons.rose(i)){
30+
Serial.print("B");
31+
Serial.print(i);
32+
Serial.println(" rose");
33+
}
34+
}
35+
if (buttons.heldUntil(2,3000)) Serial.println("B1 held for 3s. Mode activated.");
36+
if (buttons.held(3) && buttons.duration(3) >= 2000) Serial.println("Push it, baby");
37+
if (buttons.intervalTick(4,1000)) {
38+
Serial.print("B4 held for ");
39+
Serial.print(buttons.duration(4)/1000);
40+
Serial.println("s");
41+
}
42+
if (buttons.upUntil(5, 5000)) Serial.println("B5 haven't been pressed in 5s");
43+
}

examples/Multibutton/Multibutton.ino

Lines changed: 0 additions & 62 deletions
This file was deleted.

examples/Simple/Simple.ino

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Simple example using Bugtton - button debounce library.
2+
// Created by Sami Kaukasalo / sakabug, July 20, 2021.
3+
4+
#include <Bugtton.h>
5+
6+
// Button count and button pin array
7+
// Default is Active-Low with pinMode INPUT_PULLUP
8+
// Negative pin number is Active-High with pinMode INPUT
9+
const uint8_t buttonCount = 18;
10+
const uint8_t buttonPins[buttonCount] = {2,3,4,-5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
11+
Bugtton buttons(buttonCount, buttonPins, 25);
12+
13+
void setup() {
14+
Serial.begin(57600);
15+
delay(500);
16+
}
17+
18+
void loop() {
19+
20+
// Update button states handler
21+
buttons.update();
22+
23+
// Testing buttons
24+
for (uint8_t i=0; i<buttonCount; i++){
25+
if (buttons.fell(i)) {
26+
Serial.print("B");
27+
Serial.print(i);
28+
Serial.println(" fell");
29+
}
30+
if (buttons.rose(i)){
31+
Serial.print("B");
32+
Serial.print(i);
33+
Serial.println(" rose");
34+
}
35+
}
36+
}

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=Bugtton
2-
version=1.0.4
2+
version=1.0.5
33
author=Sami Kaukasalo <[email protected]>
44
maintainer=Sami Kaukasalo <[email protected]>
55
sentence=Fast button debounce library for ATmega328P. Uses registers instead of digitalRead.
6-
paragraph=It's fast and I want it faster.
6+
paragraph=Library tries to minimize any excess cycle time when buttons are unpressed. Individual Active-Low and Active-High.
77
category=Signal Input/Output
88
url=https://github.com/sakabug/Bugtton
99
architectures=avr

src/Bugtton.cpp

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// It's fast and I want it faster.
66

77
// Created by Sami Kaukasalo / sakabug, July 20, 2021.
8-
// Updated 9.12.2021
98

109
// MIT License
1110

@@ -32,26 +31,38 @@
3231
#include "Bugtton.h"
3332

3433
// Bugtton buttons(buttonCount, buttonPins(array), INPUT/INPUT_PULLUP, debounce time)
35-
Bugtton::Bugtton(const uint8_t a, const uint8_t *b, uint8_t mode, uint8_t dt){
34+
Bugtton::Bugtton(const uint8_t a, const uint8_t *b, uint8_t dt){
3635
// Init values
3736
_maskD = B00000000;
3837
_maskB = B00000000;
3938
_maskC = B00000000;
39+
_idleD = B00000000;
40+
_idleB = B00000000;
41+
_idleC = B00000000;
4042
_count = a;
4143
_debounceTime = dt;
4244
_allStable = false;
4345
_flag1 = false;
4446

45-
// Create buttons (was first separate classes, but this is the way I went)
47+
// Create buttons
4648
_pins = new uint8_t[_count];
4749
_bits = new uint8_t[_count];
4850
_stateStarted = new uint32_t[_count];
4951
_ticksStarted = new uint32_t[_count];
5052
// Init button data
5153
for(uint8_t i=0; i<_count; i++){
52-
setMode(b[i], mode);
53-
_pins[i] = b[i];
54-
_bits[i] = B11100000;
54+
// If pin # negative, it's inverted pin
55+
int8_t pin = b[i];
56+
if(pin<0){
57+
pin *= -1;
58+
_bits[i] = B11100001;
59+
setMode(pin, INPUT);
60+
}
61+
else{
62+
_bits[i] = B11100000;
63+
setMode(pin, INPUT_PULLUP);
64+
}
65+
_pins[i] = pin;
5566
_stateStarted[i] = 0;
5667
_ticksStarted[i] = 0;
5768
}
@@ -60,12 +71,30 @@ Bugtton::Bugtton(const uint8_t a, const uint8_t *b, uint8_t mode, uint8_t dt){
6071
makeMasks();
6172
}
6273

63-
// Bitmask for registers, formed from pin array
74+
// Bitmask for registers, formed from pin array, mark active registers
6475
void Bugtton::makeMasks(){
6576
for (uint8_t i=0; i<_count; i++){
66-
if (_pins[i] < 8) bitWrite(_maskD, _pins[i], 1);
67-
else if (_pins[i] >= 8 && _pins[i] < 14) bitWrite(_maskB, (_pins[i]-8), 1);
68-
else if (_pins[i] >= 14 && _pins[i] < 20) bitWrite(_maskC, (_pins[i]-14), 1);
77+
if (_pins[i] < 8) {
78+
// Write to maskD (active buttons)
79+
bitWrite(_maskD, _pins[i], 1);
80+
// Write to idleD (button idle state)
81+
if (flippedBit(i)) bitWrite(_idleD, _pins[i], 0);
82+
else bitWrite(_idleD, _pins[i], 1);
83+
}
84+
else if (_pins[i] >= 8 && _pins[i] < 14) {
85+
// Write to maskB (active buttons)
86+
bitWrite(_maskB, (_pins[i]-8), 1);
87+
// Write to idleB (button idle state)
88+
if (flippedBit(i)) bitWrite(_idleB, (_pins[i]-8), 0);
89+
else bitWrite(_idleB, (_pins[i]-8), 1);
90+
}
91+
else if (_pins[i] >= 14 && _pins[i] < 20) {
92+
// Write to maskC (active buttons)
93+
bitWrite(_maskC, (_pins[i]-14), 1);
94+
// Write to idleC (button idle state)
95+
if (flippedBit(i)) bitWrite(_idleC, (_pins[i]-14), 0);
96+
else bitWrite(_idleC, (_pins[i]-14), 1);
97+
}
6998
}
7099
}
71100

@@ -79,14 +108,14 @@ void Bugtton::printBIN(uint8_t b){
79108
// If you need set debounce time with code, THIS IS set at constructor
80109
void Bugtton::debounceTime(uint16_t a){ _debounceTime = a; }
81110

82-
// Updates all buttons at once, needs to run only once in loop, this is what I wanted
111+
// Updates all buttons at once, needs to run only once in loop
83112
void Bugtton::update(){
84-
_allUp = false;
85113
if (_allStable){
86-
if ((_maskD == (PIND&_maskD)) &&
87-
(_maskB == (PINB&_maskB)) &&
88-
(_maskC == (PINC&_maskC)) ){
89-
// if no buttons down, and buttons states are stable
114+
// Buttons unpressed?
115+
if ((_idleD == (PIND&_maskD)) &&
116+
(_idleB == (PINB&_maskB)) &&
117+
(_idleC == (PINC&_maskC)) ){
118+
// Let function run once, then keep skipping until changes in registers
90119
if (_flag1) {
91120
return;
92121
}
@@ -95,21 +124,25 @@ void Bugtton::update(){
95124
}
96125
//Update bits
97126
for (uint8_t i=0; i<_count; i++){
98-
99127
// Reset changedBit
100128
changedBit(i, 0);
101-
102-
// Update currentBit from registers
103-
if (_pins[i] < 8) currentBit(i, PIND&(1<<_pins[i]) );
104-
else if (_pins[i] < 14) currentBit(i, PINB&(1<<(_pins[i]-8) ));
105-
else if (_pins[i] < 20) currentBit(i, PINC&(1<<(_pins[i]-14) ));
106-
129+
// Active low (pull up)
130+
if ((_bits[i]&B00000001) == B00000000){
131+
if (_pins[i] < 8) currentBit(i, PIND&(1<<_pins[i]) );
132+
else if (_pins[i] < 14) currentBit(i, PINB&(1<<(_pins[i]-8) ));
133+
else if (_pins[i] < 20) currentBit(i, PINC&(1<<(_pins[i]-14) ));
134+
}
135+
// Active high (pull down)
136+
else{
137+
if (_pins[i] < 8) currentBit(i, !(PIND&(1<<_pins[i])) );
138+
else if (_pins[i] < 14) currentBit(i, !(PINB&(1<<(_pins[i]-8)) ));
139+
else if (_pins[i] < 20) currentBit(i, !(PINC&(1<<(_pins[i]-14)) ));
140+
}
107141
//No change in button state
108142
if ( currentBit(i) == oldBit(i)){
109143
stableBit(i, 1);
110144
_allStable = true;
111145
}
112-
113146
//Change in button state
114147
else {
115148
_allStable = false;
@@ -145,6 +178,8 @@ void Bugtton::heldUntilUsed(uint8_t i, bool a) { bitWrite(_bits[i], 3, a); }
145178
bool Bugtton::heldUntilUsed(uint8_t i) { return bitRead(_bits[i], 3); }
146179
void Bugtton::tickBit(uint8_t i, bool a) { bitWrite(_bits[i], 2, a); }
147180
bool Bugtton::tickBit(uint8_t i) { return bitRead(_bits[i], 2); }
181+
void Bugtton::flippedBit(uint8_t i, bool a) { bitWrite(_bits[i], 0, a); }
182+
bool Bugtton::flippedBit(uint8_t i) { return bitRead(_bits[i], 0); }
148183

149184
// Timestamps for debounce, and duration function
150185
void Bugtton::stateStarted(uint8_t i, uint32_t a){ _stateStarted[i] = a; }
@@ -246,8 +281,3 @@ bool Bugtton::intervalTick(uint8_t i, uint32_t t){
246281
}
247282
return false;
248283
}
249-
250-
251-
252-
253-

0 commit comments

Comments
 (0)