Problem counting pulses

I want to count pulses and find the frequency. Here is the picture of pulses from the oscilloscope: Obviously, frequency is around 1/2.3 ms = 420 Hz.

First I tried this program:

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(26,GPIO.IN)
ecnt=0

def evnt(channel):
global ecnt
ecnt += 1

while(True):
estr=ecnt
time.sleep(10)
efin=ecnt
print((efin-estr)/10)

Program returns frequencies around 1200 Hz!

I also tried this program:

import pigpio
import time

mypi=pigpio.pi()

mypi.set_mode(26, pigpio.INPUT)

wind_cb = mypi.callback(26)

while(True):
estr=wind_cb.tally()
time.sleep(10)
efin=wind_cb.tally()
print((efin-estr)/10)

This program returns frequency of 470 Hz, which is much better but still about 10% to much.

On suggestion from @joan I tried this

import pigpio

mypi=pigpio.pi()

mypi.set_mode(26, pigpio.INPUT)

ecnt=0
edat=[0,0]

def evnt(gpio,level,tick):
global ecnt
global edat
if level == 1:
ecnt += 1
edat=[ecnt,tick]

cb = mypi.callback(26,pigpio.RISING_EDGE,evnt)

while(True):
estr=edat
time.sleep(10)
efin=edat
tdif=pigpio.tickDiff(estr,efin)/1000000.0
if (tdif>0):
freq=(efin-estr)/tdif
else:
freq=0
print(freq)

cb.cancel()
mypi.stop()

This makes minor improvement (time between two events is actually 10.03s and not 10s), so it still gives 10% higher frequency than it should.

What is wrong, what should I do?

• Comments are not for extended discussion; this conversation has been moved to chat. – goldilocks Sep 2 '18 at 9:39
• I want to notify an interested reader that I found the solution for the problem. Currently interest for this question (upvote indicator) is zero, however if interest rises enough, I will post the answer with programming sample and extensive explanation. – Pygmalion Sep 4 '18 at 13:27
• ..so you're holding the answer hostage? – tedder42 Apr 7 at 23:31
• @tedder42 Ehm, I thought nobody is interested, so why bother. And now I don't remember what exactly was wrong. If you are interested, I can post the last code I and is probably OK. – Pygmalion Apr 8 at 18:11

Below is the working example. There are two adaptations of the original code:

1. For some reason RISING EDGE option of pigpio does not work properly. Fortunately, EITHER EDGE works fine, but you have to divide the result by 2 because one cycle has one rising and one falling edge.
2. Falling edge in my case is not as sharp as rising edge. In order to prevent false falling edge event, I added a filter that prevents two events happening sooner than 50 microseconds.

Hope this helps.

import pigpio
import time

mypi=pigpio.pi()

mypi.set_mode(26, pigpio.INPUT)

save=0
ecnt=0
edat=[0,0]

def evnt(gpio,level,tick):
global save
global ecnt
global edat
if (level<2) and (tick-save>50):
save=tick
ecnt += 1
edat=[ecnt,tick]

cb = mypi.callback(26,pigpio.EITHER_EDGE,evnt)

while(True):
estr=edat
time.sleep(1)
efin=edat
tdif=pigpio.tickDiff(estr,efin)/1000000.0
if (tdif>0):
freq=(efin-estr)/2/tdif
else:
freq=0
print(freq)

cb.cancel()
mypi.stop()