Client-server package to remotely control a Raspberry Pi Pico W.
This package provides a client-server architecture to remotely control a Raspberry Pi Pico W. The server runs on the Pico W, handling direct hardware interaction, while the client runs on e.g. a Raspberrypi.
This design allows for lightweight "agents" (Pico W devices) to perform hardware-specific tasks, while the raspberrypi handles centralized orcheastration and higher-order logic.
For testing/debugging purposes, the server can also run on the raspberrypi itself.
The current security model assumes the LAN is secure. mTLS might be implemented later (if even possible on the Pico W).
To handle scenarios where the client-server connection is disrupted after an actuator has been activated, changing a pin state (write_pin
command) requires a timeout to be specified.
After the timeout, the server will revert the pin state to its previous value.
Initial pin state must be set upon pin setup (setup_pin
command).
This package has been tested and is known to work with the following versions:
- MicroPython: v1.23.0
- Firmware: v1.23.0 on 2024-06-02 (GNU 13.2.0 MinSizeRel)
- Python: 3.11
Install the package with pip
:
pip install piconetcontrol
-
Connect the PicoW to your laptop/desktop/raspberrypi via a cable (recommended: use a raspberrypi)
-
Run the setup CLI and follow the prompt:
piconetcontrol setup
This will install the firmware, connect the board to WiFi, generate SSL certificates and copy necessary files to run the server
Verify successful setup by checking the onboard LED's blinking patterns (see details below).
It is recommended to reserve a static IP for the Pico W, see your router's documentation. As of today, mDNS for using a hostname (instead of an IP) seems to not be supposed on Pico W.
We show a simple example both the shell and in Python.
$ python run_client.py 192.168.1.111 12345 -c action=setup_pin pin=2 mode=output value=0 \
-c action=read_pin pin=2 \
-c action=write_pin pin=2 value=1 timeout=5 \
-c action=read_pin pin=2
$ sleep 5 # wait for the write_pin timeout to expire
$ python run_client.py 192.168.1.111 12345 -c action=read_pin pin=2
from time import sleep
from piconetcontrol.client import Client
client = Client('192.168.1.111', 12345)
client.send_commands([
{"action": "setup_pin", "pin": 2, "mode": "output", "value": 0},
{"action": "read_pin", "pin": 2},
{"action": "write_pin", "pin": 2, "value": 1, "timeout": 5},
{"action": "read_pin", "pin": 2},
])
# wait for the write_pin timeout to expire
sleep(5)
client.send_commands([
{"action": "read_pin", "pin": 2},
])
The Pico W board is equipped with an LED that can be used to indicate the status of the server.
Status | Pattern |
---|---|
Connecting to WiFi | 3 blinks of 100ms, 200ms apart, then 1s pause |
Server Listening | Infinite blinks of 1.5s on, 1.5s off |
Ongoing Connection | Continuous 20ms blinks, 100ms apart |
If the board isn't blinking:
-
Server might not be running
-
Board might be in light or deep sleep mode
- If in light sleep, the server wakes up upon receiving a command
The server and the Raspberry Pi Pico W (client) communicate over a TCP/IP connection.
Message exchange occurs via JSON-encoded dictionaries.
Multiple instructions can be sent through a single connection,
a \n
EOF signal is used to indicate the end of a command.
This enables sending long messages more than 1024 bytes (the buffer size).
The client sends a \n\n
EOF signal to indicate no more commands are to be sent,
following what the server will close the connection.
Command | Description | JSON Structure | Response |
---|---|---|---|
Setup Pin | Configure a GPIO pin as input or output, optionally setting its value. |
|
Echoes back the command. |
Set Pin Value | Set a GPIO pin to a specified value (high or low) for a given duration. |
|
Echoes back the command (does not wait for timeout). |
Read Pin Value | Request the current value (high or low) of a GPIO pin. |
|
Echoes back the command and includes the value field (high/low). |
Command | Description | JSON Structure | Response |
---|---|---|---|
Reset Board | Reset the board using the machine.reset() method. |
|
Echoes back the command. |
Sleep for Low Power | Enter a low-power state for a specified duration. |
|
Echoes back the command. |
Get Resource Info | Request information about the client's resources (e.g., memory, CPU). |
|
Echoes back the command and includes the info field. |
Get Server Version | Request the version of the server software. |
|
Echoes back the command and includes the version field. |
List Actions | Request a list of available actions supported by the client. |
|
Echoes back the command and includes the actions field. |
Update Server Software | Instruct the client to update the server software. |
|
Updates the software and restarts the server. Reverts to the previous version on failure. |