picocalc-network

This skill should be used when the user asks to build WiFi or BLE networking features for PicoCalc, mentions "WiFi for PicoCalc", "BLE feature", "Bluetooth PicoCalc", "network connectivity", "WiFi scanning", "connect to WiFi", "BLE file transfer", "wireless PicoCalc", "ProxiScan", "FoxHunt", or wants to add any network/wireless functionality to a PicoCalc application.

Build PicoCalc Network Features

Implement WiFi and BLE connectivity on the Pico 2W for the PicoCalc platform.

WiFi Pattern

import network
import time

wlan = network.WLAN(network.STA_IF)
wlan.active(True)

# Scan
results = wlan.scan()  # [(ssid, bssid, channel, rssi, security, hidden), ...]

# Connect with timeout
wlan.connect(ssid, password)
timeout = 10
while timeout > 0 and not wlan.isconnected():
    time.sleep(1)
    timeout -= 1

if wlan.isconnected():
    ip, subnet, gateway, dns = wlan.ifconfig()

Credential Storage (brad.py pattern)

import json
def save_wifi(ssid, password):
    with open('wifi.json', 'w') as f:
        json.dump({"ssid": ssid, "password": password}, f)

def load_wifi():
    try:
        with open('wifi.json', 'r') as f:
            return json.load(f).get("ssid",""), json.load(f).get("password","")
    except:
        return "", ""

Retry Pattern

for attempt in range(3):
    try:
        results = wlan.scan()
        if results: break
    except OSError:
        wlan.active(False)
        time.sleep(0.5)
        wlan.active(True)
        time.sleep(0.5)

BLE Pattern

import bluetooth
from micropython import const

_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)

ble = bluetooth.BLE()
ble.active(True)

# Nordic UART Service UUIDs
NUS_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
NUS_RX   = bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
NUS_TX   = bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")

BLE Scanning

def ble_irq(event, data):
    if event == _IRQ_SCAN_RESULT:
        addr_type, addr, adv_type, rssi, adv_data = data
        # Parse advertisement for device name, RSSI, MAC
    elif event == _IRQ_SCAN_DONE:
        pass

ble.irq(ble_irq)
ble.gap_scan(duration_ms, interval_us, window_us)

Critical Constraints

  • WiFi and BLE coexist on Pico 2W but consume significant memory
  • Call gc.collect() before/after network operations
  • Always handle OSError (interface may be busy)
  • BLE MTU typically 200-512 bytes; use chunked transfer for files
  • Never hardcode credentials; use wifi.json
  • Derive BLE device name from MAC suffix for uniqueness

Additional Resources