Just trying to customize some Picamera functionality though this is my first time coding in Python. Basically I am using the GPIO with a button switch to essentially turn just the preview on and off. Ideally i did not want to use wait_for_edge because I wanted the pi to do other stuff in the interim and not be locked up waiting for the button press. Then I submitted to using it after the event detection I set up since its fine that the program waits while in preview mode (for this case).

The issue comes with just trying to use one button. I basically initiate event detection on the button, then remove it once preview mode starts. Then I set it up to wait for the button press again. But I run into:

RuntimeError: Conflicting edge detection already enabled for this GPIO channel

The following is meat of the code thus far:

from time import sleep
import picamera
import RPi.GPIO as GPIO
import datetime

today = datetime.datetime.today()
captureOn = 25

GPIO.setup(captureOn, GPIO.IN, pull_up_down=GPIO.PUD_UP)
startPrev = True

def preview(channel):

        global captureOn
        global startPrev

        if GPIO.input(captureOn):
            print ("Rising Edge detected")

            if (startPrev == True):

                with picamera.PiCamera() as camera:
                    camera.resolution = 1920, 1080
                    camera.framerate = 30
                    camera.rotation = 0
                    camera.brightness = 50
                    while True:
                          print('preview started')
                          startPrev = False
                          if GPIO.input(captureOn):

                ...stop preview code?

                print('stop preview')

GPIO.add_event_detect(captureOn, GPIO.BOTH, callback=preview, bouncetime=1000)

EDIT: It seems that while in my IF statement, the GPIO event detection is disabled or not being called as pressing the button does nothing (no print outs either) FIXED: partially due to a wiring issue but added some code in the while statement above!

1 Answer 1


I highly suggest for practicality you eliminate the falling and rising reinstating altogether by using GPIO.BOTH as shown here. You would use GPIO.add_event_detect(25, GPIO.BOTH, callback=my_callback) and then check the input like so:

GPIO.setup(25, GPIO.IN) 
def my_callback(channel):
    if GPIO.input(25):     # if port 25 == 1
        print "Rising edge detected on 25"
    else:                  # if port 25 != 1
        print "Falling edge detected on 25"

# when a changing edge is detected on port 25, regardless of whatever 
# else is happening in the program, the function my_callback will be run
GPIO.add_event_detect(25, GPIO.BOTH, callback=my_callback)

Of course, you would replace the "print" lines with the turn on and off preview code. This link above contains a whole tutorial on the topic. Hope that helps!

EDIT: To print a different statement each time the button is pressed and switch between statement a and b use this code(its in c++ because I am more familiar with it, but you could convert it to Python quickly.):

bool printb = 0;

if(printb = 0)
  printb = 1;
 printb = 0;
  • Ah, that link was totally what I was looking for. I had implemented GPIO.BOTH before but the program kept turning the preview on and off incrementally even though no action had been taken. Thanks for the info.
    – Chaz
    Jun 5, 2015 at 1:53
  • Actually now I am a little curious. Using a typical push button, the above code would print "Rising..." on the pressing action and then print "Falling..." when the button comes up, all in one motion correct? What if I wanted an initial press (full action of rising and falling) to print(a) and a subsequent press (again, full action) to print(b). Then the next press would print(a) and the next would print(b) and so on?
    – Chaz
    Jun 5, 2015 at 2:20
  • You could use some Boolean logic. Make a variable called printb and set it to 0. Then in my function above, in the else part, add an if clause(c++ version): if(printb = 0){println(a);printb=1}else{println(b);printb=0} This way it the code keeps track of what to print and only prints the line after the rise and fall.
    – NULL
    Jun 5, 2015 at 10:57
  • See my revised answer for better format.
    – NULL
    Jun 5, 2015 at 11:05
  • Null, so I get it to work using the print statements, but now the only issue I am having is placement of the camera init code and the start_preview/stop_preview functions. I've moved them all over the place and seem to have it working when all if i is in the if statement above. Only issue is that after I start_preview (followed by sleep) the preview shuts off after the sleep time. Edited what I have in above.
    – Chaz
    Jun 13, 2015 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.