Robert and I will doing a recording about CircuitPython. These are the examples we'll cover in the recording.
Getting started
Go to https://circuitpython.org/downloads to download the appropriate UF2. Hold boot button on plugging in and then drag and drop the file.
See this guide for workflow details: https://learn.adafruit.com/welcome-to-circuitpython
See this guide for more simple API examples: https://learn.adafruit.com/circuitpython-essentials/
import digitalio
import board
import time
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
Libraries
They come in the bundle zip for manual install. I'll do that. circup is an automated way to do it: https://github.com/adafruit/circup
Bundle zip is here: https://github.com/adafruit/Adafruit_CircuitPython_Bundle Get the py version.
import digitalio
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)
while True:
pixels.fill(0x000000)
time.sleep(0.5)
pixels.fill(0xff0000)
time.sleep(0.5)
import digitalio
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)
first_key = digitalio.DigitalInOut(board.KEY1)
first_key.pull = digitalio.Pull.UP
while True:
color = 0x000000
if not first_key.value:
color = 0xff0000
pixels.fill(color)
time.sleep(0.05)
import digitalio
import board
import time
import neopixel
import adafruit_vcnl4200
import rainbowio
pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)
i2c = board.STEMMA_I2C()
sensor = adafruit_vcnl4200.Adafruit_VCNL4200(i2c)
while True:
prox = sensor.proximity
print(f"Proximity is: {prox}")
pixels.fill(rainbowio.colorwheel(min(prox, 255)))
time.sleep(0.05)
import digitalio
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)
first_key = digitalio.DigitalInOut(board.KEY1)
first_key.pull = digitalio.Pull.UP
key_up = True
while True:
pressed = not first_key.value
if not pressed and not key_up:
pixels.fill(0x000000)
key_up = True
print("up")
elif pressed and key_up:
pixels.fill(0xff0000)
print("down")
key_up = False
import digitalio
import board
import time
import neopixel
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)
first_key = digitalio.DigitalInOut(board.KEY1)
first_key.pull = digitalio.Pull.UP
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard) # We're in the US :)
# print(dir(Keycode))
key_up = True
while True:
pressed = not first_key.value
if not pressed and not key_up:
pixels.fill(0x000000)
key_up = True
print("up")
keyboard.release_all()
elif pressed and key_up:
pixels.fill(0xff0000)
print("down")
key_up = False
# KEYPAD_ONE doesn't work because we may need numlock
keyboard.press(Keycode.ONE)
Non-US Layout
Generated a colemak keyboard layout from https://github.com/Neradoc/Circuitpython_Keyboard_Layouts
import digitalio
import board
import time
import neopixel
import usb_hid
from adafruit_hid.keyboard import Keyboard
from keyboard_layout_win_cmk import KeyboardLayout
from adafruit_hid.keycode import Keycode
pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayout(keyboard) # We're in the US :)
print(dir(Keycode))
button = digitalio.DigitalInOut(board.BUTTON)
button.pull = digitalio.Pull.UP
last_value = True
while True:
value_now = button.value
if value_now == last_value:
continue
if value_now:
pixels[0] = 0x000000
print("up")
keyboard.release_all()
else:
pixels[0] = 0x0000FF
print("down")
# KEYPAD_ONE doesn't work because we may need numlock
keyboard_layout.write("hello")
last_value = value_now
Networking
Guide here: https://learn.adafruit.com/networking-in-circuitpython/making-http-andhttps-requests
Edit settings.toml to include wifi info:
CIRCUITPY_WIFI_SSID="myssid" CIRCUITPY_WIFI_PASSWORD="mypassword" CIRCUITPY_WEB_API_PASSWORD="hello"
Basic HTTP Request
From: https://learn.adafruit.com/networking-in-circuitpython/making-http-andhttps-requests
import adafruit_connection_manager
import wifi
import adafruit_requests
TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
# Initalize Wifi, Socket Pool, Request Session
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
requests = adafruit_requests.Session(pool, ssl_context)
with requests.get(TEXT_URL) as response:
print(response.text)
Basic Blink HTTPServer
Slimmed down from: https://learn.adafruit.com/pico-w-http-server-with-circuitpython/code-the-pico-w-http-server
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import os
import time
import ipaddress
import wifi
import socketpool
import busio
import board
import microcontroller
import displayio
import terminalio
from digitalio import DigitalInOut, Direction
from adafruit_httpserver import Server, Request, Response, POST
# onboard LED setup
led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
led.value = False
print("Connected to WiFi")
pool = socketpool.SocketPool(wifi.radio)
server = Server(pool, "/static", debug=False)
# variables for HTML
# font for HTML
font_family = "monospace"
# the HTML script
# setup as an f string
# this way, can insert string variables from code.py directly
# of note, use {{ and }} if something from html *actually* needs to be in brackets
# i.e. CSS style formatting
def webpage():
html = f"""
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html{{font-family: {font_family}; background-color: lightgrey;
display:inline-block; margin: 0px auto; text-align: center;}}
h1{{color: deeppink; width: 200; word-wrap: break-word; padding: 2vh; font-size: 35px;}}
p{{font-size: 1.5rem; width: 200; word-wrap: break-word;}}
.button{{font-family: {font_family};display: inline-block;
background-color: black; border: none;
border-radius: 4px; color: white; padding: 16px 40px;
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}}
p.dotted {{margin: auto;
width: 75%; font-size: 25px; text-align: center;}}
</style>
</head>
<body>
<title>Pico W HTTP Server</title>
<h1>Pico W HTTP Server</h1>
<br>
<p class="dotted">This is a Pico W running an HTTP server with CircuitPython.</p>
<br>
<p class="dotted">
<h1>Control the LED on the Pico W with these buttons:</h1><br>
<form accept-charset="utf-8" method="POST">
<button class="button" name="LED ON" value="ON" type="submit">LED ON</button></a></p></form>
<p><form accept-charset="utf-8" method="POST">
<button class="button" name="LED OFF" value="OFF" type="submit">LED OFF</button></a></p></form>
</body></html>
"""
return html
# route default static IP
@server.route("/")
def base(request: Request): # pylint: disable=unused-argument
# serve the HTML f string
# with content type text/html
return Response(request, f"{webpage()}", content_type='text/html')
# if a button is pressed on the site
@server.route("/", POST)
def buttonpress(request: Request):
# get the raw text
raw_text = request.raw_request.decode("utf8")
# print(raw_text)
# if the led on button was pressed
if "ON" in raw_text:
# turn on the onboard LED
led.value = True
print("on")
# if the led off button was pressed
if "OFF" in raw_text:
# turn the onboard LED off
led.value = False
print("off")
# respond
return Response(request, f"{webpage()}", content_type='text/html')
print("starting server..")
# startup the server
try:
server.start(str(wifi.radio.ipv4_address))
print("Listening on http://%s:%d" % (wifi.radio.ipv4_address, server.port))
# if the server fails to begin, restart the pico w
except OSError:
time.sleep(5)
print("restarting..")
microcontroller.reset()
ping_address = ipaddress.ip_address("8.8.4.4")
next_ping = time.monotonic()
while True:
# every 30 seconds ping server to verify connection
if next_ping < time.monotonic():
if wifi.radio.ping(ping_address) is None:
print("lost connection")
else:
print("connected")
next_ping = time.monotonic() + 30
# poll the server for incoming/outgoing requests
server.poll()
This page (Robert Feranec Stream Notes) was last updated on January 23, 2025.
Text editor powered by tinymce.