Portenta H7: IRQ wakes device up, but callback is not called

I really wanted to try getting this working on my own, since interrupts are a pretty standard practice, but I just cannot figure out why my callback is not being called.

I am able to run the extint_wakeup.py example, and the interrupt does indeed wakeup the MCU. However, when I tried modifying the code a bit so set off a flag, I found the that the callback isn’t called. Im currently trying to just toggle the led in the callback to verify:

import sensor, image, time, pyb, machine
from pyb import Pin, ExtInt

imageCtr = 1
RED_LED_PIN = 1
GREEN_LED_PIN = 2
BLUE_LED_PIN = 3

global led
led = pyb.LED(BLUE_LED_PIN)

def callback(line):
    led.toggle()
    print("line =", line)

# Attempt 1
pin = Pin("PC7", Pin.IN, Pin.PULL_UP)
ext = ExtInt(pin, ExtInt.IRQ_FALLING, Pin.PULL_UP, callback)

#Attempt 2
#pin = machine.Pin("PC7", machine.Pin.IN, machine.Pin.PULL_UP)
#pin.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)

print("Initialized")

while (True):
    #if takeShot_flag:
        #takeshot_flag = False
        #led.toggle()
    #machine.sleep()
    #print("awake!")
    time.sleep_ms(1000)
    led.toggle()
    time.sleep_ms(1000)

I tried initializing the interrupts in two ways, but neither seemed to work. I am currently using the Portenta H7 with the vision board attached to it. Any advice or guidance would be appreciated!

Try removing this:

    print("line =", line)

You can’t call any functions that allocate memory in callbacks.

I appreciate you responding. I added that line at some point because I saw it in example code somewhere.

I commented out that line of code but there’s no change in behavior; the LED blinks periodically, but triggering the pin still does not toggle the LED between the blinking. Therefore, I assume the callback isn’t being called.

May or may not be related, but I found a different post with a similar problem but on a different board:

The variable needs to be global only if you assign to it, and the global should be inside the function.

I updated the code to better demonstrate the issue:

import sensor, image, time, pyb, machine
from pyb import Pin, ExtInt


RED_LED_PIN = 1
GREEN_LED_PIN = 2
BLUE_LED_PIN = 3

led = pyb.LED(BLUE_LED_PIN)

flag = False
def callback(line):
    global flag
    flag = True

# Attempt 1
pin = Pin("PC7", Pin.IN, Pin.PULL_UP)
ext = ExtInt(pin, ExtInt.IRQ_FALLING, Pin.PULL_UP, callback)

#Attempt 2
#pin = machine.Pin("PC7", machine.Pin.IN, machine.Pin.PULL_UP)
#pin.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)

print("Initialized")

while (True):
    if flag:
        flag = False
        for i in range(1,10):
            led.toggle()
            time.sleep_ms(250)
    #print("awake!")
    time.sleep_ms(1000)
    led.toggle()
    time.sleep_ms(1000)
    
    machine.sleep()

Asserting ground on pin PC7 does wake up the Portenta, the LED toggles. However, the flag should also have been set to ‘True’, so I also expected the led to toggle quickly in the for loop. However, that never happens.

So it seems the the IRQ is setup correctly and the pin is accepting falling edge assertions that wake the device up, but the callback is not being called at all.

It’s not an issue with the example or your code, I tested the same script on one of our boards and it works fine, so it’s an issue with EXTI callback on the H747/Portenta.

I found an issue that I’ll fix later, but for now just avoid any pins from 5->9 for EXIT, for example if you use PJ11 it will work.

You’re awesome! Thank you.

1 Like

If you try the latest development release, PC7 should be working now, keep in mind you still need to remove the print from callback (and any code that allocates memory, directly or indirectly).

1 Like