Bike speedometer software
//Versiunea 08 //modificat in 12 01 2012 // CIRCUIT // Vitezometru // (Gnd) ---- (R) --------|------- (Reed Switch) ---- (+5v) // | // Digital Pin 11 // pt.ca valoare indicata sa fie cea corecta, //senzorul trebuie sa fie activat cel putin 300 micosecunde // // Voltmetru // (Gnd) ---- (R2) -------|------- (R1) ---- (Vin) // | // Vout -> Analog Pin 5 // // // Termometru // (Gnd) ---------------LM35----------- (+5v) // | // Analog Pin 0 float temperatura = 0; // // includem libraria EEPROM: #include EEPROM.h // // includem libraria pt conectare la LCD: #include LiquidCrystal.h //initializam libraria si definim pini de conectare la LCD // (RS, EN, D4,D3,D2,D1); LiquidCrystal lcd(10, 9, 8, 7, 6, 5); //--------voltmetru----------- int IntrareVoltmetru = 5; float vin = 0.0; float R1 = 15000.0; // !! valoarea rezistentei R1 !! float R2 = 1000.0; // !! valoarea rezistentei R2 !! float formula = 0; //------------------------------------------------------ #define LED 13 // iesire pentru LED #define SWITCH 11 // intrare pentru senzor #define RESET 4 // intrare butonul reset distanta int circumferinta = 185; // circumferinţa în cm int val = 0; // folosit pentru a memora valoarea de intrare int ValoareaAnterioara = 0; // folosit pentru a elimina citirea repetata a senzorului in timpul opririi int debounce = 10; // Valoarea trebuie crescuta daca este necesar float rotatii = 1; // numărul total de rotaţii float VitezaCurenta = 0; // viteza curentă în km / h float VitezaMedie = 0; // viteza medie de cand am pornit float VitezaMaxima = 0; // viteza maxima de cand am pornit unsigned long revTimer; // creem un cronometru pentru citirea timpului dintre impulsurii unsigned long rideTimer; // cronometru călătorie boolean activeRiding = false; // suntem în mişcare? boolean activityChange = true; // doar o modalitate de a tine cont de cât timp suntem inactivi float inactivityTimer; // millis() la care am început inactivitatea float activeRidingOffset = 0; // timpul scăzut din timpul total de mers când se calculează viteza medie float DistantaParcursa = 0; // distanţa totală parcursă de cand am pornit unsigned long DistantaTotala = 0; unsigned long DistantaMemorata = 0; int memorare = 0; //-------------afisare--------------------------- long TimpLcdAnterior = 0; // pentru actualizare ecran long LcdInterval = 1000; // timpul intre afisari int ecran = 0; // ecranul afişat int ecranMax = 24; // nr. de ecrane afisate boolean schimbareEcran = true; // initial avem un nou ecran //------------------------------------------------------ void setup() { // declaram pinii de interfata pinMode(LED, OUTPUT); // LED este o ieşire, pinMode(SWITCH, INPUT); // si SWITCH este intrare pinMode(IntrareVoltmetru, INPUT);// intrare masura tensiune pinMode(RESET, INPUT); // RESET este intrare analogReference(INTERNAL); // Folosim referinta interna de 1.1V // setam numarul de coloane şi rânduri pe LCD lcd.begin(20, 2); lcd.clear(); lcd.setCursor(6, 0); lcd.print("ATENTIE"); lcd.setCursor(2, 1); lcd.print("puneti-va casca!"); delay(2000); lcd.clear(); // citire distanta totala din EEPROM DistantaMemorata = (EEPROM.read(10) * 65536) + (EEPROM.read(11) * 256) + (EEPROM.read(12)); DistantaTotala = DistantaMemorata; //-----------voltmetru-------------------- formula = ((1.1/1023)/(R2/(R1+R2))); //---------------------------------------- revTimer = millis(); // Start cronometru puls rideTimer = millis(); // start cronometru călătorie } void loop(){ //-----------resetare distanta------------ if (digitalRead(RESET) == LOW) { EEPROMclear(); //memoram valorile in eeprom delay(500); DistantaTotala = 0; DistantaMemorata = 0; DistantaParcursa = 0; lcd.setCursor(0, 0); lcd.print(" Distanta "); lcd.setCursor(0, 1); lcd.print(" Resetata "); delay(2000); lcd.clear(); ecran = 0; // începe de la capăt cu afisarea } //---------------------------------------- if(activityChange) { inactivityTimer = millis(); activityChange = false; } else { if(activityChange) { activeRidingOffset += millis() - inactivityTimer; activityChange = false; } } val=digitalRead(SWITCH); // citeşte valoarea de intrare şi memoreaz-o. if (val==HIGH) { // verifica dacă intrare este "HIGH" (magnetu-l este in raza senzorului) digitalWrite(LED, HIGH); // "aprinde" LED-ul ValoareaAnterioara = HIGH; // permite următoarul "impuls" pentru a fi numărat } else { digitalWrite(LED, LOW); // Stinge led-ul if (ValoareaAnterioara != LOW && millis() - revTimer > debounce) { // daca... pulse(); // inseamna ca ne miscam } ValoareaAnterioara = LOW; // în cazul în care magnetul este în raza de acţiune a senzorului in timpul stationarii. } if(millis()-revTimer > 2000) { // daca a trecut prea mult timp de la ultimul impuls, VitezaCurenta = 0; // inseamna ca stam pe loc if(activeRiding) { activityChange = true; activeRiding = false; } } //----------Memorare distanta--------------- if(millis()-revTimer > 10000) { // daca a trecut prea mult timp de la ultimul impuls, if (memorare == 1) { // si memorarea este activata EEPROMwrite(); //memoram distanta in eeprom delay(500); lcd.setCursor(0, 0); lcd.print(" Distanta "); lcd.setCursor(0, 1); lcd.print(" Salvata "); delay(2000); lcd.clear(); memorare = 0; //setam memorarea 0 pt a preveni scriierea repetata ecran = 0; // începe de la capăt cu afisarea } } //----------Afisare Rezultate------------- unsigned long TimpLcdActual = millis(); if(TimpLcdActual - TimpLcdAnterior > LcdInterval) // memoram ultima data cand am afisat { TimpLcdAnterior = TimpLcdActual; ecran++; if (ecran > ecranMax) ecran = 0; // toate ecranele afisate ? => începe de la capăt schimbareEcran = true; if (schimbareEcran) // actualizare numai în cazul în care ecranul se schimbă. { schimbareEcran = false; // resetare pentru urmatoarea schimbare switch(ecran) { case 0: DisTotala(); break; case 1: DisTotala(); break; case 2: DisTotala(); break; case 3: DisTotala(); break; case 4: DisTotala(); break; case 5: VitMedie(); break; case 6: VitMedie(); break; case 7: VitMedie(); break; case 8: VitMedie(); break; case 9: VitMedie(); break; case 10: VitMaxima(); break; case 11: VitMaxima(); break; case 12: VitMaxima(); break; case 13: VitMaxima(); break; case 14: VitMaxima(); break; case 15: Temp(); break; case 16: x(); break; case 17: x(); break; case 18: x(); break; case 19: x(); break; case 20: volt(); break; case 21: x(); break; case 22: x(); break; case 23: x(); break; case 24: x(); break; default: break; } } } //------------------------------------------------------ } void pulse() { memorare = 1; //activam memorarea pt urmatoarea oprire rotatii++; // incrementam nr. de rotatii DistantaParcursa = (float) circumferinta * rotatii / 100000;// distata in KM DistantaTotala = DistantaMemorata + DistantaParcursa; VitezaCurenta = (float) (millis() - revTimer)*0.001; // Convertim timpul trecut din milisecunde in secunde VitezaCurenta = circumferinta/VitezaCurenta; // V = d/t: Circumferinta rotii / timp trecut VitezaCurenta = VitezaCurenta*0.036; // Km/h Conversion: 1 cm/s = 0.01 m/s * 3600 s/hr = 0.036 Km/h if (VitezaMaxima < VitezaCurenta) { VitezaMaxima = VitezaCurenta; } // calculam timpul de cand am pornit din care scadem stationarile unsigned long activeRidingMillis = millis() - rideTimer - activeRidingOffset; float activeRidingHours = (float) activeRidingMillis / 1000/60/60; // transformam in ore VitezaMedie = DistantaParcursa / activeRidingHours; //viteza medie = distanta parcursa/timp revTimer = millis(); // memoram momentul actual pt. a calcula viteza data viitoare if(!activeRiding) { activityChange = true; activeRiding = true; } } void DisTotala() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(VitezaCurenta,0); lcd.print("Kmh"); lcd.setCursor(10, 0); lcd.print(DistantaParcursa); lcd.print("km"); lcd.setCursor(0, 1); lcd.print("DistTot:"); lcd.setCursor(10, 1); lcd.print(DistantaTotala); lcd.print("Km"); } void VitMedie() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(VitezaCurenta,0); lcd.print("Kmh"); lcd.setCursor(10, 0); lcd.print(DistantaParcursa); lcd.print("km"); lcd.setCursor(0, 1); lcd.print("V.Medie:"); lcd.setCursor(10, 1); lcd.print(VitezaMedie,1); lcd.print("Kmh"); } void VitMaxima() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(VitezaCurenta,0); lcd.print("Kmh"); lcd.setCursor(10, 0); lcd.print(DistantaParcursa); lcd.print("km"); lcd.setCursor(0, 1); lcd.print("V.Maxima:"); lcd.setCursor(10, 1); lcd.print(VitezaMaxima,1); lcd.print("Kmh"); } void Temp() { temperatura = (1.1*analogRead(0)*100/1024); lcd.clear(); lcd.setCursor(0, 0); lcd.print(VitezaCurenta,0); lcd.print("Kmh"); lcd.setCursor(10, 0); lcd.print(DistantaParcursa); lcd.print("km"); lcd.setCursor(0, 1); lcd.print("Temp:"); lcd.setCursor(10, 1); lcd.print(temperatura,1); lcd.print((char)223); // scrie caracterul pt. grade celsius lcd.print("C"); } void volt() { //-----------voltmetru------------------- // citim valoarea de pe intrarea analogica si calculam tensiunea vin = ((analogRead(IntrareVoltmetru) * formula) + 0.6); // adaugam caderea de tensiune pe dioda //---------------------------------------- lcd.clear(); lcd.setCursor(0, 0); lcd.print(VitezaCurenta,0); lcd.print("Kmh"); lcd.setCursor(10, 0); lcd.print(DistantaParcursa); lcd.print("km"); lcd.setCursor(0, 1); lcd.print("Tensiune:"); lcd.setCursor(10, 1); lcd.print(vin,1); lcd.print("V"); } void x() { lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); lcd.print(VitezaCurenta,0); lcd.print("Kmh"); lcd.setCursor(10, 0); lcd.print(DistantaParcursa); lcd.print("km "); } void EEPROMwrite() { // Memorarea distantei // memoreaza variabilele in EEPROM EEPROM.write(10, byte((DistantaTotala & 16711680)/65536)); EEPROM.write(11, byte((DistantaTotala & 65280)/256)); EEPROM.write(12, byte((DistantaTotala & 255))); } void EEPROMclear() { // Stergerea distantei EEPROM.write(10, byte((0 & 16711680)/65536)); EEPROM.write(11, byte((0 & 65280)/256)); EEPROM.write(12, byte((0 & 255))); }
Best Bike Speedometer
ReplyDelete