Skip to main content

Hardware List

ItemPurposeNotes
Raspberry Pi Pico WMain boardMust be the W variant (with WiFi)
Micro-USB cablePower and programmingData-capable, not charge-only
DHT22 sensor (optional)Temperature and humidityConnect to GP15 with 10k pull-up
LED (optional)Status indicatorOnboard LED works for basic use
Breadboard + jumpersWiringFor connecting sensors

Setup with Thonny

1

Install Thonny IDE

Download Thonny for your operating system. Thonny has built-in MicroPython support for the Pico W.
2

Flash MicroPython firmware

  1. Hold the BOOTSEL button on the Pico W
  2. While holding, connect the USB cable to your computer
  3. Release BOOTSEL — the Pico appears as a USB drive
  4. Download the latest .uf2 firmware from micropython.org/download/RPI_PICO_W
  5. Drag the .uf2 file onto the Pico USB drive
  6. The Pico reboots automatically with MicroPython
3

Configure Thonny for Pico W

  1. Open Thonny
  2. Go to Tools > Options > Interpreter
  3. Select MicroPython (Raspberry Pi Pico)
  4. Select the correct port (usually auto-detected)
  5. Click OK
  6. You should see the MicroPython REPL in the bottom panel
4

Upload the Lua device library

  1. Open lua_device.py in Thonny
  2. Go to File > Save as…
  3. Select Raspberry Pi Pico as the target
  4. Save as lua_device.py on the Pico
5

Configure WiFi credentials

Create a config.py file on the Pico with your WiFi and Lua credentials:
# config.py -- save this to the Pico
WIFI_SSID = "YOUR_WIFI_NETWORK"
WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"
LUA_AGENT_ID = "your-agent-id"
LUA_API_KEY = "your-api-key"
LUA_DEVICE_NAME = "pico-sensor"
Keep config.py on the Pico only. Do not commit WiFi passwords or API keys to version control.
6

Create main.py

Create the main application file. This runs automatically when the Pico boots:
# main.py -- save this to the Pico
import network
import machine
import time
import config

# -- WiFi connection --
led = machine.Pin("LED", machine.Pin.OUT)
led.off()

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(config.WIFI_SSID, config.WIFI_PASSWORD)

print("Connecting to WiFi...")
timeout = 30
while not wlan.isconnected() and timeout > 0:
    led.toggle()
    time.sleep(0.5)
    timeout -= 1

if not wlan.isconnected():
    print("WiFi connection failed!")
    # Blink rapidly to indicate error
    for _ in range(20):
        led.toggle()
        time.sleep_ms(100)
    machine.reset()

led.on()
print("WiFi connected:", wlan.ifconfig()[0])

# -- Optional: DHT22 sensor --
try:
    import dht
    dht_sensor = dht.DHT22(machine.Pin(15))
    has_dht = True
    print("DHT22 sensor detected on GP15")
except Exception:
    has_dht = False
    print("No DHT22 sensor -- using simulated values")

# -- Device setup --
from lua_device import LuaDevice

device = LuaDevice(
    agent_id=config.LUA_AGENT_ID,
    api_key=config.LUA_API_KEY,
    device_name=config.LUA_DEVICE_NAME,
    server="mqtt.heylua.ai",
)

@device.command("led_on")
def led_on(payload):
    led.on()
    return {"status": "on"}

@device.command("led_off")
def led_off(payload):
    led.off()
    return {"status": "off"}

@device.command("blink")
def blink(payload):
    count = payload.get("count", 3)
    for _ in range(count):
        led.on()
        time.sleep_ms(200)
        led.off()
        time.sleep_ms(200)
    led.on()  # leave on (connected state)
    return {"blinked": count}

@device.command("read_environment")
def read_environment(payload):
    if has_dht:
        dht_sensor.measure()
        return {
            "temperature": dht_sensor.temperature(),
            "humidity": dht_sensor.humidity(),
            "source": "DHT22",
        }
    else:
        return {
            "temperature": 22.0 + (time.ticks_ms() % 50) / 10,
            "humidity": 55 + (time.ticks_ms() % 200) / 10,
            "source": "simulated",
        }

@device.command("system_info")
def system_info(payload):
    import gc
    gc.collect()
    return {
        "free_memory": gc.mem_free(),
        "ip_address": wlan.ifconfig()[0],
        "rssi": wlan.status("rssi"),
        "uptime_ms": time.ticks_ms(),
    }

# -- Connect and run --
device.connect()
print("Lua device connected -- listening for commands")

device.run()
7

Run and test

  1. Click the green Run button in Thonny (or press F5)
  2. You should see:
    Connecting to WiFi...
    WiFi connected: 192.168.1.42
    DHT22 sensor detected on GP15
    [lua-device] Connected as pico-sensor
    Lua device connected -- listening for commands
    [lua-device] Listening for commands...
    
  3. Open lua chat in your terminal and try:
    > Turn on the LED on pico-sensor
    > Read the environment from pico-sensor
    > Blink the LED 5 times
    > What's the system info on pico-sensor?
    

File Structure on Pico

After setup, the Pico should have these files:
/
├── lua_device.py      # Lua device client library
├── config.py          # WiFi and API credentials
└── main.py            # Your application (runs on boot)

Troubleshooting

  • Make sure you are holding BOOTSEL before plugging in the USB cable
  • Try a different USB cable (some are charge-only, not data)
  • Try a different USB port on your computer
  • Pico W only supports 2.4 GHz WiFi (not 5 GHz)
  • Check SSID and password in config.py (case-sensitive)
  • Move the Pico closer to the router
  • Check wlan.status() for error codes: -1 = connection failed, -2 = no matching SSID, -3 = auth failed
  • Verify agent_id and api_key in config.py
  • Check WiFi is connected first (wlan.isconnected())
  • Ensure port 8883 is not blocked by your network
  • Try device = LuaDevice(..., use_ssl=False) temporarily for debugging
  • Add import gc; gc.collect() periodically in your code
  • Compile lua_device.py to bytecode: mpy-cross lua_device.py, then copy lua_device.mpy
  • Reduce payload sizes in command responses
  • Keep the dedup cache small (it auto-cleans at 100 entries)
  • Check the REPL output for error messages
  • Verify command names match between the handler and what the agent expects
  • Ensure device.run() is being called (it is the message processing loop)
  • Check that device.connect() completed without errors
  • Check wiring: data pin to GP15, 10k pull-up resistor between data and 3.3V
  • DHT22 requires at least 2 seconds between readings
  • Try dht_sensor.measure() in the REPL first to verify

Next Steps

MicroPython Client

Full LuaDevice class reference

Factory Monitor

Industrial monitoring example on Pico W

MQTT Transport

MQTT topic structure and QoS details

Triggers

Send events from the Pico W to your agent