> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Raspberry Pi Pico W Setup

> Step-by-step guide to running a Lua device on a Raspberry Pi Pico W

## Hardware List

| Item                    | Purpose                  | Notes                                 |
| ----------------------- | ------------------------ | ------------------------------------- |
| Raspberry Pi Pico W     | Main board               | Must be the **W** variant (with WiFi) |
| Micro-USB cable         | Power and programming    | Data-capable, not charge-only         |
| DHT22 sensor (optional) | Temperature and humidity | Connect to GP15 with 10k pull-up      |
| LED (optional)          | Status indicator         | Onboard LED works for basic use       |
| Breadboard + jumpers    | Wiring                   | For connecting sensors                |

## Setup with Thonny

<Steps>
  <Step title="Install Thonny IDE">
    Download [Thonny](https://thonny.org/) for your operating system. Thonny has built-in MicroPython support for the Pico W.
  </Step>

  <Step title="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](https://micropython.org/download/RPI_PICO_W/)
    5. Drag the `.uf2` file onto the Pico USB drive
    6. The Pico reboots automatically with MicroPython
  </Step>

  <Step title="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
  </Step>

  <Step title="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
  </Step>

  <Step title="Configure WiFi credentials">
    Create a `config.py` file on the Pico with your WiFi and Lua credentials:

    ```python theme={null}
    # 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"
    ```

    <Warning>
      Keep `config.py` on the Pico only. Do not commit WiFi passwords or API keys to version control.
    </Warning>
  </Step>

  <Step title="Create main.py">
    Create the main application file. This runs automatically when the Pico boots:

    ```python theme={null}
    # 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()
    ```
  </Step>

  <Step title="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?
       ```
  </Step>
</Steps>

## 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

<AccordionGroup>
  <Accordion title="Pico does not appear as USB drive">
    * 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
  </Accordion>

  <Accordion title="WiFi connection fails">
    * 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
  </Accordion>

  <Accordion title="MQTT connection fails">
    * Verify `agent_id` and `api_key` in `config.py`
    * Check WiFi is connected first (`wlan.isconnected()`)
    * Ensure port 443 (WebSocket) is not blocked by your network
    * Try `device = LuaDevice(..., use_ssl=False)` temporarily for debugging
  </Accordion>

  <Accordion title="MemoryError during operation">
    * 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)
  </Accordion>

  <Accordion title="Device connects but commands do not work">
    * 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
  </Accordion>

  <Accordion title="DHT22 sensor not reading">
    * 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
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="MicroPython Client" icon="microchip" href="/devices/micropython-client">
    Full LuaDevice class reference
  </Card>

  <Card title="Factory Monitor" icon="industry" href="/devices/examples/industrial-sensor">
    Industrial monitoring example on Pico W
  </Card>

  <Card title="MQTT Transport" icon="tower-broadcast" href="/devices/mqtt-client">
    MQTT topic structure and QoS details
  </Card>

  <Card title="Triggers" icon="bolt" href="/devices/triggers">
    Send events from the Pico W to your agent
  </Card>
</CardGroup>
