Closed AlfaBravoX closed 2 years ago
In the callback you should use the argument level
to determine the pin's value. This is because the callbacks are generated from post processing GPIO samples collected by the DMA. The post processing occurs each millisecond.
In the callback you should use the argument
level
to determine the pin's value. This is because the callbacks are generated from post processing GPIO samples collected by the DMA. The post processing occurs each millisecond.
Thanks, Basically the problem is following: When interrupting the script by kill or ctrl+c in the moment when PIN is LOW (pigpio.PUD_DOWN), and after running the script again, first falling edge is missed.
Regarding level
I did some testing and level
holds permanent value 0/1 that initiated the callback. So for example If I need to verify the PIN state later in callback function, (PIN level could changed in the meantime), I need to use read() function. Or? I am not sure, but using level
to filter out electrical fluctuations in the code is impossible.
First, you should initialize the pin mode and state before the callback and filter:
pi_gpio.set_mode(_gpin_a, pigpio.INPUT)
pi_gpio.set_pull_up_down(_gpin_a, pigpio.PUD_UP)
time.sleep(1) # give pin some time to settle
pi_gpio.set_glitch_filter(_gpin_a, 5000)
pi_gpio.gpio_trigger(_gpin_a, 100, 1) # workaround
pi_gpio.callback(_gpin_a, pigpio.EITHER_EDGE, _callback)
Then, your callback should look something like this:
def _callback(channel, level, tick):
global _gpin_a_state
try:
if _gpin_a_state == level:
print(f"___####glitch,pin was {level} returning")
return
except Exception as e:
print(e)
print(f"previous _gpin_a_state: {_gpin_a_state}")
print("_callback_a called for gpin #{} current state is: {}".format(channel, level)
_gpin_a_state = level
This may not be be exactly what you want but it should give you an idea of how to use the callback api.
Thanks!
Again, this issue is about following problem: If you stop the script by ctrl+c or kill when PIN is LOW, then next time you start it, first falling edge is not reported to callback. Even if workaround is used, it does not help. I did a lot of playing last 24 hours and conclusion is following:
when setting PIN, you need to set pigpio.PUD_UP
after callback and by sw filter out that callback, so it is not reported.
Example:
def _callback(channel, level, tick):
if bool(starting):
print("ignoring_callbacks_when_starting_the_script")
return
time.sleep(.3)
if pi_gpio.read(channel) != level:
print(f"___####false calbacks ignored, level was {level} and real pin state was {pi_gpio.read(channel)} -> returning")
return
print("_callback fully executed for gpin #{} current state is: {}".format(channel, bool(level)))
starting = True #important to filter callback when setting up pin
pi_gpio.set_glitch_filter(_gpin_a, 500)
pi_gpio.set_mode(_gpin_a, pigpio.INPUT)
time.sleep(0.3)
pi_gpio.callback(_gpin_a, pigpio.EITHER_EDGE, _callback)
pi_gpio.set_pull_up_down(_gpin_a, pigpio.PUD_UP)
time.sleep(0.3) # give pin some time to settle
starting = False
This logic works as expected, you can kill the script anytime and none of edges will be missed. If there are other ideas, I am more then happy to see better way of handling this logic.
I am happy to help but I see that you have chosen to ignore my suggestions. I'll try once more.
Please read the documentation for the callback api and note that it says to NOT call read()
in the callback. I tried to explain that the callbacks are looking into the past and therefore are timestamped (tick
). Once you begin dealing with faster signal rates you will understand why this is a feature of pigpio.
Also, you again are generating a spurious edge during initialization:
starting = True #important to filter callback when setting up pin
pi_gpio.set_glitch_filter(_gpin_a, 500)
pi_gpio.set_mode(_gpin_a, pigpio.INPUT)
time.sleep(0.3)
pi_gpio.callback(_gpin_a, pigpio.EITHER_EDGE, _callback)
# This will cause an edge depending on the initial state of the pin
pi_gpio.set_pull_up_down(_gpin_a, pigpio.PUD_UP)
...
I don't see a problem with the library here so I'm going to have to close this issue.l
Thanks, appreciate your comments. I haven't chosen to ignore your suggestions. You can see that in my previous post, I shared revised the code and I removed read()
everywhere with one exception of following line: if pi_gpio.read(channel) != level:
The reason I left it there is because I am not sure how I detect current pin state if it changed right after callback was called. Why? Because my RPI is installed in 220V fuse board and there are frequent power glitches caused by 220V relays that are sometimes not captured by glitch filter. Noises are either too long or repetitive. So for this reason to exclude 100% spurious edges, I need to check real PIN state in callback function. This mechanism is nothing new and widely used in others project as well.
Also I see little misunderstanding here. My very first question was not about this level
stuff (even I learned that here too). My initial question was, that killing the script in the moment, when PIN is LOW causing the callback misses initial falling edge after script is restarted when PUD_UP
in INIT is set before defining callback as you are suggesting me.
Yes, my solution is not perfect, on one hand setting pi_gpio.set_pull_up_down(_gpin_a, pigpio.PUD_UP)
after setting callback generating a spurious edge (i can detect it and filter that out on software level) , but initial falling edge is not missed.
The reason I opened this thread is that RPi.GPIO
lib does not behave like this. If I set callback
after PUD_UP
as you are suggesting, initial falling edges are not missed:
_gpin_a = 27
GPIO.setup(
_gpin_a,
GPIO.IN,
pull_up_down=GPIO.PUD_UP
) # input alarm Reset both SW/HW button
_gpin_a_state = GPIO.input(_gpin_a)
GPIO.add_event_detect(
_gpin_a, GPIO.BOTH, callback=_callback, bouncetime=500
)
So I wanted to know why.
Hi, I appreciate help, because my project is quite large and using this lib, however i noticed, that sometimes initial falling edge is not detected, after script is restarted. I know there were many discussions on that topic here, ie. #385, but I was assuming the issue is resolved if workaround to use
gpio_trigger()
is used. However in my case none of wokrarouns works.I have RPI 3 with:
pigpiod -v 79
and when using this code with different lib, callback works reliably 100% also for initial falling edge:
but when I set same with this lib:
in second case i have absolutely unpredictable first falling edge results. Sometimes callback is triggered just fine, sometimes not.
Because this first callback reliability is critical for me , I am considering to revert to RPI.GPIO lib, but I want to try all options before taking decision.
thanks for any advises!