è 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
}
}
}
/*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?
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
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.
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?
@ 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;
}
}
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 ) 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
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.
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
}
}