Cronometro particolare x gare di pattinaggio

Ciao Pgiagno,
Ho fatto il programma come mi hai detto tu, sostituendo init() con begin() per l'LCD, ma mi da errore e non me lo caricava. inserendo init, mi ha caricato il programma.
ho editato per scrivere nelle altre corsie, e ci sono riuscito senza problema, ma ho un dubbio:

all'inizio del listato, c'è settato il pulsante all'uscita 11, (start) ma non sono settati i pulsanti di stop. Per settarli, riscrivo lo stesso pezzo di programma, sostituendo 11 con le porte che userò, ma non riesco a capire come abbinarlo alla linea del display specifica.

Ciao e grazie

Ivan

ecco il programma:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

#define BUTTON 11
int val;

void setup()
{
 pinMode(BUTTON, INPUT_PULLUP);
 lcd.init();                      // initialize the lcd 
 // Print a message to the LCD.
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("CORSIA 1 ");
 lcd.setCursor(0,1);
 lcd.print("CORSIA 2 ");
 lcd.setCursor(0,2);
 lcd.print("CORSIA 3 ");
 lcd.setCursor(0,3);
 lcd.print("CORSIA 4 ");
}

void loop()
{
 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,0);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,0);
   lcd.print("NON ATTIVA");
 }

 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,1);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,1);
   lcd.print("NON ATTIVA");
 }
 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,2);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,2);
   lcd.print("NON ATTIVA");
 }
 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,3);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,3);
   lcd.print("NON ATTIVA");
 }
 
}

>big-ivan: ti ricordo che in conformità al 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

Ciao,
Chiedo scusa, ma ero convinto che il code fosse un comando del programma, invece era per il forum!!!

Scusate ancora

Grazie
Ivan

Ciao pgiagno,
Se hai tempo, riesci a mandarmi lo scema elettrico, che inizio ad assemblarlo?

Grazie
Ivan

Devi definire altri pulsanti e associarli ad altri pin, ad es. così:

#define BUTTON1 11 //pulsante stop corsia 1
#define BUTTON2 10 //pulsante stop corsia 2
#define BUTTON3 9 //pulsante stop corsia 3
#define BUTTON4 8 //pulsante stop corsia 4

e quindi devi modificare così le istruzioni

. . .
 val = digitalRead((BUTTON1);
. . .
 val = digitalRead((BUTTON2);
. . .
 val = digitalRead((BUTTON3);
. . .
 val = digitalRead((BUTTON4);
. . .

Per lo schema elettrico non ho problemi, ma devi dirmi tu a quali pin di Arduino collegherai i vari dispositivi.

Io ti avevo inviato un esempio, che qui ripeto

//Il layout è composto da:
//- 4 luci verdi connesse ai pin 2, 3, 4, 5
//- 4 luci rosse connesse ai pin 6, 7, 8, 9
//- 1 sirena connessa al pin 10
//- 4 pulsanti di stop connessi ai pin A0, A1, A2, A3
//- 1 pulsante (start) connesso al pin 11
//- 1 pulsante di reset
//- 1 display lcd i2c connesso ai pin A4, A5
//
//La configurazione è la seguente:
//- CORSIA 1 led verde al pin 2, led rosso al pin 6, pulsante di stop al pin A0
//- CORSIA 2 led verde al pin 3, led rosso al pin 7, pulsante di stop al pin A1
//- CORSIA 3 led verde al pin 4, led rosso al pin 8, pulsante di stop al pin A2
//- CORSIA 4 led verde al pin 5, led rosso al pin 9, pulsante di stop al pin A3

ma tu sei partito con #define BUTTON 11, quindi dammi anche le altre corrispondenze.

Devi anche dirmi cosa userai per le luci verdi e rosse. Se userai led con assorbimenti inferiori a 20mA per led non occorrono transistor buffer, altrimenti devo prevederli.

Ciao,
P.

Si hai ragione!!!
Per i led, pensavo di mettere dei classici bicolori sul pannello comandi e sulla periferica di start, e un led Jumbo da 10mm sulla scatola del pulsante di stop.

Grazie ancora
ivan

Ricapitolando:

  • Ho bisogno di sapere a quali pin di Arduino vuoi connettere led e pulsanti. Se ti vanno bene quelli che ti ho proposto io, lo schema elettrico è già pronto, se ne vuoi altri, dimmi quali e io lo correggo.

  • Ogni led consuma di suo dai 10 ai 20 mA. Metterne altri in parallelo sul pannello comandi può portare l'assorbimento da ogni pin vicino al massimo assoluto (che è 40 mA per pin), ma comunque si può far in modo da starci. Però la domanda è: se sul pannello comandi c'è già il display che indica: CORSIA 1 PRONTA oppure CORSIA 1 NON ATTIVA, ha senso mettere anche un led? comunque se ti piace si può fare.

  • Ho bisogno di sapere che led hai preso, per capire quanto assorbono. Se li hai presi online posta un link.

Ciao,
P.

Ciao Pgiagno

Si i pin che mi hai elencato tu vanno benissimo, non cambia nulla per quel che mi riguarda.
I led bicolori che ho preso sono questi:

Per la domanda perché sia sulla consolle di start che sulla periferica esterna, è solamente per vedere la corsia non arriva a colpo d’occhio, senza dover leggere sul display. Ma se ci sono problemi di assorbimento, li metto solo sulla periferica esterna.

Inoltre i led jumbo Rossi che ho preso per vedere se in corsia il pulsante è stato premuto, sono questi:

Grazie ancora
Ivan

P.s. Scusa la latitanza di questi giorni ma ero in montagna per le feste di Pasqua e la connessione è scarsa (e nella casa non ho Wi-Fi).

In allegato lo schema che, come ti dicevo era già pronto.

I led bicolori vanno bene (perché usati?). Ci sono da dimensionare alcuni componenti come le resistenze di limitazione. È necessaria una resistenza differente per il verde e per il rosso perché hanno tensioni di soglia differenti e quindi assorbimenti differenti. È necessario che ciascuna parte del led bicolore NON assorba più di 10-15mA. Valori fra 270 e 330 ohm dovrebbero andar bene.

È stato previsto anche un circuito antirimbalzo per il pulsante di stop. Non dovrebbe essere necessario, data la funzione one-shot del pulsante, ma il lungo cavo potrebbe raccogliere sporcizia elettromagnetica e falsare lo stop. Questa sarà la PRIMA prova da fare: stendere un cavo lungo quanto ti servirà e vedere come si comporta in vicinanza di frigorifero, lavastoviglie, lavatrice, lampade al neon (favolose all'accensione, queste). A questo proposito per i connettori ti volevo segnalare che è possibile usare queste spine e queste prese . Si trovano anche cavi di connessione già intestati. Hanno il pregio di avere 8 fili twistati 2 a 2. Se ne possono usare 4 per i segnali e 4 per GND ottenendo anche un'ottima protezione contro i disturbi.

Se i led ripetitori sulla console assorbissero troppo si può mettere un transistor buffer. Per cui è un problema che si può risolvere dopo.

Credo che i led jumbo che hai scelto ti deluderanno. A mio avviso hanno un fascio molto concentrato. Io li ho colorati con lo smalto da unghie. Sono diventati accettabili.

Puoi ignorare il circuito per la sirena.

Con il software come va? (ahi, ahi).

Ciao,
P.

P.S. Sto sperimentando una connessione radio fra la console e i terminali di corsia, alimentati da power bank. L'incognita è il consumo. Vedremo.

Ciao,
i led sono nuovi non so perchè è indicato "usato".........per lo schema elettrico ok, ma i led jumbo rossi, li metto in parallelo agli altri (parte rossa)?
Questi servono solo per sapere se il pulsante è stato premuto e che lo sto sia avvenuto, direttamente da bordo corsia.

per quel che riguarda il il collegamento wireless, il problema consumo non lo vedo molto ptoblematico, in quando potrei procurarmi delle batterie LiPo a 2s (7.4v) a buon prezzo e di vari amperaggi, e cabiarle nella pausa pranzo. (ho collaborato per anni con una azienda che produceva e rivendeva batterie LiPo per modellismo e industriali.

Leggendo la tua sperimentazione wireless, mi è venuto in mente............perchè se funziona il collegamento senza fili, non metterci un rilevatore IR per rilevare il passaggio e fare uno stop automatico? :slight_smile: :slight_smile: lo so lo so, l'appetito vien mangiando!!!!

Per quel che riguarda il software, ancora non ci ho messo mano, perchè non avevo preso in montagna non avevo con me nessun computer!!!
Adesso vedo di mettermici dietro e vedo di riuscire a scrivere il programma.

grazie

Ivan

Ciao,
ho provato a editare il sw....
adesso se chiudo a massa il pin 11, riesco a far cambiare stato alle scritte da "pronta" a "non attiva", ma cambiano su tutte e 4 le corsie.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

#define BUTTON 11
#define BUTTON1 A0 //pulsante stop corsia 1
#define BUTTON2 A1 //pulsante stop corsia 2
#define BUTTON3 A2 //pulsante stop corsia 3
#define BUTTON4 A3 //pulsante stop corsia 4
#define LED 2 //led start corsia 1
#define LED 3 //led start corsia 2
#define LED 4 //led start corsia 3
#define LED 5 //led start corsia 4
#define LED 6 //led stop corsia 1
#define LED 7 //led stop corsia 2
#define LED 8 //led stop corsia 3
#define LED 9 //led stop corsia 4
int val;

void setup()
{
 pinMode(BUTTON, INPUT_PULLUP);
 lcd.init();                      // initialize the lcd 
 // Print a message to the LCD.
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("CORSIA 1 ");
 lcd.setCursor(0,1);
 lcd.print("CORSIA 2 ");
 lcd.setCursor(0,2);
 lcd.print("CORSIA 3 ");
 lcd.setCursor(0,3);
 lcd.print("CORSIA 4 ");
}

void loop()
{
 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,0);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,0);
   lcd.print("NON ATTIVA");
 }

 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,1);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,1);
   lcd.print("NON ATTIVA");
 }
 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,2);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,2);
   lcd.print("NON ATTIVA");
 }
 val = digitalRead(BUTTON);
 if (val == HIGH) {         //il pulsante è rilasciato
   lcd.setCursor(9,3);
   lcd.print("PRONTA    ");
 }
 if (val == LOW) {          //il pulsante è premuto
   lcd.setCursor(9,3);
   lcd.print("NON ATTIVA");
 }
 
}

dove sto sbagliando?

guardando lo schema, hai inserito i bicolori nelle corsie, mentre i bicolori sono solo sulla consolle esterna, mentre in corsia con il pulsante c'è solo il led jumbo rosso.

ciao e grazie

Ivan

Non avevo capito il posizionamento dei led. Aggiorno lo schema elettrico e te lo rinvio.

Per il wireless e il rilavatore IR... piano! Va bene che il proverbio dice che l'appetito vien mangiando, ma anche che non bisogna mettere troppa carne al fuoco. Comincia con lo stop manuale, poi vediamo. Il wireless per ora sembra rispondere bene, ma devo testare distanza e disturbi. Se si reinizializza durante una corsa sono guai. E una volta è successo. Devo capire perché.

Ho corretto e fatto un passo avanti col programma. Cerca di capire quello che ho aggiunto/corretto e fallo tuo. Togli i commenti che ho aggiunto per farti capire dove ho messo le mani.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

//DEFINIZIONI   //======commento aggiunto
#define BUTTONSTART 11 //pulsante di start  //======istruzione modificata
#define BUTTON1 A0 //pulsante stop corsia 1
#define BUTTON2 A1 //pulsante stop corsia 2
#define BUTTON3 A2 //pulsante stop corsia 3
#define BUTTON4 A3 //pulsante stop corsia 4
#define BUTTONSTART 11 //pulsante di start
#define LEDVERDE1 2 //led start corsia 1   //======istruzione modificata
#define LEDVERDE2 3 //led start corsia 2   //======istruzione modificata
#define LEDVERDE3 4 //led start corsia 3   //======istruzione modificata
#define LEDVERDE4 5 //led start corsia 4   //======istruzione modificata
#define LEDROSSO1 6 //led stop corsia 1    //======istruzione modificata
#define LEDROSSO2 7 //led stop corsia 2    //======istruzione modificata
#define LEDROSSO3 8 //led stop corsia 3    //======istruzione modificata
#define LEDROSSO4 9 //led stop corsia 4    //======istruzione modificata

//VARIABILI   //======commento aggiunto
int val;
bool statoCorsia1; //flag corsia1   //======istruzione aggiunta
bool statoCorsia2; //flag corsia2   //======istruzione aggiunta
bool statoCorsia3; //flag corsia3   //======istruzione aggiunta
bool statoCorsia4; //flag corsia4   //======istruzione aggiunta

void setup()
{
// pinMode(BUTTON, INPUT_PULLUP);    //======istruzione tolta
 pinMode(BUTTON1, INPUT_PULLUP);     //======istruzione aggiunta
 pinMode(BUTTON2, INPUT_PULLUP);     //======istruzione aggiunta
 pinMode(BUTTON3, INPUT_PULLUP);     //======istruzione aggiunta
 pinMode(BUTTON4, INPUT_PULLUP);     //======istruzione aggiunta
 pinMode(BUTTONSTART, INPUT_PULLUP); //======istruzione aggiunta
 pinMode(LEDVERDE1, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDVERDE2, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDVERDE3, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDVERDE4, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDROSSO1, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDROSSO2, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDROSSO3, OUTPUT);         //======istruzione aggiunta
 pinMode(LEDROSSO4, OUTPUT);         //======istruzione aggiunta

//spegni tutti i led                 //======commento aggiunto
 digitalWrite(LEDVERDE1, LOW);       //======istruzione aggiunta
 digitalWrite(LEDVERDE2, LOW);       //======istruzione aggiunta
 digitalWrite(LEDVERDE3, LOW);       //======istruzione aggiunta
 digitalWrite(LEDVERDE4, LOW);       //======istruzione aggiunta
 digitalWrite(LEDROSSO1, LOW);       //======istruzione aggiunta
 digitalWrite(LEDROSSO2, LOW);       //======istruzione aggiunta
 digitalWrite(LEDROSSO3, LOW);       //======istruzione aggiunta
 digitalWrite(LEDROSSO4, LOW);       //======istruzione aggiunta

 lcd.init();                      // initialize the lcd 

 // Print a message to the LCD.
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("CORSIA 1 ");
 lcd.setCursor(0,1);
 lcd.print("CORSIA 2 ");
 lcd.setCursor(0,2);
 lcd.print("CORSIA 3 ");
 lcd.setCursor(0,3);
 lcd.print("CORSIA 4 ");
 
//inizializza flag corsie      //======commento aggiunto
 statoCorsia1 = false;         //======istruzione aggiunta
 statoCorsia2 = false;         //======istruzione aggiunta
 statoCorsia3 = false;         //======istruzione aggiunta
 statoCorsia4 = false;         //======istruzione aggiunta
}

void loop()
{
//======commento aggiunto
/*Il programma si svolge in due fasi. La prima è una "loop infinita" che serve
 * solo a verificare lo stato di attività delle 4 corsie. Da questa loop
 * infinita si esce con l'istruzione "break;". In questo caso si esce nel
 * momento in cui viene premuto il pulsante di start. Alla pressione del
 * pulsante di start parte il cronometraggio e si entra in una seconda loop
 * infinita durante la quale si controllano i pulsanti rossi di stop relativi
 * ALLE SOLE CORSIE PRONTE. Per fare questo è necessario "tenere memoria" delle
 * corsie attive e di quelle non attive al momento della pressione del tasto
 * start all'uscita dalla prima loop infinita. Questo si ottiene tramite il
 * meccanismo delle "flag" che non sono altro che variabili booleane che vengono
 * posizionate a "true" o "false" a seconda dello stato che vogliono significare.
 * Al tuo programma ho aggiunto queste variabili (statoCorsia1, ...2, etc.) e il
 * loro posizionamento.
 * Ho aggiunto la gestione del led verde e della flag della prima corsia.
 * Alle altre pensaci tu
*/

 for (;;) {  //inizio loop infinita scansione corsie //======istruzione aggiunta
   val = digitalRead(BUTTON1); //======istruzione modificata
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,0);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE1, HIGH); //======istruzione aggiunta
     statoCorsia1 = true;           //======istruzione aggiunta
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,0);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDVERDE1, LOW); //======istruzione aggiunta
     statoCorsia1 = false;         //======istruzione aggiunta
   }
   val = digitalRead(BUTTON2); //======istruzione modificata
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,1);
     lcd.print("PRONTA    ");
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,1);
     lcd.print("NON ATTIVA");
   }
   val = digitalRead(BUTTON3); //======istruzione modificata
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,2);
     lcd.print("PRONTA    ");
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,2);
     lcd.print("NON ATTIVA");
   }
   val = digitalRead(BUTTON4); //======istruzione modificata
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,3);
     lcd.print("PRONTA    ");
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,3);
     lcd.print("NON ATTIVA");
   }
   val = digitalRead(BUTTONSTART); //======istruzione aggiunta
   if (val == LOW) {               //======istruzione aggiunta
     //è stato premuto il pulsante di start, si esce dalla prima loop infinita
     break;                        //======istruzione aggiunta
   }
 }  //FINE LOOP INFINITA SCANSIONE CORSIE   //======istruzione aggiunta
//inizia il cronometraggio e la scansione del pulsante rosso delle SOLE corsie
//attive
}

Ciao,
P.

Il nuovo schema elettrico.

Ciao,
P.

Ciao,
Ho guardato il listato, e oltre d aver capito come si assegnano le porte di ingresso dei pulsanti (non li avevo definiti), non sono riuscito ad accendere neanche un led, ma solo far andare i pulsanti di stop e reset. Se chiudo a massa il pulsante 11, non fa nulla.......................penso che manchi la parte di listato (millis) che fa partire il cronometraggio.
er quel che riguarda l'accensione dei led, ancora non ci ho capito nulla, ma ci studio un po sopra in questi gg.
Domenica vado a fare l'ultima gara di stagione (per questo tipo di gare, e vorrei portarmi la basetta da far vedere al comitato organizzativo (di cui farò parte nella stagione 2020), quindi dovrò studiare per bene i listati.

due cose, dato che ho un alimentatore stabilizzato da 5A da utilizzare, basta un 7805 in ingresso per portare la tensione a 5v?
Inoltre esiste un display sempre 20x4 ma di dimensioni più grandi?

grazie ancora

Ivan

oltre ad aver capito come si assegnano le porte di ingresso dei pulsanti

Bene, bravo.

Se chiudo a massa il pulsante 11, non fa nulla...penso che manchi la parte di listato (millis) che fa partire il cronometraggio

Esatto! Cerca di imbastirla, poi ti aiuto. Manca anche quella successiva di test dei pulsanti rossi, cha sarà un'altra loop infinita (for ( ; ; )) che terminerà quando il pulsante rosso dell'ULTIMA CORSIA ATTIVA sarà stato premuto. A quel punto i valori cronometrati verranno scritti sul display e il programma verrà fermato in attesa di un reset.

Per quel che riguarda l'accensione dei led, ancora non ci ho capito nulla

I led bicolori come i tuoi hanno tre terminali: uno per il colore rosso, uno per il colore verde e uno comune (catodo) per la massa (GND). Per accenderli occorre collegare il terminale centrale più lungo al meno dell'alimentazione. Poi si prende una resistenza con un valore compreso fra 270 e 470 ohm e la si mette in serie fra il più dell'alimentatore a 5V e uno dei due altri terminali. A questo punto, se il diodo funziona ed è a catodo comune, il diodo si accenderà di rosso o di verde a seconda del terminale che hai alimentato. Già che ci sei controlla con un milliamperometro (lo sai usare, vero?) quanta corrente assorbono con la resistenza che ci metti. Per avere circa la stessa corrente assorbita dal led verde e dal led rosso dovrai mettere due resistenze di valore diverso, perché i due led hanno tensioni di soglia differenti.

Per farli accendere da un pin dell'Arduino colleghi il terminale centrale comune (catodo) a GND e la resistenza al pin prescelto, inizializzato come OUTPUT. Con il comando "digitalWrite(pin, HIGH);" accendi il led, con il comando "digitalWrite(pin, LOW);" lo spegni.

dato che ho un alimentatore stabilizzato da 5A da utilizzare, basta un 7805 in ingresso per portare la tensione a 5v?

Suppongo che il tuo alimentatore stabilizzato sia da 12V. Lo schema che ti ho dato prevede un'alimentazione da 7 a 9V nel pin VIN per non stressare l'Arduino (che sopporta [male] anche il 12V sul pin VIN). Il pin VIN necessita di ALMENO 7V per far funzionare l'Arduino e gli eventuali led attaccati ai suoi pin. Puoi alimentare il tutto DIRETTAMENTE dal pin 5V con un 7805 montato su una piccola aletta di raffreddamento, con all'ingresso un elettrolitico da 100uF 16Vl in parallelo a un ceramico da 100nF e un elettrolitico da 10uF 16Vl più ceramico da 100nF all'uscita. Fa' attenzione a non sbagliare, il 5V NON è protetto da inversioni di polarità.

esiste un display sempre 20x4 ma di dimensioni più grandi?

Non conosco altri display 20x4 più grandi. Occorre passare a display grafici, ma cambiano sia il prezzo che la gestione.

Ciao,
P.

sono riuscito (dopo aver stampato il listato) a vedere cosa andava fatto per i led, modificando le stringhe che mi avevi dato d'esempio e modificandole in base all'uscita di accensione e di corsia.

Per l'accensione del led, devo comprare le resistenze, cosa che se non le prendo online, devo andare per forza a Bologna, perchè da noi non ci sono più negozi.
per quel che riguarda la funzione cronometro (millis), ho trovato qualcosa in rete, ma non sono riuscito a capire dove modificarlo, per fa scrivere minuti e secondi.

questo è quello che ho trovato online.........sulle pagine di Daniele Alberti

#include <Wire.h>
#include "rgb_lcd.h"
rgb_lcd lcd;
int pinpuls1 = 10;
int pinpuls2 = 11;
int statopuls1;
int statopuls2;
unsigned long tempo_base;
unsigned long tempo_cronometrato = 0;
unsigned long tempo_congelato;
unsigned long temposec;
int flag = 1;
void setup()
{
  delay(1000);
  lcd.begin(16, 2);
  lcd.setRGB(255, 255, 255);
  lcd.setCursor(0, 0);
  lcd.print("DanieleAlberti");
  lcd.setCursor(13, 1);
  lcd.print(".It");
  delay(3000);
  lcd.clear();
  lcd.setRGB(50, 100, 200);
  lcd.setCursor(2, 0);
  lcd.print("Cronometrino");
  pinMode (pinpuls1, INPUT_PULLUP);
  pinMode (pinpuls2, INPUT_PULLUP);
}
void loop()
{
  statopuls1 = digitalRead (pinpuls1);
  statopuls2 = digitalRead (pinpuls2);
  if ((statopuls1 == LOW) && (flag < 2))
  {
    tempo_base = millis();
    flag = 0;
  }
  if ((statopuls1 == LOW) && (flag == 2))
  {
    flag = 0;
  }
  if (flag == 0)
  {
    lcd.setRGB(200, 100, 00);
    lcd.setCursor(0, 0);
    lcd.print("TEMPO  (secondi)");
    lcd.setCursor(0, 1);
    lcd.print("PARTITO!    ");
    tempo_cronometrato = millis() - tempo_base;
    temposec = tempo_cronometrato / 1000;
    if (temposec <= 9)
    {
      lcd.setCursor(12, 1);
      lcd.print("   ");
      lcd.print(temposec);
    }
    if ((temposec > 9) && (temposec <= 99))
    {
      lcd.setCursor(12, 1);
      lcd.print("  ");
      lcd.print(temposec);
    }
    if ((temposec > 99) && (temposec <= 999))
    {
      lcd.setCursor(12, 1);
      lcd.print(" ");
      lcd.print(temposec);
    }
    if ((temposec > 999) && (temposec <= 9999))
    {
      lcd.setCursor(12, 1);
      lcd.print(temposec);
    }
  }
  if (statopuls2 == LOW)
  {
    lcd.setRGB(100, 200, 0);
    lcd.setCursor(0, 0);
    lcd.print("TEMPO (millisec)");
    lcd.setCursor(0, 1);
    lcd.print("STOP!    ");
    if ((tempo_cronometrato > 9) && (tempo_cronometrato <= 99))
    {
      lcd.setCursor(9, 1);
      lcd.print("     ");
      lcd.print(tempo_cronometrato);
    }
    if ((tempo_cronometrato > 99) && (tempo_cronometrato <= 999))
    {
      lcd.setCursor(9, 1);
      lcd.print("    ");
      lcd.print(tempo_cronometrato);
    }
    if ((tempo_cronometrato > 999) && (tempo_cronometrato <= 9999))
    {
      lcd.setCursor(9, 1);
      lcd.print("   ");
      lcd.print(tempo_cronometrato);
    }
    if ((tempo_cronometrato > 9999) && (tempo_cronometrato <= 99999))
    {
      lcd.setCursor(9, 1);
      lcd.print("  ");
      lcd.print(tempo_cronometrato);
    }
    if ((tempo_cronometrato > 99999) && (tempo_cronometrato <= 999999))
    {
      lcd.setCursor(9, 1);
      lcd.print(" ");
      lcd.print(tempo_cronometrato);
    }
    if ((tempo_cronometrato > 999999) && (tempo_cronometrato <= 9999999))
    {
      lcd.setCursor(9, 1);
      lcd.print(tempo_cronometrato);
    }
    flag = 2;
  }
}

ecco come ho editato la parte di programma per quel che riguarda i led:

for (;;) {  //inizio loop infinita scansione corsie 
   val = digitalRead(BUTTON1); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,0);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE1, HIGH);
     statoCorsia1 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,0);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO1, LOW); 
     statoCorsia1 = false;         
   }
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,1);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE2, HIGH); 
     statoCorsia2 = true;          
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,1);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO2, LOW); 
     statoCorsia2 = false;         

   }
   val = digitalRead(BUTTON3);
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,2);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE3, HIGH); 
     statoCorsia3 = true;          
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,2);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO3, LOW); 
     statoCorsia3 = false;        

   }
   val = digitalRead(BUTTON4); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,3);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE4, HIGH); 
     statoCorsia4 = true;          
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,3);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO4, LOW); 
     statoCorsia4 = false;

Per il display................ vedremo più avanti........quando riuscirò a far funzionare il tutto.

per il circuito di alimentazione, ok per l'inversione di polarità.
se per te il 7805 è troppo basso di voltaggio, posso anche utilizzare un 7809, con lo stesso circuito, teoricamente dovrebbe scaldare un po meno :slight_smile:

ciao e grazie

Ivan

Per l'accensione del led, devo comprare le resistenze, cosa che se non le prendo online, devo andare per forza a Bologna, perchè da noi non ci sono più negozi.

Nonostante abiti a Milano io mi servo solo online. Ampia scelta e pago meno di qualsiasi negozio. Ti consiglierei di prenderti un kit completo, per quello che costa. Ad esempio questo.

per quel che riguarda la funzione cronometro (millis)

Per quello che riguarda il progetto ti basta sapere che la funzione millis() è una funzione che quando viene chiamata fornisce IL TEMPO IN MILLISECONDI DALL'ACCENSIONE (O RESET) DELL'ARDUINO. Questo significa che, dopo il caricamento del programma, non appena l'Arduino parte, un contatore interno al processore comincia a contare i millisecondi partendo da 0. Se leggi il reference della funzione, apprendi che, trattandosi di un contatore a 32 bit (unsigned long), questo si azzererà DA SOLO dopo circa 50 giorni. Non c'è quindi pericolo di overflow e sballo nei conteggi.

Come puoi usarlo come cronometro nel progetto? È semplice: definisci cinque variabili del tipo unsigned long, che chiamerai ad es. startTime, corsia1Time, corsia2Time, corsia3Time e corsia4Time. Alla pressione del tasto start memorizzerai nella variabile startTime il valore di millis() così:

 startTime = millis();

Poi passerai a testare i pulsanti rossi DELLE SOLE CORSIE ATTIVE. Non appena un pulsante rosso viene premuto memorizzerai nella variabile corrispondente il valore che avrà assunto millis() in quel momento così:

 corsia1Time = millis();

Il tempo realizzato (in millisecondi) sarà dato dalla differenza fra i due valori

 time1 = corsia1Time - startTime;

Poi bisogna trasformarlo in minuti, secondi, millesimi di secondo e scriverlo sul display

ecco come ho editato la parte di programma per quel che riguarda i led:

La guardo domattina, ma metti sempre il codice al completo.

posso anche utilizzare un 7809, con lo stesso circuito, teoricamente dovrebbe scaldare un po meno

Esatto, benissimo. Così puoi alimentare il tutto da VIN.

Ciao,
P.

ecco quello che ho scritto, ma sicuramente ho fatto un'errore perchè mi segnala un'anomalia.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

#define BUTTONSTART 11 //pulsante di start 
#define BUTTON1 A0 //pulsante stop corsia 1
#define BUTTON2 A1 //pulsante stop corsia 2
#define BUTTON3 A2 //pulsante stop corsia 3
#define BUTTON4 A3 //pulsante stop corsia 4
#define LEDVERDE1 2 //led start corsia 1 
#define LEDVERDE2 3 //led start corsia 2 
#define LEDVERDE3 4 //led start corsia 3 
#define LEDVERDE4 5 //led start corsia 4   
#define LEDROSSO1 6 //led stop corsia 1    
#define LEDROSSO2 7 //led stop corsia 2    
#define LEDROSSO3 8 //led stop corsia 3    
#define LEDROSSO4 9 //led stop corsia 4    

int val;
bool statoCorsia1; //flag corsia1   
bool statoCorsia2; //flag corsia2   
bool statoCorsia3; //flag corsia3   
bool statoCorsia4; //flag corsia4   

void setup()
{
 startTime = millis();
 corsia1Time = millis();
 corsia2Time = millis();
 corsia3Time = millis();
 corsia4Time = millis();
 time1 = corsiaTime1 – startTime;
 time2 = corsiaTime2 – startTime;
 time3 = corsiaTime3 – startTime;
 time4 = corsiaTime4 – startTime;
 pinMode(BUTTON1, INPUT_PULLUP);     
 pinMode(BUTTON2, INPUT_PULLUP);     
 pinMode(BUTTON3, INPUT_PULLUP);     
 pinMode(BUTTON4, INPUT_PULLUP);     
 pinMode(BUTTONSTART, INPUT_PULLUP); 
 pinMode(LEDVERDE1, OUTPUT);         
 pinMode(LEDVERDE2, OUTPUT);         
 pinMode(LEDVERDE3, OUTPUT);         
 pinMode(LEDVERDE4, OUTPUT);         
 pinMode(LEDROSSO1, OUTPUT);         
 pinMode(LEDROSSO2, OUTPUT);         
 pinMode(LEDROSSO3, OUTPUT);         
 pinMode(LEDROSSO4, OUTPUT);         

 digitalWrite(LEDVERDE1, LOW);       
 digitalWrite(LEDVERDE2, LOW);       
 digitalWrite(LEDVERDE3, LOW);       
 digitalWrite(LEDVERDE4, LOW);       
 digitalWrite(LEDROSSO1, LOW);       
 digitalWrite(LEDROSSO2, LOW);       
 digitalWrite(LEDROSSO3, LOW);       
 digitalWrite(LEDROSSO4, LOW);       

 lcd.init();                      // initialize the lcd 

 // Print a message to the LCD.
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("CORSIA 1:");
 lcd.setCursor(0,1);
 lcd.print("CORSIA 2:");
 lcd.setCursor(0,2);
 lcd.print("CORSIA 3:");
 lcd.setCursor(0,3);
 lcd.print("CORSIA 4:");
 
//inizializza flag corsie      
 statoCorsia1 = false;         
 statoCorsia2 = false;         
 statoCorsia3 = false;         
 statoCorsia4 = false;         
}

void loop()
{

 for (;;) {  //inizio loop infinita scansione corsie 

   val = digitalRead(BUTTON1); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,0);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE1, HIGH); 
     statoCorsia1 = true; 
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,0);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO1, LOW); 
     statoCorsia1 = false;         
   }
   val = digitalRead(BUTTON2); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,1);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE2, HIGH); 
     statoCorsia2 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,1);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO2, LOW); 
     statoCorsia2 = false;         

   }
   val = digitalRead(BUTTON3); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,2);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE3, HIGH); 
     statoCorsia3 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,2);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO3, LOW); 
     statoCorsia3 = false;         

   }
   val = digitalRead(BUTTON4); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,3);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE4, HIGH); 
     statoCorsia4 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,3);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO4, LOW); 
     statoCorsia4 = false;         

   }
   val = digitalRead(BUTTONSTART); 
   if (val == LOW) {               
     //è stato premuto il pulsante di start, si esce dalla prima loop infinita
     break;                        
   }
 }  //FINE LOOP INFINITA SCANSIONE CORSIE   
}

ciao e grazie

Ivan

Forse mi sono spiegao male sul funzionamento di millis().

millis() è una funzione DINAMICA. Significa che ti da un valore nel momento in cui la "fotografi". Corrisponde al "tempo parziale" di un cronometro normale. Quindi all'avvio di Arduino il cronometro (millis()) parte da solo e da quel momento tu puoi solo calcolare i tempi per differenza fra una prima "fotografia" (alla pressione del tasto start) e una seconda "fotografia" (alla pressione del tasto stop)- Allora alla pressione del tasto start devi memorizzare il valore di millis() e poi lo devi memorizzare in un'altra variabile alla pressione del tasto stop. Il tempo impiegato dal concorrente è dato dalla differenza dei due valori. Ho corretto il programma.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

#define BUTTONSTART 11 //pulsante di start 
#define BUTTON1 A0 //pulsante stop corsia 1
#define BUTTON2 A1 //pulsante stop corsia 2
#define BUTTON3 A2 //pulsante stop corsia 3
#define BUTTON4 A3 //pulsante stop corsia 4
#define LEDVERDE1 2 //led start corsia 1 
#define LEDVERDE2 3 //led start corsia 2 
#define LEDVERDE3 4 //led start corsia 3 
#define LEDVERDE4 5 //led start corsia 4   
#define LEDROSSO1 6 //led stop corsia 1    
#define LEDROSSO2 7 //led stop corsia 2    
#define LEDROSSO3 8 //led stop corsia 3    
#define LEDROSSO4 9 //led stop corsia 4    

int val;
bool statoCorsia1; //flag stato corsia1   
bool statoCorsia2; //flag stato corsia2   
bool statoCorsia3; //flag stato corsia3   
bool statoCorsia4; //flag stato corsia4   
bool stopCorsia1;  //flag stop corsia1   //======istruzione aggiunta
bool stopCorsia2;  //flag stop corsia2   //======istruzione aggiunta   
bool stopCorsia3;  //flag stop corsia3   //======istruzione aggiunta
bool stopCorsia4;  //flag stop corsia4   //======istruzione aggiunta
unsigned long startTime;           //======istruzione aggiunta
unsigned long corsia1Time;         //======istruzione aggiunta
unsigned long corsia2Time;         //======istruzione aggiunta
unsigned long corsia3Time;         //======istruzione aggiunta
unsigned long corsia4Time;         //======istruzione aggiunta
unsigned long time1;               //======istruzione aggiunta
unsigned long time2;               //======istruzione aggiunta
unsigned long time3;               //======istruzione aggiunta
unsigned long time4;               //======istruzione aggiunta

void setup()
{
// startTime = millis();            //======istruzione eliminata
// corsia1Time = millis();          //======istruzione eliminata
// corsia2Time = millis();          //======istruzione eliminata
// corsia3Time = millis();          //======istruzione eliminata
// corsia4Time = millis();          //======istruzione eliminata
// time1 = corsiaTime1 - startTime; //======istruzione eliminata
// time2 = corsiaTime2 - startTime; //======istruzione eliminata
// time3 = corsiaTime3 - startTime; //======istruzione eliminata
// time4 = corsiaTime4 - startTime; //======istruzione eliminata

//Inizializza pin I/O
 pinMode(BUTTON1, INPUT_PULLUP);     
 pinMode(BUTTON2, INPUT_PULLUP);     
 pinMode(BUTTON3, INPUT_PULLUP);     
 pinMode(BUTTON4, INPUT_PULLUP);     
 pinMode(BUTTONSTART, INPUT_PULLUP); 
 pinMode(LEDVERDE1, OUTPUT);         
 pinMode(LEDVERDE2, OUTPUT);         
 pinMode(LEDVERDE3, OUTPUT);         
 pinMode(LEDVERDE4, OUTPUT);         
 pinMode(LEDROSSO1, OUTPUT);         
 pinMode(LEDROSSO2, OUTPUT);         
 pinMode(LEDROSSO3, OUTPUT);         
 pinMode(LEDROSSO4, OUTPUT);         

//Spegni tutti i led
 digitalWrite(LEDVERDE1, LOW);       
 digitalWrite(LEDVERDE2, LOW);       
 digitalWrite(LEDVERDE3, LOW);       
 digitalWrite(LEDVERDE4, LOW);       
 digitalWrite(LEDROSSO1, LOW);       
 digitalWrite(LEDROSSO2, LOW);       
 digitalWrite(LEDROSSO3, LOW);       
 digitalWrite(LEDROSSO4, LOW);       

 lcd.init();                      // initialize the lcd 

//Inizializza il display
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("CORSIA 1:");
 lcd.setCursor(0,1);
 lcd.print("CORSIA 2:");
 lcd.setCursor(0,2);
 lcd.print("CORSIA 3:");
 lcd.setCursor(0,3);
 lcd.print("CORSIA 4:");
 
//inizializza flag corsie e stop
 statoCorsia1 = false;         
 statoCorsia2 = false;         
 statoCorsia3 = false;         
 statoCorsia4 = false;         
 stopCorsia1 = false;         //======istruzione aggiunta
 stopCorsia2 = false;         //======istruzione aggiunta
 stopCorsia3 = false;         //======istruzione aggiunta
 stopCorsia4 = false;         //======istruzione aggiunta
}

void loop()
{

 for (;;) {  //inizio loop infinita scansione corsie 

   val = digitalRead(BUTTON1); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,0);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE1, HIGH); 
     statoCorsia1 = true; 
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,0);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO1, LOW); 
     statoCorsia1 = false;         
   }
   val = digitalRead(BUTTON2); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,1);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE2, HIGH); 
     statoCorsia2 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,1);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO2, LOW); 
     statoCorsia2 = false;         

   }
   val = digitalRead(BUTTON3); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,2);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE3, HIGH); 
     statoCorsia3 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,2);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO3, LOW); 
     statoCorsia3 = false;         

   }
   val = digitalRead(BUTTON4); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,3);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE4, HIGH); 
     statoCorsia4 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,3);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO4, LOW); 
     statoCorsia4 = false;         

   }
   val = digitalRead(BUTTONSTART); 
   if (val == LOW) {               
     //è stato premuto il pulsante di start, si esce dalla prima loop infinita
     break;                        
   }
 }  //FINE LOOP INFINITA SCANSIONE CORSIE
 
//======inizio parte aggiunta
//È stato premuto il tasto start
 startTime = millis();         //memorizza millisecondo di start
 //Segnala sul display le corsie che stanno cronometrando
 if (statoCorsia1 == true) {   //se CORSIA 1 attiva
   lcd.setCursor(9, 0);        //segnala che si sta cronometrando
   lcd.print("CRONOMETRO");
 }
//INSERISCI QUI DI SEGUITO LA SEGNALAZIONE PER LE ALTRE CORSIE
// . . .
//INIZIA LOOP INFINITA PER IL TEST DEI PULSANTI ROSSI
 for (;;) {
   //controllo tasto rosso corsia1
   if (statoCorsia1 == true &&        //se la corsia è attiva
       stopCorsia1 == false &&        //se il tempo non è ancora stato preso
       digitalRead(BUTTON1) == LOW) { //se il tasto rosso è stato premuto
     //se tutte queste condizioni sono soddisfatte, allora
     corsia1Time = millis();          //blocca il cronometro per CORSIA 1
     digitalWrite(LEDVERDE1, LOW);    //spegni la luce verde
     digitalWrite(LEDROSSO1, HIGH);   //accendi la luce rossa
     stopCorsia1 = true;              //segnala tasto rosso già premuto
   }
//INSERISCI QUI DI SEGUITO LA SEGNALAZIONE PER LE ALTRE CORSIE
// . . .
 }
//======fine parte aggiunta

}

Ti ho anche inserito la prima parte del seguito del programma. Come puoi vedere è stato necessario inserire altre "flag" di segnalazione per l'avvenuto stop al cronometro per QUELLA corsia mentre si esaminano le altre, altrimenti il cronometro verrebbe ri-stoppato a ogni passaggio. Quindi durante la seconda loop infinita le condizioni per lo "stop al cronometro" per OGNI corsia sono:

  • che la corsia sia attiva;
  • che il tasto rosso sia premuto (LOW);
  • che lo "stop al cronometro" non sia già stato fatto.
    Se una sola di questa condizioni non è soddisfatta (AND logico) si salta alla successiva corsia senza far niente.

Correggi il programma e aggiungi le parti mancanti. Poi postalo ancora per intero che andiamo avanti.

Ciao,
P.

Buongiorno (vedo che sei mattiniero come me""")

ecco cio che ho fatto stamattina:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 20 chars and 4 line display

#define BUTTONSTART 11 //pulsante di start 
#define BUTTON1 A0 //pulsante stop corsia 1
#define BUTTON2 A1 //pulsante stop corsia 2
#define BUTTON3 A2 //pulsante stop corsia 3
#define BUTTON4 A3 //pulsante stop corsia 4
#define LEDVERDE1 2 //led start corsia 1 
#define LEDVERDE2 3 //led start corsia 2 
#define LEDVERDE3 4 //led start corsia 3 
#define LEDVERDE4 5 //led start corsia 4   
#define LEDROSSO1 6 //led stop corsia 1    
#define LEDROSSO2 7 //led stop corsia 2    
#define LEDROSSO3 8 //led stop corsia 3    
#define LEDROSSO4 9 //led stop corsia 4    

int val;
bool statoCorsia1; //flag corsia1   
bool statoCorsia2; //flag corsia2   
bool statoCorsia3; //flag corsia3   
bool statoCorsia4; //flag corsia4   
bool stopCorsia1;  //flag stop corsia1   
bool stopCorsia2;  //flag stop corsia2    
bool stopCorsia3;  //flag stop corsia3    
bool stopCorsia4;  //flag stop corsia4  
unsigned long startTime;            
unsigned long corsia1Time;          
unsigned long corsia2Time;          
unsigned long corsia3Time;          
unsigned long corsia4Time;          
unsigned long time1;                
unsigned long time2;                
unsigned long time3;              
unsigned long time4; 
              
void setup()
{

 //Inizializza pin I/O

 pinMode(BUTTON1, INPUT_PULLUP);     
 pinMode(BUTTON2, INPUT_PULLUP);     
 pinMode(BUTTON3, INPUT_PULLUP);     
 pinMode(BUTTON4, INPUT_PULLUP);     
 pinMode(BUTTONSTART, INPUT_PULLUP); 
 pinMode(LEDVERDE1, OUTPUT);         
 pinMode(LEDVERDE2, OUTPUT);         
 pinMode(LEDVERDE3, OUTPUT);         
 pinMode(LEDVERDE4, OUTPUT);         
 pinMode(LEDROSSO1, OUTPUT);         
 pinMode(LEDROSSO2, OUTPUT);         
 pinMode(LEDROSSO3, OUTPUT);         
 pinMode(LEDROSSO4, OUTPUT);         

 digitalWrite(LEDVERDE1, LOW);       
 digitalWrite(LEDVERDE2, LOW);       
 digitalWrite(LEDVERDE3, LOW);       
 digitalWrite(LEDVERDE4, LOW);       
 digitalWrite(LEDROSSO1, LOW);       
 digitalWrite(LEDROSSO2, LOW);       
 digitalWrite(LEDROSSO3, LOW);       
 digitalWrite(LEDROSSO4, LOW);       

 lcd.init();                      // initialize the lcd 

 // Print a message to the LCD.
 lcd.backlight();
 lcd.setCursor(0,0);
 lcd.print("CORSIA 1:");
 lcd.setCursor(0,1);
 lcd.print("CORSIA 2:");
 lcd.setCursor(0,2);
 lcd.print("CORSIA 3:");
 lcd.setCursor(0,3);
 lcd.print("CORSIA 4:");
 
//inizializza flag corsie      
 statoCorsia1 = false;         
 statoCorsia2 = false;         
 statoCorsia3 = false;         
 statoCorsia4 = false; 
 stopCorsia1 = false;          
 stopCorsia2 = false;         
 stopCorsia3 = false;          
 stopCorsia4 = false;          
       
}

void loop()
{

 for (;;) {  //inizio loop infinita scansione corsie 

   val = digitalRead(BUTTON1); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,0);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE1, HIGH); 
     statoCorsia1 = true; 
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,0);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO1, LOW); 
     statoCorsia1 = false;         
   }
   val = digitalRead(BUTTON2); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,1);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE2, HIGH); 
     statoCorsia2 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,1);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO2, LOW); 
     statoCorsia2 = false;         

   }
   val = digitalRead(BUTTON3); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,2);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE3, HIGH); 
     statoCorsia3 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,2);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO3, LOW); 
     statoCorsia3 = false;         

   }
   val = digitalRead(BUTTON4); 
   if (val == HIGH) {         //il pulsante è rilasciato
     lcd.setCursor(9,3);
     lcd.print("PRONTA    ");
     digitalWrite(LEDVERDE4, HIGH); 
     statoCorsia4 = true;           
   }
   if (val == LOW) {          //il pulsante è premuto
     lcd.setCursor(9,3);
     lcd.print("NON ATTIVA");
     digitalWrite(LEDROSSO4, LOW); 
     statoCorsia4 = false;         

   }
   val = digitalRead(BUTTONSTART); 
   if (val == LOW) {               
     //è stato premuto il pulsante di start, si esce dalla prima loop infinita
     break;                        
   }
 }  //FINE LOOP INFINITA SCANSIONE CORSIE 

//È stato premuto il tasto start
 startTime = millis();         //memorizza millisecondo di start
 //Segnala sul display le corsie che stanno cronometrando
 if (statoCorsia1 == true) {   //se CORSIA 1 attiva
   lcd.setCursor(9, 0);        //segnala che si sta cronometrando
   lcd.print("  IN GARA ");

 startTime = millis();         //memorizza millisecondo di start
 //Segnala sul display le corsie che stanno cronometrando
 if (statoCorsia2 == true) {   //se CORSIA 2 attiva
   lcd.setCursor(9, 1);        //segnala che si sta cronometrando
   lcd.print("  IN GARA ");
 startTime = millis();         //memorizza millisecondo di start
 //Segnala sul display le corsie che stanno cronometrando
 if (statoCorsia3 == true) {   //se CORSIA 3 attiva
   lcd.setCursor(9, 2);        //segnala che si sta cronometrando
   lcd.print("  IN GARA ");

 startTime = millis();         //memorizza millisecondo di start
 //Segnala sul display le corsie che stanno cronometrando
 if (statoCorsia4 == true) {   //se CORSIA 4 attiva
   lcd.setCursor(9, 3);        //segnala che si sta cronometrando
   lcd.print("  IN GARA ");

   }
//INIZIA LOOP INFINITA PER IL TEST DEI PULSANTI ROSSI
 for (;;) {
   //controllo tasto rosso corsia1
   if (statoCorsia1 == true &&        //se la corsia è attiva
       stopCorsia1 == false &&        //se il tempo non è ancora stato preso
       digitalRead(BUTTON1) == LOW) { //se il tasto rosso è stato premuto
     //se tutte queste condizioni sono soddisfatte, allora
     corsia1Time = millis();          //blocca il cronometro per CORSIA 1
     digitalWrite(LEDVERDE1, LOW);    //spegni la luce verde
     digitalWrite(LEDROSSO1, HIGH);   //accendi la luce rossa
     stopCorsia1 = true;              //segnala tasto rosso già premuto
   }

for (;;) {
   //controllo tasto rosso corsia2
   if (statoCorsia2 == true &&        //se la corsia è attiva
       stopCorsia2 == false &&        //se il tempo non è ancora stato preso
       digitalRead(BUTTON2) == LOW) { //se il tasto rosso è stato premuto
     //se tutte queste condizioni sono soddisfatte, allora
     corsia2Time = millis();          //blocca il cronometro per CORSIA 2
     digitalWrite(LEDVERDE2, LOW);    //spegni la luce verde
     digitalWrite(LEDROSSO2, HIGH);   //accendi la luce rossa
     stopCorsia2 = true;              //segnala tasto rosso già premuto
   }
for (;;) {
   //controllo tasto rosso corsia3
   if (statoCorsia3 == true &&        //se la corsia è attiva
       stopCorsia3 == false &&        //se il tempo non è ancora stato preso
       digitalRead(BUTTON3) == LOW) { //se il tasto rosso è stato premuto
     //se tutte queste condizioni sono soddisfatte, allora
     corsia3Time = millis();          //blocca il cronometro per CORSIA 3
     digitalWrite(LEDVERDE3, LOW);    //spegni la luce verde
     digitalWrite(LEDROSSO3, HIGH);   //accendi la luce rossa
     stopCorsia3 = true;              //segnala tasto rosso già premuto
   }
for (;;) {
   //controllo tasto rosso corsia4
   if (statoCorsia4 == true &&        //se la corsia è attiva
       stopCorsia4 == false &&        //se il tempo non è ancora stato preso
       digitalRead(BUTTON4) == LOW) { //se il tasto rosso è stato premuto
     //se tutte queste condizioni sono soddisfatte, allora
     corsia4Time = millis();          //blocca il cronometro per CORSIA 4
     digitalWrite(LEDVERDE4, LOW);    //spegni la luce verde
     digitalWrite(LEDROSSO4, HIGH);   //accendi la luce rossa
     stopCorsia4 = true;              //segnala tasto rosso già premuto
   }

}

se stampo il listato, riesco a capire meglio dove devo mettere le mani, sul monitor faccio più fatica....... :open_mouth:

Ciao e Grazie

Ivan