Pico/micropython Switch callbacks

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
JaqueBullet
Posts: 2
Joined: Wed Apr 28, 2021 5:17 pm

Pico/micropython Switch callbacks

Post by JaqueBullet » Wed Apr 28, 2021 5:48 pm

Hi,
I thought I would try a Pico to power a number of led circuits to light a model. I have managed to get a set of leds to power on and another set to flash via a while true loop. I have tried to expand this to work off a momentary switch - as a test I tried this code (to switch on an led, pause, then switch on some flashing leds and then switch everything off :

Code: Select all

from machine import Pin
import utime

button = Pin(14, Pin.IN, Pin.PULL_DOWN)

deck_lights = Pin(13, Pin.OUT)
nav_lights = Pin(15, Pin.OUT)

def button_callback(pin):
    # Switch on the deck lights
    deck_lights.value(1)
    utime.sleep(2)
    i = 0
    while i < 10:
        nav_lights.value(0)
        utime.sleep(1)
        nav_lights.value(1)
        utime.sleep(0.1)
        i+=1
    nav_lights.value(0)   
    utime.sleep(2)
    deck_lights.value(0)
    
button.irq(button_callback, Pin.IRQ_FALLING)
However, I tried to get clever and it all went wrong! I defined a global 'lights' and set it to True; I changed the while loop to read "while lights" - this ran OK but obviously never ended. So I set up another switch and coded that to change the value of the global to False hoping that it would stop the while loop. But it didn't. Can someone tell me the behaviour of the callbacks? If I press the switch that starts the lights running, does the program get 'stuck' in the while loop and not recognise the press of the second button?

Any help would be appreciated! Sorry, but I lost the code showing both buttons (but I'll recreate it and paste here if required)

Thanks,

Steve

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Pico/micropython Switch callbacks

Post by pythoncoder » Thu Apr 29, 2021 1:20 pm

I'm afraid there is a lot wrong with that solution. Writing firmware (in any language) involves a significant learning curve.

As a first step you should read this doc detailing the use of interrupts. Secondly, read - or at least take in the gist of - this which explains contact bounce, an issue with mechanical switches. Finally you might want to read this which explains how to use uasyncio and details a Switch class: this class enables you to associate a callback with a switch in a way which copes with contact bounce.
Peter Hinch
Index to my micropython libraries.

JaqueBullet
Posts: 2
Joined: Wed Apr 28, 2021 5:17 pm

Re: Pico/micropython Switch callbacks

Post by JaqueBullet » Thu Apr 29, 2021 2:25 pm

I was just trying to expand on things from the 'Official Raspberry Pi Pico Guide' ..... :(

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Pico/micropython Switch callbacks

Post by pythoncoder » Fri Apr 30, 2021 10:19 am

There is no escaping the fact that using interrupts requires some know-how. Putting delays in an interrupt service routine is a bad idea, and you need to consider the fact that contact bounce could (almost certainly will) cause the interrupt to occur multiple times.

You could write code which checks the switch state periodically. This would avoid any need for interrupts.
Peter Hinch
Index to my micropython libraries.

rafl
Posts: 10
Joined: Tue Mar 23, 2021 7:15 am

Re: Pico/micropython Switch callbacks

Post by rafl » Fri Apr 30, 2021 6:48 pm

pythoncoder wrote:
Fri Apr 30, 2021 10:19 am
Putting delays in an interrupt service routine is a bad idea
Aren't these callbacks just scheduled for execution outside of the ISR context with mp_sched_schedule anyway?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Pico/micropython Switch callbacks

Post by pythoncoder » Sat May 01, 2021 11:13 am

This depends on the hardware platform. ESP32 and ESP8266 use soft IRQ's only. Bare metal platforms can run hard IRQ's.
Peter Hinch
Index to my micropython libraries.

Post Reply