Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2023:alucaci:cyclocomputer [2023/05/26 22:43]
bogdan_gabriel.toma [Software Design]
pm:prj2023:alucaci:cyclocomputer [2023/06/02 21:31] (current)
bogdan_gabriel.toma [Concluzii]
Line 41: Line 41:
   * Arduino IDE   * Arduino IDE
   * Wokwi   * Wokwi
 +
 +Laboratoare folosite (fara GPIO):
 +  * Intreruperi
 +  * Timere / PWM
 +  * SPI
 +  * I2C
  
 Pentru inceput, functiile clasice arduino (si anume setup() si loop()) arata in felul urmator: Pentru inceput, functiile clasice arduino (si anume setup() si loop()) arata in felul urmator:
Line 46: Line 52:
 ''''​ ''''​
   void setup() {   void setup() {
-    cli(); 
     Serial.begin(9600);​     Serial.begin(9600);​
     setupButtons();​     setupButtons();​
     setupI2C();     setupI2C();
 +    initGyro();
     setupLCD();     setupLCD();
 +    cli();
     setupInterrupt();​     setupInterrupt();​
     sei();     sei();
Line 82: Line 89:
 ''''​ ''''​
 Aceasta functie porneste comunicatia I2C prin initializarea Wire. Aceasta functie porneste comunicatia I2C prin initializarea Wire.
 +
 +''''​
 +  void initGyro() {
 +    Wire.beginTransmission(MPU);​
 +    Wire.write(0x3B);​
 +    Wire.endTransmission(false);​
 +    Wire.requestFrom(MPU,​ 6, true);
 +    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0;
 +    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0;
 +    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0;
 +    AngleY = (atan(-1 * AccX / sqrt(pow(AccY,​ 2) + pow(AccZ, 2))) * 180 / PI) + 1.58 - 3.1;
 +  }
 +''''​
 +Aceasta functie initializeaza unghiul Y, calculandu-l folosind informatiile din accelerometru,​ nu giroscop. (abia dupa initializare intra in joc giroscopul)
  
 ''''​ ''''​
Line 147: Line 168:
           rec = false;           rec = false;
         }         }
-        else if(mode < 1)  mode++;+        else if(mode < 2)  mode++;
         else  mode = 0;         else  mode = 0;
       }       }
Line 160: Line 181:
     else if(mode == 1) {     else if(mode == 1) {
       setWheelMode();​       setWheelMode();​
 +    }
 +    else if(mode == 2){
 +      setWeightMode();​
     }     }
     if(rec) {     if(rec) {
-      seconds = ((millis() - baseTime) / 1000) % 60 - 5;+      seconds = ((millis() - baseTime) / 1000) % 60;
       minutes = (seconds / 60) % 60;       minutes = (seconds / 60) % 60;
       hours = (minutes / 60) % 24;       hours = (minutes / 60) % 24;
Line 183: Line 207:
       lcd.clear();​       lcd.clear();​
       lcd.setCursor(0,​ 0);       lcd.setCursor(0,​ 0);
-      lcd.print(String(kilometers, ​3) + " km");+      ​if(kilometers < 10) 
 +        ​lcd.print(String(kilometers, ​2) + " ​km"​);​ 
 +      else if(kilometers >= 10 && kilometers < 100) 
 +        lcd.print(String(kilometers,​ 1) + " km"​);​ 
 +      else if(kilometers >= 100 && kilometers < 1000) 
 +        lcd.print(String(kilometers,​ 0) + " km"​);​ 
 +      else  
 +        lcd.print("​999 ​km");
       lcd.setCursor(0,​ 1);       lcd.setCursor(0,​ 1);
       (hours >= 10) ? lcd.print(String(hours)) : lcd.print("​0"​ + String(hours));​       (hours >= 10) ? lcd.print(String(hours)) : lcd.print("​0"​ + String(hours));​
Line 194: Line 225:
       lcd.setCursor(6,​ 1);       lcd.setCursor(6,​ 1);
       (seconds >= 10) ? lcd.print(String(seconds)) : lcd.print("​0"​ + String(seconds));​       (seconds >= 10) ? lcd.print(String(seconds)) : lcd.print("​0"​ + String(seconds));​
-      lcd.setCursor(9, 0);+      lcd.setCursor(8, 0);
       lcd.print("​Cal"​);​       lcd.print("​Cal"​);​
-      lcd.setCursor(13, 0);+      lcd.setCursor(12, 0);
       lcd.print(String((int)calories));​       lcd.print(String((int)calories));​
       lcd.setCursor(9,​ 1);       lcd.setCursor(9,​ 1);
Line 233: Line 264:
 ''''​ ''''​
 Aceasta functie a rolul de a afisa pe LCD informatiile de interes modului 2, si anume, Set Wheel Mode. Tot aici apasarile butoanelor 2 si 3 conduc la modificarea diametrului rotii. Aceasta functie a rolul de a afisa pe LCD informatiile de interes modului 2, si anume, Set Wheel Mode. Tot aici apasarile butoanelor 2 si 3 conduc la modificarea diametrului rotii.
 +
 +''''​
 +  void setWeightMode() {
 +    if(millis() - prevTimeLCD >= 500) {
 +      lcd.clear();​
 +      lcd.setCursor(0,​ 0);
 +      lcd.print("​Weight:"​);​
 +      lcd.setCursor(0,​ 1);
 +      lcd.print(String(weight) + " cm");
 +      prevTimeLCD = millis();
 +    }
 +    if(!(PIND & (1 << PB3)) && pressedPD[3] == false) {
 +      pressedPD[3] = true;
 +      weight += 10;
 +      weightMultiplier = (1.6 * (weight / 80)) / 2;
 +    }
 +    else if(PIND & (1 << PB3)) pressedPD[3] = false;
 +    if(!(PIND & (1 << PB4)) && pressedPD[4] == false) {
 +      pressedPD[4] = true;
 +      if(wheelDiameterCm >= 10){
 +        weight -= 10;
 +        weightMultiplier = (1.6 * (weight / 80)) / 2;
 +      }
 +    }
 +    else if(PIND & (1 << PB4)) pressedPD[4] = false;
 +  }
 +''''​
 +Aceasta functie a rolul de a afisa pe LCD informatiile de interes modului 3, si anume, Set Weight Mode. Tot aici apasarile butoanelor 2 si 3 conduc la modificarea gretutatii.
  
 ''''​ ''''​
Line 258: Line 317:
       distance = (2 * 3.14 * (wheelDiameterCm / 2)) / 100000;       distance = (2 * 3.14 * (wheelDiameterCm / 2)) / 100000;
       if(rec){       if(rec){
-        kilometers += distance; +        ​if(kilometers < 1000) 
-        if(GyroAngleY ​>= 0.6) +          ​kilometers += distance; 
-          calories += distance * 32 * GyroAngleY / 1.72+        if(calories < 9999) { 
-        else if (GyroAngleY ​>= -0.6 && ​GyroAngleY ​< 0.6) +          slopeMultiplier = 3 * AngleY / 1.72; 
-          calories += distance * 32; +          if(AngleY ​>= 0.6) 
-        else +            calories += distance * 32 * slopeMultiplier ​weightMultiplier
-          calories += distance * 32 * -1 / 3 GyroAngleY / 1.72;+          else if (AngleY ​>= -0.6 && ​AngleY ​< 0.6) 
 +            calories += distance * 32; 
 +          else 
 +            calories += distance * 32 / (slopeMultiplier ​(-1)) weightMultiplier; 
 +        }
       }       }
       speedKmh = distance * 3600000/​(millis() - prevTimeKmh);​       speedKmh = distance * 3600000/​(millis() - prevTimeKmh);​
 +      if(speedKmh > 999)
 +        speedKmh = 999;
       prevTimeKmh = millis();       prevTimeKmh = millis();
       interrupt = false;       interrupt = false;
Line 272: Line 337:
   }   }
 ''''​ ''''​
-Aceasta functie calculeaza distanta, in km,  bazat pe diametrul rotii (variabile booleana **interrupt** este folosita pentru a nu avea intretuperi multiple (un fel de debouncing pentru intreruperi). Tot aici, in cazul in care inregistram (variabila **rec** este **true**) contorizam km, calculam caloriile si viteza. Calculul caloriilor se bazeaza pe date colectate din sursele ce urmeaza a fi citate mai jos, si pe regula de 3 simpla ​(pe scurt un om arde, in medie, de 3 ori mai multe calorii cand pedaleaza pe o rampa avand panta 3% (1.72 grade). De aici ne putem da seama de caloriile arse in functie de panta). Pentru calculul vitezei se tine cont de diametrul rotii si de timpul dintre 2 intreruperi. in cazul in care acesta este mai mare de 1 secunda, viteza se reseteaza folosind functia urmatoare.+Aceasta functie calculeaza distanta, in km,  bazat pe diametrul rotii (variabile booleana **interrupt** este folosita pentru a nu avea intretuperi multiple (un fel de debouncing pentru intreruperi). Tot aici, in cazul in care inregistram (variabila **rec** este **true**) contorizam km, calculam caloriile si viteza. Calculul caloriilor se bazeaza pe date colectate din sursele ce urmeaza a fi citate mai jos, si pe regula de 3 simpla. Pentru calculul vitezei se tine cont de diametrul rotii si de timpul dintre 2 intreruperi. in cazul in care acesta este mai mare de 1 secunda, viteza se reseteaza folosind functia urmatoare.
  
 ''''​ ''''​
Line 291: Line 356:
   float kilometers = 0, distance = 0;   float kilometers = 0, distance = 0;
   int hours = 0, minutes = 0, seconds = 0;   int hours = 0, minutes = 0, seconds = 0;
-  float wheelDiameterCm = 0;+  float wheelDiameterCm ​= 0, weight ​= 0;
   float calories = 0;   float calories = 0;
   int mode = 0;   int mode = 0;
Line 300: Line 365:
   bool PWMOn = false;   bool PWMOn = false;
   bool freeze = false;   bool freeze = false;
 +  float slopeMultiplier = 0, weightMultiplier = 0;
 ''''​ ''''​
-===== Rezultate Obţinute ===== 
  
-<note tip> +=== Explicatie ecuatii calorii: ===
-Care au fost rezultatele obţinute în urma realizării proiectului vostru. +
-</​note>​+
  
-===== Concluzii =====+Luand ca referinta average male (175 cm, 80 kg) si o viteza medie (20 km/h) avem urmatoarele date: 
 +  * calorii arse intr-un km ~32 
 +  * calorii arse intr-o ora de ciclat pe teren plat ~300, calorii arse intr-o ora de ciclat in rampa de 3% (1.72 grade) ~900 (3 ori mai mult) 
 +  * calorii arse intr-o ora de ciclat ~300, calorii arse intr-o ora de cicalt, de aceeasi persoana, dar kilograme duble ~480 (1.6 ori mai mult)
  
-===== Download =====+Cunoscand aceste date, putem aplica regula de 3 simpla pentru a afla caloriile arse pentru diferite unghiuri de panta sau kilograme astfel:
  
-<note warning>​ +----
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului:​ surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).+
  
-Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**Namespace-ul în care se încarcă fişierele este de tipul **:​pm:​prj20??:​c?​** sau **:​pm:​prj20??:​c?:​nume_student** (dacă este cazul)**Exemplu:​** Dumitru Alin, 331CC -> **:​pm:​prj2009:​cc:​dumitru_alin**. +caloriile arse 3 ori mai mult  ​... 1.72 unghi
-</​note>​+
  
-===== Jurnal =====+calorii arse de x ori mai mult ... y unghi (furnizat de giroscop)
  
-<note tip> +----
-Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. +
-</​note>​+
  
-===== Bibliografie/​Resurse =====+calorii arse de 1.6 ori mai mult ... avem de 2 ori 80 kg 
 + 
 +calorii arse de x ori mai mult   ... avem de y ori 80 kg 
 + 
 +---- 
 + 
 +Cele doua reguli conduc la urmatoarele ecuatii: 
 +  * caloriile += (distanta parcursa la o tura de roata, in km) * 32 (average calorii arse intr-un km) * ((3 * AngleY) / 1.72) 
 +  * caloriile += (distanta parcura la o tura de roata, in km) * 32 (average calorii arse intr-un km) * ((1.6 * (weight / 80) / 2); 
 + 
 + 
 +===== Rezultate Obţinute ===== 
 + 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_1_btoma.jpeg?​400|}} 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_2_btoma.jpeg?​400|}} 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_3_btoma.jpeg?​400|}} 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_4_btoma.jpeg?​400|}} 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_5_btoma.jpeg?​400|}} 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_6_btoma.jpeg?​400|}} 
 +===== Concluzii ===== 
 + 
 +In urma acestui proiect am realizat ca este mult mai usor sa te accidentezi stand la o masa decat ai crede. In saptamanile de proiect m-am accidentat cu: 
 +  * Foarfeca 
 +  * Letcon 
 +  * Fire 
 +  * Alta foarfeca 
 +  * Cositor 
 +  * Pini 
 +Asadar, in urma instalarii unui usor PTSD la simplul contact vizual cu o unealta din campul electronicii / electrotehnicii / orice cuvant prefixat, sau sufixat, de termenul "​electro",​ am invatat sa dau importanta normelor de protectia muncii. 
 +Tot in cadrul proiectului am invatat ca led-urile cumparate de la un magazin, cel putin dubios, dintr-un imobil interbelic, a carui cale de acces (usa) se afla in curtea din spate, deloc primitoare, comuna cu alte imobile invecinate, pot fi putin, putin mai mult, peste pretul de piata. 
 + 
 +Desigur, pe parcursul proiectului am invatat cum se configureaza un arduino folosind registri, ceea ce conduce la o viteza conisderabil mai mare a programului si la minimizarea spatiului utilizat, cum compilatorul optimizeaza codul, cum functioneaz intreruperile,​ timerele, etc.  dar asta nu este foarte important. In viata mai des te intalnesti cu o foarfeca (nu o sa o iert) decat cu un timer pe 16 biti care trebuie configurat in asa fel incat sa genereze un semnal PWM pe pinul D9 cu un duty cycle de 50%, avand frecventa nealterata (16MHz). 
 + 
 +Dar ca sa concluzionam,​ scurt, foarte frumos, mai facem™ :like: 
 +===== Download ===== 
 +{{:​pm:​prj2023:​alucaci:​cyclocomputer_toma_bogdan_gabriel.rar|}} 
 + 
 + 
 +===== Bibliografie/​Resurse[[http://​example.com|External Link]] ​=====
  
 [[https://​ww1.microchip.com/​downloads/​en/​DeviceDoc/​Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|ATmega328P Datasheet]] [[https://​ww1.microchip.com/​downloads/​en/​DeviceDoc/​Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf|ATmega328P Datasheet]]
Line 330: Line 430:
  
 [[https://​www.livestrong.com/​article/​315791-calories-burned-by-biking-uphill/#:​~:​text=The%20same%20person%20traveling%20at,​nearly%20850%20calories%20per%20hour.|Calories burned cycling uphill]] [[https://​www.livestrong.com/​article/​315791-calories-burned-by-biking-uphill/#:​~:​text=The%20same%20person%20traveling%20at,​nearly%20850%20calories%20per%20hour.|Calories burned cycling uphill]]
 +
 +[[https://​keisan.casio.com/​exec/​system/​1350958587|Cycling calories burned calculator]]
 +
 +[[https://​mountainpassessouthafrica.co.za/​news/​facebook/​item/​449-conversion-table-to-ratio-to-degrees.html|Slope to degrees table]]
 +
 +[[https://​www.healthline.com/​health/​mens-health/​average-weight-for-men#​average-weight-around-the-world|Average height / weight men]]
 +
 +[[https://​www.healthline.com/​health/​womens-health/​average-height-for-women|Average height / weight women]]
 +
 +[[https://​www.archtoolbox.com/​calculating-slope/​|Slope grade formulas]]
  
 <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
  
pm/prj2023/alucaci/cyclocomputer.1685130209.txt.gz · Last modified: 2023/05/26 22:43 by bogdan_gabriel.toma
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0