a simple frequency counter

hi guys
i was trying to build a simple frequency counter using the arduino and a 555 timer for testing , but iam having some problems :

1- i used the pulsein function to measure the time period for HIGH and LOW and summed them to get the total time period . but once i change the data from float to unsigned long the reading of the calculated frequency is way off , why? .

2 - i tried to make some for loops for averaging the data to get more accuracy but something seems wrong , the first reading might be accurate ( i am using a 555 timer calculator to verify) but the further reading has the first reading off like ( if the frequency was 1.82 ) the arduino frequency array of 3 values is like :

1.81
1.82
1.83

9.61--------- don’t understand why this appear ( and it is making the average way off )
1.82
1.81

the code :

int IC = 8 ;
float pulseH[3] ;
float pulseL[3] ;
float pulseT[3] ;
float freq[3] ;
float sumcounts = 0 ;
int num = 3 ;
float avg ;
int i = 0 ;
void setup() {
Serial.begin(9600);
pinMode(IC,INPUT) ;

}
void loop() {
for (i=0;i<num;i=i+1){
pulseH[i] = pulseIn(IC,HIGH);
}
for (i=0;i<num ;i=i+1){
pulseL[i] = pulseIn(IC,LOW);
}
for (i=0;i<num;i=i+1){
pulseT[i] = pulseH[i] + pulseL[i] ;
}
for (i=0;i<num;i = i+1){
freq[i] = 1000000/pulseT[i] ;
Serial.println(freq[i]) ;
}
for (i =0;i<num ;i= i+1){
sumcounts = sumcounts + freq[i] ;
}
avg = sumcounts/num ;
//Serial.println(avg) ;
delay(10);
sumcounts = 0 ;
}

is there any thing wrong with the code ?

i will appreciate any help
thanks .

Print the raw data so you can see what's throwing your calculations off.

wildbill: Print the raw data so you can see what's throwing your calculations off.

you mean the pulsein output , the pulse in HIGH array also has the same issue :

446695.00 445081.00 0.00-------------- why ?? 443454.00 441303.00 0.00--------------- 443000.00 446439.00

Check the documentation for pulsin- it will return zero if you don't get a pulse within the one second default timeout. Try increasing the timeout a little.

1) If a timeout is not specified for pulsein() it defaults to 1 second.

2) Your pulses are about 0.44 seconds.

3) When measuring a high pulse, pulsein() waits for the signal to go low before looking for the next pulse.

4) On the transition from looking for low pulses to high pulses, the signal has just gone high, so there will be most of a high pulse period, a low pulse period, and then the pulse of interest or close to 3 * 0.44 = 1.32 seconds to complete the measurement, so pulsein() will timeout on the first high pulse measurement after the low pulse measurement set and vice versa. Setting a longer timeout as per post #3 should fix your immediate problem.

As an aside, for such low frequencies I would think polling the pin (or edge interrupts) and logic to measure the period of a single full cycle would be a preferred approach since the reading would be more responsive.

i changed the pulsein TIMEOUT to 1.5 sec like you guys suggested and that fixed it for low frequencies such as 1.8Hz , but when i increase the frequency of the 555 timer to say 686Hz the frequency measured is 630 Hz this is way off by about 50 Hz which is a lot although the pulse in problem seems to be resolved the measured freq is yet way off for higher frequencies , why is that ?

the pulsein problem seems to be resolved but the values itself is off by about 25 microseconds ,why is that ? the pulse in suppose to be relatively accurate for measuring such times ?! this is like 3.5% error !

ahmed44:
i changed the pulsein TIMEOUT to 1.5 sec like you guys suggested and that fixed it for low frequencies such as 1.8Hz , but when i increase the frequency of the 555 timer to say 686Hz the frequency measured is 630 Hz this is way off by about 50 Hz which is a lot although the pulse in problem seems to be resolved the measured freq is yet way off for higher frequencies , why is that ?

How do you know your 555 actually outputs 686 Hz, not 630 Hz?

the pulsein problem seems to be resolved but the values itself is off by about 25 microseconds ,why is that ?
the pulse in suppose to be relatively accurate for measuring such times ?! this is like 3.5% error !

The typical error of a 555 is already 1%. If you’re using cheap ceramic capacitors for timing that easily explains the rest (use good quality film caps instead if you want accurate timing).

The numbers given in #2 also show 1.2% difference between the highest and lowest.

wvmarle: How do you know your 555 actually outputs 686 Hz, not 630 Hz?

The typical error of a 555 is already 1%. If you're using cheap ceramic capacitors for timing that easily explains the rest (use good quality film caps instead if you want accurate timing).

The numbers given in #2 also show 1.2% difference between the highest and lowest.

i am just calculating it using an online 555 timer calculator .

do you suggest that the accumulation of errors in the 555 timer and the capacitors as well as the tolerance in the resistors could produce that ~56Hz error which is about 8.16% error in the output . don't you think that this is a lot ?! i mean i can't do any useful measurements with that kind of accuracy , i used a thin film capacitor and yet it still has about 6-7% error .

so now its the components bad , not my arduino program right ?

do you have any suggestion for another more accurate square wave oscillator apart from the 555 timer ? that could be more accurate for scientific measurements maybe within a tolerance of 0.5~1% .

ahmed44:
do you suggest that the accumulation of errors in the 555 timer and the capacitors as well as the tolerance in the resistors could produce that ~56Hz error which is about 8.16% error in the output .
don’t you think that this is a lot ?!
i mean i can’t do any useful measurements with that kind of accuracy , i used a thin film capacitor and yet it still has about 6-7% error .

Typical tolerance of film capacitors is 5-10%. The resistors you use add typically 1-5% to that - you didn’t specify this. Carbon resistors are a poor choice for timing, you need proper metal film resistors. I don’t know the tolerance of a typical 555 (the actual high and low level trigger points, that is), check the data sheet of your specific incarnation (there are many different versions of the 555). That all can easily explain the measured frequency difference.

A few years ago I built a project where I used an old TS555CN (it was at the time already marked “obsolete” by the manufacturer; I just happen to have some in my parts box) as oscillator to produce an AC current to measure a resistance, then measured the resulting frequency. Got very good results, easily <1% variation during the short term bench testing that I did. I didn’t care about tolerances at the time as those were just part of the calibration.

do you have any suggestion for another more accurate square wave oscillator apart from the 555 timer ?
that could be more accurate for scientific measurements maybe within a tolerance of 0.5~1% .

Your Arduino can produce a very accurate and stable square wave. Just use the tone() function. Easily <0.1% error, mostly subject to the stability of the crystal driving the Arduino clock.

If that’s not what you’re looking for, give us the full picture of what it really is you’re trying to accomplish.

ahmed44: i am just calculating it using an online 555 timer calculator .

do you have any suggestion for another more accurate square wave oscillator apart from the 555 timer ? that could be more accurate for scientific measurements maybe within a tolerance of 0.5~1% .

What is the application that needs a frequency counter using an Arduino. You will probably have to CALIBRATE" your Arduino meter, using the 555 and another frequency counter as the standard or a scope. Tom.... :)

wvmarle:
Typical tolerance of film capacitors is 5-10%. The resistors you use add typically 1-5% to that - you didn’t specify this. Carbon resistors are a poor choice for timing, you need proper metal film resistors. I don’t know the tolerance of a typical 555 (the actual high and low level trigger points, that is), check the data sheet of your specific incarnation (there are many different versions of the 555). That all can easily explain the measured frequency difference.

A few years ago I built a project where I used an old TS555CN (it was at the time already marked “obsolete” by the manufacturer; I just happen to have some in my parts box) as oscillator to produce an AC current to measure a resistance, then measured the resulting frequency. Got very good results, easily <1% variation during the short term bench testing that I did. I didn’t care about tolerances at the time as those were just part of the calibration.

Your Arduino can produce a very accurate and stable square wave. Just use the tone() function. Easily <0.1% error, mostly subject to the stability of the crystal driving the arduino clock.

If that’s not what you’re looking for, give us the full picture of what it really is you’re trying to accomplish.

my main goal is to build a low resistance meter ( or thats what i hoped for ) by using the 555 timer in an Astable mode and then measure the frequency using the arduino then calculate the resistance by using the equation of the 555 frequency .

i thought this might work more accurate than measuring current and voltage …ohms law , as the arduino is mush more accurate in measuring pulse timing than voltages and currents but this turns out to be a big failure .
but i might try something else for measuring low resistance . any suggestion ?

Hi, Have you googled arduino low resistance meter

look at; https://circuits4you.com/2016/05/13/low-value-resistance-measurement/

Tom... :)

What resistance are you talking about, really? How low is low?

One problem that I see is the charge/discharge current of your timing capacitor. That increases as the resistor value decreases, and that current has to come from somewhere. If that source can not supply the current needed, your measurements are off, and frequencies measured lower than you expect. That may be yet another reason your measured 630 Hz is so much off your expected 686 Hz.

What value of components are you actually using?

Are you using the regular astable circuit or the 50% duty cycle variation?

wvmarle: do you have any suggestion for another more accurate square wave oscillator apart from the 555 timer ? that could be more accurate for scientific measurements maybe within a tolerance of 0.5~1% .

The ceramic resonator that is the time base for most Arduino Uno clones is typically specified as 0.5% or better. A computer grade crystal based Arduino board should be on the order of 0.01% time accuracy. Watch grade crystals are about 0.001%.