This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This sketch allows an Arduino to act as a speedometer. Data input can come from | |
magnets glued to the rim or spoke of a wheel along with a hall-effect sensor or | |
reed switch. You can also use an optical sensor using the spokes to break the | |
beam of light. | |
(If you use a reed switch instead of a hall-effect sensor, you will probably | |
need to modify the sketch to include some debouncing. If you use an optical | |
sensor, you might need Schmitt trigger circuitry.) | |
The sketch times how long it takes in milliseconds between pulses from the | |
sensor, and converts it into feet per minute. It is written for a bandsaw with | |
16-inch wheels, and six magnets evenly spaced on one of the wheels. | |
The data is written to an LCD with Hitachi HD44780 compatible chipsets using the | |
LiquidCrystal library. | |
For more information about LiquidCrystal, visit | |
https://www.arduino.cc/en/Reference/LiquidCrystal | |
The circuit: | |
* LCD RS pin to digital pin 12 | |
* LCD Enable pin to digital pin 11 | |
* LCD D4 pin to digital pin 5 | |
* LCD D5 pin to digital pin 4 | |
* LCD D6 pin to digital pin 3 | |
* LCD D7 pin to digital pin 2 | |
* LCD R/W pin to ground | |
* LCD VSS pin to ground | |
* LCD VCC pin to 5V | |
* 10K resistor: | |
* ends to +5V and ground | |
* wiper to LCD VO pin (pin 3) | |
Library originally added 18 Apr 2008 | |
by David A. Mellis | |
library modified 5 Jul 2009 | |
by Limor Fried (http://ladyada.net) | |
example added 9 Jul 2009 | |
by Tom Igoe | |
modified 22 Nov 2010 | |
by Tom Igoe | |
modified 7 Nov 2016 | |
by Arturo Guadalupi | |
modified 21 Aug 2018 from LiquidCrystal Hello World sketch by Emily Velasco | |
This example code is in the public domain. | |
*/ | |
// Include the library code: | |
#include <LiquidCrystal.h> | |
// Initialize the library by associating any needed LCD interface pin with the | |
// arduino pin number it is connected to | |
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; | |
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); | |
// Unsigned long is necessary for these variables because they hold millisecond | |
// values, which add up quickly as the program runs, and would overflow as int | |
// variables | |
unsigned long TimerCount; | |
unsigned long previousTimerCount; | |
unsigned long LCDUpdateTime; | |
int sensorPin = 8; | |
int pinState = LOW; | |
int oldpinState = LOW; | |
int LCDprintValue = 0; | |
int sawPulse = 1; | |
void setup() { | |
pinMode(sensorPin, INPUT); | |
// Gives TimerCount a millisecond value to start with. millis() is the current | |
// time in milliseconds since the Arduino booted up | |
TimerCount = millis(); | |
// Gives previousTimerCount a millisecond value to start with | |
previousTimerCount = millis(); | |
// Set up the LCD's number of columns and rows. Change this to match your LCD | |
// dimensions | |
lcd.begin(20, 4);// | |
lcd.print("Feet per minute:"); | |
} | |
void loop() { | |
pinState = digitalRead(sensorPin); | |
// Checks to see if the sensor is reading high and if that's | |
// different than the last time it checked. if both are true, it | |
//means a pulse from the sensor is being received | |
if (pinState == HIGH && pinState != oldpinState){ | |
// Records the time in milliseconds so we know when the pulse was | |
// received | |
TimerCount = millis(); | |
// Subtracts the time the last pulse was received from the time the newest | |
// pulse was receieved to determine the milliseconds between each pulse. | |
// Fewer milliseconds between pulses mean the wheel is turning faster. The | |
// constant, 41887.8, is derived from a series of calculations that turn | |
// milliseconds between pulses into revolutions per minute, and then | |
// revolutions per minute into feet per minute. This constant depends on how | |
// many pulses per rotation the wheel sensor generates, and the diameter of | |
// the wheel. In this case, I have six pulses per rotation, and 16-inch | |
// wheels. | |
// mpp = milliseconds per pulse = TimerCount - previousTimerCount | |
// circumference of band saw wheel = 16 inch diameter * Pi | |
// cif = circumference in feet = (16 * Pi)/12 | |
// | |
// 1 pulse 60000 ms 1 rev cif 41887.8 | |
// ------- X -------- X ------- X ----- = ------- = feet per minute | |
// mpp ms 1 min 6 pulse 1 rev mpb | |
LCDprintValue = (((unsigned long)41887.8)/(TimerCount - previousTimerCount)); | |
// Sets a flag that we can use to tell if the speed has dropped | |
// to zero | |
sawPulse = 1; | |
// Sets previousTimerCount to whatever value was recorded for | |
// TimerCount before math was calculated | |
previousTimerCount = TimerCount; | |
} | |
// Checks to see if LCDUpdateTime is less than current time in | |
// milliseconds. this is so the LCD only updates once a second | |
if (LCDUpdateTime <= millis()){ | |
// Places the cursor in the first column on the second row of the | |
// LCD | |
lcd.setCursor(0, 1); | |
// Checks to see if sawPulse was set to 1 by the first if | |
// statement. if it has been, it means a pulse was detected | |
// within the last second and the wheel is still turning | |
if (sawPulse == 1){ | |
// Prints the speed value calculated above to the LCD | |
lcd.print(LCDprintValue); | |
// Prints spaces to clear the line now in preparation for the | |
// next speed value to be displayed | |
lcd.print(" "); | |
// Resets sawPulse to zero in preparation for the else statement | |
// below | |
sawPulse = 0; | |
} | |
// If sawPulse is anything besides 1, it means the program has | |
// not detected a new pulse within the last second, and it can | |
// be assumed speed has dropped to zero | |
else { | |
lcd.print("0"); //Prints zero for the speed | |
// Prints spaces to clear the line now in preparation for the | |
// next speed value to be displayed | |
lcd.print(" "); | |
} | |
// Checks the time, adds 1000 milliseconds (1 second) to it, and | |
// records it. this value is compared against the time in | |
// milliseconds above to see if a second has elapsed. | |
LCDUpdateTime = (millis()+1000); | |
} | |
// Sets oldpinState to the last measured state from the sensor so it can be | |
// used to see if that state has changed next time the loop runs | |
oldpinState = pinState; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment