Pulsanti lenti a far avanzare il led

Ciao a tutti , sono arrivato ad un punto strano del mio progetto, praticamente con una combinazione di led scatta il rele', il problema e' che prima di poter premere ancora un pulsante sembrerebbe che il programma debba leggere prima tutto l array e poi mi permette di far funzionare ancora i pulsanti, potreste dare un occhiata al programma ?Grazie in anticipo

#define P 4
#define L 4
#define ABBASTANZA 5000
const byte PULSANTI [P] = {2, 3, 4, 5};
const byte LED [P][L] =
{
  6, 7, 8, 9,
  10, 11, 12, 13,
  14, 15, 16, 17,
  19, 18, 21, 20
};
#define RELE 22
const byte PASSWORD [P] = {0, 1, 2, 0};
byte puntatori [P];
const byte T_acceso = 500;
const byte T_spento = 500;
boolean fatto = true;
void setup()
{
  for (byte i = 0; i < P; i++)
  {
    pinMode (PULSANTI [i], INPUT);//Leggo tutto l'array di pulsanti e lo setto input
  }
  for (byte i = 0; i < P; i++)
  {
    for (byte j = 0; j < L; j++)
    {
      pinMode (LED [i][j], OUTPUT);

    }
    digitalWrite (LED [i][0], HIGH);//Accendo il primo led di ogni fila pulsanti (gli array cominciano con 0
  }
}
//fine setup()
void loop()
{
  for (byte i = 0; i < P; i++)
  {
    if (digitalRead (PULSANTI [i]))
    {
      digitalWrite (LED [i][puntatori[i]], LOW);
      puntatori [i]++;//Alzo di 1 il puntatore
      if (puntatori [i] == L)
      {
        puntatori [i] = 0;
      }
      digitalWrite (LED [i][puntatori[i]], HIGH);
      delay (ABBASTANZA);
    }
  }
  //Fine procedura cambio led. Inizio procedura confronto password
  boolean uguale = true;
  for (byte i = 0; i < P; i++)
  {
    if (PASSWORD [i] != puntatori [i])
    {
      uguale = false;
    }
  }
  if (uguale && fatto)
  {
    Setta(0);
    Lampeggiafila();
    Setta(0);
    Lampeggiatutti();
    Setta(0);
    digitalWrite (RELE, !digitalRead (RELE));
    fatto = true;
  }
}


void Lampeggiafila() {
  for (byte i = 0; i < L + 1; i++)
  {
    for (byte lucifinali = 0; lucifinali < L ; lucifinali++) {
      digitalWrite(LED[i][lucifinali], HIGH);
    }
    delay(1000);
    for (byte lucifinali = 0; lucifinali < L ; lucifinali++) {
      digitalWrite(LED[i][lucifinali], LOW);
    }
  }
}

void Setta(byte stato ) {
  for (byte i = 0; i < L + 1; i++)
  {
    for (byte lucispente = 0; lucispente < L + 1; lucispente++) {
      digitalWrite(LED[i][lucispente], stato);
    }
  }
}



void Lampeggiatutti() {

  for (byte a = 0; a < 4; a++)
  {
    Setta(1);
    delay (T_acceso);
    Setta(0);
    delay(T_spento);
  }

}

Nulla di strano, dei for con dentro addirittura dei delay sono bloccanti

nid69ita:
Nulla di strano, dei for con dentro addirittura dei delay sono bloccanti

quindi non hai idea del perche' ci mettano circa 10 secondi i pulsanti a funzionare ancora?

gtanix:
quindi non hai idea del perche' ci mettano circa 10 secondi i pulsanti a funzionare ancora?

Veramente l'idea ce l'ha molto chiara e te l'ha detta ... sei tu che non l'hai capita ... rileggi la sua risposta !

Guglielmo

gpb01:
Veramente l'idea ce l'ha molto chiara e te l'ha detta ... sei tu che non l'hai capita ... rileggi la sua risposta !

Guglielmo

si ma non ho capito quindi come dovrei procedere

...aggiungo che anche questo non è proprio "corretto":

const byte T_acceso = 500;
const byte T_spento = 500;

ogni una di queste due costanti non ha valore 500 ma 244.

per risolvere il tutto dovresti eliminare i delay() all'interno delle funzioni e ripensare al progetto usando millis()

ORSO2001:
...aggiungo che anche questo non è proprio "corretto":

const byte T_acceso = 500;

const byte T_spento = 500;



ogni una di queste due costanti non ha valore 500 ma 244.

per risolvere il tutto dovresti eliminare i delay() all'interno delle funzioni e ripensare al progetto usando millis()

ho capito grazie ora ci provo

nid69ita:
Nulla di strano, dei for con dentro addirittura dei delay sono bloccanti

gtanix:
si ma non ho capito quindi come dovrei procedere

Nid ha detto che quello che frenano sono i FOR in combinazione con i delay().
Per i delay puoi toglierli usando millis() (vedi esempio blink without delay)

Ciao Uwe

gpb01:
Veramente l'idea ce l'ha molto chiara e te l'ha detta ... sei tu che non l'hai capita ... rileggi la sua risposta !

Guglielmo

Guglielmo alla fine ho risolto cosi'(devo fare un altra domanda pero su questo programma si deve chiudere questa e se ne fa un altra o continuiamo qua?):

#define P 4
#define L 4
#define ABBASTANZA 500
#define LperP 4
const byte LEDperPULSANTI [P] [LperP] = { 23,24,25,26};
const byte PULSANTI [P] = {2, 3, 4, 5};
const byte LED [P][L] =
{
  6, 7, 8, 9,
  10, 11, 12, 13,
  14, 15, 16, 17,
  19, 18, 21, 20
};
#define RELE 22
const byte PASSWORD [P] = {0, 1, 2, 0};
byte puntatori [P];
const byte T_acceso = 500;
const byte T_spento = 500;
boolean fatto = true;
byte stato_pwd;
unsigned long start;
void setup()
{
  for (byte i = 0; i < P; i++)
  {
    pinMode (PULSANTI [i], INPUT);//Leggo tutto l'array di pulsanti e lo setto input
  }
  for (byte i = 0; i < P; i++)
  {
    for (byte j = 0; j < L; j++)
    {
      pinMode (LED [i][j], OUTPUT);

    }
    digitalWrite (LED [i][0], HIGH);//Accendo il primo led di ogni fila pulsanti (gli array cominciano con 0
  }
}
//fine setup()
void loop()
{
  for (byte i = 0; i < P; i++)
  {
    if (digitalRead (PULSANTI [i]))
      //Qui lo posso usare direttamente senza passare per una variabile perché appunto mi serve subito
    {
      digitalWrite (LED [i][puntatori[i]], LOW);
      //Magata: spengo il led (sicuramente acceso)
      //presente sotto il pulsante i, certamente premuto,
      //nella posizione attuale presa da un array di posizioni, nella posizione il cui numero è ancora i
      puntatori [i]++;//Alzo di 1 il puntatore
      if (puntatori [i] == L)
      {
        puntatori [i] = 0;
      }
      digitalWrite (LED [i][puntatori[i]], HIGH);
      delay (ABBASTANZA);
    }
  }
  Ledperpulsanti;
  if (!confronto())
  {
    stato_pwd = 0;
  }
  if (confronto() && stato_pwd == 0 )
  {
    start = millis();
    stato_pwd = 1;
  }
  if (stato_pwd == 1 )
  {
    if ( millis() - start > 5000)
    {
      stato_pwd = 2;
    }
  }
  if (stato_pwd == 2 )
  {
    gioco_luci();
    stato_pwd = 3;
  }
}


void Lampeggiafila() {
  for (byte i = 0; i < L + 1; i++)
  {
    for (byte lucifinali = 0; lucifinali < L ; lucifinali++) {
      digitalWrite(LED[i][lucifinali], HIGH);
    }
    delay(1000);
    for (byte lucifinali = 0; lucifinali < L ; lucifinali++) {
      digitalWrite(LED[i][lucifinali], LOW);
    }
  }
}

void Setta(byte stato ) {
  for (byte i = 0; i < L + 1; i++)
  {
    for (byte lucispente = 0; lucispente < L + 1; lucispente++) {
      digitalWrite(LED[i][lucispente], stato);
    }
  }
}



void Lampeggiatutti() {

  for (byte a = 0; a < 4; a++)
  {
    Setta(1);
    delay (T_acceso);
    Setta(0);
    delay(T_spento);
  }

}

byte confronto ()
{
  boolean uguale = true;
  for (byte i = 0; i < P; i++)
  {
    if (PASSWORD [i] != puntatori [i])
    {
      uguale = false;
    }
  }
  return (uguale);
}



void gioco_luci()
{
  Setta(0);
  Lampeggiafila();
  Setta(0);
  Lampeggiatutti();
  Setta(0);
  digitalWrite (RELE, !digitalRead (RELE));
  fatto = true;
}





void Ledperpulsanti()
{
  for (byte i = 0; i < P; i++)
  {
    digitalWrite (LEDperPULSANTI[i], digitalRead (PULSANTI[i]));
  }
}

gtanix:
... devo fare un altra domanda pero su questo programma si deve chiudere questa e se ne fa un altra o continuiamo qua?

Se l'argomento è lo stesso ... continua tranquillamente qui :slight_smile:

Guglielmo

grazie Guglielmo, allora il problema e'... ogni volta che premo il pulsante deve accendersi il led del pulsante (questi ultimi sono separati dagli altri led e con loro non centrano nulla), il programma dovrebbe funzionare tranquillamente ma purtroppo nulla, io per farlo andare ho usato una void ledperpulsanti che trovate nel programma , richiamata poi nella loop, voi che ne dite?

Stupenda la "#define ABBASTANZA 500"... :slight_smile:
Ci manca però anche una:

int Modà = !ABBASTANZA;

(scusate non ho resistito :wink: ).

Per tornare in argomento, praticamente hai abbassato il delay da 5000 (5 secondi) a 500 (mezzo secondo) ma c'è sempre un delay(). Inoltre ti avevano già segnalato che è scorretto fare:

const byte T_acceso = 500;
const byte T_spento = 500;

un "byte" ha valore massimo 255, non puoi dargli 500 come valore. O li fai diventare "int" o, essendo valori costanti, fai prima (e meglio) con due macro:

#define T_ACCESO 500
#define T_SPENTO 500

docdoc:
Stupenda la "#define ABBASTANZA 500"... :slight_smile:
Ci manca però anche una:

int Modà = !ABBASTANZA;

(scusate non ho resistito :wink: ).

Per tornare in argomento, praticamente hai abbassato il delay da 5000 (5 secondi) a 500 (mezzo secondo) ma c'è sempre un delay(). Inoltre ti avevano già segnalato che è scorretto fare:

const byte T_acceso = 500;
const byte T_spento = 500;

un "byte" ha valore massimo 255, non puoi dargli 500 come valore. O li fai diventare "int" o, essendo valori costanti, fai prima (e meglio) con due macro:

#define T_ACCESO 500
#define T_SPENTO 500

ah gia scusa, ho corretto per il byte, volevo dire che il delay mi funge da debounce

gpb01:
Se l'argomento è lo stesso ... continua tranquillamente qui :slight_smile:

Guglielmo

tu sapresti dirmi altro?

gtanix:
volevo dire che il delay mi funge da debounce

Debounce con un delay(500)? :astonished: (azz, dove sta la faccina che vomita?)

Beh comunque in questo caso se tu in vece di "ABBASTANZA" l'avessi chiamato "DEBOUNCE" uno avrebbe capito meglio (ah, i nomi significativi...)

Inoltre più che debounce ad occhio mi pare che se tieni premuto lo stesso tasto per più di mezzo secondo, viene ripetuta l'azione. tu dovresti invece aspettare che vada a LOW prima di proseguire (immagino che la digitazione sia sequenziale e non con due o più pulsanti contemporanei) ad aspettare il successivo.

docdoc:
Debounce con un delay(500)? :astonished: (azz, dove sta la faccina che vomita?)

Beh comunque in questo caso se tu in vece di "ABBASTANZA" l'avessi chiamato "DEBOUNCE" uno avrebbe capito meglio (ah, i nomi significativi...)

Inoltre più che debounce ad occhio mi pare che se tieni premuto lo stesso tasto per più di mezzo secondo, viene ripetuta l'azione. tu dovresti invece aspettare che vada a LOW prima di proseguire (immagino che la digitazione sia sequenziale e non con due o più pulsanti contemporanei) ad aspettare il successivo.

si certo sono d accordo, ora pero posso sembrare anche arrogante, pero ti chiedo un attimo di soffermarti sulla questione led per pulsanti, se analizzi bene la loop e la funzione in basso, tu che sei di sicuro piu esperto mi saprai correggere.

gtanix:
ti chiedo un attimo di soffermarti sulla questione led per pulsanti, se analizzi bene la loop e la funzione in basso, tu che sei di sicuro piu esperto mi saprai correggere.

Sto al lavoro quindi non è che possa studiarmi molto il codice, però intanto vedo questo:

const byte LEDperPULSANTI [P] [LperP] = { 23,24,25,26};

Tu stai definendo un array di byte (e fin qui ok), ma non ho capito perché hai messo 2 indici (P e LperP), ed in base a questo, perché hai messo solo 4 valori? Se P vale 4 ed anche LperP vale 4, dovresti avere 16 (4x4) elementi. Se i led sono solamente uno per pulsante, leva "LperP" e lascia solo il primo indice:

const byte LEDperPULSANTI [P] = { 23,24,25,26};

Ora passiamo alla funzione "Ledperpulsanti".

In sostanza dovrebbe aggiornare lo stato dei LED dei pulsanti in base ai pulsanti stessi, esatto? Per cui correggendo l'array LEDperPULSANTI come sopra, dovrebbe ora funzionare.

Ma dato che hai già una porzione di codice dove verifica se un pulsante sia premuto o meno, perché non metti lì l'accensione di quei led? Tra l'altro nei commenti leggo cose che non capisco (es. "spengo il led (sicuramente acceso) presente sotto il pulsante i, certamente premuto" :o ) ma tralascio.

Ad esempio nel loop() farei (per ora ignoro totalmente cosa fai con "puntatori[]" e relativa logica ma dò per scontato che vada bene):

  for (byte i = 0; i < P; i++)
  {
    if (digitalRead (PULSANTI [i]))
    {
      digitalWrite (LEDperPULSANTI[i], HIGH); // aggiunta accensione led del pulsante
      digitalWrite (LED [i][puntatori[i]], LOW);
      puntatori [i]++;//Alzo di 1 il puntatore
      if (puntatori [i] == L)
        puntatori [i] = 0;
      digitalWrite (LED [i][puntatori[i]], HIGH);
      delay (ABBASTANZA);
    }
    else  // aggiunto l'else per spegnere il led del pulsante
      digitalWrite (LEDperPULSANTI[i], LOW);
  }
  //Ledperpulsanti; questo non serve più

Per finire, qualche altro consiglio diciamo più che altro "stilistico", che quindi puoi accettare o meno visto che sono più che altro "convenzioni", ma penso siano utili per cercare sempre di fare un codice più leggibile, che significa anche rendere a te (e non solo) più facile il debug.

Intanto con identificativi lunghi è preferibile usare la cosiddetta forma "cammellata" ossia con le sole iniziali maiuscole e, più che altro per convenzione, la prima lettera minuscola (es. non "LEDperPULSANTI" ma "ledPerPulsanti") e più immediatamente rappresentativi del loro scopo (es. non "T_acceso" e "T_spento", ma "tempoON" e "tempoOFF", una funzione che aggiorna i led dei pulsanti la chiamerei "aggiornaLedPulsanti", e l'array dove metto i pin corrispondenti ai led "ledPulsanti[]").

Le maiuscole si usano solo per le costanti (come hai fatto) ma anche queste dandogli un nome più significativo possibile anche se relativamente abbreviato (es. non solo "P" ma "TOT_PULSANTI", e, come detto, non "ABBASTANZA" ma "DEBOUNCE" o "RITARDO_TASTO" ad esempio).

Poi le quadre che contengono gli indici (lo stesso vale per le parentesi delle funzioni) meglio metterle sempre vicino al nome per evidenziare più facilmente subito che si tratta di un array o una funzione (es. non "pinMode (PULSANTI , INPUT)" ma "pinMode(PULSANTI*, INPUT)" lo stesso quando richiamo una funzione, es. non "Ledperpulsanti;" meglio "Ledperpulsanti();") .*

docdoc:
...omissis

Poi le quadre che contengono gli indici (lo stesso vale per le parentesi delle funzioni) meglio metterle sempre vicino al nome per evidenziare più facilmente subito che si tratta di un array o una funzione (es. non

 "pinMode (PULSANTI [i], INPUT)

" ma "

pinMode(PULSANTI[i], INPUT)

" lo stesso quando richiamo una funzione, es. non "Ledperpulsanti;" meglio "Ledperpulsanti();") .

qui però il problema (presumibilmente) è dato dalla formattazione automatica del codice e dalle impostazioni del famoso format.conf se non le cambi ti mette automaticamente gli spazi.... almeno a me li metteva ed ho dovuto modificarlo...:wink:

docdoc:
Sto al lavoro quindi non è che possa studiarmi molto il codice, però intanto vedo questo:.....

grazie mille ho risolto cosi, pero' adesso ce un altro problema..... dal pin 22 fino al 53 non arriva bene la corrente e si accendono 2 led decentemente , 1 veramente poco e l'ultimo per nulla, consigli?

--- NON serve ogni volta quotare tutto il testo, basta una parte per far capire a che post ci si riferisce. Ho editato io, la prossima volta tienne conto. Grazie - gpb01

non so che resistenze ci siano sui led ma se ho capito bene 31 led* minimo 10mA l'uno fanno 310mA, forse sono troppi da ciucciare...