/* |
|
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 |
|
// 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; |
|
} |