Interrupt Question

I am wanding if someone can help me with a coding error?

I am trying to disable the interrupt and then reenable the interrupt when the function completes. As you can I disabled the interrupt event on line 681. This line is not throwing an error. Then I want to reenable the interrupt on line 684 I get an error. The error message state ::::

already enabled for this GPIO channel

I have used this disable and enable code in other functions without any errors

So the question become why is it that’s throwing the error?

See About the Python Help category for now to post code.
Posting pictures of code is not useful.

Also please post the full error that python prints.

Where can I find Markdown and use it? Here is the code ( I do not how to include line numbers). The lines that I talked about in my post are in BOLD text

def Push_Button_Function(channel):

global Push_BUTTON_Pin
global override

override = 1

#First let's check the the state of the push button
if GPIO.input(PUSH_BUTTON_Pin) == True: #The push botton not pressed so just return
	return

#The push botton is press (0) so run the push button code

#Debug Point
print(‘>>>PUSH Button Decorated<<<’)

#Next disable the button interrup so we do not have a interrupt while runing the function code
**GPIO.remove_event_detect(PUSH_BUTTON_Pin)**

statusbar.config(text="Push Button Detected")
Disable_Buttons()

#First turn off the Ready LED
Set_Ready_LED_Off()

SmackBottomSelected(override)

override = None

#Debug Point
print(" Waiting for botton to be released")

wait for the button to released

GPIO.wait_for_edge(PUSH_BUTTON_Pin, GPIO.RISING)

#Debug Point
print(" Botton has been released")

#Reenbale the push button interrup 
**GPIO.add_event_detect(PUSH_BUTTON_Pin , GPIO.BOTH,**

** callback = Push_Button_Function,**
** bouncetime=95)**

Set_Ready_LED_On()

Restore_Buttons()

statusbar.config(text="Ready")

return

When you post your code, format it with:
```
On a line by itself before the first line of your code, and again after the last line of the code. This way it will be formatted correctly.

I’d also suggest cutting down your code to just the part you’re trying to test, along with any necessary initialization. Then see if you still get the error. If you do, then post just the cut down version; it’ll make it easier for us to see where the problem might be.

OK, will try that. But first, how can I highlight a line of code to show the line causing an error? like in the picture I first posted.

Don’t try - it’s not supported. Instead, try to create a proper minimal, reproducible example of the problem, so that there is as little other code as necessary, which lets us see the problematic code more clearly; format the code with multiple code blocks so that you can talk about each code block appropriately; and show a complete error traceback (since that will include the line where the error occurs, along with other useful debugging information). Make sure the traceback corresponds to the code that is actually shown; copy and paste, starting from the line that says Traceback (most recent call last): all the way to the end; and format it the same way as the code.

OK, let’s try this again.

I disable the interrupt at "Debug Point 1 "and then reenable it at “Debug Point 2”. This reenabling the interrupt is where I am getting the error.

I am running this code on a Raspberry and I do not know how to do a screenshot of the error message The error says Debug Point 2 >>
RuntimeError : Conflicting Edge Detection is already enabled for this GPIO channel


def Push_Button_Function(channel):

global Push_BUTTON_Pin
global override

override = 1

#First let's check the state of the push button
if GPIO.input(PUSH_BUTTON_Pin) == True: #The push button not pressed so just return
	return

#The push botton is press (PUSH_BUTTON_Pin = FALSE) so run the push button code

#Debug Point 1
#Next disable the button interrupt so we do not have a interrupt while running this function’s code
GPIO.remove_event_detect(PUSH_BUTTON_Pin)

statusbar.config(text="Push Button Detected")
Disable_Buttons()

#Debug Point 2
#Reenbale the push button interrup
GPIO.add_event_detect(PUSH_BUTTON_Pin , GPIO.FALLING,
callback = Push_Button_Function,
bouncetime=95)

statusbar.config(text="Ready")

return


:

I’m wondering whether it’s complaining because you’re trying to add a callback for an event while in the callback for that same event.

Incidentally, I also wonder the bouncetime parameter will (or would) have an effect because I think the documentation says that what parameter does is set how much time must elapse before it’ll invoke that callback again, so if you’re disabling and then re-enabling it, it might just forget that the callback has just occurred.

I think you might be right about trying to reenable the interrupt while in the called function. I am thinking about using a flag variable to prevent the coding from running if the function is already running. What type of variable type is seen only by the function and remembers when the function is called again?

Example >> The first line of the function is to check the flag to see if the function is running, flag = TRUE, then just return. If the flag is FALSE then the flag will be set to TRUE and the function will execute with the last line of the function code will reset the flag to FALSE.

Do you have a link to interrupt documentation?

If I understand correctly, only one callback can be active a time, so a callback won’t be invoked during a callback.

That’s correct. Only one callback can be called, all other calls will be in ignored until the function is done. Which can take from 5 to 7 seconds to complete.

5-7 seconds sounds like a long time for an interrupt handler, which should normally be quick in order not to miss other interrupts. I’d suggest just signalling a worker, possibly using (software) events or a queue and threading if it needs to work in the background.

Yes, you are very, very correct. Normally an interrupt is very short possibly in the microseconds range. Like a sensor interrupt the code when it has a new value. This app is controlling stepper motors. When the operator presses a button a stepper motor changes position and then resumes the main code body. This repositioning of the stepper is why it will take 5 to 7 seconds to complete. Thus this function can not be interrupted while moving to the new position.

Why should the code have to wait until the motor has actually moved until it proceeds? And why does it take that long to reposition a stepper motor?

I still think it’s a bad idea to have a slow interrupt handler. It would be better just to signal a worker and have that decide whether to perform the action.

It’s a bit like when you code a GUI, where the event handlers should be fast so that the GUI itself remains responsive, and you temporarily disabling buttons and use progress bars, leaving any slow tasks to background threads.

1 Like