Hopefully there is a simple solution to this, but I am trying to read in an RPM signal from a motor, which goes from 0 to 20,000 RPM. Ideally I am wanting my Arduino to detect every RPM change, ie have a resolution of 0 to 20,000 - but I know that its only 10 bit.. I really need 15 bit don't I...
What is the simplest solution to this problem? Do I need to get a external ADC chip of some kind, and potentially communicate to it via SPI or I2C, in order to get the required resolution, or can I do something fancy like join two ADC channels together some how?
Some assistance would be most appriciated
I am going to have to get some sort of coverter to change from the output of the motor transducer, to 0-5V also... so hopefully I can find something that has a small enough resolution for that too. I dont yet know the voltage range the motor transducer works at yet, it hasnt arrived yet.
You need a stable time base, in this case the difference between lastmilis and milis() function, then you count interrupts, you need to use interrupts so you know you don't fail a single rpm, then its just maths.
One more thing, you need to condition the rpm signal, if it is from an engine it may be a hall sensor, also known as pick-up and that is a inductive sensor, so you need to make sure the signal will only be 5V at MAX and you need to damp the inherent oscillations of a inductive pick up, you will need to buffer that signal and treat it so it will be a 0 to 5v signal, and the most perfectly square the signal become better.
You don't mention what the sensor you're using is, but if it is just a standard pulse encoder (maybe a hall sensor or slit wheel IR), you don't need to do a voltage conversion. Just tie the output (which will be a pulsing square wave of a certain voltage level, one or more pulses per revolution of the shaft) to a digital input, and do an attachInterrupt() on that pin to a routine to count and time the rotations. As long as the output of the sensor is 0V for LOW and 3.3V or higher (but less than or equal to 5V) for HIGH, you can sense it directly with a pin on the Arduino (you may need a pull-down resistor on the pin). At that point, you're only limited by the speed of the processor, and 20,000 PPS (pulse-per-minute - if it is only a pulse per revolution) should be well within the capabilities of the ATMega @ 16 MHz, I think (you may need to do direct port access).
I am aware that this is not the normal method for counting RPM, as yes - they are generally pulses. However my concern was the amount of counting the Arduino would have to do in order to count this signal at the high RPM.
20,000RPM is 333 pulses per second. I wasnt sure if the Arduino is capable of counting at this rate.
I was going to look at some form of frequency to voltage conversion in order to get the signal into an analog reading so it can be simply read at 10 bit (or higher with another chip) by the arduino, as it then wouldnt have to be flat out counting.
To extend the problem, this is one of potentially 4 signals that are going to be like this. My concern was if I have 4 digital input pulses coming in to the arduino at once, is it going to be able to keep up with the counting?
I didnt mention the sensor I am using on purpose, as I dont yet know this. It hasnt been determined yet. It may be an inductive pickup off one of the spark plug leads, it may be from a hall sensor. Regardless, it is irrelevant. It will be a pulse train, but I wasnt sure if I would need to convert this to an analog voltage for the ADC or if the arduino could infact cound the pulses.
I am going to have a 0 - 20,000 pulse count for RPM (333 pulses per second)
I am going to have a 0 - 9,000 pulse count for km/h (150 pulses per second)
The other two are yet to be decided if they will be pulses or voltages, however is the arduino actually capable of doing all this counting?
Yes it can count up to two pulses, as it only as 2 external interrupt lines, there are frequency to voltage converting chips that are usually used to make shift ligths but they dont seen acurate enough to count rpm, km/h maybe yes.
The big problem that you will face is updating all this data in one lcd or other type of display, you need some clever coding so you dont create lagging functions.
Avoid at all divisions, as the arduino will never fail a interrupt, but again, you need to treat the signal, other thing, the arduino works at 16Mhz, there is a lot of time between each pulse, with clever coding all is possible.
A little OT, can you shown me a inductive clamp to measure rpm, as i'm a bit of a gear head, and two stroke oil is my blood and I can help you a bit in the rpm measure thing as I want to make one for me too.
Hi Senso
Thanks - wasnt expecting such a quick reply!
Well that sounds great then. Yes shame about the 2 external interrupts - I should have realised this myself. I am use to using the 644P, but never in anger like this project is demanding.
inductive clamp - just the same sort as you would get on a standard timing light, or inductive pickup on a current sensing multimeter. I dont have one yet, but I know they are available.
So yes, counting 333 pulses per second on 1 interrupt, and counting 150 pulses per second on the 2nd interrupt, along with outputting at 9600 baud to the serial port, and potentially outputting to an LCD (yet to be determined if I need this) all sounds possible then.
I suppose 16Mhz is 16,000,000 Hz, so incrementing a count every 48,000 Hz of the processor (333 a second) etc does sound more possible I suppose.
Well if the micro is running at 16,000,000 Hz - which is 16,000,000 a second, then if I get a pulse coming in 333 times a second (once every 0.003 seconds), then the processor would have processed about 48,000 Hz worth of stuff between each pulse ?
9600 baud is a bit slow on the serial, and could take some considerable time to output information to an LCD... could you up the baud to something a bit higher?
Yeah I could do.
Currently I am just generating randoms sine waves and outputting it to serial every loop, at 9600 baud, and the serial is coping fine. The PC is getting every single pass so it seems 9600 is coping no worries.
I put an LCD on the arduino and am printing to that, along with the serial, and also calculating the ms it takes to complete each loop, and its currently sitting at 30ms. So 30ms every serial print, at 9600 baud, and all data is going through...
So 9600 seems fine.
But yes, I can up this to a higher value if needed.