3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

Arduino-Based Optical Tachometer

Step 4Programming

Programming
The program for calculating the RPM of the motor is pretty simple. I adapted it from a Hall Effect motor speed calculator at the excellent Arduino Playground site.

You can download the "sketch" for the program below.

The rpm_fun function is the interrupt function that will be called whenever the data on pin 2 changes from HIGH to LOW (a FALLING pulse). It updates the global rpmcount, then toggles the status LED.

 void rpm_fun() {   //Each rotation, this interrupt    //function is run twice, so take    //that into consideration for    //calculating RPM   //Update count      rpmcount++;         //Toggle status LED      if (status == LOW) {     status = HIGH;   } else {     status = LOW;   }   digitalWrite(statusPin, status);}

Setup initializes the variables, configures the serial parameters, sets the pin modes, and sets up the interrupt function.

void setup() {   Serial.begin(9600);   //Interrupt 0 is digital pin 2, so that is where    //the IR detector is connected   //Triggers on FALLING (change from HIGH to LOW)   attachInterrupt(0, rpm_fun, FALLING);      //Turn on IR LED   pinMode(ledPin, OUTPUT);    digitalWrite(ledPin, HIGH);      //Use statusPin to flash along with interrupts   pinMode(statusPin, OUTPUT);   rpmcount = 0;   rpm = 0;   timeold = 0;   status = LOW; }

The loop function, as the name implies, is the main processing loop that "runs forever" while the board is powered up. The first statement delays for one second (1000 milliseconds), but note that the interrupt function will break in every time the value of pin 2 changes and run the rpm_fun function. After the 1 second delay, the interrupt is temporarily disabled (this may not be necessary, but seems safer) then the RPM is calculated based on the number of interrupts and the elapsed time between now and the last time the calculation occurred. The result is sent back to the computer over the serial port, then the interrupt is restored.
 void loop() {   //Update RPM every second   delay(1000);   //Don't process interrupts during calculations   detachInterrupt(0);   rpm = 30*1000/(millis() - timeold)*rpmcount;   timeold = millis();   rpmcount = 0;      //Write it out to serial port   Serial.println(rpm,DEC);      //Restart the interrupt processing   attachInterrupt(0, rpm_fun, FALLING);  }

Note that the way the motor and the IR detector is configured, each single turn of the coil will result in two transitions, so the calculation takes that into effect. The same would occur for a two bladed fan or propeller. If only one light break per revolution occurred, such as a swinging arm, the calculation would be:

   rpm = 60*1000/(millis() - timeold)*rpmcount;

For a three bladed fan, the calculation would be:

   rpm = 20*1000/(millis() - timeold)*rpmcount;

« Previous StepDownload PDFView All StepsNext Step »
5 comments
Jun 9, 2011. 11:46 AMkkrumm says:
Hello,
I have uploaded the code to my arduino and it works great, up to about 7500RPM then it starts sending random numbers and the occasional 0.
Have I run into a timing limit or what? I really need to read up to about 20,000RPM . I am using a signal generator sending a square wave to the board on the bench and the output goes wierd with a 250hz square wave inout from the sig gen. At 250hz the RPM indicates 7500rpm on the nose. Thanks for your assistance. Great program!!
Dec 14, 2011. 3:56 AMstringstretcher says:
If you read the fine print on the picture of Mims notebook, he says to use a large value resistor for higher sensitivity, and a smaller value for faster speeds. Maybe this helps?
Sep 14, 2011. 4:51 PMos_sanches says:
Hi, what your sugest to i´m use this sketch to measure rotations over 200.000rpm?
Apr 6, 2011. 2:28 PMeddy40 says:
please upload a proper program file.
May 30, 2010. 6:31 PMRANDOMFISHYFACE says:
 for me when i down load the program it comes up as a tmp file so could you post it replying to this comment

Nov 24, 2009. 5:28 PMCairie says:
i added a Serial.println and the serial data is in very strange characters. ascii maybe? anyway, it's not in number form. do you have any suggestions on how to make it voltage change in integers? i want to bring it over to Pd and create some sounds.
thank you!
Nov 24, 2009. 6:22 PMkikiclint says:
You could use an op-amp as a comparator, so that the output would only be on, or off.  It is really simple.  By changing the voltage at the non inverting input voltage, you can change the sensitivity as well.  http://web.telia.com/~u85920178/begin/opamp00.htm gives an example of how to do this.  You might be able to leave off the negative voltage and have it still work.

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
13
Followers
3
Author:CMPalmer