Differences

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

Link to this comparison view

pm:prj2022:apredescu:speedometer [2022/06/01 20:38]
victor.hincu
pm:prj2022:apredescu:speedometer [2022/06/01 20:59] (current)
victor.hincu [Bibliografie/Resurse]
Line 4: Line 4:
 <note tip> <note tip>
 Prezentarea pe scurt a proiectului vostru: Prezentarea pe scurt a proiectului vostru:
-  * ce face +  * Vitezometru si Odometru, bazat pe o placa de baza Arduino Uno 
-  * care este scopul lui +  * monitorizarea vitezei si a performantei pe durata a 99 de ture 
-  * care a fost ideea de la care aţi pornit +  * nevoia unei cunostinte ​de a avea un vitezometru 
-  * de ce credeţi că este util pentru ​alţii şi pentru voi+  * elimina nevoia ​de a purta un telefon in buzunar ​pentru ​a monitoriza performantele ce pot fi eventual eronate
 </​note>​ </​note>​
 ===== Descriere generală ===== ===== Descriere generală =====
Line 21: Line 21:
 <note tip> <note tip>
 Aici puneţi tot ce ţine de hardware design: Aici puneţi tot ce ţine de hardware design:
-  * listă de piese +  * Arduino Uno - 1 
-  * scheme electrice (se pot lua şi de pe Internet şi din datasheet-uri, e.g. http://​www.captain.at/​electronic-atmega16-mmc-schematic.png) +  * Hall Effect Sensor ​
-  * diagrame de semnal ​ +  * Push Buttons ​
-  * rezultatele simulării+  * 16x2 LCD Display ​1 
 +  * 10kΩ Potentiometer - 1 
 +  * 10kΩ Resistor - 2 
 + 
 +{{:​pm:​prj2022:​apredescu:​image_2022-06-01_205619478.png?​200|}} 
 </​note>​ </​note>​
  
Line 31: Line 36:
  
 <note tip> <note tip>
-Descrierea codului aplicaţiei ​(firmware): + 
-  ​* mediu de dezvoltare ​(if any) (e.gAVR StudioCodeVisionAVR+    * Arduino IDE 
-  * librării şi surse 3rd-party (e.gProcyon AVRlib+    * Additional Libraries: Wire/​EEPROM/​RTClib/​LiquidCrystal 
-  ​* algoritmi şi structuri pe care plănuiţi să le implementaţi + 
-  * (etapa 3) surse şi funcţii implementate+<code cvp> 
 +#include <​LiquidCrystal.h>​ 
 + 
 +LiquidCrystal lcd(12, 11, 8, 7, 6, 5); 
 + 
 +float bicycleWheelCircumference = 2.1206; ​  
 + 
 +const int pauseButton = 2; 
 +boolean lastPauseButton = LOW; 
 +boolean currentPauseButton = LOW; 
 + 
 +const int displayModeButton = 3; 
 +boolean lastDisplayModeButton = LOW; 
 +boolean currentDisplayModeButton = LOW; 
 + 
 +const int revolutionButton = 4; 
 +boolean lastRevolutionButton = LOW; 
 +boolean currentRevolutionButton = LOW; 
 + 
 +boolean startShown = HIGH; 
 + 
 +boolean paused = LOW; 
 +boolean pausedShown = LOW; 
 +unsigned long pausedStartTime = 0; 
 + 
 +boolean wheelTurningShown = LOW; 
 +unsigned long wheelTurningStartTime = 0; 
 + 
 +boolean cycleSafelyShown = LOW; 
 +unsigned long cycleSafelyStartTime = 0; 
 + 
 +unsigned long lastRevolutionStartTime = 0; 
 +unsigned long revolutionTime = 0; 
 + 
 +int currentDisplayMode = 0; 
 +int showLap = 0; 
 +int lapCurrentlyShown = 100; 
 +int currentLap = 0; 
 + 
 +float currentDistance;​ 
 +unsigned long currentDuration;​ 
 +int currentMaximumKPH;​ 
 +int currentAverageKPH;​ 
 +int currentKPH;​ 
 + 
 +float arrayDistance[100];​ 
 +unsigned long arrayDuration[100];​ 
 +int arrayMaximumKPH[100];​ 
 +int arrayAverageKPH[100];​ 
 + 
 +unsigned long revolutionCount = 0; 
 +unsigned long currentTime = 0; 
 +unsigned long lapStartTime = 0; 
 + 
 +float km = 0.00; 
 +float kph = 0.00; 
 +int intHours; 
 +int intMinutes;​ 
 +int intSeconds;​ 
 + 
 +unsigned long milliSecondsInSecond = 1000; 
 +unsigned long milliSecondsInMinute = 60000; 
 +unsigned long milliSecondsInHour = 3600000; 
 + 
 +void setup() 
 +
 + 
 +  pinMode ​(revolutionButton,​ INPUT); 
 +  pinMode (pauseButton,​ INPUT); 
 +  pinMode (displayModeButton,​ INPUT); 
 + 
 +  arrayMaximumKPH[0] = 0; 
 + 
 +  lcd.begin(16, 2); 
 +  lcd.clear(); 
 +  lcd.setCursor(20); 
 +  ​lcd.print("​PRESS BUTTON"​);​ 
 +  lcd.setCursor(4,​ 1); 
 +  lcd.print("​TO START"​);​ 
 +   
 +
 + 
 +void loop() { 
 + 
 +  currentTime = millis(); 
 + 
 +  currentRevolutionButton = debounce(lastRevolutionButton,​ revolutionButton);​ 
 +  if (lastRevolutionButton == HIGH && currentRevolutionButton == LOW) { 
 +     
 +    if (!startShown && !paused) { 
 + 
 +      revolutionCount++;​ 
 + 
 +      lcd.setCursor(0,​ 0); 
 +      lcd.print("​+"​);​ 
 +      wheelTurningShown = HIGH; 
 +      wheelTurningStartTime = currentTime;​ 
 + 
 +      if (lastRevolutionStartTime > 0) { 
 + 
 +        revolutionTime = currentTime - lastRevolutionStartTime;​ 
 + 
 +        kph = (3600000 / revolutionTime) ​bicycleWheelCircumference / 1000; 
 +        currentKPH = kph; 
 + 
 +        if (currentMaximumKPH < currentKPH) { 
 +          currentMaximumKPH = currentKPH;​ 
 +        } 
 +      } 
 +      lastRevolutionStartTime = currentTime;​ 
 +    } 
 +  } 
 +  lastRevolutionButton = currentRevolutionButton;​ 
 + 
 +  currentPauseButton = debounce(lastPauseButton,​ pauseButton);​ 
 +  if (lastPauseButton == LOW && currentPauseButton == HIGH) { 
 + 
 +    if (startShown) { 
 + 
 +      startShown = LOW;   
 + 
 +      showCycleSafely();​ 
 +      cycleSafelyShown = HIGH; 
 +      cycleSafelyStartTime = currentTime;​ 
 + 
 +      currentLap = 1; 
 +      resetLapVariables();​ 
 +      currentDisplayMode = 1; 
 + 
 +    } 
 +    else { 
 +       
 +      if (paused) { 
 + 
 +        paused = LOW; 
 + 
 +        showCycleSafely();​ 
 +        cycleSafelyShown = HIGH; 
 +        cycleSafelyStartTime = currentTime;​ 
 + 
 +        currentLap++;​ 
 + 
 +        if (currentLap > 99) { 
 +          currentLap = 99; 
 +          lapCurrentlyShown = 100; 
 +        } 
 + 
 +        resetLapVariables();​ 
 +        currentDisplayMode = 1; 
 +      } 
 + 
 +      else { 
 + 
 +        paused = HIGH; 
 + 
 +        currentDuration = currentTime ​lapStartTime;​ 
 + 
 +        if (currentDuration < 2000) { 
 +          currentLap--;​ 
 +        } 
 +        else { 
 + 
 +          if (revolutionCount > 0) { 
 +            currentDistance = revolutionCount * bicycleWheelCircumference / 1000; 
 +            currentAverageKPH = currentDistance * 3600000 / currentDuration;​ 
 +          } 
 +           
 +          arrayDistance[currentLap] = currentDistance;​ 
 +          arrayDuration[currentLap] = currentDuration;​ 
 +          arrayAverageKPH[currentLap] = currentAverageKPH;​ 
 +          arrayMaximumKPH[currentLap] = currentMaximumKPH;​ 
 +   
 +          arrayDistance[0] = arrayDistance[0] + currentDistance;​ 
 +          arrayDuration[0] = arrayDuration[0] + currentDuration;​ 
 +          arrayAverageKPH[0] = arrayDistance[0] * 3600000 / arrayDuration[0]; ​  
 +          if (currentMaximumKPH > arrayMaximumKPH[0]) { 
 +            arrayMaximumKPH[0] = currentMaximumKPH;​ 
 +          }         
 +        } 
 + 
 +        cycleSafelyShown = LOW; 
 +         
 +        showPaused();​ 
 +        pausedShown = HIGH; 
 +        pausedStartTime = currentTime;​ 
 + 
 +        showLap = currentLap;​ 
 +        currentDisplayMode = 3; 
 + 
 +        lapCurrentlyShown = 100; 
 +      } 
 +    } 
 +  } 
 +  lastPauseButton = currentPauseButton;​ 
 + 
 +  currentDisplayModeButton = debounce(lastDisplayModeButton,​ displayModeButton);​ 
 +  if (lastDisplayModeButton == LOW && currentDisplayModeButton == HIGH) { 
 + 
 +    if (startShown) { 
 + 
 +      startShown = LOW;   
 + 
 +      showCycleSafely();​ 
 +      cycleSafelyShown = HIGH; 
 +      cycleSafelyStartTime = currentTime;​ 
 + 
 +      currentLap = 1; 
 +      resetLapVariables();​ 
 +      currentDisplayMode = 1; 
 + 
 +    } 
 +    else { 
 +       
 +      if (!cycleSafelyShown && !pausedShown) { 
 + 
 +        if (!paused) { 
 + 
 +          if (currentDisplayMode == 1) { 
 +            currentDisplayMode = 2; 
 +          } 
 +          else { 
 +            currentDisplayMode = 1; 
 +          } 
 +           
 +          showLabels(currentDisplayMode);​ 
 +        } 
 +         
 +        else { 
 +          currentDisplayMode = 3; 
 +          showLap++;​ 
 +          if (showLap > currentLap) { 
 +            showLap = 0; // Show totals 
 +          } 
 +        } 
 +      } 
 +    } 
 +  } 
 +  lastDisplayModeButton = currentDisplayModeButton;​ 
 + 
 +  if (wheelTurningShown && !startShown && !paused && (currentTime >= (wheelTurningStartTime + 250))) { 
 +    wheelTurningShown = LOW; 
 +    lcd.setCursor(0,​ 0); 
 +    lcd.print("​ "); 
 +  ​
 + 
 +  ​if (!startShown && !paused && (currentTime >= (lastRevolutionStartTime + 10000)) && currentKPH > 0) { 
 +    currentKPH = 0; 
 +  } 
 + 
 +  if (cycleSafelyShown && (currentTime >= (cycleSafelyStartTime + 2000))) { 
 +    cycleSafelyShown = LOW; 
 +    showLabels(currentDisplayMode);​ 
 +  } 
 + 
 +  if (pausedShown && (currentTime >= (pausedStartTime + 2000))) { 
 +    pausedShown = LOW; 
 +    showLabels(currentDisplayMode);​ 
 +  } 
 + 
 +  if (!startShown && !paused) { 
 + 
 +    currentDuration = currentTime - lapStartTime;​ 
 + 
 +    if (revolutionCount > 0) { 
 +      currentDistance = revolutionCount ​bicycleWheelCircumference / 1000; 
 + 
 +      currentAverageKPH = currentDistance * 3600000 / currentDuration;​ 
 +    } 
 +  } 
 + 
 +  if (!startShown && !cycleSafelyShown && !pausedShown) { 
 + 
 +    if (currentDisplayMode < 3) 
 + 
 +      lcd.setCursor(1,​ 0); 
 +      lcd.print(currentDistance);​ 
 +      lcd.print("​ km"​);​ 
 + 
 +      lcd.setCursor(14,​ 0); 
 +      if (currentKPH < 10) { 
 +        lcd.print("​ "); 
 +      } 
 +      lcd.print(currentKPH);​ 
 + 
 +      computeHMS(currentDuration);​ 
 +      lcd.setCursor(1,​ 1); 
 +      if (intHours < 10) { 
 +        lcd.print("​0"​);​ 
 +      } 
 +      lcd.print(intHours);​ 
 +       
 +      lcd.print(":"​);​ 
 +      if (intMinutes < 10) { 
 +        lcd.print("​0"​);​ 
 +      } 
 +      lcd.print(intMinutes);​ 
 +       
 +      lcd.print(":"​);​ 
 +      if (intSeconds < 10) { 
 +        lcd.print("​0"​);​ 
 +      } 
 +      lcd.print(intSeconds);​ 
 + 
 +      lcd.setCursor(12,​ 1); 
 +      lcd.print("​A"​);​ 
 + 
 +      if (currentDisplayMode == 1) { 
 +        lcd.setCursor(12,​ 1); 
 +        lcd.print("​A"​);​ 
 +        lcd.setCursor(14,​ 1); 
 +        if (currentAverageKPH < 10) { 
 +          lcd.print("​ "); 
 +        } 
 +        lcd.print(currentAverageKPH);​ 
 +      } 
 +      else { 
 +        lcd.setCursor(12,​ 1); 
 +        lcd.print("​M"​);​ 
 +        lcd.setCursor(14,​ 1); 
 +        if (currentMaximumKPH < 10) { 
 +          lcd.print("​ "); 
 +        } 
 +        lcd.print(currentMaximumKPH);​ 
 +      } 
 +    } 
 + 
 +    else { 
 + 
 +      if (lapCurrentlyShown != showLap) { 
 + 
 +        lapCurrentlyShown = showLap; 
 +         
 +        lcd.clear();​ 
 + 
 +        lcd.setCursor(0,​ 0); 
 +        if (showLap == 0) { 
 +          lcd.print("​T "); 
 +        }  
 +        else { 
 +          lcd.print(showLap);​ 
 +        } 
 + 
 +        lcd.setCursor(3,​ 0); 
 +        lcd.print("​Avg"​);​ 
 +        lcd.setCursor(7,​ 0); 
 +        lcd.print(arrayAverageKPH[showLap]);​ 
 +        if (arrayAverageKPH[showLap] < 10) { 
 +          lcd.print("​ "); 
 +        } 
 + 
 +        lcd.setCursor(10,​ 0); 
 +        lcd.print("​Max"​);​ 
 +        lcd.setCursor(14,​ 0); 
 +        lcd.print(arrayMaximumKPH[showLap]);​ 
 +        if (arrayMaximumKPH[showLap] < 10) { 
 +          lcd.print("​ "); 
 +        } 
 +         
 +        lcd.setCursor(0,​ 1); 
 +        lcd.print(" ​       "); 
 +        lcd.setCursor(0,​ 1); 
 +        lcd.print(arrayDistance[showLap]);​ 
 + 
 +        computeHMS(arrayDuration[showLap]);​ 
 +        lcd.setCursor(8,​ 1); 
 +        if (intHours < 10) { 
 +          lcd.print("​0"​);​ 
 +        } 
 +        lcd.print(intHours);​ 
 +         
 +        lcd.print(":"​);​ 
 +         
 +        if (intMinutes < 10) { 
 +          lcd.print("​0"​);​ 
 +        } 
 +        lcd.print(intMinutes);​ 
 +         
 +        lcd.print(":"​);​ 
 +         
 +        if (intSeconds < 10) { 
 +          lcd.print("​0"​);​ 
 +        } 
 +        lcd.print(intSeconds);​ 
 +      }         
 +    } 
 +  } 
 +
 + 
 +void computeHMS(unsigned long duration) { 
 + 
 +  float floatHours;​ 
 +  float floatMinutes;​ 
 +  float floatSeconds;​ 
 + 
 +  intHours = 0; 
 +  intMinutes = 0; 
 +  intSeconds = 0; 
 + 
 +  if (duration >= 1000) { 
 +      floatSeconds = duration / milliSecondsInSecond % 60; 
 +      intSeconds = floatSeconds;​ 
 +       
 +      floatMinutes = duration / milliSecondsInMinute % 60; 
 +      intMinutes = floatMinutes;​ 
 +       
 +      floatHours = duration / milliSecondsInHour % 24; 
 +      intHours = floatHours;​ 
 +  } 
 +
 + 
 +void resetLapVariables() { 
 +  revolutionCount = 0; 
 + 
 +  lapStartTime = currentTime;​ 
 + 
 +  currentDistance = 0; 
 +  currentDuration = 0; 
 +  currentMaximumKPH = 0; 
 +  currentAverageKPH = 0; 
 +
 + 
 +void showCycleSafely() { 
 +  lcd.clear();​ 
 +  lcd.setCursor(5,​ 0); 
 +  lcd.print("​CYCLE"​);​ 
 +  lcd.setCursor(4,​ 1); 
 +  lcd.print("​SAFELY!"​);​ 
 +
 + 
 +void showPaused() { 
 +  lcd.clear();​ 
 +  lcd.setCursor(4,​ 0); 
 +  lcd.print("​PAUSED!"​);​ 
 +
 + 
 +void showLabels(int currentDisplayMode) { 
 + 
 +  lcd.clear();​ 
 +  switch (currentDisplayMode) ​    { 
 +  case 1: 
 +    lcd.setCursor(12,​ 0); 
 +    lcd.print("​S"​);​ 
 +    lcd.setCursor(12,​ 1); 
 +    lcd.print("​A"​);​ 
 +    break; 
 +  case 2: 
 +    lcd.setCursor(12,​ 0); 
 +    lcd.print("​S"​);​ 
 +    lcd.setCursor(12,​ 1); 
 +    lcd.print("​M"​);​ 
 +    break; 
 +  } 
 +
 + 
 +boolean debounce(boolean last, int pin) 
 +
 +  boolean current = digitalRead(pin);​ 
 +  if (last != current) { 
 +    delay(5); 
 +    current = digitalRead(pin);​ 
 +  } 
 +  return current; 
 +
 +</​code>​
 </​note>​ </​note>​
  
Line 63: Line 531:
  
 <​note>​ <​note>​
-Listă cu documente, datasheet-uri,​ resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**.+    ​[[https://​www.arduino.cc/​reference/​en/​language/​functions/​communication/​wire/​|WIRE Library]] 
 +    ​*[[https://​docs.arduino.cc/​learn/​built-in-libraries/​eeprom|EEPROM Library]] 
 +    ​[[https://​www.arduino.cc/​reference/​en/​libraries/​rtclib/​|RTC Library]] 
 +    ​*[[https://​www.arduino.cc/​reference/​en/​libraries/​liquidcrystal/​|Liquid Crystal]]
 </​note>​ </​note>​
  
 <​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/prj2022/apredescu/speedometer.1654105119.txt.gz · Last modified: 2022/06/01 20:38 by victor.hincu
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