Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 7503

General • Using PIO to trigger external Pico reset aka watchdog

$
0
0
I made a solar powered temperature sensor using Micropython on a Pico W and have been using a NANO Timer on my Pico W solar powered sensor to conserve battery power.

However, if the program hangs then the DONE signal is not sent to the NANO Timer and the battery power is consumed until a board reset enables the proper running of the program.
I tried using the onboard WatchDog Timer, but it has a maximum timeout of 8331 ms. Which made debugging difficult.
Eventually I found that there was some sort of problem with the Micropython sleep() function and WiFI.

I decided to try and create a PIO trigger to reset the NANO Timer. Not knowing much about PIO I used Google Gemini as coding buddy (with a Youtube channel 'Life with David' ) and was able to create a basic countdown timer. It worked as a one time trigger, but I couldn’t reset (feed) the countdown. My problem was not clearing the OSR, but with the help of the forum post viewtopic.php?t=347682#p2082827 Iwas able to implement a suitable countdown timer that could be fed like a watchdog timer.

The following is my implementation of a PIO based countdown timer that can be used to trigger an action such as a DONE signal for the NANO Timer or a reset to external circuitry on the RUN pin of the Pico. The following article has been useful for implementing that on a powered Pico, viewtopic.php?t=308166&start=25

Code:

# PIO_delay.py## Uses the PIO to generate a delayed trigger HIGH on pin.# Can use as a reset with external circuit, even when main loop fails (hangs)#import rp2import utimefrom machine import Pin@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW, autopull=True)def PIO_watchdog(): # Will set a pin high after it has countdown to zero. Can be restarted with new loop count.    # --- Initialization ---    #  Pull a 32-bit loop count from the FIFO into the OSR.    pull()  # Load initial loop count into OSR. Auto pull will load values after PIO starts        label("data_available") # used when not_osre -> OSR is NOT empty and has new value    # Get latest loop count. Clear the OSR so that it only becomes non-empty when new data is provided.    out(x, 32)    # Output into X register from OSR (clearing it); FIFO now empty.    # --- Main Delay Loop ---    label("wait_delay")    # Check if new delay data is available in the FIFO:    jmp(not_osre, "data_available")  # If OSR is filled (new data available), jump to reload branch.        # No new data: continue countdown.    jmp(x_dec, "wait_delay")  # Decrement X and loop until it reaches zero.        # When countdown reaches zero, trigger the event.    set(pins, 1) # Set the output pin HIGH (triggers the external reset circuit).    DEBUG_PIO_DELAY = True#DEBUG_PIO_DELAY = Falsedef calculate_delay_count(delay_seconds, PIO_freq):    # Calculate the value to send to the PIO    # Delay loop takes 2 cycles (each jmp instruction takes 1 cycle)    # Target loop Count = delay_secs (seconds) * PIO_freq (cycles/seconds) / 2 cycles    loop_count_for_pio = int(delay_seconds * (PIO_freq /2))    if DEBUG_PIO_DELAY:        print(f'Required delay {delay_seconds} seconds, PIO Clock frequency: {PIO_freq}, calculated delay value {loop_count_for_pio}')    return loop_count_for_pio    # -------------------------------------------------# Helper funtion enable_PIO_watchdog sets up the PIO and calculates delay countdef enable_PIO_watchdog(delay_seconds=100, trigger_pin=Pin(22, Pin.OUT)):    #set pin low    trigger_pin.low()    # Use a PIO frequency that works for the delay calculation    PIO_freq = 100_000    # Get the PIO instance and load the program    sm = rp2.StateMachine(0, PIO_watchdog, freq=PIO_freq, set_base=trigger_pin)    if DEBUG_PIO_DELAY:        print(f'Trigger Pin is {trigger_pin}')        # calculate the loop count for the required delay     loop_count_for_pio = calculate_delay_count(delay_seconds, PIO_freq)    # Run the state machine    sm.active(1)    # Put the loop count into the PIO's TX FIFO    # The PIO will pull this value then start, subsequent puts are auto pulled    sm.put(loop_count_for_pio)        # return state machine instance and calculated delay for later use if needed    return sm, loop_count_for_pio# -------------------------------------------------# Helper function feed_watchdog wraps the PIO state machine put function for readiabilitydef feed_watchdog(sm, delay_count):    sm.put(delay_count)# --- Example Usage ---if __name__ == "__main__":    # Define the pin for the watchdog trigger    WATCHDOG_PIN = Pin(22, Pin.OUT)     import time    start_tick_ms = time.ticks_ms()    sm, delay_count = enable_PIO_watchdog(trigger_pin=WATCHDOG_PIN, delay_seconds=20)    # Main loop: Feed the watchdog every defined interval    while True:        utime.sleep_ms(2000)        elapsed_time = (time.ticks_ms()-start_tick_ms)/1000        print(" Time ", elapsed_time)                if int(elapsed_time) <= 10:            # feeds the watch dog, can change delay count to expected max time in each section            feed_watchdog(sm, delay_count) # helper function for sm.put(delay_count)


The NANO Timer can be found at https://core-electronics.com.au/makerve ... -pico.html

In one application I cut the header pin that connects to the Pico VBUS so I could connect a solar panel to the VBUS pin on the NANO Timer. and use the board's charging circuit for a LiPo.

Not sure if this is of any value, but I had to learn a lot to get this all done and it was from others posting that I was able to solve my problems.

I found the Youtube channel 'Life with David' specifically his playlist 'Raspberry PI Pico PIO' https://www.youtube.com/playlist?list=P ... 2NUmk_mtEI

There is a specific clip on PIO Interrupts
https://youtu.be/AaxrtL4SZHQ?si=tr2xIKqTy9-AQu6g
I used interrupts from the PIO and outputting numbers to be able to debug/track the PIO program.

Thanks to all that contribute to shared knowledge and experience.

Statistics: Posted by PicoP — Sat Jul 12, 2025 5:12 am — Replies 0 — Views 28



Viewing all articles
Browse latest Browse all 7503

Trending Articles