Arduino project - DIY bike odometer and speedometer menggunakan Arduino UNO
Friday, 31 August 2018
Add Comment
Hai bertemu lagi dengan saya pada blog saya malasnugas.com disini saya
akan memberikan sebuah program untuk referensi kalian jika kalian akan
membuat sebuah project menggunakan arduino uno . projek yang akan saya
bagikan kali ini adalah berisi program untuk membuat ordometer serta
sepedometer yang bisa digunakan untuk mengukur kecepatan sepeda menggunakan
arduino uno. Alat –alat yang dibutuhkan pada project kali ini adalah
1. Siapkan aplikasi alat dan bahan setelah itu rangkailah seperti pada gambar sistematik dibawah ini :
2. Buka aplikasi arduino kalian setelah itu copykan program dibawah ini pada lembar kerja baru :
Berikut adalah hasilnya :
jangan lupa untuk membaca postingan saya tentang Aplikasi motor stepper menggunakan arduino uno dan Interupsi eksternal pada arduino uno .... terima kasih
- 1 unit arduino uno
- 1 unit RGB 16X2 Display multicolor LCD
- 1 unit switch/saklar
- Resistor 221 ohm
- Resistor 10k ohm
- Singel turn potensiometer-10k ohms
- Sensor half effect
1. Siapkan aplikasi alat dan bahan setelah itu rangkailah seperti pada gambar sistematik dibawah ini :
2. Buka aplikasi arduino kalian setelah itu copykan program dibawah ini pada lembar kerja baru :
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 8, 7, 6, 5); // Circumference of bicycle wheel expressed in meters 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; int currentDisplayMode = 0; int showLap = 0; int lapCurrentlyShown = 100; int currentLap = 0; float currentDistance; unsigned long currentDuration; int currentMaximumKPH; int currentAverageKPH; int currentLastMinuteKPH; float arrayDistance[100]; unsigned long arrayDuration[100]; int arrayMaximumKPH[100]; int arrayAverageKPH[100]; unsigned long revolutionCount = 0; unsigned long lastRevolutionCount = 0; unsigned long currentTime = 0; unsigned long lapStartTime = 0; unsigned long lastMinuteStartTime = 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() { // Configure digital input pins for push buttons and Hall sensor pinMode (revolutionButton, INPUT); pinMode (pauseButton, INPUT); pinMode (displayModeButton, INPUT); // Initialize maximum KPH in totals as this may not be calculated if no maximum was computed for laps // and there may be random data in memory location arrayMaximumKPH[0] = 0; // Initialize LCD screen & show "PRESS BUTTON TO START" lcd.begin(16, 2); lcd.clear(); lcd.setCursor(2, 0); lcd.print("PRESS BUTTON"); lcd.setCursor(4, 1); lcd.print("TO START"); } void loop() { // Get current millis currentTime = millis(); // Read revolution Hall sensor currentRevolutionButton = debounce(lastRevolutionButton, revolutionButton); if (lastRevolutionButton == LOW && currentRevolutionButton == HIGH) { // If initial "PRESS BUTTON TO START" is not dislayed and not currently paused... if (!startShown && !paused) { // Increase wheel revolution count revolutionCount++; // Display "+" to show that one revolution was recorded lcd.setCursor(0, 0); lcd.print("+"); wheelTurningShown = HIGH; wheelTurningStartTime = currentTime; } } lastRevolutionButton = currentRevolutionButton; // Read PAUSE/RESUME push button currentPauseButton = debounce(lastPauseButton, pauseButton); if (lastPauseButton == LOW && currentPauseButton == HIGH) { // If "PRESS BUTTON TO START" message has been showing then we now need to start 1st lap/period if (startShown) { startShown = LOW; // Show "CYCLE SAFELY!" message showCycleSafely(); cycleSafelyShown = HIGH; cycleSafelyStartTime = currentTime; currentLap = 1; resetLapVariables(); currentDisplayMode = 1; } else { // Otherwise if pause is active then we need to take it out of pause and start new lap/period if (paused) { paused = LOW; // Show "CYCLE SAFELY!" message showCycleSafely(); cycleSafelyShown = HIGH; cycleSafelyStartTime = currentTime; // Increment lap counter currentLap++; // If we are starting a 100th lap/period then we should write data into 99th array position (overwriting this lap) // as we can only keep track of 99 laps/periods in total if (currentLap > 99) { currentLap = 99; // Pretend lap 100 (out-of-bounds value) is currently shown (even though 99 is currently shown) // to force display of new data for lap 99 lapCurrentlyShown = 100; } resetLapVariables(); currentDisplayMode = 1; } // Otherwise pause is not currently active so we need to save lap/period data and activate pause else { paused = HIGH; // Calculate duration currentDuration = currentTime - lapStartTime; // If lap duration is less than 2 seconds (which means user pressed the pause button while "CYCLE SAFELY!" message // was shown) then do not store the lap/ignore it if (currentDuration < 2000) { currentLap--; } // Otherwise store the lap else { // Compute distance and average kilometers per hour if bicycle moved if (revolutionCount > 0) { currentDistance = revolutionCount * bicycleWheelCircumference / 1000; currentAverageKPH = currentDistance * 3600000 / currentDuration; } // Store data for lap/period into array arrayDistance[currentLap] = currentDistance; arrayDuration[currentLap] = currentDuration; arrayAverageKPH[currentLap] = currentAverageKPH; arrayMaximumKPH[currentLap] = currentMaximumKPH; // Update totals for all laps/periods arrayDistance[0] = arrayDistance[0] + currentDistance; arrayDuration[0] = arrayDuration[0] + currentDuration; arrayAverageKPH[0] = arrayDistance[0] * 3600000 / arrayDuration[0]; if (currentMaximumKPH > arrayMaximumKPH[0]) { arrayMaximumKPH[0] = currentMaximumKPH; } } // In case "CYCLE SAFELY!" has been showing, turn it off now since we want to show "PAUSED!" message // and we don't want it to be removed when "CYCLE SAFELY!" times out cycleSafelyShown = LOW; // Show "PAUSED!" message showPaused(); pausedShown = HIGH; pausedStartTime = currentTime; // We will need to show data for lap which was just finished showLap = currentLap; currentDisplayMode = 3; // Set out-of-bounds value to lapCurrentlyShown to force lap data to be shown lapCurrentlyShown = 100; }}} lastPauseButton = currentPauseButton; // Read DISPLAY MODE push button currentDisplayModeButton = debounce(lastDisplayModeButton, displayModeButton); if (lastDisplayModeButton == LOW && currentDisplayModeButton == HIGH) { // If "PRESS BUTTON TO START" message has been showing then we now need to start 1st lap/period if (startShown) { startShown = LOW; // Show "CYCLE SAFELY!" message showCycleSafely(); cycleSafelyShown = HIGH; cycleSafelyStartTime = currentTime; currentLap = 1; resetLapVariables(); currentDisplayMode = 1; } else { // Otherwise if "CYCLE SAFELY!" message is not shown nor is "PAUSED!" message shown... if (!cycleSafelyShown && !pausedShown) { // If not currently paused (so lap is ongoing)... if (!paused) { // Flip between the two different display modes available if (currentDisplayMode == 1) { currentDisplayMode = 2; } else { currentDisplayMode = 1; } // Clear display and show appropriate labels showLabels(currentDisplayMode); } // Otherwise we are in paused mode so cycle through lap data available, including totals page else { currentDisplayMode = 3; showLap++; if (showLap > currentLap) { showLap = 0; // Show totals } } } } } lastDisplayModeButton = currentDisplayModeButton; // If wheel revolution indicator has been showing, take if off if it has been 250 millis or more if (wheelTurningShown && !startShown && !paused && (currentTime >= (wheelTurningStartTime + 250))) { wheelTurningShown = LOW; lcd.setCursor(0, 0); lcd.print(" "); } // If "Cycle Safely!" has been showing, take it off if it has been 2 seconds or more if (cycleSafelyShown && (currentTime >= (cycleSafelyStartTime + 2000))) { cycleSafelyShown = LOW; showLabels(currentDisplayMode); } // If "Paused!" has been showing, take it off if it has been 2 seconds or more if (pausedShown && (currentTime >= (pausedStartTime + 2000))) { pausedShown = LOW; showLabels(currentDisplayMode); } // If "PUSH BUTTON TO START" is not showing and not currently paused... if (!startShown && !paused) { // Compute milliseconds since start of lap currentDuration = currentTime - lapStartTime; // Compute distance and average kilometers per hour if bicycle has moved if (revolutionCount > 0) { // Compute kilometers traveled // Circumference of wheel is in meters currentDistance = revolutionCount * bicycleWheelCircumference / 1000; // Compute average kilometers per hour since start of lap currentAverageKPH = currentDistance * 3600000 / currentDuration; } // If one minute has expired then compute average kilometers per hour for distance traveled during last minute if (currentTime > (lastMinuteStartTime + 60000)) { if ((revolutionCount - lastRevolutionCount) > 0) { // Compute kilometers traveled since start of minute // Circumference of wheel is 2.1206 meters km = (revolutionCount - lastRevolutionCount) * 2.1206 / 1000; // Compute average kilometers per hour for last minute kph = km * 3600000 / 60000; // Convert to integer for display currentLastMinuteKPH = kph; } else { currentLastMinuteKPH = 0; } // If speed last minute is higher than maximum stored so far then store new maximum if (currentLastMinuteKPH > currentMaximumKPH) { currentMaximumKPH = currentLastMinuteKPH; } lastRevolutionCount = revolutionCount; lastMinuteStartTime = currentTime; } } // If no messages are currently showing then update data on display if (!startShown && !cycleSafelyShown && !pausedShown) { if (currentDisplayMode < 3) { lcd.setCursor(1, 0); lcd.print(currentDistance); lcd.print(" km"); lcd.setCursor(14, 0); if (currentLastMinuteKPH < 10) { lcd.print(" "); } lcd.print(currentLastMinuteKPH); 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); } } // Otherwise device is paused so show historical lap information else { // Update display only if we need to show data for different lap to that currently shown // this way display is not constantly cleared and refreshed with same data which would // cause display to flicker and is not needed anyway as data is not changing 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); } } } } // Compute hours, minutes and seconds for given duration expressed in milliseconds 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; } } // Reset all variables used for calculating current/ongoing lap void resetLapVariables() { revolutionCount = 0; lapStartTime = currentTime; lastMinuteStartTime = currentTime; currentDistance = 0; currentDuration = 0; currentMaximumKPH = 0; currentAverageKPH = 0; currentLastMinuteKPH = 0; } // Show "CYCLE SAFELY!" void showCycleSafely() { lcd.clear(); lcd.setCursor(5, 0); lcd.print("CYCLE"); lcd.setCursor(4, 1); lcd.print("SAFELY!"); } // Show "PAUSED!" void showPaused() { lcd.clear(); lcd.setCursor(4, 0); lcd.print("PAUSED!"); } // Show appropriate labels for current mode void showLabels(int currentDisplayMode) { lcd.clear(); switch (currentDisplayMode) { case 1: lcd.setCursor(12, 0); lcd.print("1"); lcd.setCursor(12, 1); lcd.print("A"); break; case 2: lcd.setCursor(12, 0); lcd.print("1"); lcd.setCursor(12, 1); lcd.print("M"); break; } } //A debouncing function that can be used for any button boolean debounce(boolean last, int pin) { boolean current = digitalRead(pin); if (last != current) { delay(5); current = digitalRead(pin); } return current; } |
jangan lupa untuk membaca postingan saya tentang Aplikasi motor stepper menggunakan arduino uno dan Interupsi eksternal pada arduino uno .... terima kasih
0 Response to "Arduino project - DIY bike odometer and speedometer menggunakan Arduino UNO"
Post a Comment