Hi everyone,
I'm working on a project with a Raspberry Pi Pico W where I need to control a set of sump pumps using sensors and relays. The idea/goal is to use the PIO to handle the timing and control of these pumps so that they continue operating even if higher-level code (handling Wi-Fi connectivity, sending status emails, etc.) crashes or is interrupted. This would be an improved version that previously used an Arduino for pump control and a Pi W Zero for notifications, but I was attracted to the Pico for its simplicity, and wanted to learn about the PIO system anyway. The autonomous nature of the PIOs seemed to lend itself to the idea of reliability for the pumps in case the rest of the system crashed.
Here's the setup:
Each pump has a water sensor and a relay.
Sensors are normally high, and the pumps should trigger when the sensors go low.
I need the relays to switch on and off based on the sensor inputs.
The timing involved in controlling the relays needs to be on the order of several seconds to minutes.
Issue:
I've been trying to use PIO for this purpose, but I'm encountering issues with achieving long delays. The PIO seems to be toggling the relays at either incredibly slow rates or MHz speeds, and nothing in between, and I'm struggling to get it to handle the required delays... Things which are normally very simple in Micropython proper: On when water is detected, off when water is no longer detected (ideally with a 5-second delay or so after the water sensor clears), and debouncing of the sensors.
What I've Tried:
Basic PIO Program: Simple program to toggle relays based on button presses.
Using Debouncing: Added debouncing logic but still faced issues with the timing.
Combining PIO and Timer: Used a Micropython timer to trigger the PIO, which helped but defeated the purpose.
Direct Control via Python: Moved the timing logic to Python with PIO only detecting button presses, but this also still relies on crashable code, and doesn't put the pump logic entirely into the PIOs.
Requirements:
The PIO should handle the full pump timing and control to ensure continuous operation of the pumps, despite higher-level code issues.
Delays and toggling should be reliable over long periods (seconds to minutes).
Sensors should be debounced to avoid false triggers.
Example Code:
I'm clearly doing something wrong, but here's a simplified example of what I have currently tried with the PIO, in MicroPython. I was trying more complex ideas but kept working backwards when they didn't work, and found that I couldn't even get a proof of concept working correctly, where pressing buttons toggles the relays on and off:
Pretty much any time I try to involve any timing within the PIO code, things fall apart. Probably because of the relatively huge delays involved?
Questions:
How can I achieve reliable, long delays (seconds to minutes) with PIO?
Is there a way to debounce the sensor inputs directly within the PIO to avoid false triggers?
Are there any examples or best practices for using PIO to handle such long-duration tasks?
Any guidance, suggestions, or examples would be greatly appreciated!
Thank you!
I'm working on a project with a Raspberry Pi Pico W where I need to control a set of sump pumps using sensors and relays. The idea/goal is to use the PIO to handle the timing and control of these pumps so that they continue operating even if higher-level code (handling Wi-Fi connectivity, sending status emails, etc.) crashes or is interrupted. This would be an improved version that previously used an Arduino for pump control and a Pi W Zero for notifications, but I was attracted to the Pico for its simplicity, and wanted to learn about the PIO system anyway. The autonomous nature of the PIOs seemed to lend itself to the idea of reliability for the pumps in case the rest of the system crashed.
Here's the setup:
Each pump has a water sensor and a relay.
Sensors are normally high, and the pumps should trigger when the sensors go low.
I need the relays to switch on and off based on the sensor inputs.
The timing involved in controlling the relays needs to be on the order of several seconds to minutes.
Issue:
I've been trying to use PIO for this purpose, but I'm encountering issues with achieving long delays. The PIO seems to be toggling the relays at either incredibly slow rates or MHz speeds, and nothing in between, and I'm struggling to get it to handle the required delays... Things which are normally very simple in Micropython proper: On when water is detected, off when water is no longer detected (ideally with a 5-second delay or so after the water sensor clears), and debouncing of the sensors.
What I've Tried:
Basic PIO Program: Simple program to toggle relays based on button presses.
Using Debouncing: Added debouncing logic but still faced issues with the timing.
Combining PIO and Timer: Used a Micropython timer to trigger the PIO, which helped but defeated the purpose.
Direct Control via Python: Moved the timing logic to Python with PIO only detecting button presses, but this also still relies on crashable code, and doesn't put the pump logic entirely into the PIOs.
Requirements:
The PIO should handle the full pump timing and control to ensure continuous operation of the pumps, despite higher-level code issues.
Delays and toggling should be reliable over long periods (seconds to minutes).
Sensors should be debounced to avoid false triggers.
Example Code:
I'm clearly doing something wrong, but here's a simplified example of what I have currently tried with the PIO, in MicroPython. I was trying more complex ideas but kept working backwards when they didn't work, and found that I couldn't even get a proof of concept working correctly, where pressing buttons toggles the relays on and off:
Code:
import rp2from machine import Pin, Timerimport time# Define pins for relays and sensorsPINS = [ {'relay': 21, 'sensor': 18}, # Relay 1 and its sensor pin {'relay': 20, 'sensor': 17}, # Relay 2 and its sensor pin {'relay': 19, 'sensor': 16} # Relay 3 and its sensor pin]# Initialize devicesdevices = []# Define PIO program for controlling relays based on sensor inputs@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)def relay_control(): wrap_target() wait(1, pin, 0) # Wait for sensor to go low (water detected) set(pins, 1) # Turn on relay mov(x, 31250000) # Load x with delay count for debounce (~0.25s at 1 MHz) label("debounce") jmp(x_dec, "debounce") wait(0, pin, 0) # Wait for sensor to go high (water no longer detected) set(pins, 0) # Turn off relay mov(x, 31250000) # Load x with delay count for debounce (~0.25s at 1 MHz) label("debounce_off") jmp(x_dec, "debounce_off") wrap()# Initialize each relay, sensor, and state machinedef init_device(i, pins): relay_pin = Pin(pins['relay'], Pin.OUT) sensor_pin = Pin(pins['sensor'], Pin.IN, Pin.PULL_UP) sm = rp2.StateMachine(i, relay_control, in_base=sensor_pin, out_base=relay_pin, set_base=relay_pin, freq=1_000_000) sm.active(1) print(f"State machine {i} is active for relay {pins['relay']} and sensor pin {pins['sensor']}") devices.append({ 'relay': relay_pin, 'sensor': sensor_pin, 'sm': sm })# Initializefor i, pins in enumerate(PINS): init_device(i, pins)# Debug loop, print relay stateswhile True: for i, device in enumerate(devices): relay_state = device['relay'].value() print(f"Relay {i+1} (Pin {PINS[i]['relay']}): {relay_state}") time.sleep(1)
Questions:
How can I achieve reliable, long delays (seconds to minutes) with PIO?
Is there a way to debounce the sensor inputs directly within the PIO to avoid false triggers?
Are there any examples or best practices for using PIO to handle such long-duration tasks?
Any guidance, suggestions, or examples would be greatly appreciated!
Thank you!
Statistics: Posted by Darkhand — Sat Aug 03, 2024 5:27 am — Replies 2 — Views 69