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
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
6475void 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
80109void 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
83112void 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); }
145178bool Bugtton::heldUntilUsed (uint8_t i) { return bitRead (_bits[i], 3 ); }
146179void Bugtton::tickBit (uint8_t i, bool a) { bitWrite (_bits[i], 2 , a); }
147180bool 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
150185void 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