@tslater & @peekay123: I know there might be better ways to do this and it’s not completely bullet proof, but here I’ve got a little demo code that supports short/long/excessive button-press recoginition via an interrupt.
The two range-check blocks can be filled with any functionality (including System.reset()
, WiFi.listen()
, …) and there is also the option for double tap recognition
//SYSTEM_THREAD(ENABLED)
SYSTEM_MODE(SEMI_AUTOMATIC)
STARTUP(prepare())
#define DEBOUNCE 5
#define SHORTPRESS 1500
#define LONGPRESS 3000
#define DBLTAP 1500
const int pinIRQ = D6;
volatile uint32_t blinkPattern = 0x88;
volatile uint32_t msTrig; // when was last reliable trigger
volatile uint32_t msPress; // when was the last press/hold
volatile uint32_t msRelease; // when did it get released
volatile uint32_t msHeld; // how long was it held
volatile uint32_t msDblTap; // how much time since last release
void ISR()
{
if (millis() - msTrig <= DEBOUNCE) return;
msTrig = millis();
if (!digitalRead(pinIRQ))
{ // PRESSED
msPress = msTrig;
msDblTap = msPress - msRelease;
msRelease = 0;
if (msDblTap > DBLTAP)
msDblTap = 0;
}
else
{ // RELEASED
msRelease = msTrig;
msHeld = msRelease - msPress;
msPress = 0;
// ******************** range check for hold time *********************
if (DEBOUNCE < msHeld && msHeld < SHORTPRESS)
blinkPattern = 0x08;
else if (SHORTPRESS < msHeld && msHeld < LONGPRESS)
blinkPattern = 0x80;
else
blinkPattern = 0x88;
// ********************************************************************
}
}
void prepare()
{
pinMode(D7, OUTPUT);
pinMode(pinIRQ, INPUT_PULLUP);
attachInterrupt(pinIRQ, ISR, CHANGE);
Particle.connect();
}
void setup() { }
void loop()
{
uint32_t msHold;
uint8_t factor = 0;
if (msPress)
{ // feedback during hold
msHold = millis() - msPress;
factor = 4; // dim the LED
}
else // after release
msHold = msHeld;
// ******************** range check for hold time *********************
if (DEBOUNCE < msHold && msHold < SHORTPRESS)
{
RGB.control(true);
RGB.color(0, 0, 255 >> factor);
}
else if (SHORTPRESS < msHold && msHold < LONGPRESS)
{
RGB.control(true);
RGB.color(255 >> factor ,128 >> factor, 0);
}
else
RGB.control(false);
// ********************************************************************
digitalWrite(D7, (millis() >> 2) & blinkPattern);
}
@tslater, have a play with the time constants and get a feel about the response time