Libreria OneButton implementata su 4 pulsanti.

Ciao Forum
Un po di tempo passato a fare altro… E non frequentare lo splendido qui forum :slight_smile:
Ho un piccolo programma che vorrei portare avanti, nel tempo libero. Tra le cose che fa il programma c’è la gestione di eventi per quattro pulsanti.
A me sembra che ho fatto una cosa disordinata, visto che non sono a conoscenza di altre tecniche per poterlo fare in maniera più elegante.
Qui di seguito un esempio del programma riferito all’ uso dei pulsanti

#include <OneButton.h>
#define DEBUG

// create the buttons
OneButton menu(12,0);
OneButton select(13,0);
OneButton plus(14,0);
OneButton minus(15,0);

uint8_t pressed[4] = {0, 0, 0, 0};
uint8_t longpress[4] = {0, 0, 0, 0};

void menuclick() {
    /* a callback when the button is pressed
    */
#ifdef DEBUG
    Serial.println("MENU is click. ");
#endif
    pressed[MENU] = 1;                     // set pressed
    bklTime = bklDelay;                 // reset backlight timer
}

void menudoubleclick() {
    /* a callback when the button is clicked twice
    */
#ifdef DEBUG
    Serial.println("MENU is doubleclick. ");
#endif
    pressed[MENU] = 255;                  // set pressed to maximum
    bklTime = bklDelay;                 // reset backlight timer
}

void menurelease() {
    /* a callback when the button is released. So longpress returns to zero
    */
#ifdef DEBUG
    Serial.println("MENU is release. ");
#endif
    longpress[MENU] = 0;                  // clear the byte
    bklTime = bklDelay;                 // reset backlight timer
}

void menulongPress() {
#ifdef DEBUG
    Serial.println("MENU is longPress... ");
#endif
    if (longpress[MENU] < MAXWAIT) longpress[0]++;    // increase the count upto 11
    bklTime = bklDelay;                 // reset backlight timer
}
void selectclick() {
    /* a callback when the button is pressed
    */
#ifdef DEBUG
    Serial.println("SELECT is click. ");
#endif
    pressed[SELECT] = 1;                    // set pressed
    bklTime = bklDelay;                 // reset backlight timer
}

void selectdoubleclick() {
    /* a callback when the button is clicked twice
    */
#ifdef DEBUG
    Serial.println("SELECT is doubleclick. ");
#endif
    pressed[SELECT] = 255;                  // set pressed to maximum
    bklTime = bklDelay;                 // reset backlight timer
}

void selectrelease() {
    /* a callback when the button is released. So longpress returns to zero
    */
#ifdef DEBUG
    Serial.println("SELECT is release. ");
#endif
    longpress[SELECT] = 0;                  // clear the byte
    bklTime = bklDelay;                 // reset backlight timer
}

void selectlongPress() {
#ifdef DEBUG
    Serial.println("SELECT is longPress... ");
#endif
    if (longpress[SELECT] < MAXWAIT) longpress[SELECT]++;    // increase the count upto 11
    bklTime = bklDelay;                 // reset backlight timer
}
void minusclick() {
    /* a callback when the button is pressed
    */
#ifdef DEBUG
    Serial.println("MINUS is click. ");
#endif
    pressed[MINUS] = 1;                    // set pressed
    bklTime = bklDelay;                 // reset backlight timer
}

void minusdoubleclick() {
    /* a callback when the button is clicked twice
    */
#ifdef DEBUG
    Serial.println("MINUS is doubleclick. ");
#endif
    pressed[MINUS] = 255;                  // set pressed to maximum
    bklTime = bklDelay;                 // reset backlight timer
}

void minusrelease() {
    /* a callback when the button is released. So longpress returns to zero
    */
#ifdef DEBUG
    Serial.println("MINUS is release. ");
#endif
    longpress[MINUS] = 0;                  // clear the byte
    bklTime = bklDelay;                 // reset backlight timer
}

void minuslongPress() {
#ifdef DEBUG
    Serial.println("3 is longPress... ");
#endif
    if (longpress[MINUS] < MAXWAIT) longpress[MINUS]++;    // increase the count upto 11
    bklTime = bklDelay;                 // reset backlight timer
}
void plusclick() {
    /* a callback when the button is pressed
    */
#ifdef DEBUG
    Serial.println("PLUS is click. ");
#endif
    pressed[PLUS] = 1;                    // set pressed
    bklTime = bklDelay;                 // reset backlight timer
}

void plusdoubleclick() {
    /* a callback when the button is clicked twice
    */
#ifdef DEBUG
    Serial.println("PLUS is doubleclick. ");
#endif
    pressed[PLUS] = 255;                  // set pressed to maximum
    bklTime = bklDelay;                 // reset backlight timer
}

void plusrelease() {
    /* a callback when the button is released. So longpress returns to zero
    */
#ifdef DEBUG
    Serial.println("PLUS is release. ");
#endif
    longpress[PLUS] = 0;                  // clear the byte
    bklTime = bklDelay;                 // reset backlight timer
}

void pluslongPress() {
#ifdef DEBUG
    Serial.println("PLUS is longPress... ");
#endif
    if (longpress[PLUS] < MAXWAIT) longpress[PLUS]++;    // increase the count upto 11
    bklTime = bklDelay;                 // reset backlight timer
}

void setup()
{
    menu.setClickTicks(TMPRESS);            // set period for a click
    menu.setPressTicks(LNGPRESS);           // and a long press
    select.setClickTicks(TMPRESS);
    select.setPressTicks(LNGPRESS);
    minus.setClickTicks(TMPRESS);
    minus.setPressTicks(LNGPRESS);
    plus.setClickTicks(TMPRESS);
    plus.setPressTicks(LNGPRESS);
    menu.attachClick(menuclick);             // callback for the click
    menu.attachLongPressStop(menurelease);   // callback for button releas
    menu.attachDoubleClick(menudoubleclick);
    menu.attachDuringLongPress(menulongPress);
    select.attachClick(selectclick);
    select.attachLongPressStop(selectrelease);
    select.attachDoubleClick(selectdoubleclick);
    select.attachDuringLongPress(selectlongPress);
    minus.attachClick(minusclick);
    minus.attachLongPressStop(minusrelease);
    minus.attachDoubleClick(minusdoubleclick);
    minus.attachDuringLongPress(minuslongPress);
    plus.attachClick(plusclick);
    plus.attachLongPressStop(plusrelease);
    plus.attachDoubleClick(plusdoubleclick);
    plus.attachDuringLongPress(pluslongPress);
}

void loop()
{
    menu.tick();                        // detect menu button press
    select.tick();                      // detect select button press
    minus.tick();                       // detect minus button press
    plus.tick();                        // detect plus button press
}

Io penso che ci potrebbe essere anche un modo di non ripetere le chiamate alle callback di ogni pulsante in modo separato. in fondo fanno tutte la stessa cosa.
Pensavo ad una unica routine che passasse il valore per il pulsante ricercato. Sfortunatamente la libreria non accetta parametri (se ricordo bene) da poter passare ad ogni callback.

Qualche suggerimento ?
Grazie per l’ attenzione.

Link della libreria?

OneButton

Io stavo pensando all' overloading della classe OneButton. Per esempio

plus[] = OneButton.tick(PLUS);
minus[] = OneButton.tick(MINUS);

Da questo poi si può passare il puntatore e costruire i valori di ritorno. Chiaramente l' array può contenere i 6 stati del pulsante.

Oppure penso che tutti e quattro i pulsanti possano usare la stessa callback, ma solo una variabile globale deve dire quale valore dell' array cambiare, prima di chiamare tick().

A parte questo metodo, che usa un polling esagerato, pensavo anche ad usare l' Interrupt On Change per i piedini interessati. Al momento il problema è quello di individuare quale è stato premuto e che non sia affetto da rimbalzi.

In generale direi che la soluzione che uso attualmente di OneButton funziona, semplicemente occupa, nel mio programma 4 volte il necessario (Secondo me).

Potresti aprire una issue (in inglese) spiegando all'autore cosa vorresti fare. Potrebbe anche aiutarti.
--> GitHub - mathertel/OneButton: An Arduino library for using a single button for multiple purpose input.

C'è già qualcosa di simile.