Cronometro azionato tramite valori analogici

Buongiorno,
avrei necessità di creare un cronometro tramite l’utilizzo di arduino che funzioni così:

  • arduino rileva il valore di tensione sull’ingresso analogico A0 e l’associa ad un variabile (ValPressioneIngressoIniziale)
  • inizia il conteggio appena è in condizione è in questa condizione A0<=1 e A1=0
  • termina il conteggio appena è in condizioni che sull’ingresso analogico A0 =>ValPressioneIngressoIniziale
    Il tutto deve essere restituito sul display in real time.

Il codice ho pensato è questo:

#include
#include "rgb_lcd.h"
rgb_lcd lcd;
int TensioneEVPil = A1; // PIN a cui è connessa l'elettrovalvola per il ritardo
int PressioneIng = A0; // PIN a cui è connesso Ingresso Analogico Sensore Wika ad Arduino
int ValPressioneIng;
int ValTensioneEVPil;
float ValTensioneEVPil_perc;
float ValTensioneEVPilotaggio;
float ValPressione_perc;
float ValPressioneIngressoIniziale;
float ValPressioneIngresso;
float calc_res_pressione;
float calc_res_tensione;
float R_press_1 = 10000; //modificare questi valori con i valori realmente utilizzati.
float R_press_2 = 10000; //modificare questi valori con i valori realmente utilizzati.
float R_tensione_1 = 10000;
float R_tensione_2 = 10000;
int flag = 1;
unsigned long tempo_base;
unsigned long tempo_cronometrato = 0;
unsigned long tempo_congelato;
unsigned long temposec;
void setup()
{
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Bosch Rexroth");
  lcd.setCursor(0, 1);
  lcd.print("Cronometro");
  pinMode (ValPressioneIngresso, INPUT);
  pinMode (ValTensioneEVPilotaggio, INPUT);
  calc_res_pressione = (R_press_1 + R_press_2) / R_press_2;
  calc_res_tensione = (R_tensione_1 + R_tensione_2) / R_tensione_2;
}
void loop()
{
  ValPressioneIng = analogRead(PressioneIng); // assegnazione valore per la parte di Pressione
  ValPressione_perc = map (ValPressioneIng, 0, 1023, 0, 500); //leggerò 1023 quando ho 5 volt sul pin, quindi scalo 0-1023 in 0-500.
  ValPressioneIngressoIniziale = ValPressione_perc * calc_res_pressione / 100 ; //ora divido tutto per 100 perchè sopra ho scalato da 0 a 500 anzichè da 0 a 5V
  ValPressioneIngresso = ValPressione_perc * calc_res_pressione / 100 ; //ora divido tutto per 100 perchè sopra ho scalato da 0 a 500 anzichè da 0 a 5V

  ValTensioneEVPil = analogRead(TensioneEVPil); // assegnazione valore per la parte di Tensione
  ValTensioneEVPil_perc = map (ValTensioneEVPil, 0, 1023, 0, 500); //leggerò 1023 quando ho 5 volt sul pin, quindi scalo 0-1023 in 0-500.
  ValTensioneEVPilotaggio = ValTensioneEVPil_perc * calc_res_tensione / 100 ; //ora divido tutto per 100 perchè sopra ho scalato da 0 a 500 anzichè da 0 a 5V

  if ((ValPressioneIngresso <= 1) && (ValTensioneEVPilotaggio <= 0))
  {
    tempo_base = millis();
    flag = 0;
  }

  if (flag == 0)
  {
    lcd.clear();
    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 (ValPressioneIngresso == ValPressioneIngressoIniziale)
  {

    lcd.setCursor(0, 0);
    lcd.print("TEMPO (secondi)");
    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;
  }
}

Sapete dirmi se funziona tutto?

Grazie.

Due cose …

1. prendi il tuo codice e con Arduino IDE fai CTRL-T e fallo sistemare automaticamente con tutte le indentature e quant’altro che … così è illegibile :wink:

2. in conformità al regolamento, punto 7, devi editare il tuo post (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 (… fosse anche UNA sola riga) all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).
In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo.

Grazie.

Guglielmo

P.S.: Ti ricordo anche che, purtroppo, fino a quando non avrai sistemato il codice come richiesto, nessuno ti potrà rispondere, quindi ti consiglio di farlo al più presto. :wink:

Grazie mille per la dritta :slight_smile:

Se funziona tutto non è facile dirlo senza avere un riscontro oggettivo, in linea di massima puoi incontrare il problema delle letture su porta analogica su porte differenti, dovresti sempre scartare la prima tipo così:

ValPressioneIng = analogRead(PressioneIng); // assegnazione valore per la parte di Pressione
ValPressioneIng = analogRead(PressioneIng); // assegnazione valore per la parte di Pressione
...
ValTensioneEVPil = analogRead(TensioneEVPil);
ValTensioneEVPil = analogRead(TensioneEVPil);

Non necessario, se non ricordo male, se i due pin sono sulla medesima porta, ma qui bisognerebbe anche sapere su che arduino gira il programma (Uno? Due? Mega? ecc.)
L’altra cosa che mi sento di consigliarti… sono due :slight_smile: visto che aggiorni l’LCD con i secondi è controproducente aggiornare i dati ogni giro di loop e con l’“aggravante” di care una clear, provoca sfarfallio e probabile anche blocchi più o meno frequenti.
Aggiorna solo le parti che variano (i secondi nel tuo caso) e lascia il resto dell’LCD non toccato e, soprattutto, aggiornalo solo quando serve ovvero ogni secondo (mi par di capire che con l’uso di millis() ci siamo) quindi verifica se è trascorso il tempo. Se non vuoi usare un aggiornamento fisso ogni secodno ma solo quando il dato varia allora puoi anche fare così, ovvero aggiornerai la parte dei secondi solo quando i secondi trascorsi sono differenti rispetto al numero di secondi trascorsi che avevi scritto sul display.
Come seconda cosa per evitare la sequenaza di if per posizionare il cursore nel posto giusto in base ai secondi trascorsi potresti prendere in considerazione l’uso della funzione snprintf, va un poco studiata ma ha mille modi di formattare i dati.
Poi questo

if (ValPressioneIngresso == ValPressioneIngressoIniziale)

Rischi che se non becchi il momento esatto in cui le due pressioni si equivalgono non finisci più di aspettare usa un >= o <= in modo che quando la pressione è nel range desiderato la procedura risponda come dalle tue specifiche.
Manca la libreria che includi nella prima include :slight_smile:

Intanto grazie per la risposta. Preciso che è il tutto gira su Arduino Mega.

Per il discorso dell'aggiornamento del display, farlo ogni secondo è troppo poco, perchè a me interessano anche i decimi di secondo, ecco perche' vorrei farlo aggiornare ogni loop.

Il terzo consiglio è più che corretto, e quindi modificherò con >=.

In questi giorni proverò a creare il circuito elettronico e proverò lo sketch vedendo se il tutto funziona.

Il succo non cambia, anche se metti in piedi i decimi di secondo il loop gira molto più velocemente.
Io comunque, di solito, suggerisco di aggiornare un dato solo quando è variato rispetto a quanto visualizzato sul display, in questo modo, a discapito di dover memorizzare i valori stampati sull'lcd quindi un poco di memoria impegnata, che il dato vari ogni anno,ora,secondo,millisecondo poco importa lo si aggiorna solo quando necessario, con grande performance e stabilità di quanto visualizzato sull'lcd.

Aggiungo solo una cosa … dato che prima parlavi di sfarfallio, per l’uso della lcd clear … per evitarlo si potrebbe, ma serve usare qualche variabile in piu e raddoppiare le scritture …

Se ad esempio cambi l’intero LCD, allora la clear ci sta … se invece ad esempio cambi solo un valore, per evitare lo sfarfallio bisognerebbe scrivere il vecchio valore con il colore di sfondo, ed immediatamente dopo scrivere il nuovo … pero’ questo implica che servono piu variabili, almeno una in piu per ogni valore che si deve aggiornare, per salvarci il nuovo valore …

Ad esempio, ne prendo uno a caso, temposec … ti servira’ anche temposecold (nome a caso) … cosi dovresti fare

stampa temposecold con colore sfondo
stampa temposec con colore primario
temposecold = temposec

in questo modo riscrivi solo il numero interessato dopo aver coperto il precedente, ed il display non dovrebbe sfarfallare …

@Etemenanki è quello che avevo già suggerito e ribadito nel post #5, sicuramente in modo appositamente meno dettagliato ma il succo è quello

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.