A Raspberry Pi Pico W can put live sensor data on a cloud dashboard with a few lines of MicroPython — no MQTT broker, no SDK. You POST JSON to one HTTPS endpoint and poll a second one for commands. This guide builds the whole loop against a real backend (nodrix, which deploys to your own Cloudflare account), using the Pico W’s own onboard temperature sensor so you can run it with no wiring at all. Variables appear on your dashboard the first time they’re seen.
The mental model
The board is just a bag of variables:
- Telemetry (up): POST
{"metrics": {"temperature": 23.4}}; each key becomes a variable. - Control (down): a dashboard toggle or an automation queues a write — “set
ledtoon”. The board fetches pending writes, applies them, and acks.
Two endpoints, one token.
Step 1 — Connect Wi-Fi
import network, time, ujson, urequests
from machine import Pin, ADC, deepsleep
SSID = "your-ssid"
PASS = "your-password"
HOST = "https://nodrix.you.workers.dev"
TOKEN = "tok_your_project_token"
HEADERS = {"Authorization": "Bearer " + TOKEN, "Content-Type": "application/json"}
def connect_wifi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASS)
while not wlan.isconnected():
time.sleep(0.25)
print("Wi-Fi up:", wlan.ifconfig()[0])
return wlan
Step 2 — Read a sensor and POST it
No external sensor needed to start: the RP2040 has an onboard temperature sensor on ADC channel 4.
def read_temp_c():
raw = ADC(4).read_u16() * 3.3 / 65535
return 27 - (raw - 0.706) / 0.001721 # datasheet conversion
def send_telemetry(metrics):
body = ujson.dumps({"metrics": metrics})
r = urequests.post(HOST + "/v1/telemetry", headers=HEADERS, data=body)
print("POST /v1/telemetry ->", r.status_code) # 204 = success
r.close() # always close — frees the socket
Open your dashboard and the temperature variable is already there. Drop a value or gauge
widget on it and you’re watching live data; the chart widget plots a time window.
Always call
r.close()after a urequests call. The Pico W has limited sockets, and leaking them is the most common reason a long-running script stops sending after a while.
Step 3 — Receive commands back
The board asks for pending commands and applies them. The Pico W’s onboard LED is a perfect test
output — it’s addressed as Pin("LED").
def poll_control():
r = urequests.get(HOST + "/v1/control", headers=HEADERS)
if r.status_code == 200:
data = r.json()
# { "control": [ { "id": "ctl_x", "variable": "led", "value": "on" } ] }
for w in data.get("control", []):
if w["variable"] == "led":
Pin("LED", Pin.OUT).value(1 if w["value"] == "on" else 0)
# POST w["id"] to /v1/control/ack so the platform stops resending it
r.close()
Toggle the led variable from a dashboard control widget and the onboard LED follows. Poll every few
seconds for near-real-time control.
Step 4 — The main loop (and an honest note on sleep)
On mains power, a simple loop is fine:
connect_wifi()
while True:
send_telemetry({"temperature": read_temp_c()})
poll_control()
time.sleep(15)
For battery, you can deep sleep instead — but be realistic about the RP2040. machine.deepsleep
resets the board and re-runs your script from the top on wake, like an ESP, yet its sleep-current
floor is higher than an ESP32’s, so the same duty cycle gives shorter battery life:
connect_wifi()
send_telemetry({"temperature": read_temp_c()})
poll_control()
deepsleep(15 * 60 * 1000) # milliseconds; board resets and re-runs on wake
If long battery life is the goal, an ESP32 or ESP8266 with deep sleep will outlast a Pico W. The Pico W is at its best on mains power, short missions, or where you specifically want MicroPython and the RP2040’s PIO.
Production checklist
- Verify TLS for anything sensitive. urequests encrypts but doesn’t authenticate the server by
default — pass an
SSLContextloaded with the server certificate if confidentiality isn’t enough. - Close every response.
r.close()after each call; leaking sockets is the classic Pico W bug. - Wrap network calls in try/except. Wi-Fi blips happen — catch the exception, back off, and retry rather than crashing the script.
- Keep the token secret. The project token is a credential; keep it out of shared code.
That’s a Pico W reporting to a dashboard you own, with commands flowing back — and the read API behind it means you can pull the same telemetry into Grafana or your own app whenever you like.