So, in case you need both frequency measurement and 3+ PWM outputs in your Arduino project, you may want to use another way – pulseIn() function:

pulseIn(pin, value) pulseIn(pin, value, timeout)

Use **LOW** as a value – it provides more stable results (that still depends on your case).

PulseIn function returns the length of the pulse (in microseconds) or 0 if no pulse started before the timeout. To get the frequency you can use f = 1 / t equation, however, that depends on duty cycle of the signal.

To get frequency in Hz for a 50% square wave you can use

freq2 = 500000/pulseIn(5, LOW, 5000);

Notice the value of 500,000 - that means 1,000,000 microseconds divided by 2*pulseIn (for a duty cycle of 50%). The actual period of the signal (red lines) in this case is equal to two pulse lengths:

However, that way of measurement frequency with Arduino **often gives lesser values** than the precise ones.

#### In case you want to use pulseIn for measurements, you can create a calibration function that will approximate results for more accurate ones (like ones that FreqCounter library provides).

A general approach to this looks like:

- Create an additional sketch that measures the frequency on a PWM-capable pin (pin 5, for instance) with both ways - FreqCounter and pulseIn() - and sends measurements data to the PC? separated by \t (tab delimiter) for convinence.
void measureFrequency(){ FreqCounter::f_comp= 8; // Set compensation to 12 FreqCounter::start(1000); // Start counting with gatetime of 1000ms while (FreqCounter::f_ready == 0) // wait until counter ready long freq=FreqCounter::f_freq; // read result long freq2=0; for(unsigned int j=0;j<1024;j++) // get 1024 samples freq2 += 500000/pulseIn(5, LOW, 5000); freq2 = freq2/1024; // get average values Serial.print(freq);Serial.print("\t");Serial.println(freq2); }

- Change the frequency source in the widest possible range. Better to do it several times while running the sketch to get more samples and more accuracy.
- Open any spreadsheet processor. Microsoft Excel is a good choice.
- Copy and paste the data from Console window to Excel
- Calculate the difference between
**FreqCounter**and**pulseIn**values in another column - "**difference**". - Copy only
**pulseIn**and**difference**columns to text file, like input.txt. - Calculate the average value of compensation (difference) for each collected sample. (You can use my Ruby program listed below for this)
- Paste output.txt to another sheet. Create a chart.
- Create approximation mathematical functions. I chose a simple set of linear ( y=ax+b ) functions. (Notice the red lines on a chart above)
- Encode those compensation functions to your sketch, like:

#### That way you will get more accurate readings while using pulseIn function than the raw ones. However, those results are not very precise, so it's better to use them when you all other frequency measurement methods are unavailable, and you do not need precise readings.

Notice that we may have several samples of pulseIn measurements with corresponding compensation values. We need to get only one, average value of compensation for each pulseIn-measured value. You can calculate this on your own, or use this tiny Ruby program that will do that for you:

f = File.open("input.txt") additions = Hash.new(0) count = Hash.new(0) f.each do |line| tmp = line.split("\t") freq = tmp[0].to_i correction = tmp[1].to_i if (additions.has_key? freq) count[freq] += 1 additions[freq] += correction else count[freq] = 1 additions[freq] = correction end end f.close fw = File.new("output.txt", "w"); additions.each do |k,v| fw.puts(k.to_s + "\t" + (v/count[k]).to_s ) end fw.close