circuitpython-runner

star 2

Run CircuitPython code on a connected CircuitPython device and read the output. Use when testing CircuitPython code, debugging hardware interactions, or working with microcontrollers.

adafruit By adafruit schedule Updated 6/5/2026

name: circuitpython-runner description: Run CircuitPython code on a connected CircuitPython device and read the output. Use when testing CircuitPython code, debugging hardware interactions, or working with microcontrollers. license: MIT metadata: version: "1.0" requires: ["python3", "circuitpython device"]

CircuitPython Runner Skill

This skill enables you to run CircuitPython code on a connected CircuitPython device and capture the output.

When to Use This Skill

Use this skill when you need to:

  • Test CircuitPython code on actual hardware
  • Debug sensor readings or hardware interactions
  • Prototype microcontroller applications
  • Verify CircuitPython library functionality
  • Run code that requires physical hardware (displays, sensors, LEDs, etc.)

Requirements

  • Python 3 installed on the host system

USB Workflow Runner

  • A CircuitPython-compatible device connected and mounted
  • pyserial installed inside the python virtual environment
  • The circuitpython_usb_runner.py script available in the skills scripts/ directory

Web Workflow Runner

  • A CircuitPython-compatible device accessible over the local network
  • circup, websocket-client, and requests installed inside the python virtual environment
  • The circuitpython_web_runner.py script available in the skills scripts/ directory

How It Works

For the USB Workflow: The CircuitPython device appears as a USB drive. Run the usb_runner script to copy a code file to the device, execute it on the CircuitPython device and capture serial output. For the Web Workflow: The CircuitPython device hosts an HTTP server with API for modifying files, and a websocket connection for communicating serial output. Run the web_runner script to copy a code file to the device, execute it, and capture the serial output.

Usage Instructions

Step 1: Write the CircuitPython Code

Save your CircuitPython code to a local file in the working directory.

Example:

# Simple blink example
import time
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

for i in range(5):
    led.value = True
    print(f"LED ON - iteration {i+1}")
    time.sleep(0.5)
    led.value = False
    print(f"LED OFF - iteration {i+1}")
    time.sleep(0.5)

print("Done!")

Step 2: Use One Of the Runner Scripts

After saving the code, run the circuitpython_usb_runner.py or circuitpython_web_runner.py script to copy the code, execute it and capture the device's output:

python3 circuitpython_usb_runner.py the_code_file.py
python3 circuitpython_web_runner.py the_code_file.py

The script will:

  1. Copy the file specified in the filename argument to the CircuitPython device.
  2. Connect to the CircuitPython device's serial port or websocket. Default is serial port is /dev/ttyACM0, use --port to change.
  3. Run the code by issuing ctrl+C and ctrl+D inputs
  4. Capture and display all printed output
  5. Return after 10 seconds or the time specified by the --duration argument

Complete Workflow Example

# 1. Save your code to a local file
cat > example_code.py << 'EOF'
import time
print("Hello from CircuitPython!")
for i in range(3):
    print(f"Count: {i}")
    time.sleep(1)
print("Goodbye!")
print("~~END~~")
EOF

# 2. Run the output reader
# USB:
python3 circuitpython_usb_runner.py example_code.py
# Web:
python3 circuitpython_web_runner.py --host 192.168.1.122 --password $CIRCUITPYTHON_WW_PASSWORD example_code.py

Common Patterns

End Print

Put at the end of CircuitPython test scripts so that the runner script will be able to return without waiting the full duration when possible.

print("~~END~~")

Sensor Reading

import board
import adafruit_dht

dht = adafruit_dht.DHT22(board.D4)
try:
    temperature = dht.temperature
    humidity = dht.humidity
    print(f"Temp: {temperature}°C, Humidity: {humidity}%")
except RuntimeError as e:
    print(f"Error reading sensor: {e}")
print("~~END~~")

I2C Device Communication

import board
import busio

i2c = busio.I2C(board.SCL, board.SDA)
while not i2c.try_lock():
    pass

print("I2C devices found:", [hex(addr) for addr in i2c.scan()])
i2c.unlock()
print("~~END~~")

NeoPixel Control

import board
import neopixel

pixels = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)
pixels[0] = (255, 0, 0)  # Red
print("NeoPixel set to red")
print("~~END~~")

Tips and Best Practices

  1. Always include print statements - The output reader captures printed text, so add informative print statements to track execution
  2. Handle errors gracefully - Use try-except blocks to catch and report errors without crashing
  3. Keep code concise - CircuitPython devices have limited memory; keep your test code focused
  4. Add delays when needed - Some hardware operations need time to complete; use time.sleep() appropriately
  5. Import only what you need - Minimize imports to reduce memory usage
  6. print("~~END~~") at end of scripts - Print this string to help the runner script finish faster when possible.

Common Edge Cases

  • Device not mounted: If CIRCUITPY/ is not accessible, as the user to check that the device is properly connected and recognized by the system
  • Permission errors: You may need appropriate permissions to write to the mounted device path
  • Code syntax errors: If the code has syntax errors, the device will display an error message that the script should capture
  • Infinite loops: If your code contains an infinite loop without output, the reader script may timeout
  • Import errors: If libraries are missing from the device, you'll see ImportError messages in the output

Troubleshooting

No output received:

  • Ask the user to verify the device is connected and mounted, or that the web workflow device is running
  • Check that the serial port is accessible
  • Ensure your code contains print statements

Script timeouts:

  • The output reader has a --duration argument to control the timeout length
  • Ensure your CircuitPython code completes in a reasonable time
  • Add a final print statement to signal completion

Help command:

  • The runner script supports the --help argument to print information about the script and its parameters.
Install via CLI
npx skills add https://github.com/adafruit/Agent_Skills --skill circuitpython-runner
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator