// Rispetto alla versione 8.2 si elimina il display dei microsecondi trascorsi // e lo si sostituisce con info sulla temperatura ed umidità al momento della misura. // Al pin 2 corrisponde il valore del secondo bit nel registro PIND // Al Pin 3 corrisponde il valore del terzo bit nel registro PIND // Al Pin 12 corrisponde il valore del quarto bit nel registro PINB // LA CONDIZIONE NORMALE E' UNO e diventa ZERO quando passa l'ombra. // Il tubo originale si è rotto e nel nuovo è cambiata anche la distanza tra i fotodiodi // che adesso si trovano a 523 millimetri l'uno dall'altro. // // Invece che due pin analogici leggo i pin digitali 3 e 12 comandati da un trigger esterno // controllando solo se stanno ad uno o a zero // quando passa un'ombra e NON FACENDO ALTRO se non il controllo del pin 2 per il reset // Il display DFRobot porta in uscita solo i pin D0,D1,D2,D3,D11,D12 // e gli analogici A1,A2,A3,A4.A5 usa A0 per leggere quale pulsante // è stato premuto // ************ FUNZIONA **************** /*-----( Importa le librerie necessarie)-----*/ #include "LiquidCrystal.h" #include "DHT.h" #define DHTPIN 11 #define DHTTYPE DHT22 /*-----( Dichiarazioni Variabili )-----*/ int Diodo_Uno = 0; int Diodo_Due = 0; int pin2 = 1; int pin3 = 1; int pin12 = 1; int pinA1 = 0; unsigned long Tempo = 0; unsigned long Tempo_Start = 0; unsigned long Tempo_Stop = 0; unsigned long Tempo_Loop_1 = 0; unsigned long Tempo_Loop_2 = 0; unsigned long Start_Loop_1 = 0; unsigned long Start_Loop_2 = 0; unsigned long Stop_Loop_1 = 0; unsigned long Stop_Loop_2 = 0; float V2; float Errore_Metri; float Volt; float Metri_Secondo = 0; int h; int t; DHT dht(DHTPIN, DHTTYPE); LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Sono i piedini usati dal display LCD void setup() /*----( SETUP: Viene letto solo alla partenza )----*/ { lcd.begin(16, 2); // Fa partire l'oggetto lcd che gestisce il display lcd dht.begin(); // Fa partire l'oggetto dht che gestisce i sensori temp e umid pinMode(2, INPUT); // Pin a cui è connesso il pulsante di reset pinMode(3, INPUT); // Pin a cui è connesso il primo fotodiodo triggherato pinMode(12, INPUT); // Pin a cui è connesso il secondo fotodiodo triggherato pinMode(A1,INPUT); // ci leggo la tensione di batteria //Serial.begin(9600); // Inizializzo la porta seriale lcd.clear(); lcd.setCursor(0, 0); lcd.print("CRONOGRAFO V.9 "); //Scrivo versione ed autore lcd.setCursor(0, 1); lcd.print("di Pino Grasso"); delay(2000); lcd.clear(); // ripulisco lo schermo e ci scrivo lcd.setCursor(0, 0); // i campi fissi normali sul display lcd.print("m/s= "); lcd.setCursor(0, 1); lcd.print("Temp= "); lcd.setCursor(8, 1); lcd.print("Umid= "); }/*--(Fine setup )---*/ void loop() /*----( LOOP: Gira costantemente)----*/ { Diodo_Uno = 0; // Azzero gli indicatori di evento Diodo_Due = 0; do { if (((B00000001 & (PIND >> 2))) == 0) // se è stato pigiato il pulsante di RESET azzero e mostro la tensione di batteria // il piedino due si trova nel secondo bit del registro PIND // allora sposto o destra di due posizioni tutti i bit del registro, così il primo a destra è lui // poi faccio un AND logico in binario col il byte 00000001 // e dato che l'AND torna UNO solo se entrambi i bit sono a UNO // leggo lo stato di quel bit. { azzera(); } } while ((B00000001 & (PIND >> 3)) == 1); // continua a girare fino a quando il pin 3 sta alto // il piedino tre si trova nel terzo bit del registro PIND // allora sposto o destra di tre posizioni tutti i bit del registro, così il primo a destra è lui // poi faccio un AND logico in binario col il byte 00000001 // e dato che l'AND torna UNO solo se entrambi i bit sono a UNO // leggo lo stato di quel bit. Tempo_Start = micros(); // dato che è uscito dal loop mi segno il tempo dell'evento ed alzo il flag del diodo uno Diodo_Uno = 1; do { // passo ad osservare il secondo fotodiodo if ((micros() - Tempo_Start ) > 1000000) // Controllo il tempo che passa aspettando un segnale { break; // se è passato troppo tempo dal primo evento esco dal ciclo while } // perché è una falsa partenza } while ((B00000001 & (PINB >> 4)) == 1); // altrimenti continua il giro fino a quando succede qualcosa anche al diodo due sul pin12 // il piedino dodici si trova nel quarto bit del registro PINB // allora sposto o destra di quattro posizioni tutti i bit del registro, così il primo a destra è lui // poi faccio un AND logico in binario col il byte 00000001 // e dato che l'AND torna UNO solo se entrambi i bit sono a UNO // leggo lo stato di quel bit. Tempo_Stop = micros(); // è uscito dal loop perchè ha sentito qualcosa o perché è passato troppo tempo e mi segno il tempo Tempo = (Tempo_Stop - Tempo_Start); // mi calcolo l'intervallo tra i due eventi if (Tempo < 1000000 && Tempo > 100) // Se il tempo è maggiore di 100 microsecondi e minore di un secondo { Diodo_Due = 1; // alzo il flag del diodo due perché qualcosa è passato davvero } else { Diodo_Due = 0; // altrimenti lo abbasso per un falso allarme } if ((Diodo_Uno == 1) && (Diodo_Due == 1)) // se entrambi i diodi hanno sentito un evento faccio i conti { Metri_Secondo = ((0.523 * 1000000) / Tempo); // 0.523 metri è la distanza fisica tra i diodi V2 = ((0.523 * 1000000) / (Tempo+4)); // Calcolo la velocità con l'incertezza dei 4 microsecondi // se il proiettile, nei microsecondi indicati da Tempo, // ha percorso mezzo metro, quanti metri percorrerà in un milione di microsecondi ? // Tempo sta a 0.523 come 1000000 sta ad x quindi x=0.523*1000000/Tempo Errore_Metri = Metri_Secondo - V2; // Errore in metri della misura della velocità leggi_temperatura(); // Leggo temperatura e umidità scrivi_sul_display(); // scrivo sul display i valori calcolati e rilevati } } // Chiude il LOOP principale /*-----( Dichiarazioni di funzioni)-----*/ void azzera() { lcd.clear(); // Pulisco lo schermo lcd.setCursor(0, 0); // Posiziono il cursore all'inizio della prima riga lcd.print(" VOLT BATTERIA "); // Scrivo sul display pinA1 = analogRead(A1); // Leggo il piedino analogico 1 Volt = 3*pinA1; // a cui ho applicato la tensione di batteria diviso tre (tre resistenze uguali in serie) Volt=Volt*5/1023; // calcolo i volt corrispondenti lcd.setCursor(0, 1); // posiziono il cursore all'inizio della seconda riga lcd.setCursor(6, 1); // Posiziono il cursore alla sesta posizione della seconda riga lcd.print(Volt); // Scrivo sul display il valore della tensione misurata delay(1000); // Aspetto un secondo per dare modo di leggere quei valori lcd.clear(); // poi ripulisco lo schermo e ci scrivo lcd.setCursor(0, 0); // i campi fissi normali sul display lcd.print("m/s= "); lcd.setCursor(0, 1); lcd.print("Temp= "); lcd.setCursor(8, 1); lcd.print("Umid= "); Metri_Secondo = 0; // Azzero tutte le variabili Tempo_Start = 0; Tempo_Stop = 0; Tempo = 0; Diodo_Uno = 0; Diodo_Due = 0; t = 0; h = 0; } // FUNZIONE CHE SCRIVE SUL DIPLAY void scrivi_sul_display() { lcd.setCursor(0, 0); // Scrivo i campi fissi sul display lcd.print("m/s= "); lcd.setCursor(12, 1); lcd.print(" "); lcd.setCursor(4, 0); // Cursore alla posizione 6 della prima riga lcd.print(Metri_Secondo); // Scrive la velocità rilevata in m/s lcd.setCursor(9, 0); lcd.print("+o-"); lcd.setCursor(13, 0); lcd.print(Errore_Metri); lcd.setCursor(0, 1); // Cursore alla posizione 0 della seconda riga lcd.print("Temp= "); lcd.setCursor(5, 1); // Cursore alla posizione 5 della seconda riga lcd.print(t); // Scrive la temperatura rilevata lcd.setCursor(8, 1); // Cursore alla posizione 8 della seconda riga lcd.print("Umid= "); lcd.setCursor(13, 1); // Cursore alla posizione 13 della seconda riga lcd.print(h); //Scrive l'umidità rilevata } // FUNZIONE CHE LEGGE LA TEMPERATURA E L'UMIDITA' void leggi_temperatura() { h = dht.readHumidity(); // Leggo l'umidità e la metto in h t = dht.readTemperature(); // Leggo la temperatura in gradi Celsius e la metto in t }