Please let me know if there are any questions or comments. Thanks.
Code: Select all
/*
Pulse Tach by R. Drechsler
The setup...
I'm using Arduino Ethernet or Uno but should work with any.
I have a 1.875"dia plexiglass wheel, painted flat black, attached directly to a small motor shaft.
The wheel has a single .116" wide notch cut into, about a .250" deep. The motor is powered by a 0-3A, 0-12V power supply.
I'm using a sparkfun photo interrupter (http://www.sparkfun.com/products/9299) sensing the notch. The signal
goes low when the the photo interrupter is blocked. The signal wire is to Pin 2.
The numbers...
Math to define some "magic" numbers... adjust as needed...
timerrevCalc = duration * 50.7801;
RPM = 60000000/timerrevCalc; //See above
Where:
duration = amount of time notch exposes IR to sensor in uS.
50.7801 = the notch is 50.7801 times smaller than the remainder of the wheel (so the circumference of my 1.875"dia wheel = 5.8905, 5.8905" / .116" = 50.7801
^^^^^^^ this number needs to be calculated and adjusted per application.
60000000 is a convertion from uS to just minutes.
The good...
This appears to be VERY fast at reading RPM. The RPM is calculated with EACH pulse. So instead of using a interrupt and have to wait
the interrupt interval to refresh the data, the data comes in after each pulse is timed.
Also, when using interrupts, you have limited resolution. Example, 10 pulses, counted over 250ms = 40 pulses a second. 40 pulses a second x 60 seconds = 2400 RPM, right?
So 1 pulse per 250ms = 4 pulses per second or 240 RPM and 2 pulse per 250ms = 8 pulses per second or 480 RPM!!! 1 pulse more = 240 RPM?!?!
To get better resolution, you need a longer interrupt interval. A longer interrupt interval = slower repsonse.
*/
const int Pin = 2; // Photo Interrupter. http://www.sparkfun.com/products/9299
const int ledPin = 9; //LED pin on the arduino ethernet, to help visualize the notch passing by
int photoState = 0;
long RPM = 0;
long timerrevCalc = 0;
unsigned long duration;
void setup() {
Serial.begin(38400); // had problems with 9600...
pinMode(ledPin, OUTPUT);
pinMode(Pin, INPUT);
}
void loop(){
duration = pulseIn(Pin, HIGH, 100000); //times the amount of microseconds the notch is exposing the IR, Times out after 100000 uS. Raise the timeout for slower RPM readings.
timerrevCalc = duration * 50.7801; //See above
RPM = 60000000/timerrevCalc; //See above
Serial.print(duration); //print out results.
Serial.print(" ");
Serial.println(RPM);
}