Pulsante per controllo led sk6812 (addressable strip led)

Ciao a tutti,
eccomi nuovamente a giocare con Arduino e chiedere a voi esperti. :slight_smile:
Stò lavorando su un progetto dove controllo una striscia led SK6812 (quelle indirizzabili) con arduino nano, dove ho creato vari effetti mettendoli in delle funzioni.
Tutto funziona bene fin che richiamo le funzioni nel loop principale ma vorrei aggiungere un o due pulsanti per poter cambiare la luminosità e l'effetto alla pressione di quest'ultimo/i.

Ho fatto uno sketch per lavorare con un pulsante utilizzando la libreria "ClickButton" e funziona sia il singolo click che il long press richiamando nel loop principale la funzione che gestisce le due tipologie di pressioni.

Il problema è che non posso unirli in quanto gli effetti possono anche richiedere tempo per la loro esecuzione e quindi se premo il pulsante durante una funzione che stà eseguendo un'animazione non succede nulla.
Questa funzione non può essere utilizzata come interrup perchè utilizza i millisec per lavorare e se non ho capito male negli interrup vengono sospesi anche quelli.

Esiste un modo per far eseguire ad arduino due cose contemporaneamente o come potrei integrare un/due pulsanti che vengano letti anche durante l'esecuzione di una funzione?

Grazie mille a tutti.

maw81maw:
Esiste un modo per far eseguire ad arduino due cose contemporaneamente o come potrei integrare un/due pulsanti che vengano letti anche durante l'esecuzione di una funzione?

Certo ... scrivendo BENE il codice e modificando le funzioni che sono bloccanti in funzioni che NON lo sono :slight_smile:
I casi in cui una cosa è veramente bloccante ... credo si contino sulle dita di una sola mano, tutti gli atri casi sono solo librerie scritte con i piedi, codice scritto male, analisi del problema non fatta, ecc. ecc.

Purtroppo, in questi casi, si deve prendere il programma, buttarlo e ripensarlo in tutt'altro modo ... ad esempio con la logica delle "macchine a stati finiti" o con tecniche che fanno una cosa alla volta suddividendo il tempo tra le varie cose.

Altri "trucchi" su piccole MCU come Arduino UNO, non ci sono ...

Guglielmo

P.S.: Considera che io un'applicazione (su ESP8266) che fa giochi di luce in continuazione su dei WS2812B (NeoPixel) e ... contemporaneamente non solo legge un pulsante, ma legge un RTC, controlla se è arrivata un'intera pagina WEB e cambia i giochi di colore di conseguenza e ... è solo fatta utilizzando la logica della "macchina a stati" senza altre cose.

Grazie Guglielmo,
non sò bene cosa s'intenda per "macchine a stati finiti" ma se devi far fare un ciclo lento di cambio colore, quinid un face lento tra un colore e l'altro come ti comporteresti?
cambi colore, poi esci e torni nel loop principale, poi rientri cambi colore e via dicendo e non utilizzeresti un ciclo for con un delay?

Se ti và di condividermi il tuo codice o parte per farmi capire sarà ben accetto. :slight_smile:

Intanto grazie.

Maw

P.S.: tenete presente che sono un niubbio.

maw81maw:
Se ti và di condividermi il tuo codice o parte per farmi capire sarà ben accetto. :slight_smile:

Sono svariate migliaia di righe ... fa parecchie cose, ma ... l'idea è quella che hai detto ...
... fai una funzione in cui memorizzi lo stato attuale del colore, ogni volta che la chiami passo allo stato successivo e ritorni indietro. Il loop() gira alla massima velocità, controlla i tasti, e chiama la funzione ... essa avanza di uno step e torna al loop() che continua a girare senza fermarsi mai.

L'importante è solo mantenere lo stato a cui è arrivata, ad ogni chiamata, la funzione che fa i giochi di luce. Lo puoi fare in due modi ...

  1. utilizzando una o più variabili globali, ma ... è la strada meno elegante.

  2. utilizzando la parlona magica "static" associata ad una o più variabili dentro la funzione ... ed è la strada più elegante.

Esempio di variabile dentro a funzione che CONSERVA il suo valore quando si esce e si rientra dalla funzione:

void miaFunzione(void) {
   static int miaVariabile;    // il valore di questa variabile rimane anche quando esco e poi rientro nella funzione
   ...
   ...
}

... ovviamente ... da usare con parsimonia perché, mentre le NON statiche vengono rilasciate e NON occupano memoria, le statiche rimangono li e occupano memoria anche quando la funzione non è richiamata :wink:

Guglielmo

P.S.: Se così fosse troppo veloce :slight_smile: ... puoi, con millis() decidere ogni quanti msec richiamare la funzione che cambia i colori ...

Prova a buttare giù la cosa ... poi, se hai difficoltà, ti passo un pezzetto di codice ... ma sono sicuro che, se capisci il meccanismo di "avanzare un passetto per volta" (ovvero uno stato alla volta), arrivi a fare tutto quello che vuoi senza fermare mai il programma :wink:

A, se cerchi (con la lente in alto a destra) la seguent dicitura in italiano "stati finiti", trovi molte discussioni in cui si è parlato di FMS (finite-state machine) e link a thread esplicativi :slight_smile:

Guglielmo

Grazie mille Guglielmo,
ci farò un pensiero, mi documenterò e ti scriverò hehehehe.

Grazie e buone feste.

Maw