Go Down

Topic: Cronometro particolare x gare di pattinaggio (Read 3463 times) previous topic - next topic

big-ivan

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



pgiagno

#61
Apr 25, 2019, 06:40 pm Last Edit: Apr 25, 2019, 06:42 pm by pgiagno
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.

big-ivan

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
Code: [Select]

#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:

Code: [Select]

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 :)

ciao e grazie

Ivan

pgiagno

#63
Apr 26, 2019, 12:25 am Last Edit: Apr 26, 2019, 12:28 am by pgiagno
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ì:
Code: [Select]
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ì:
Code: [Select]
corsia1Time = millis();

Il tempo realizzato (in millisecondi) sarà dato dalla differenza fra i due valori
Code: [Select]
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.

big-ivan

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

Code: [Select]
#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

pgiagno

#65
Apr 26, 2019, 08:03 am Last Edit: Apr 26, 2019, 08:04 am by pgiagno
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.

Code: [Select]

#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.

big-ivan

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

ecco cio che ho fatto stamattina:

Code: [Select]

#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....... :O

Ciao e Grazie

Ivan

pgiagno

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

Sono vecchio. Mi bastano sei ore di sonno e, come ti ho detto, il progetto mi intriga.

ecco ciò che ho fatto stamattina:

Hai postato un codice che non compila. Si impara dagli errori.

Questi gli errori segnalati:

Code: [Select]

Arduino:1.8.8 (Linux), Scheda:"Arduino Nano, ATmega328P (Old Bootloader)"

/home/user/Arduino/sketch_apr26c/sketch_apr26c.ino: In function 'void loop()':
sketch_apr26c:232:1: error: expected '}' at end of input
}
^
sketch_apr26c:232:1: error: expected '}' at end of input
sketch_apr26c:232:1: error: expected '}' at end of input
sketch_apr26c:232:1: error: expected '}' at end of input
sketch_apr26c:232:1: error: expected '}' at end of input
sketch_apr26c:232:1: error: expected '}' at end of input
sketch_apr26c:232:1: error: expected '}' at end of input

exit status 1
expected '}' at end of input

Questo report potrebbe essere più ricco di informazioni abilitando l'opzione
"Mostra un output dettagliato durante la compilazione"
in "File -> Impostazioni"

Bisogna impratichirsi a interpretare gli errori segnalati dal compilatore. In buona sostanza ti segnala che mancano un certo numero di "}" di chiusura di gruppi di istruzioni che devono essere rinchiusi fra {}. Te lo segnala come errore all'ultima riga, perché le ha cercate fino in fondo, ma non le ha trovate. In realtà per ogni if che hai aperto nella sezione scansione corsie manca la relativa } di chiusura.

Ho corretto il programma e ho inserito i commenti e i suggerimenti all'interno. Lo trovi in allegato perché sta diventando lungo. Puoi anche lasciare i commenti, il programma compila lo stesso, ma devi aggiungere le parti mancanti. Poi ti aiuto.

Ciao,
P.

big-ivan

Ciao,
si avevo visto che c'èra un errore di parentesi, ma poi nel pomeriggio non ci sono potuto andare dietro, per alcuni impegni.
adesso stampo e verifico

grazie
Ivan

big-ivan

ho messo mano al listato,
ho modificato e aggiunto le corsie mancanti.
quello che ho notato  che quando chiudo l'ultimo pulsante rosso, mi viene scritto "T" solo nella corsia 1

per quel che riguarda l'operazione di calcolo, ho dato ai millisecondi 1, ai secondi 1000 e ai minuti 60000.
non so se è giusto........
per il resto vorrei che il cronometro mi dia il tempo ad ogni pressione di stop e non fino a quando siano arrivati tutti. Questo solo perchè chi trascrive i tempi nella tabella excel, lo puo fare man mano che finiscono e non aspettando la fine di tutti (cosi si risparmia tempo).

.......poi mi spiegherai come allegare il file .ino.


Grazie
Ivan

pgiagno

vorrei che il cronometro mi dia il tempo ad ogni pressione di stop e non fino a quando siano arrivati tutti.

Hai perfettamente ragione. Mi stavo complicando la vita perché volevo che la scansione dei pulsanti rossi avvenisse il più velocemente possibile, ma dal momento che non stiamo cronometrando una formula 1 possiamo semplificare il tutto.

per quel che riguarda l'operazione di calcolo, ho dato ai millisecondi 1, ai secondi 1000 e ai minuti 60000.

È corretto.

ho modificato e aggiunto le corsie mancanti. Quello che ho notato  che quando chiudo l'ultimo pulsante rosso, mi viene scritto "T" solo nella corsia 1

È probabile che ci sia un errore. Dovrei vedere il codice.

poi mi spiegherai come allegare il file .ino

È semplice. Vai nel riquadro Quick Replay e scrivi il testo della risposta (il testo NON il file.ino). Poi clicca su Preview (in basso a destra). Compare un altro riquadro. Clicca su Attachments and other options (in blu in basso a sinistra). Clicca su Scegli file. Seleziona il file .ino da allegare. Tutto qui.

Ho corretto il programma come vuoi tu e viene anche più semplice. Ho "ripulito" il programma dei commenti inutili e ne ho aggiunti di nuovi. Completa le parti che mancano come suggerito nei commenti e... vediamo se abbiamo finito.

PER ORA! (ricorda l'appetito  :D ).

Posta il codice provvisoriamente definitivo che compila senza errori formali.

Ciao,
P.

pgiagno

Sto rivedendo il programma.

La gestione dei led durante la scansione delle corsie non mi convince. Tu vuoi che prima dello start, se un pulsante rosso è premuto, oltre a spegnersi il led verde, si accenda il led rosso, oppure devono rimanere spenti il led verde e quello rosso? In ogni caso il codice è sbagliato. Questo è quello della corsia 1

Code: [Select]
  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;        

Nel primo caso (led verde spento, led rosso acceso e viceversa) occorre modificare così

Code: [Select]
  if (val == HIGH) {         //il pulsante è rilasciato
    lcd.setCursor(9,0);
    lcd.print("PRONTA    ");
    digitalWrite(LEDVERDE1, HIGH);
    digitalWrite(LEDROSSO1, LOW);   //======istruzione da agguingere
    statoCorsia1 = true;
  }
  if (val == LOW) {          //il pulsante è premuto
    lcd.setCursor(9,0);
    lcd.print("NON ATTIVA");
    digitalWrite(LEDVERDE1, LOW);   //======istruzione da agguingere
    digitalWrite(LEDROSSO1, HIGH);  //======istruzione modificata
    statoCorsia1 = false;        

Nel secondo caso (solo il led verde acceso/spento, il led rosso sempre spento) occorre modificare così

Code: [Select]
  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(LEDVERDE1, LOW);   //======istruzione modificata
    statoCorsia1 = false;        

e così per le altre corsie.

Ciao,
P.

big-ivan

Ciao,
allora adesso metto mano al file, per quel che riguarda il led rosso, deve rimanere acceso solo quando il pulsante è premuto. se il tasto è rilasciato si accende il led verde.

Ora mi metto al lavoro


Grazie

Ivan

big-ivan

Eccomi qua, dopo aver editato il listato con le tue indicazioni, mi sono permesso di personalizzare un po la grafica :)

per adesso gira che è una bellezza.....GRAZIE GRAZIE GRAZIE.

si si ho un'appetito, come le fotocellule ti arrivo al posto dei pulsanti!!!!  :) :)

Adesso inizio a progettare la scatola.......

Grazie

Ivan

pgiagno

...mi sono permesso di personalizzare un po la grafica

E hai fatto benissimo. Ricorda che il programma è TUO. Qui sul forum si fornisce solo supporto.

Una raccomandazione: adesso che hai ancora fresco in mente il funzionamento del programma disseminalo di commenti e spiegazioni e, soprattutto, descrivi come è connesso l'hardware (display, led e pulsanti) e come funziona. Non fidarti della tua memoria che sarà sicuramente migliore della mia, ma fra qualche mese non saprai più metterci le mani.

Un'altra ancora. Quando ho cominciato a programmare un vecchio del mestiere mi ha passato una massima fondamentale:

Se un programma funziona quanto basta,
lascialo stare, sennò si guasta


Intendeva dire che, se vuoi introdurre migliorie, crea una copia di quello che funziona e lavora su quella. Dopo che avrai fatto pasticci potrai sempre buttarlo via e tornare all'originale.

Quando sarà finito, allega una foto. Buon lavoro.

Ciao,
P.

Go Up