Arduino project - DIY bike odometer and speedometer menggunakan Arduino UNO

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 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
Untuk langkah-langkah pengerjaan project ini adalah sebagai berikut :
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;
}
Berikut adalah hasilnya :

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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel