I have develloped a class to dynamically read and debounce buttons. This class is eventually to be used with my state machine within separate files. At this point I am not entirely sure if a class is the proper solution. Perhaps that a struct is better for this use-case.
.cpp:
Button::Button(unsigned char _pin) {
pinMode(_button, INPUT_PULLUP);
pin = _pin; }
Button::unsigned char readButton() {
return state; }
Button::unsigned char updateButton() {
static bool oldSample = false;
static unsigned char statePrev;
bool newSample = digitalRead(pin);
if(newSample == oldSample) { // if the same state is detected atleast twice in 20ms...
if(newSample != statePrev) { // if a flank change occured return RISING or FALLING
statePrev = newSample;
if(newSample) state = RISING;
else state = FALLING; }
else { // or if there is no flank change return PRESSED or RELEASED
if(newSample) state = PRESSED;
else state = RELEASED; } }
oldSample = newSample;
return state; }
.h:
#ifndef button_h
#define button_h
enum states {
RISING,
FALLING,
PRESSED,
RELEASED };
class Button {
public:
Button(unsigned char _pin);
readButton();
updateButton();
private:
unsigned char state;
unsigned char pin; };
#endif
The works/idea:
To avoid confusions, I’ll use the word ‘level’ to indicate the actual voltage of the input pin. And the word ‘state’ refers to one of the 4 possible states of a button.
The function ‘updateButton()’ is called as a round robin tasks, once every ~20ms.
newSample is compared to oldSample for the debouncing part. If the same level is detected within 2 iterations, the button state is updated. This may be: rising, falling, pressed or released.
After I am sure that the flank is changed. I compare the new ‘level’ with the old one (‘statePrev’) to determen the new state of the button.
The first problem:
For every button there is the ‘updateButton’ function. I know I can stuff all buttons in the array using:
.. in io.h
#define buttonAmmount 3
enum buttonNames {
button1,
button2,
button3 };
.. setup:
Button buttons[buttonAmmount ] = {
Button(11),
Button(12),
Button(13) };
I am busy with letting scripts generate code for me and I want to manage my IO in a separate file “IO.h”.
To update the buttons in roundRobinTasks.c;
for(int i=0;i<buttonAmmount;i++) buttons[i].updateButton(); // right?
The problem:
The button objects are to be accessible in more than 1 file. Every state machine has it’s own cpp and h files and the round robin tasks are also in separate files. But how does one access all button objects from all files? I suppose I have to use a pointer, but how?
I know that with structs that I can simply make them extern (global) and every other file which includes that files has acces to these structs.
Am I good to go with a class or should I move back to structs?
P.S.
The button class is neither tested nor compiled yet.