Resettare " millis() "

è possibile resettare il conteggio della funzione millis?

esempio

Input -> inizia a contare
Input -> smette e resetta il conteggio

come il cronometro di un auto in pista per capirci...

meglio ancora... ecco lo sketch.
dopo l'if vorrei che millis() si resettasse e re inizi il programma.

/*Cronomentro IR 
 Legge il valore del pin A0 dove c'è un sensore ir 
 se il valore è inferiore a 1023 parte il cronometro che registra
 un TIME e quando riceve un altro valore inferiore a 1023:
 "LOOP"
 1)Stoppa il cronometro 
 2)Invia il time via seriale 
 3)riavvia il cronometro 
 "/LOOP "
 */
void setup () {
  Serial.begin(9600);
}

void loop() {

  int valoreir = analogRead(A0); // Legge valore ir 
  if (valoreir <1020) { // Se valore ir <1020
    
    unsigned long mtime = millis(); // Inizia a contare
    unsigned long time = (mtime/100);//converte in centesimi di secondi
    
    
    
    
    delay(10);



    int valoreir2 = analogRead(A1); // Legge valore ir 
    if (valoreir2<1020) {

  
    Serial.println(time, DEC);// mostra sul pc il tempo
    
    
    
    }  
    
  } 

}

Aspetta qualche saggio, ma secondo me via software non si può, devi collegare un pin dell'arduino a quello del reset

/*Cronomentro IR
 Legge il valore del pin A0 dove c'è un sensore ir
 se il valore è inferiore a 1023 parte il cronometro che registra
 un TIME e quando riceve un altro valore inferiore a 1023:
 "LOOP"
 1)Stoppa il cronometro
 2)Invia il time via seriale
 3)riavvia il cronometro
 "/LOOP "
 */
void setup () {
  Serial.begin(9600);
}

void loop() {

  //int valoreir = analogRead(A0);    |||||||||spreco di variabile
  if (analogRead(A0)<1020) { // Se valore ir <1020
    
    unsigned long mtime = millis(); // prelevo valore millis al primo passaggio
      
    //delay(10); a cosa serve?
  // int valoreir2 = analogRead(A1); |||||||||spreco di variabile
    if (analogRead(A0)<1020) {
  unsigned long time = millis()-mtime;
  time = (time/100);
    Serial.println(time);// mostra sul pc il tempo
    
    
    
    }  
    
  }

}

dovrebbe funzionare

non ho capito quale analog devi leggere per secondo. 0o1? al max modifica nel secondo if

abche variato qualcosetta per evitare codice inutile che rallenta il programma e usa variabili in più... avanzi un sacco di ram ma ottimizzare non fa male.

magari si può ottimizzare ben oltre ma già così va.

via seriale cosa vuoi inviare solo centesimi o vuoi convertire in minuti sec e via dicendo?

ciao Nikka93
2 cose:

  • perché devi resettare il milli() ?
    non puoi fare una differenza del tempo di fine con quello di start e hai come risultato la differenza che cervcavi.

  • Per secondo il Tuo programma non funziona.

  • devi mettere un limite piú basso per definire il criterio di start. 1020 é un valore troppo vicino al valore massimo e con un pochetino di disturbi ci arrivi facilmente. metti qualcosa come 900 o 800.
  • se la condizine di start é data copi il tempo in un a variabile, ( che servirá qualche frazione di milisecondo) e aspetti 10 milisecondi. Poi controlli se il secondo pin é scattato e trasmetti il dato.
    In questo modo misuri il tempo dal ritorno del primo segnale sopra il limite e lo stampi quando arriva al secondo sensore.

il sketch funzionante dal primo segnale al secondo: semre triggerato col fiano discendente:

unsigned long mtime;
unsigned long time; 
int start = 0;
 
void setup () {
  Serial.begin(9600);
}

void loop() {

    if (analogRead(A0) < 800 && start == 0) 
    { // Se valore ir < 800 ed il segnale viene per la prima volta    
    mtime = millis(); // tempo di inizio conteggio
    start=1;    
    }    
    if (analogRead(A1) < 800 && start == 1) 
    { //Stop
    time = (millis() - mtime)/100;// fa la differenza e converte in centesimi di secondi
    start = 0;
    Serial.println(time, DEC);// mostra sul pc il tempo
    }  
  }

Probabilmente non é necessario usare delle entrate analogiche ma bastano 2 entrate digitali.
Ciao Uwe

edit: garinus era piú veloce

uwe start lo hai messo per evitare inversioni tra la peartenza e la fine usando due analog diverse?

@garinus

Non era una scelta mia, ma quello che Nikka93 aveva scritto nel suo codice.
Presumo che vuole usare due sensori ottici, uno per l' inizio del percorso e uno alla fine.
Mi sono messo a migliorare il suo codice e farlo fuzionante, eliminando la necessitá di dover resetare millis() e facendo attenzione di avere problemi di un roll over dopo ca 70 giorni.

La misura sbaglia se il tempo cronometrato supera questi 70 giorni.

Ciao Uwe

Presumo che vuole usare due sensori ottici, uno per l' inizio del percorso e uno alla fine.

No è un solo sensore IR su arduino e un led IR sulla macchina

Ciao Nikka93

Allora per favore spiegati meglio.

Nel codice hai usato 2 entrate per lo Start e lo stop del tempo (A0 e A1).

Spiega anche per favore come vuoi usare il trasmettitore sulla macchian e il ricevitore a terra; non é meglio avere tutti due a terra e la maccina interrompe il facio IR?

Ciao Uwe

Ooops!

C'è un errore nel codice che ho "incollato" nel primo post.

C'è un solo sensore IR sulla porta A0 :slight_smile:

L'idea era questa.

Sensore sul traguardo.
Led Sull' auto.

Quando l'auto passa il sensore rileva il cambiamento e parte il cronomentro.
Appena finisce il giro e ripassa sul traguardo:

  1. invia il tempo tramite seriale.
  2. inizia a cronometrare il giro che inizia a fare l'auto.

:-/

Non posso fare come dici tu Uwe perchè sul circuito ci sono varie auto non solo la mia :slight_smile:

beh cmq il mio codice dovrebbe andare imposta la soglia giusta e sei apposto

@ garinus
non del tutto. devi controllare che il segnale ci sia, poi che non ci sia e per il stop che ci sia di nuovo.
Come Tu hai scritto il codice hai subito dopo il start un stop perché il sensore é ancora nello stesso stato di come era per fare partire il tempo.
@ Nikka93
Si puó aggiungere dei ritardi per fare piu immune il programma a deri disturbi. se sai che tempi miuri ( un giro dura al minimo 2 minuti puoi disattivare la lettura per 1 minuto e mezzo perché siccuramente non passi dopo quel tempo).
Devi adeguare i limiti alle letture del sensore. Ho messo un isteresi per essere piú immune a dei disturbi. Al limite devi adeguare questi limiti.
Attenzione non ho compilato il codice; spero che non ci siano dei errori.

unsigned long mtime;
unsigned long time;
int start = 0;

void setup () {
  Serial.begin(9600);
}

void loop() {

    if (analogRead(A0) < 800 && start == 0)
    { // Se valore ir < 800 ed il segnale viene per la prima volta    
    mtime = millis(); // tempo di inizio conteggio primo giro
    start=1;    
    }    
    
    if (analogRead(A0) > 900 && start == 1)
    { 
    start=2;    
    }    


    if (analogRead(A0) < 800 && start == 2)
    { //Stop
    time = (millis() - mtime)/100;// fa la differenza e converte in centesimi di secondi
    Serial.println(time, DEC);// mostra sul pc il tempo
    
    mtime = millis(); // tempo di inizio conteggio per il prossimo giro
    start = 3;
    }  

    if (analogRead(A0) > 900 && start == 3) 
    { 
    start=2;    
    }  
  }

Ciao Uwe

hai ragione nella fretta non ci ho pensato... ;D

e io spero che il mio sia funzionante visto che non ho fatto test. :sunglasses:
Ciao Uwe

Scusate ma riguardo al fatto di azzerare millis secondo me non serve: ora non ricordo bene ma se non erro tempo fa avevo fatto delle prove con la calcolatrice e mi sembra che il problema non esiste perchè la variabile viene dichiarata come unsigned long (cioè senza segno) quindi facendo la differenza tra un numero molto piccolo (cioè dopo il rollover) e un numero molto grande (cioè prima del rollover) si dovrebbe ottenere comunque il risultato corretto.

quando millis va in overflow setta un registro, o comunque te ne accorgi perchè la seconda lettura è inferiore a quella precedente (se il controllo viene eseguito abbastanza spesso, almeno una volta ogni 50 giorni :slight_smile: ) e se fai ( valore massimo unsigned long ( che è 2^32 - 1) - vecchiovalore )+nuovo valore (occhio alle parantesi o vai in overflow) ottieni i millis trascorsi :slight_smile:

Ciao lesto, Ciao Ambrogio

Le vostre preoccupazioni sono giá state considerate nel codice e funziona anche durante un roll over; L' unica limitazione é che il tempo misurato deve essere minore di 50 giorni.

Ciao Uwe

Uwe in questo codice se volessi mettere un Delay in modo che se l'auto passa sotto un certo tempo non venga visualizzato il tempo come posso fare?

Esempio... l'auto passa , inizia arduino a contare , ri arriva il segnale dopo 5 secondi ma lui non mostra nulla e continua a contare...

unsigned long mtime;
unsigned long time;
int start = 0;

void setup () {
  Serial.begin(9600);
}

void loop() {

    if (analogRead(A0) < 800 && start == 0)
    { // Se valore ir < 800 ed il segnale viene per la prima volta    
    mtime = millis(); // tempo di inizio conteggio
    start=1;    
    }    
    if (analogRead(A1) < 800 && start == 1)
    { //Stop
    time = (millis() - mtime)/100;// fa la differenza e converte in centesimi di secondi
    start = 0;
    Serial.println(time, DEC);// mostra sul pc il tempo
    }  
  }