Step 4Programming
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 Step | Download PDFView All Steps | Next Step » |












































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!!
thank you!