Salve a tutti!
Avete presente il piano inclinato? Forza parallela ecc? Io ho la necessità di far scorrere una pallina su un binario inclinato. Lungo tale binario ci sono ogni 15cm un led emittente ed una fotoresistenza ricevente. In tutto ci sono 3 led e conseguentemente 3 resistenze. Quando la pallina interrompe il fascio di luce di uno di questi "sensori" (chiamiamoli così), deve partire un timer.
Allorchè la pallina passa davanti al secondo sensore, devo poter sapere quanto tempo ha impiegato per passare da un sensore all'altro ma il timer deve anche continuare a contare, in quanto dopo che la pallina ha attraversato tutti i sensori, ho la necessità di sapere il tempo totale.
Quello che voglio sapere io è una funzione che mi permette di misurare (con buona precisione possibilmente) i tempi sopraccitati.
A riguardo ho letto della famosa "millis()" o della "pulsein()", ma non credo facciano al caso mio.
Vi chiedo solo un piccolo spunto inziale! Grazie!
p.s: con i PIC avrei incrementato un contatore (ad esempio Timer1) ogni 1ms e quando la pallina passava davanti ad un sensore prendevo il tempo in quell'istante.
Hai bisogno di un sistema basato su millis. All'avvio della corsa della pallina, salvi il valore corrente di millis nella prima cella di un array. Quello sarà il "punto 0", l'istante d'inizio. Ad ogni passaggio davanti ad un sensore, salvi il valore di millis in celle successive dell'array. Alla fine dell'operazione, arrivati al "traguardo", l'intervallo fra 2 passaggi sarà dato dalla differenza fra un tempo ed il precedente, e la differenza fra l'istante dell'arrivo e quello della partenza sarà il tempo totale.
Molto gentile, ti ringrazio!
Hai ragione il titolo adesso è più consono.
Una piccola delucidazione: Ma la funzione millis() quando la faccio partire (ovvero quando la pallina passa per il primo sensore) restituirà 0 (zero) giusto?
Per ogni evento registri il tempo della funzione millis() che è un contatore interno all'ATmega che parte da zero all'accensione (e si resetta ogni 49,7 giorni) e viene incrementato ogni millisecondo.
if (quellochevuoi) Tempo[0] = millis();
oppure
if (quellochevuoi) Tempo[1] = millis();
ecc.
Alla fine fai le differenze tra i tempi registrati.
Grazie anche a te!
Ma quello che intendevo io è sapere se il conteggio parte nel momento in cui invoco per la prima volta la funzione millis() oppure parte indipendentemente dalla funzione millis().
Il contatore interno richiamabile da millis() parte da zero al momento dell'accensione di Arduino.
Per questo motivo devi necessariamente effettuare delle differenze di tempo.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int Sensor_A = A0;
int Sensor_B = A1;
int Sensor_C = A2;
int Sensor_D = A3;
int Sensor_E = A4;
int Fine_corsa = 13;
int Button = 12;
int B_menu = 11;
int menu = 0;
float Time[5]={0,0,0,0,0};
float Time_A=0, Time_B=0, Time_C=0, Time_D=0, Time_E=0, Time_tot=0; //tempi reali
void setup(){
pinMode(Fine_corsa, INPUT);
pinMode(Button, INPUT);
pinMode(B_menu, INPUT);
lcd.begin(16, 2);
lcd.print("Mis. time +-1mS");
delay(3000);
}
void loop(){
while(digitalRead(Button)==LOW){
//Lettura dei tempi
if(digitalRead(Fine_corsa)==LOW) Time[0]=millis();
if(analogRead(Sensor_A)<=200) Time[1]=millis();//200 è un valore ADC da me calcolato attraverso il test
if(analogRead(Sensor_B)<=200) Time[2]=millis();
if(analogRead(Sensor_C)<=200) Time[3]=millis();
if(analogRead(Sensor_D)<=200) Time[4]=millis();
if(analogRead(Sensor_E)<=200) Time[5]=millis();
//Calcolo dei tempi in secondi
Time_A = (Time[1] - Time[0])/1000;
Time_B = (Time[2] - Time[1])/1000;
Time_C = (Time[3] - Time[2])/1000;
Time_D = (Time[4] - Time[3])/1000;
Time_E = (Time[5] - Time[4])/1000;
Time_tot = (Time[5] - Time[0])/1000;
lcd.setCursor(0, 5);
lcd.print("FINISH");
lcd.setCursor(1,2);
lcd.print("WITH NO ERROR");
}
if(digitalRead(B_menu)==LOW) menu++;
if(menu>=7) menu=0;
if(menu==1){
lcd.setCursor(0, 1);
lcd.print("Time A(S):");
lcd.setCursor(0, 9);
lcd.print(Time_A);
}
if(menu==2){
lcd.setCursor(0, 1);
lcd.print("Time B(S):");
lcd.setCursor(0, 9);
lcd.print(Time_B);
}
if(menu==3){
lcd.setCursor(0, 1);
lcd.print("Time C(S):");
lcd.setCursor(0, 9);
lcd.print(Time_C);
}
if(menu==4){
lcd.setCursor(0, 1);
lcd.print("Time DS):");
lcd.setCursor(0, 9);
lcd.print(Time_D);
}
if(menu==5){
lcd.setCursor(0, 1);
lcd.print("Time E(S):");
lcd.setCursor(0, 9);
lcd.print(Time_E);
}
if(menu==6){
lcd.setCursor(0, 1);
lcd.print("Time TOT(S):");
lcd.setCursor(0, 9);
lcd.print(Time_tot);
}
}//fine void loop()
Ho inserito un LCD e un pulsante per scorrere i tempi. Inoltre sto cercando di squadrare il segnale della fotoresistenza per mezzo di un operazionale, così’ da utilizzare gli ingressi digitali anche se, a dire il vero, potrei collegare la fotoresistenza direttamente a tali ingressi…
Attendo nuove
Ho inserito un nuovo costrutto molto utile in C, lo switch case che si adatta perfettamente al tuo caso.
default viene selezionato quando non sono presenti altri casi.
Ho visto che hai tolto le parentesi dall’ultimo IF di time[5], in quel caso i calcoli dei tempi vengono effettuati ad ogni ciclo così come le scritte Finish appare prima del tempo.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int Sensor_A = A0;
const int Sensor_B = A1;
const int Sensor_C = A2;
const int Sensor_D = A3;
const int Sensor_E = A4;
const int Fine_corsa = 13;
const int Button = 12;
const int B_menu = 11;
int menu = 0;
float Time[5] = {0, 0, 0, 0, 0};
float Time_A = 0, Time_B = 0, Time_C = 0, Time_D = 0, Time_E = 0, Time_tot = 0; //tempi reali
void setup() {
pinMode(Fine_corsa, INPUT);
pinMode(Button, INPUT);
pinMode(B_menu, INPUT);
lcd.begin(16, 2);
lcd.print("Mis. time +-1mS");
delay(3000);
}
void loop() {
while (digitalRead(Button) == LOW) {
//Lettura dei tempi
if (digitalRead(Fine_corsa) == LOW) Time[0] = millis();
if (analogRead(Sensor_A) <= 200) Time[1] = millis(); //200 è un valore ADC da me calcolato attraverso il test
if (analogRead(Sensor_B) <= 200) Time[2] = millis();
if (analogRead(Sensor_C) <= 200) Time[3] = millis();
if (analogRead(Sensor_D) <= 200) Time[4] = millis();
if (analogRead(Sensor_E) <= 200) Time[5] = millis();
//Calcolo dei tempi in secondi
Time_A = (Time[1] - Time[0]) / 1000;
Time_B = (Time[2] - Time[1]) / 1000;
Time_C = (Time[3] - Time[2]) / 1000;
Time_D = (Time[4] - Time[3]) / 1000;
Time_E = (Time[5] - Time[4]) / 1000;
Time_tot = (Time[5] - Time[0]) / 1000;
lcd.setCursor(0, 5);
lcd.print("FINISH");
lcd.setCursor(1, 2);
lcd.print("WITH NO ERROR");
}
if (digitalRead(B_menu) == LOW) menu++;
switch (menu) {
case 1:
lcd.setCursor(0, 1);
lcd.print("Time A(S):");
lcd.setCursor(0, 9);
lcd.print(Time_A);
break;
case 2:
lcd.setCursor(0, 1);
lcd.print("Time B(S):");
lcd.setCursor(0, 9);
lcd.print(Time_B);
break;
case 3:
lcd.setCursor(0, 1);
lcd.print("Time C(S):");
lcd.setCursor(0, 9);
lcd.print(Time_C);
break;
case 4:
lcd.setCursor(0, 1);
lcd.print("Time DS):");
lcd.setCursor(0, 9);
lcd.print(Time_D);
break;
case 5:
lcd.setCursor(0, 1);
lcd.print("Time E(S):");
lcd.setCursor(0, 9);
lcd.print(Time_E);
break;
case 6:
lcd.setCursor(0, 1);
lcd.print("Time TOT(S):");
lcd.setCursor(0, 9);
lcd.print(Time_tot);
break;
default:
menu = 0;
}
}//fine loop()