Page 1 of 1

Pico/micropython Switch callbacks

Posted: Wed Apr 28, 2021 5:48 pm
by JaqueBullet
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

Re: Pico/micropython Switch callbacks

Posted: Thu Apr 29, 2021 1:20 pm
by pythoncoder
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.

Re: Pico/micropython Switch callbacks

Posted: Thu Apr 29, 2021 2:25 pm
by JaqueBullet
I was just trying to expand on things from the 'Official Raspberry Pi Pico Guide' ..... :(

Re: Pico/micropython Switch callbacks

Posted: Fri Apr 30, 2021 10:19 am
by pythoncoder
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.

Re: Pico/micropython Switch callbacks

Posted: Fri Apr 30, 2021 6:48 pm
by rafl
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?

Re: Pico/micropython Switch callbacks

Posted: Sat May 01, 2021 11:13 am
by pythoncoder
This depends on the hardware platform. ESP32 and ESP8266 use soft IRQ's only. Bare metal platforms can run hard IRQ's.