Hi!
I have built a tachometer using an IR led and receiver. The reflection of the LED on whatever is being measured triggers an interrupt via the IR receiver. I am pretty sure it works accurately, but my question is to what rpm (or interupt per second) I can expect reliable readings?
num blades is a float because I want rpm not to be rounded like when dividing by an integer. This way I don't have to do any convert it.
What's the difference with using a volatile (sorry if it's a dumb question)?
In the ISR I count the number of times something passes infront if the sensor, and records the time from the first pass to the most recent pass.
When I measure the RPM of a propeller spinning at rather high RPMs I generally reach 20-30 passes before the loop() has had time to process it.
Since loop() calculates the RPM by "passes / time" and time is always the timespan from pass one to the most recent I don't see this as a problem at all.
Thank you for your input to improve my code, but it is working I was just wondering to which RPM I can expect it to continue working.
Thank you for your reply Pylon. Would that be 60000 RPM witha 2-bladed prop or 60000 "passes of something" per minute infront of the sensor (i.e. 30000RPM for a 4-bladed prop)?
num blades is a float because I want rpm not to be rounded like when dividing by an integer. This way I don't have to do any convert it.
It doesn't need to be.
float RPM = passesPerSecond * 60.0 / numBlades;
Divide a float by an int, and you still get a float.
What's the difference with using a volatile (sorry if it's a dumb question)?
The volatile declaration tells the compiler that the value can change at any time. Otherwise, in loop(), the value may be cached, and changes to the variable won't be seen.
In the ISR I count the number of times something passes infront if the sensor, and records the time from the first pass to the most recent pass.
Only if the "most recent pass" is pass number 10 or more. At very slow speeds, your RPM values will be wrong.
The whole idea of recording time only after 10 passes is flawed. Record the time EVERY time.
Thank you for your input to improve my code, but it is working
by measuring the time of 10 passes instead of 1 I get a more stable reading, with the average speed over 10 passes instead of every pass.
How will it be wrong if I am at less than ten? If you've missed it, I don't calculate if I havent got 10 or more passes, so a calculation with 5 passes and a old time would never occur.
Would that be 60000 RPM witha 2-bladed prop or 60000 "passes of something" per minute infront of the sensor (i.e. 30000RPM for a 4-bladed prop)?
Sorry, I missed the blades calculation, my calculation was with the passes. So you get up to approx. 60000 passes per minute but at that level you loose a lot of precision with that code although that's completely unnecessary.
Do you have any suggestions as to how I could improve my code?
As I said: use micros() instead of millis(), then you could calculate the RPM at each pass because you have an increased precision by about a factor of 100. You also don't have to count the passes, just store the difference between the last two interrupts in microseconds and do the calculation in the loop when you request the RPM value. This way you keep the ISR short and fast but keep a high precision. If you also want a high accuracy, use an Arduino with a crystal, not a resonator.