venturiand
Posts: 5
Joined: Mon Oct 28, 2013 7:15 pm

RPi GPIO: GPIO.RISING detects also falling edges?

Mon Oct 28, 2013 8:18 pm

Hello,

I have connected an IR presence sensor to my Raspberry pi according to the top diagram here:
http://www.cl.cam.ac.uk/projects/raspbe ... tected.jpg
where the IR presence sensor replace "Switch 1".
Then I have written the following python script:

Code: Select all

#! /usr/bin/python
import RPi.GPIO as GPIO
import time
import datetime
channel = 17
def presence_detected(channel):
  now = datetime.datetime.now()
  print "Presence detected in channel ",channel,now
def presence_absence_detected(channel):
  now = datetime.datetime.now()
  print "Presence/Absence detected in channel ",channel,now
def absence_detected(channel):
  now = datetime.datetime.now()
  print "Absence detected in channel ",channel,now
def main():
  GPIO.setmode(GPIO.BCM)
  GPIO.setup(channel,GPIO.IN,pull_up_down=GPIO.PUD_UP)
  GPIO.add_event_detect(channel,GPIO.RISING,callback=presence_detected)
#  GPIO.add_event_detect(channel,GPIO.FALLING,callback=absence_detected)
#  GPIO.add_event_detect(channel,GPIO.BOTH,callback=presence_absence_detected)
  start=datetime.datetime.now()
  delta=datetime.timedelta(seconds=15)
  future=start+delta
  now=datetime.datetime.now()
  while (now < future):
#    GPIO.wait_for_edge(channel,GPIO.BOTH)
    status=GPIO.input(channel)
    print datetime.datetime.now(), status
    time.sleep(1.)
    now=datetime.datetime.now()
  print GPIO.VERSION	
  GPIO.cleanup()
if __name__ == "__main__":
   main()


When I execute it and I trigger the presence sensor I got this output:


2013-10-28 21:09:53.674144 0
2013-10-28 21:09:54.677240 0
Presence detected in channel 17 2013-10-28 21:09:55.543159
2013-10-28 21:09:55.678810 1
2013-10-28 21:09:56.681420 1
2013-10-28 21:09:57.682998 1
Presence detected in channel 17 2013-10-28 21:09:57.925071
2013-10-28 21:09:58.684581 0
2013-10-28 21:09:59.686158 0
2013-10-28 21:10:00.687734 0
2013-10-28 21:10:01.689307 0
Presence detected in channel 17 2013-10-28 21:10:02.499103
2013-10-28 21:10:02.690870 1
2013-10-28 21:10:03.692510 1
Presence detected in channel 17 2013-10-28 21:10:04.010306
2013-10-28 21:10:04.694133 0
2013-10-28 21:10:05.695718 0
2013-10-28 21:10:06.697311 0
2013-10-28 21:10:07.698888 0
0.5.3a

where it looks like that the event is detected also when the GPIO input change from 1 to 0 and not only from 0 to 1 as defined in the code. As I cross check I have modified the code by replacing GPIO.RISING with GPIO.FALLING and in that case the output is like:

2013-10-28 21:13:34.080134 0
2013-10-28 21:13:35.083223 0
2013-10-28 21:13:36.084807 0
2013-10-28 21:13:37.086391 0
2013-10-28 21:13:38.087994 0
2013-10-28 21:13:39.089658 1
2013-10-28 21:13:40.091252 1
2013-10-28 21:13:41.092910 1
2013-10-28 21:13:42.094499 1
Absence detected in channel 17 2013-10-28 21:13:42.132005
2013-10-28 21:13:43.096084 0
2013-10-28 21:13:44.097680 0
2013-10-28 21:13:45.099278 1
2013-10-28 21:13:46.100872 1
2013-10-28 21:13:47.102471 1
Absence detected in channel 17 2013-10-28 21:13:47.596853
2013-10-28 21:13:48.104070 0
0.5.3a

which looks correct and, finally, I have replaced GPIO.FALLING with GPIO.BOTH and I got this:


2013-10-28 21:15:26.526504 0
2013-10-28 21:15:27.529757 0
2013-10-28 21:15:28.531339 0
Presence/Absence detected in channel 17 2013-10-28 21:15:29.464044
2013-10-28 21:15:29.532940 1
2013-10-28 21:15:30.534548 1
2013-10-28 21:15:31.536134 1
2013-10-28 21:15:32.537716 1
Presence/Absence detected in channel 17 2013-10-28 21:15:32.707919
2013-10-28 21:15:33.539304 0
2013-10-28 21:15:34.540892 0
Presence/Absence detected in channel 17 2013-10-28 21:15:35.190003
2013-10-28 21:15:35.542473 1
2013-10-28 21:15:36.545153 1
2013-10-28 21:15:37.546742 1
Presence/Absence detected in channel 17 2013-10-28 21:15:38.182656
2013-10-28 21:15:38.548389 0
2013-10-28 21:15:39.549962 0
2013-10-28 21:15:40.551530 0
0.5.3a

which looks ok, too.
Therefore it looks like there is a problem only with GPIO.RISING.

Has anyone an idea about why it happens?

Thanks and ciao

Andrea

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Mon Oct 28, 2013 10:39 pm

might be 'chatter' from one of the sensor 'edges' (presumably the falling one). Although you would expect multiple edges from it falling and rising your sleep might be filtering those out. Try it without a sleep and see what you get.

With a quadrature encoder I found I could get ten or twenty false edges if I turned it very slowly
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

venturiand
Posts: 5
Joined: Mon Oct 28, 2013 7:15 pm

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Tue Nov 12, 2013 7:51 am

Hi,

thanks for the suggestion and sorry for the late answer.
I will try without the "sleep" but I already see an inconsistency in my outputs:
if, when I use GPIO.RISING, the action is triggered also when I have a transition from "1" to "0" because of multiple edges, then I would expect in that event N+1 transition from "1" to "0" and N transition from "0" to "1" since, eventually it ends up in "0". But this is not visible in the outputs neither when I use GPIO.FALLING, where I see only _one_ transition from "1" to "0", and not two as I should see if there is a bounce, nor when I use GPIO.BOTH where only _one_ transition of any kind, and not _at least_ three as it should be if there is a bounce.
Does anyone think that there is a way to explain the facts above without concluding the GPIO.RISING actually detects also falling edges and behaves exactly as GPIO.BOTH?

Thanks and ciao

Andrea

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Tue Nov 12, 2013 4:06 pm

I think that the edge detect event interrupt on the pi isn't quite as 100% hardware as it might be on other microcontrollers. I have seen people commenting that there seems to be up to 75micro.s lag depending what else the operating system is doing. In my experiments with the quadrature encode I had to give up on the simple assumption that every edge would trigger an event. When I test the state of the input pin after a change event (as I do in my code here) I often find that the pin has changed from 1 to 1 or from 0 to 0. With a time delay in the callback to stop double readings you could have several intermediate edges undetected.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Paradr0id
Posts: 1
Joined: Tue Jun 10, 2014 9:49 am

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Tue Jun 10, 2014 10:28 am

It seems that the problem still persists in GPIO 0.5.5. I did some testing; BOTH and FALLING are identical, they both trigger on rising and falling edges. RISING triggers on rising edges and sometimes also on falling edges, so it's useless.

This would be a serious bug, and I'm surprised I couldn't find more posts about it. How does it work for you guys, maybe it's a problem with my setup?

As an example, here's some printout from a wind sensor. The first digit is the current value read via GPIO.input() inside the callback, so 1 denotes a rising edge, 0 a falling edge (assuming the readout is fast). "rotation" is the time since the last event (so not necessarily a full rotation). Note that the high and low intervals are different in duration, due to the construction of the sensor.

Code: Select all

FALLING: Detects both rising and falling edge.
1 - rotation in 0.039927s - min: 0.034466
0 - rotation in 0.084818s - min: 0.034466
1 - rotation in 0.041101s - min: 0.034466
0 - rotation in 0.088365s - min: 0.034466
1 - rotation in 0.042531s - min: 0.034466
0 - rotation in 0.090401s - min: 0.034466
1 - rotation in 0.043843s - min: 0.034466
0 - rotation in 0.093924s - min: 0.034466
1 - rotation in 0.045273s - min: 0.034466
0 - rotation in 0.095980s - min: 0.034466
1 - rotation in 0.046504s - min: 0.034466
0 - rotation in 0.099888s - min: 0.034466
1 - rotation in 0.048070s - min: 0.034466
0 - rotation in 0.101983s - min: 0.034466
1 - rotation in 0.049661s - min: 0.034466
0 - rotation in 0.106498s - min: 0.034466

BOTH: Detects both rising and falling edge.
0 - rotation in 0.054238s - min: 0.020556
1 - rotation in 0.026104s - min: 0.020556
0 - rotation in 0.054959s - min: 0.020556
1 - rotation in 0.026519s - min: 0.020556
0 - rotation in 0.056496s - min: 0.020556
1 - rotation in 0.027205s - min: 0.020556
0 - rotation in 0.057503s - min: 0.020556
1 - rotation in 0.027730s - min: 0.020556
0 - rotation in 0.059439s - min: 0.020556
1 - rotation in 0.028517s - min: 0.020556
0 - rotation in 0.060473s - min: 0.020556
1 - rotation in 0.029091s - min: 0.020556
0 - rotation in 0.062023s - min: 0.020556
1 - rotation in 0.029850s - min: 0.020556
0 - rotation in 0.063196s - min: 0.020556
1 - rotation in 0.030578s - min: 0.020556

RISING: Inconsistent. Note that when a falling edge is missing, the following rising edge has a longer time, so it's not a problem of GPIO.input() reading a stale value in the callback handler.
1 - rotation in 0.023066s - min: 0.051631
1 - rotation in 0.073067s - min: 0.023066
0 - rotation in 0.050656s - min: 0.023066
1 - rotation in 0.024662s - min: 0.023066
0 - rotation in 0.052305s - min: 0.023066
1 - rotation in 0.025355s - min: 0.023066
1 - rotation in 0.080036s - min: 0.023066
1 - rotation in 0.082009s - min: 0.023066
1 - rotation in 0.084437s - min: 0.023066
0 - rotation in 0.058487s - min: 0.023066
1 - rotation in 0.028134s - min: 0.023066
1 - rotation in 0.088610s - min: 0.023066
1 - rotation in 0.090572s - min: 0.023066

venturiand
Posts: 5
Joined: Mon Oct 28, 2013 7:15 pm

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Sat Jun 21, 2014 5:50 pm

Hi,

actually what I reported in my original post is the opposite: BOTH and FALLING seem to behave properly while it is RISING which is triggered both by rising and falling edges (like BOTH). But I did not try with 0.5.5

User avatar
joan
Posts: 14932
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Sat Jun 21, 2014 6:22 pm

venturiand wrote:Hi,

actually what I reported in my original post is the opposite: BOTH and FALLING seem to behave properly while it is RISING which is triggered both by rising and falling edges (like BOTH). But I did not try with 0.5.5
Are you sure it's not a problem with reading the current state in the callback. You have no control of when the callback is run with respect to the time of the event. It could easily be several hundreds of milliseconds later.

What are the expected lengths of the highs and lows?

mstanley103
Posts: 1
Joined: Wed Jul 16, 2014 2:56 am

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Jul 16, 2014 3:05 am

I see the same problem with the GPIO.RISING callback being invoked on both rising and falling edges of the input. I'm using a PIR sensor with an LED which is visible when the value is one. The "falling" event is definitely associated with the PIR LED de-assertion as well as the falling voltage on the input pin (I checked it with a DVM). I'm using a model B and updated my OS just yesterday, so everything should be current.

User avatar
joan
Posts: 14932
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Jul 16, 2014 7:13 am

Code?

simplesi
Posts: 2327
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
Contact: Website

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Jul 16, 2014 7:23 am

Problem is you really need a scope to see what's going on with the real edge transitions before being able to identify that its a software issue. :(

Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter

User avatar
joan
Posts: 14932
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Jul 16, 2014 7:55 am

simplesi wrote:Problem is you really need a scope to see what's going on with the real edge transitions before being able to identify that its a software issue. :(

Simon
Trying different software might help. If the same happens it is more likely to be a true hardware transition.

@mstanley103

piscope may show if the edges are really there or not.

simplesi
Posts: 2327
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
Contact: Website

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Jul 16, 2014 9:19 am

@joan
yep it would help - but it's a bit like using a different stethoscope when exploitative surgery is really whats needed :)

SImon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter

User avatar
DMike92
Posts: 22
Joined: Mon Dec 29, 2014 12:52 am
Location: France
Contact: Website

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Tue Mar 24, 2015 8:52 pm

Still the same in 0.5.9 :-(
Le savoir ne vaut que quand il est partagé (c'est pas de moi mais j'adhère).

User avatar
DougieLawson
Posts: 39099
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Tue Mar 24, 2015 10:33 pm

DMike92 wrote:Still the same in 0.5.9 :-(
You should be running 0.5.11.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
MarkHaysHarris777
Posts: 1820
Joined: Mon Mar 23, 2015 7:39 am
Location: Rochester, MN
Contact: Website

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 7:06 am

This is a common problem, having to do with what is called hysteresis. You may need to condition the output from your sensors to get a true edge that may be relied upon to trigger an interrupt. A true falling (or rising) hysteresis will be straight, clean, sharp and distinct in a very small amount of time. If the hysteresis curve is 'curved' or has spikes, or is otherwise NOT a clean edge, then you will get false interrupts.
You need a scope so that you can see what your edges look like... when you see them, you'll know what I mean.
marcus
:ugeek:

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 10:59 am

Well, it's a strong possibility that a scope will tell you what you can deduce from the behaviour of the program, and trying a different gpio library would also (probably) confirm what you would have seen if you wired the sensors to a scope.

So a pragmatic approach might be to just add some logic to the code to cope with un-clean edges, whether they exist or not.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

User avatar
joan
Posts: 14932
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 11:44 am

I haven't seen enough information to tell whether it's a user coding error or something more serious. I'd like to see the code of the programs which generate spurious results. My guess is that these are user coding errors.

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 12:32 pm

When I had the problem myself I whittled the code down to just a few lines (but don't seem to have it any more, I must have called it temp something!) using the OP's code as a starter it was something like

Code: Select all

def presence_detected(channel):
  print("--", GPIO.input(channel), time.time())

GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(17, GPIO.RISING, callback=presence_detected)

while True:
  print(GPIO.input(17), time.time())
  time.sleep(1.0)
and as I twiddled the knob of the quadrature encoder I got all kinds of random results. If I turned the knob at exactly the right speed (very slowly) I could get the callback function to be run twenty or thirty times per edge (rising or falling) and the state of the pin read from the function (just triggered by a rising edge) was as likely to be off as on!
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

User avatar
joan
Posts: 14932
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 1:42 pm

paddyg wrote:When I had the problem myself I whittled the code down to just a few lines (but don't seem to have it any more, I must have called it temp something!) using the OP's code as a starter it was something like

Code: Select all

def presence_detected(channel):
  print("--", GPIO.input(channel), time.time())

GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(17, GPIO.RISING, callback=presence_detected)

while True:
  print(GPIO.input(17), time.time())
  time.sleep(1.0)
and as I twiddled the knob of the quadrature encoder I got all kinds of random results. If I turned the knob at exactly the right speed (very slowly) I could get the callback function to be run twenty or thirty times per edge (rising or falling) and the state of the pin read from the function (just triggered by a rising edge) was as likely to be off as on!
That is probably just switch bounce. It can bounce between on and off very rapidly.

So Linux notifies RPI.GPIO which then notifies your callback. Between the time of the switch change and the time of checking the input state with print("--", GPIO.input(channel), time.time()) there could be many milliseconds in time and there might have been many changes in state.

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 1:52 pm

rpi.gpio supports explicit bouncetime setting (since 0.5.2 if i remember right), have you tried setting it in the event detect function?

differently from PIGPIO, the callback isn't receiving also level post interrupt, i think

User avatar
paddyg
Posts: 2541
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 2:00 pm

@joan, I remember trying the debounce argument but I can't remember why it didn't work (but it didn't, maybe that was a bug, it's a while ago now) However with a quadrature encoder it's quite easy to keep track of which edges to count and which to ignore.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

User avatar
joan
Posts: 14932
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 2:08 pm

If anything it's a bug in Linux. The time, gpio, and level should be recorded in the interrupt and be passed up the chain. It wouldn't be perfect but in my view be better than that which we currently have.

gordon77
Posts: 5035
Joined: Sun Aug 05, 2012 3:12 pm

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Wed Mar 25, 2015 2:24 pm

My use is probably far simpler but FALLING and RISING appear to work OK for me

Adding the delay for debounce seems to depend on the quality of the switch. The switch is connected pin 26 to pin 25.

It will count

1 for a long press (> 1.2 seconds)
2 for a single short press
3 for 2 presses
etc

Code: Select all

import RPi.GPIO as GPIO
import time

sw_in = 26

GPIO.setmode(GPIO.BOARD)
GPIO.setup(26,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(sw_in,GPIO.FALLING)

while True:
   if GPIO.event_detected(sw_in):
      GPIO.remove_event_detect(sw_in)
      now = time.time()
      count = 1
      GPIO.add_event_detect(sw_in,GPIO.RISING)
      while time.time() < now + 1.2: # 1.2 second period
         if GPIO.event_detected(sw_in):
            count +=1
            time.sleep(.3) # debounce time
      print count
      GPIO.remove_event_detect(sw_in)
      GPIO.add_event_detect(sw_in,GPIO.FALLING)

emeyeraway
Posts: 146
Joined: Tue Mar 24, 2015 7:11 am

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Sat Aug 01, 2015 2:40 pm

It seems to me this code doesn't address the issue at hand. I think if you replace your FALLING by RISING you would see the same results.

I have also found that RISING detects both RISING and FALLING edges. In the code below, an event is detected whether the button is pushed or released.

In the circuit, when the switch is closed (button of simple DPDT is pushed), pin 22 goes high, which tells pin 18 to go high. If I hold the button in the closed position after pushing it, an event is detected when I release it (i.e., a FALLING edge is detected by the RISING option).

Replacing RISING with either FALLING or BOTH in this code leads to the expected behavior. So, just as others in this thread have observed, it appears that of the three, only the RISING option is not functioning properly.

Code: Select all

import RPi.GPIO as GPIO  
import time    
GPIO.setmode(GPIO.BOARD)    
GPIO.setup(22, GPIO.IN)   
GPIO.setup(18, GPIO.OUT)   
def printFunction(channel):
    if GPIO.input(22):
      print("pin 22 HIGH, LED ON")
      GPIO.output(18,1)
    else:
      GPIO.output(18,0)
       print("pin 22 LOW, LED OFF")
try:
    GPIO.add_event_detect(22, GPIO.RISING, callback=printFunction)
    while True:
        time.sleep(0.05) 
except KeyboardInterrupt:
    print("Keyboard Interrupt")
finally:
    GPIO.cleanup() 
    print("   Cleaned up pins")
I have a 100nanofarad capacitor across the switch, so removed the bouncetime option from the event detect statement. Removing this option is what was required to get rid of a persistent bouncing problem. The capacitor alone did not suffice.

paulv
Posts: 563
Joined: Tue Jan 15, 2013 12:10 pm
Location: Netherlands

Re: RPi GPIO: GPIO.RISING detects also falling edges?

Sun Aug 02, 2015 7:03 am

To find out what works ( or not ) and under what conditions, I suggest using a function generator in the pulse or square wave mode to feed the GPIO inputs. It produces clean rising and falling edges at a precise repetative timing interval. You could also wire-up a 555 timer based kludge and start from there.

With this you can test for the presence or missing rising/falling or both edge detections.
Varying the time-base should show where the latency issues appear in the whole chain as a possible cause for missing edge detections.

I expect that, by using a second port as a trigger, you can also test the schmitt-trigger or delay effect of the debounce option.

I do not have the time now, but this will be an interesting experiment. I'll put it on my bucket list.

Return to “Python”