reading multiple frequencies effectively?

I don't have any code for this yet, witch is why i am posting here :stuck_out_tongue:

I want to know what the best, or at least a good way to read 2 separate frequencies with an arduino, fairly accurately, without slowing down or otherwise mucking up already running code.

the Pulsein() command would seem to be the simplest way, however this seems to stop or slow down the loop while it waits for an event. So i imagine two of these would compound the problem.

The project i am working on uses a mega, I am trying to build a transmission controller/diagnostic tool, and need to monitor both the input shaft speed as well as the output shaft speed. Other functions that the mega are tasked with are controlling a Graphical LCD ( GLCD ) for user interface, monitoring a few buttons ( for shifting via solenoid control ), turning shift solenoids on or off to select different gear ranges and measuring current going to those shift coils for fault detection.

Right now I have the GLCD up and running, using a couple of ports, the solinoid shifting is also accomplished with yet another port (there are 8 solenoids on the transmission i am targeting so it works out great to use direct port control :wink: )

All of these functions i have working great and were fairly easy to code using a couple of standard libraries, but measuring the two frequency signals is where i think things might start to get messy and cause long nights of hair pulling, so i was hoping some of the wizards out there could point me in the right direction.

Another option I am considering, to keep the coding simple and the overall speed on the finished product snappy, is to use multiple arduinos. Use the mega for all the a fore mentioned stuff that requires lots of pins, and use 2 pro-micros ( just cause they are cheep ), one for each frequency input. Each micro would then only have the task of measuring the frequency on 1 pin, using an efficient library like FrequCounter, and then sending data out serially to the mega when it requested. This seems like using a sledge hammer to drive a finishing nail, but i think it would work without a whole lot of coding trail and error.

I should also add that the frequencies i am trying to measure are not terribly fast, 1 to ~2000Hz (min/max), so clock counts will be fairly large, witch is why i am worried about the code getting bogged down.

Since you need to carry out several activities concurrently, a non-blocking approach would be the best one. In this approach your code would detect when an input signal changed state and record the time it happened, compare that against the time of the previous state transition and calculate the input period from that. It would be sensible to measure the interval between successive rising (or falling) edges so that you are measuring the period of the overall signal and not just the length of the high or low part.

You can implement this either using interrupts, or by polling. Using interrupts makes it possible to support much higher frequencies but requires a much more complicated solution which is not required here - just design your sketch so that none of the code blocks (stops) the main loop() function and poll the inputs each time loop() executes. There is an example sketch which demonstrates how to do state change detection i.e. read the current state of the input and compare to the previous state to see whether it has changed.

If you can sample the input with an analog pin, then it is very quick to analyze for ALL the frequencies present in the input signal (up to about 4 kHz ) using the FFT function. The frequency resolution depends on the sample rate, but at the highest resolution (longest time to analyze) it takes about 7 milliseconds to analyze a 256 element audio sample. See these pages: ArduinoFFT - Open Music Labs Wiki

jremington:
If you can sample the input with an analog pin, then it is very quick to analyze for ALL the frequencies present in the input signal (up to about 4 kHz ) using the FFT function.

Given that the inputs are initially presented as separate digital signals, combining them into a single analog input and then trying to pick discrete frequencies out of that merged input seems to be making the problem harder, not easier. Measuring the frequency of a small number of digital inputs all at relatively low frequencies seems like a straight forward software problem.