Upgrade sw 4 tasti-4 led

Buongiorno a tutti, ho deciso di imparare ad uitilizzare Arduino, ma adesso sono bloccato a questo problema;
Questo semplice sketch, 1 tasto accende il corrispettivo led.

const int indicePin=4;
int cont=0; 
int stato=0;
int pinPulsanti[indicePin]={2,3,4,5};
int pinLed[indicePin]={10,11,12,13};
void setup() {
  for(cont=0; cont<indicePin; cont++)
  {
    pinMode(pinPulsanti[cont],INPUT);
    pinMode(pinLed[cont],OUTPUT);
  }
}

void loop() {
  for(cont=0; cont<indicePin; cont++)
  {
    stato=digitalRead(pinPulsanti[cont]);
    if(stato==HIGH)
    {
      digitalWrite(pinLed[cont],HIGH);
      }
      else
      {
        digitalWrite(pinLed[cont],LOW);
      }
    }
  }

All'inizio il sw nella parte accensione led, utilizzavo la funzione delay per tenere acceso il led tot. millisecondi e poi spegnersi, ma come ho appreso la funzione delay blocca Arduino e non permette di andare avanti nell'esecuzione del programma, ad esempio per accendere un 2°, 3° o 4° led.
Ho provato in tutti i modi, ma devo dire che non sono arrivato a capire la funzione millis appieno e quindi non riesco ad implementare questo sketch.
La mia domanda è se qualcuno potrebbe implementare il sw per fare in modo che, quando premo il tasto, un led rimanga acceso (es. 1000ms) cosi che io possa verificare che, accendendo un 2° led, il sw non si sia bloccato.
Spero di essermi spiegato, nel caso non esitate a chiedere.
Grazie per eventuali risposte.

Buongiorno, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ...

... poi, in conformità al suddetto regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread e sistemato il codice come da regolamento, nessuno ti potrà rispondere, quindi ti consiglio di fare il tutto al più presto. :wink:

ciao,

ti servono 4 variabili unsigned long (una per ogni LED),4 variabili per memorizzare il cambio stato del LED (o del pulsante) e una o più variabili/costanti per definire il tempo in cui mantenere lo stato acceso del LED.

poi...per ogni LED/pulsante (pseudo codice):

verifichi se stato memorizzato del pulsante è diverso dallo stato attuale
se passi da OFF ad ON
salvi nuovo stato
salvi il millis() su apposita variabile
imposti LED acceso
se passi da ON ad OFF
salvi nuovo stato

verifichi se millis()-millis salvato è > del timeout
se si spegni il LED

se queste variabili le metti in apposite array con un ciclo for fai tutte le verifiche....diversamente ripeti il codice per ogni LED/pulsante

PS: con questo codice se dovessi ripremere il pulsante prima del timeout il LED continuerebbe a restare acceso...se deve fare solo un ciclo e casomai se finito rifarlo...la questione è un po' diversa

ciao, grazie della risposta, ho riscritto il codice cosi:

const int indicePin=4;
int cont=0; 
int stato=0;
int t=0;
int debounce=4000;
int pinPulsanti[indicePin]={2,3,4,5};
int pinLed[indicePin]={10,11,12,13};
void setup() {
  for(cont=0; cont<indicePin; cont++)
  {
    pinMode(pinPulsanti[cont],INPUT);
    pinMode(pinLed[cont],OUTPUT);
  }
}

void loop() {
  for(cont=0; cont<indicePin; cont++)
  {
    stato=digitalRead(pinPulsanti[cont]);
    if(stato==HIGH) {
      t=millis();
      digitalWrite(pinLed[cont],HIGH);
      }
      else{
        if (millis()-t>debounce)
        digitalWrite(pinLed[cont],LOW);
      }
    }
  }

Non ho risolto del tutto il problema xké adesso riesco ad accendere anche piu led alla volta, ma fino a quando non si spegne l'ultimo led che accendo, tutti gli altri rimangono accesi fino a piu di 4 sec..

Hai usato una sola variabile tempo 't' per tutti.
Se devono essere indipendenti serve un array di variabili tempo.

poi...un "obbligo" ed un consiglio...l'obbligo è quello di usare variabili di tipo unsigned long per tutto ciò che è correlato a millis()...infatti la funzione millis() ritorna una unsigned long.
un consiglio...dato che su arduino hai poca memoria inizia a valutare il range che devi misurare/memorizzare ...ad esempio la variabile stato può essere true o false...quindi va bene una variabile tipo boolean o byte (che occupano entrambe 8 bit) anzichè una int (che occupa 16 bit) etc.

Ringrazio per la delucidazione sulle variabili. Non riesco ad implementare la funzione "t" come array...mi manca proprio un ragionamento di base a cui nn arrivo.

prova questo:

byte LED[4] = {10, 11, 12, 13}; // pin dei led
byte Pulsanti[4] = {2, 3, 4, 5}; // pin dei pulsanti
unsigned long t[4]; // array per memorizzare millis()
byte oldStatus[4] = {LOW, LOW, LOW, LOW}; // stato pulsante
unsigned long ritardo = 1000;

void setup() {
  for (byte i = 0; i < sizeof (Pulsanti); i++) {
    pinMode(Pulsanti[i], INPUT);
    pinMode(LED[i], OUTPUT);
  }
}

void loop() {

  for (byte i = 0; i < sizeof(Pulsanti); i++) { // ciclo sui pulsanti
    byte input = digitalRead(Pulsanti[i]); // leggo pulsante "i"
    if (input !oldStatus[i]) { //verifico se stato pulsante old è diverso dall'attuale
      if (input == HIGH && oldStatus[i] == LOW) { // se diverso e passo da LOW ad HIGH
        oldStatus[i] = input;
        t[i] = millis();
        digitalWrite(LED[i], HIGH);
      }
      if (input == LOW && oldStatus[i] == HIGH) { // se diverso ma passo da HIGH a LOW
        oldStatus[i] = input;
      }
    }
    if (millis() - t[i] > ritardo) { // verifico quanto tempo è passato da stato HIGH del pulsante e casomai spengo LED
      digitalWrite(LED[i], LOW);
    }
  }
}

Grazie per tutti i vostri consigli, alla fine sono riuscito ad arrivare allo scopo. Ringrazio ORSO2001 sia per il sw ma anche per l'utilizzo delle var. legato allo spazio di memoria. Posto il codice finale

const int indicePin=4;
int cont;
bool stato;
unsigned long t[4];;
unsigned long ritardo=4000;
bool oldStato[4]={LOW,LOW,LOW,LOW};
byte pinPulsanti[indicePin]={2,3,4,5};
byte pinLed[indicePin]={10,11,12,13};
void setup() {
  for(cont=0; cont<indicePin; cont++)
  {
    pinMode(pinPulsanti[cont],INPUT);
    pinMode(pinLed[cont],OUTPUT);
  }
}

void loop() {
  for(cont=0; cont<indicePin; cont++)
  {
    stato=digitalRead(pinPulsanti[cont]);
    if(stato==HIGH){
        oldStato[cont]=stato;
        t[cont]=millis();
        digitalWrite(pinLed[cont],HIGH);}
    if(stato==LOW) {
      oldStato[cont]=stato;
      if(millis()-t[cont]>ritardo){
        digitalWrite(pinLed[cont],LOW);
        t[cont]=millis();}
  }
}
}