RPM measurement using PIC - Page 1
Forum section: electronics / beginners

author: yashrk
author_rank: Frequent Contributor
timestamp: March 23, 2015, 04:28:18 pm
content: Hey guys,I am working on a project in which I have to measure RPM of a motor, I am using a hall effect sensor for it and it give a pules when magnet comes in front of it. I am using module which has an opamp in it.http://www.ebay.in/itm/121584877662?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649I am using PIC16F877A with 8MHz external oscillator. And coding in MicroCIdea is to measure the pules produce by the sensor for 1 sec and then multiply the value with 60 hence the RPM which I will display on LCD.LCD part is covered and working. But the problem is that I have no clue how to write a program to read the pulses for 1 sec, need your help there to get me started.Please tell me if my method is right and how to implement it. As I want to show rpm on lcd so I would like it be slow enough so that rpm readings are stable.Thank You,YashRK

author: Corporate666
author_rank: Unknown
timestamp: March 23, 2015, 04:42:49 pm
content: Two (easy) ways to measure RPM1) Timer/Counter for a fixed period which measures the # of pulses in that period2) Timer/Counter which measures "ticks" between pulses and calculates RPMI am not very familiar with PIC but just either poll the pin with sufficient frequency to detect your pulses, and run an interrupt when the timer finishes and check the value of your counter variable. Or, fire an interrupt when the pin pulses and update your count variable that way and check it when the timer interrupt finishes.The #2 method is just to use the pulse as a signal to start your timer interrupt and use the next pulse as a signal to stop it. Then measure the value of your timer and calculate.Keep in mind if you use the "pulses in a given period of time", your measurement time needs to be long enough so that the error you will get by not starting and stopping on a pulse will be acceptable.I am sure if you Google "PIC RPM counter", there has to be dozens of example projects you can download, no?

author: yashrk
author_rank: Frequent Contributor
timestamp: March 23, 2015, 05:13:31 pm
content: Is there any way to do it with out interrupt, I am new to interrupts and timers and not yet comfortable with it?

author: Howardlong
author_rank: Super Contributor
timestamp: March 23, 2015, 05:55:06 pm
content: There is, you can poll the GPIO pin and reset one of the timers. Wait for the next pulse, and read the timer.However, you need to be aware that the timers only have limited resolution.Do it in small steps. Don't try to do it all in one go.Make sure you can read the pulses first, perhaps toggle another GPIO pin configured as an output on each pulse. Make sure you understand the TRIS and PORT registers.Learn how to use the timers (note that the timers are not all the same by the way, there are some subtle differences between them).Then, instead of polling the GPIO pin, consider using the RB0/INT external interrupt pin. You don't yet need to use an interrupt, you can just poll and reset the INTF flag. The benefit of using an edge triggered input rather than polling a GPIO pin is that it's possible you might miss a very narrow pulse when polling.Then you might want to consider using interrupts. If you've never done this then the concept can be a bit of a hurdle, and it does take time to become comfortable with it.I've been doing PICs since the early 90s, I still do every project in small stages, unit testing each part, and gradually putting it all together. Nobody writes a complete solution in one step (and expects it to work!)

author: yashrk
author_rank: Frequent Contributor
timestamp: March 23, 2015, 06:00:07 pm
content: Thanx for your response I also follow your method too, I am done with the controlling part and lcd now just rpm remaining

author: dannyf
author_rank: Super Contributor
timestamp: March 23, 2015, 06:08:41 pm
content: Use a loop. Increment a counter in the loop until the sensor is triggered again.

author: Corporate666
author_rank: Unknown
timestamp: March 23, 2015, 06:36:02 pm
content: Quote from: dannyf on March 23, 2015, 06:08:41 pmAnd to the OP - if you use polling methods instead of "known" counts (from interrupts or from a timer), keep in mind that interrupts running in the background will change the execution speed of your code and could produce bad readings.

author: rudika79
author_rank: Regular Contributor
timestamp: March 23, 2015, 07:08:47 pm
content: /hi,I made one RPM meter with atmel cpu. I implemented one reciprocal frequency counter in software to measure elapsed time between pulses. When I have the time the cpu calculate the RPM value.

author: klr5205
author_rank: Regular Contributor
timestamp: March 23, 2015, 07:23:16 pm
content: Not for PIC but maybe download this library and see how Paul implements his frequency measuring functions:https://www.pjrc.com/teensy/td_libs_FreqMeasure.htmlOnce you understand what's going on here I bet you'll be able to write your own version to do what you want.

author: Zero999
author_rank: Super Contributor
timestamp: March 23, 2015, 07:42:17 pm
content: How many moving parts are they?What else are you doing?

author: yashrk
author_rank: Frequent Contributor
timestamp: March 24, 2015, 01:30:29 am
content: Thanx for the reply guys!I have only one moving part which is the motor itself and it is controlled by pwm that part is done and working only this rpm part is remaining.I am using only one magnet so only one sample per rotation and when i connected tacometer it showed >4000 rpm in no load condition.

author: dannyf
author_rank: Super Contributor
timestamp: March 24, 2015, 09:53:56 am
content: 4000rpm is like 70hz -> over 10ms per signal from the sensor. That's very slow for a mcu to handle.Yeah, the pulling approach would work.

author: joeqsmith
author_rank: Super Contributor
timestamp: March 24, 2015, 12:12:06 pm
content: OP, hard to say what you need to do without knowing a little more. What RPM range do you need, what resolution, how many pulses per one rotation and what sort of update rate?Say you need to measure a maximum of 9000 RPM and have two pulses per rotation. At 9000RPM or 300Hz, the time between pulses is 3.333333mS. If your minimum is 500RPM or 16.6666Hz or 60ms between edges you could use a 16-bit counter with a 1uS timer resolution. This would provide 65.535ms or a lower limit of 457.77 RPM. At 9000 RPM the resolution would be about 2RPM.If we update at 0.01 second intervals, the lowest RPM that could be recorded would be 30/0.01 or 3000RPM.Depending on your requirements, you may need two different methods.

author: klr5205
author_rank: Regular Contributor
timestamp: March 24, 2015, 03:48:40 pm
content: Quote from: joeqsmith on March 24, 2015, 12:12:06 pmStealing an explanation from the page I linked above, those different methods might be described as counting vs measuring.For low RPMs, you measure the period of 1 pulse.For high RPMs, you define a set time frame and count how many pulses occur during that window.

author: dannyf
author_rank: Super Contributor
timestamp: March 24, 2015, 03:55:16 pm
content: QuoteA PIC, at 1Mhz Fcy, can easily count up to 10Mhz, if not more, far beyond what a mechanical device can produce.For 10ms per cycle, I can count to a resolution of 1us, or +/- 0.01% in rpm talk.

author: yashrk
author_rank: Frequent Contributor
timestamp: March 24, 2015, 04:50:03 pm
content: Accuracy is not much of the issue actually dose any one have seen similar program so I can work on their code and use it for my use ?

author: joeqsmith
author_rank: Super Contributor
timestamp: March 24, 2015, 04:57:33 pm
content: Using a single pulse per rotation. 9,000 RPM or 150 RPsecond or 1 rotation in 6.666666mS. Detecting 1 RPM change is a time of 741nS. Starting to get a little more interesting for the 1MHz PIC.QuoteUsing a window may not work out so well to get you any sort of resolution and fast update rate. If we wanted a faster update rate and higher RPM, measuring the period with a higher resolution clock and wider counter works well. I normally would just do this and any filtering in hardware.Depending on OP's requirements, they may have 20 or more pulses for one rev. No idea what OP is doing but say they want to look at crank speed of an IC engine. Over the one crank rotation, the speed may be +/-100 RPM as it goes through the different cycles. If we wanted to detect this to say look at how the engine is running, we may want a lot more pulses.

author: dannyf
author_rank: Super Contributor
timestamp: March 24, 2015, 05:58:49 pm
content: At that kind of speed, it gets a little bit dicey. The typical solution is to use a timer as an external interrupt and interrupt on multiple counts of input pulses.For example, preload the timer with a value of -TMR_REPEAT_COUNT (for an up counter) at the start of the counting and when the timer overflows to 0, you stop the time base counter.Some more advanced chips have a noise filter like that.

author: Mechatrommer
author_rank: Super Contributor
timestamp: March 24, 2015, 05:59:11 pm
content: Quote from: yashrk on March 23, 2015, 05:13:31 pmnow its the time you get comfortable with it if you want to deal with your question properly because thats your only hope esp the timer... reply #1 by corporate666 is the only keypoint you'll need to go further... now that alone does not guarantee success, depending on your "hall effect for arduino" module, if the output is not enough to trigger timer counter then you'll need analog messup to increase further opamp gain, comparator or something... and then you'll have to deal with variety of voltage offset if you want to expand your "pic tachometer" usability other than measuring a motor with one magnet on its side. you mentioned you already have a tachometer, then whats the worth of doing it again? a digital laser tachometer is only less $20, works in almost every conditions of rotating machines.

author: yashrk
author_rank: Frequent Contributor
timestamp: March 24, 2015, 06:58:17 pm
content: Well its a project I have to for college so rpm measurement must be done by microwell thank you for your reply guys, you all where kind and helpful as always.