notsolowki:
yea i just realized i forget the opening and closing brackets of that last if statement. it seems like there is a lot of code involved in making a button detect short/long presses AND double/triple fast presses
Here is another that I wrote which instead uses callback functions (which are set in the constructor).
test sketch
#include "MultiPress.h"
#define LEDPIN 13
#define BUTTON_A 2
#define BUTTON_B 3
void A_ButtonActions(void); // Callback function definitions are required...
void B_ButtonActions(const int value);
MultiPress pushButtonSwitches[]= {
{BUTTON_A, 100, A_ButtonActions}, // pin, interval, callback-on-pressed
{BUTTON_B, 500, B_ButtonActions, true},
};
void setup()
{
Serial.begin(9600);
pinMode(LEDPIN, OUTPUT);
Serial.println(MultiPress::getCount());
MultiPress::beginAll();
MultiPress::setDebounceAll(50);
}
void loop()
{
MultiPress::update();
}
void A_ButtonActions(void) // simple example of registering "Pressed"
{
digitalWrite(LEDPIN, !digitalRead(LEDPIN));
}
void B_ButtonActions(const int value) // example of registering Multi-Presses
{
Serial.print(F("Button B:\t"));
switch(value)
{
case -1:
Serial.println(F("Long Press"));
break;
case 1:
Serial.println(F("One Press"));
break;
case 2:
Serial.println(F("Two Presses"));
break;
case 3:
Serial.println(F("Three Presses")); // can do more!
break;
default:
Serial.println(F("Whole Lotta Presses"));
break;
}
}
header:
#ifndef MULTIPRESS_H
#define MULTIPRESS_H
#include "Arduino.h"
#define MAX_BUTTON_INSTANCES 8
#define DEFAULT_DEBOUNCE_MILLISECONDS 75
class MultiPress{
using funcPtr = void(*)(void);
using returnFuncPtr = void(*)(const int value);
public:
MultiPress(int _pin, uint32_t _pressInterval, returnFuncPtr returnCallback, bool repeat = false);
MultiPress(int _pin, uint32_t _pressInterval, funcPtr _callBack);
bool begin();
int setDebounce(uint8_t dbounce);
static void setDebounceAll(uint8_t dbounce);
int8_t pressed();
static void update(void);
static bool beginAll();
static int getCount();
private:
// enum {
// NOT_PRESSED,
// PRESSED,
// } switchState;
bool repeatHold;
byte pressCount;
byte lastState;
byte pin;
uint32_t lastMillis;
uint8_t debouncePeriod;
uint16_t pressInterval;
returnFuncPtr returnCallback;
funcPtr callBack;
static uint8_t instanceCount;
static MultiPress* instances[MAX_BUTTON_INSTANCES];
};
#endif
implementation:
#include "MultiPress.h"
MultiPress* MultiPress::instances[MAX_BUTTON_INSTANCES];
uint8_t MultiPress::instanceCount = 0;
MultiPress::MultiPress(int _pin, uint32_t _pressInterval, returnFuncPtr _callback, bool repeat) : pin(_pin), pressInterval(_pressInterval), returnCallback(_callback), repeatHold(repeat){
debouncePeriod = DEFAULT_DEBOUNCE_MILLISECONDS;
instances[instanceCount] = this;
instanceCount++;
}
MultiPress::MultiPress(int _pin, uint32_t _pressInterval, funcPtr _callBack)
{
callBack = _callBack;
pin = _pin;
debouncePeriod = DEFAULT_DEBOUNCE_MILLISECONDS;
pressInterval = _pressInterval;
instances[instanceCount] = this;
instanceCount++;
}
bool MultiPress::begin()
{
pinMode(pin, INPUT_PULLUP);
lastState = HIGH;
Serial.println(pin);
return true;
}
bool MultiPress::beginAll()
{
for (size_t button = 0; button < instanceCount; button++)
{
instances[button]->begin();
}
return true;
}
void MultiPress::update(void)
{
for (size_t button = 0; button < instanceCount; button++)
{
int8_t pressed = instances[button]->pressed();
if(pressed)
{
if(instances[button]->returnCallback)
{
instances[button]->returnCallback(pressed);
}
else if(instances[button]->callBack)
{
instances[button]->callBack();
}
}
}
}
int8_t MultiPress::pressed()
{
byte nowState = digitalRead(pin);
if(nowState != lastState)
{
//Serial.println(F("CHANGED STATE"));
if(millis() - lastMillis < debouncePeriod) return 0;
if(nowState == LOW)
{
lastMillis = millis();
pressCount++;
}
else
{
if (millis() - lastMillis > pressInterval) // a long press
{
lastState = nowState;
pressCount = 0;
return -1;
}
}
}
if(pressCount != 0)
{
if(millis() - lastMillis > pressInterval and nowState == HIGH)
{
int presses = pressCount;
pressCount = 0;
return presses;
}
}
lastState = nowState;
return 0;
}
int MultiPress::setDebounce(uint8_t dbounce)
{
debouncePeriod = dbounce;
return debouncePeriod;
}
void MultiPress::setDebounceAll(uint8_t dbounce)
{
for (size_t button = 0; button < instanceCount; button++)
{
instances[button]->setDebounce(dbounce);
}
}
int MultiPress::getCount()
{
return instanceCount;
}