Docs Circuitpython Org en 6.3.x
Docs Circuitpython Org en 6.3.x
Docs Circuitpython Org en 6.3.x
Release 6.3.0
CircuitPython Contributors
1 CircuitPython 3
1.1 Get CircuitPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Code Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Contributing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 Branding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6 Differences from MicroPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.1 Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.2 API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.3 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7 Project Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7.1 Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7.2 Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.8 Full Table of Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.8.1 Core Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.8.2 Supported Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
1.8.3 Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
1.8.4 Additional CircuitPython Libraries and Drivers on GitHub . . . . . . . . . . . . . . . . . . 183
1.8.5 Design Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
1.8.6 Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
1.8.7 Porting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
1.8.8 Adding *io support to other ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
1.8.9 MicroPython libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
1.8.10 CircuitPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
1.8.11 Contributing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
1.8.12 Building CircuitPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
1.8.13 Building . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
1.8.14 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
1.8.15 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
1.8.16 Code Quality Checks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
1.8.17 Adafruit Community Code of Conduct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
1.8.18 MicroPython & CircuitPython license information . . . . . . . . . . . . . . . . . . . . . . 238
1.8.19 WebUSB Serial Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Index 245
i
ii
CircuitPython Documentation, Release 6.3.0
Welcome to the API reference documentation for Adafruit CircuitPython. This contains low-level API reference docs
which may link out to separate “getting started” guides. Adafruit has many excellent tutorials available through the
Adafruit Learning System.
ONE
CIRCUITPYTHON
Official binaries for all supported boards are available through circuitpython.org/downloads. The site includes stable,
unstable and continuous builds. Full release notes and assets are available through GitHub releases as well.
3
CircuitPython Documentation, Release 6.3.0
1.2 Documentation
Guides and videos are available through the Adafruit Learning System under the CircuitPython category. An API
reference is also available on Read the Docs. A collection of awesome resources can be found at Awesome Circuit-
Python.
Specifically useful documentation when starting out:
• Welcome to CircuitPython
• CircuitPython Essentials
• Example Code
GitHub doesn’t currently support code search on forks. Therefore, CircuitPython doesn’t have code search through
GitHub because it is a fork of MicroPython. Luckily, SourceGraph has free code search for public repos like Circuit-
Python. So, visit sourcegraph.com/github.com/adafruit/circuitpython to search the CircuitPython codebase online.
1.4 Contributing
See CONTRIBUTING.md for full guidelines but please be aware that by contributing to this project you are agreeing
to the Code of Conduct. Contributors who follow the Code of Conduct are welcome to submit pull requests and they
will be promptly reviewed by project admins. Please join the Discord too.
1.5 Branding
While we are happy to see CircuitPython forked and modified, we’d appreciate it if forked releases not use the name
“CircuitPython” or the Blinka logo. “CircuitPython” means something special to us and those who learn about it. As
a result, we’d like to make sure products referring to it meet a common set of requirements.
If you’d like to use the term “CircuitPython” and Blinka for your product here is what we ask:
• Your product is supported by the primary “adafruit/circuitpython” repo. This way we can update any custom
code as we update the CircuitPython internals.
• Your product is listed on circuitpython.org (source here). This is to ensure that a user of your product can always
download the latest version of CircuitPython from the standard place.
• Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
If you choose not to meet these requirements, then we ask you call your version of CircuitPython something else
(for example, SuperDuperPython) and not use the Blinka logo. You can say it is “CircuitPython-compatible” if most
CircuitPython drivers will work with it.
4 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
CircuitPython:
• Supports native USB on all boards, allowing file editing without special tools.
• Floats (aka decimals) are enabled for all builds.
• Error messages are translated into 10+ languages.
• Does not support concurrency within Python (including interrupts and threading). Some concurrency is achieved
with native modules for tasks that require it such as audio file playback.
1.6.1 Behavior
• The order that files are run and the state that is shared between them. CircuitPython’s goal is to clarify the role
of each file and make each file independent from each other.
• boot.py (or settings.py) runs only once on start up before USB is initialized. This lays the ground
work for configuring USB at startup rather than it being fixed. Since serial is not available, output is written to
boot_out.txt.
• code.py (or main.py) is run after every reload until it finishes or is interrupted. After it is done running, the
vm and hardware is reinitialized. This means you cannot read state from code.py in the REPL anymore,
as the REPL is a fresh vm. CircuitPython’s goal for this change includes reducing confusion about pins and
memory being used.
• After the main code is finished the REPL can be entered by pressing any key.
• Autoreload state will be maintained across reload.
• Adds a safe mode that does not run user code after a hard crash or brown out. The hope is that this will make it
easier to fix code that causes nasty crashes by making it available through mass storage after the crash. A reset
(the button) is needed after it’s fixed to get back into normal mode.
• RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes.
• Re-runs code.py or other main file after file system writes over USB mass storage. (Disable with
supervisor.disable_autoreload())
• Autoreload is disabled while the REPL is active.
• Main is one of these: code.txt, code.py, main.py, main.txt
• Boot is one of these: settings.txt, settings.py, boot.py, boot.txt
1.6.2 API
1.6.3 Modules
• No module aliasing. (uos and utime are not available as os and time respectively.) Instead os, time, and
random are CPython compatible.
• New storage module which manages file system mounts. (Functionality from uos in MicroPython.)
• Modules with a CPython counterpart, such as time, os and random, are strict subsets of their CPython
version. Therefore, code from CircuitPython is runnable on CPython but not necessarily the reverse.
• tick count is available as time.monotonic()
1.7.1 Core
1.7.2 Ports
Ports include the code unique to a microcontroller line and also variations based on the board.
6 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
These core modules are intended on being consistent across ports and boards. A module may not exist on a port/board
if no underlying hardware support is present or if flash space is limited. For example, a microcontroller without analog
features will not have analogio. See the Module Support Matrix - Which Modules Are Available on Which Boards
page for a list of modules supported on each board.
The following table lists the available built-in modules for each CircuitPython capable board.
8 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
10 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
12 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
14 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
16 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
18 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Elec- analogio, board, busio, digitalio, math, microcontroller, nvm, os, pulseio,
tronic Cats pwmio, random, storage, struct, supervisor, time, usb_hid, usb_midi
Hunter Cat
NFC
Electronic analogio, board, busio, digitalio, math, microcontroller, neopixel_write,
Cats NFC nvm, os, pulseio, pwmio, random, rotaryio, rtc, storage, struct, supervisor,
Copy Cat time, touchio, usb_hid, usb_midi
20 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
22 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
24 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
26 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
28 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
30 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
STM32F411E_DISCO
_bleio, _pixelbuf, analogio, binascii, bitbangio, bitmaptools, board,
busio, digitalio, displayio, errno, framebufferio, gamepad, json, math,
microcontroller, msgpack, neopixel_write, os, pulseio, pwmio, random, re,
sdcardio, sharpdisplay, storage, struct, supervisor, terminalio, time,
touchio, ulab, vectorio
STM32F412G_DISCO
_bleio, _pixelbuf, analogio, binascii, bitbangio, bitmaptools, board,
busio, digitalio, displayio, errno, framebufferio, gamepad, json, math,
microcontroller, msgpack, neopixel_write, os, pulseio, pwmio, random, re,
sdcardio, sharpdisplay, storage, struct, supervisor, terminalio, time,
touchio, ulab, vectorio
STM32F4_DISCO
_bleio, _pixelbuf, analogio, binascii, bitbangio, bitmaptools, board,
busio, canio, digitalio, displayio, errno, framebufferio, gamepad, json,
math, microcontroller, msgpack, neopixel_write, os, pulseio, pwmio,
random, re, sdcardio, sdioio, sharpdisplay, storage, struct, supervisor,
terminalio, time, touchio, ulab, vectorio
32 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
XinaBox board, busio, digitalio, math, microcontroller, nvm, os, random, rtc, storage,
CC03 struct, supervisor, time, usb_hid, usb_midi
34 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
XinaBox board, busio, digitalio, math, microcontroller, nvm, os, random, storage,
CS11 struct, supervisor, time, usb_hid
Modules
The _bleio module provides necessary low-level functionality for communicating using Bluetooth Low Energy
(BLE). The ‘_’ prefix indicates this module is meant for internal use by libraries but not by the end user. Its API
may change incompatibly between minor versions of CircuitPython. Please use the adafruit_ble CircuitPython library
instead, which builds on _bleio, and provides higher-level convenience functionality, including predefined beacons,
clients, servers.
_bleio.adapter :Adapter
BLE Adapter used to manage device discovery and connections. This object is the sole instance of _bleio.
Adapter.
exception _bleio.BluetoothError
Bases: Exception
Catchall exception for Bluetooth related errors.
Initialize self. See help(type(self)) for accurate signature.
exception _bleio.RoleError
Bases: BluetoothError
Raised when a resource is used as the mismatched role. For example, if a local CCCD is attempted to be set but
they can only be set when remote.
Initialize self. See help(type(self)) for accurate signature.
exception _bleio.SecurityError
Bases: BluetoothError
Raised when a security related error occurs.
Initialize self. See help(type(self)) for accurate signature.
_bleio.set_adapter(adapter: Optional[Adapter]) → None
Set the adapter to use for BLE, such as when using an HCI adapter. Raises NotImplementedError when
the adapter is a singleton and cannot be set.
class _bleio.Adapter(*, uart: busio.UART, rts: digitalio.DigitalInOut, cts: digitalio.DigitalInOut)
The BLE Adapter object manages the discovery and connection to other nearby Bluetooth Low Energy devices.
This part of the Bluetooth Low Energy Specification is known as Generic Access Profile (GAP).
Discovery of other devices happens during a scanning process that listens for small packets of information,
known as advertisements, that are broadcast unencrypted. The advertising packets have two different uses. The
first is to broadcast a small piece of data to anyone who cares and and nothing more. These are known as
beacons. The second class of advertisement is to promote additional functionality available after the devices
establish a connection. For example, a BLE heart rate monitor would advertise that it provides the standard BLE
Heart Rate Service.
The Adapter can do both parts of this process: it can scan for other device advertisements and it can advertise
its own data. Furthermore, Adapters can accept incoming connections and also initiate connections.
On boards that do not have native BLE, you can use an HCI co-processor. Pass the uart and pins used to
communicate with the co-processor, such as an Adafruit AirLift. The co-processor must have been reset and put
into BLE mode beforehand by the appropriate pin manipulation. The uart, rts, and cts objects are used to
communicate with the HCI co-processor in HCI mode. The Adapter object is enabled during this call.
After instantiating an Adapter, call _bleio.set_adapter() to set _bleio.adapter
On boards with native BLE, you cannot create an instance of _bleio.Adapter; this constructor will raise
NotImplementedError. Use _bleio.adapter to access the sole instance already available.
enabled :bool
State of the BLE adapter.
address :Address
MAC address of the BLE adapter.
name :str
name of the BLE adapter used once connected. The name is “CIRCUITPY” + the last four hex digits of
adapter.address, to make it easy to distinguish multiple CircuitPython boards.
advertising :bool
True when the adapter is currently advertising. (read-only)
connected :bool
True when the adapter is connected to another device regardless of who initiated the connection. (read-
only)
connections :Tuple[Connection]
Tuple of active connections including those initiated through _bleio.Adapter.connect(). (read-
only)
start_advertising(self, data: _typing.ReadableBuffer, *, scan_response: Op-
tional[_typing.ReadableBuffer] = None, connectable: bool = True,
anonymous: bool = False, timeout: int = 0, interval: float = 0.1) →
None
Starts advertising until stop_advertising is called or if connectable, another device connects to us.
Parameters
• data (ReadableBuffer) – advertising data packet bytes
• scan_response (ReadableBuffer) – scan response data packet bytes. None if no
scan response is needed.
• connectable (bool) – If True then other devices are allowed to connect to this pe-
ripheral.
• anonymous (bool) – If True then this device’s MAC address is randomized before
advertising.
• timeout (int) – If set, we will only advertise for this many seconds. Zero means no
timeout.
• interval (float) – advertising interval, in seconds
stop_advertising(self ) → None
Stop sending advertising packets.
start_scan(self, prefixes: _typing.ReadableBuffer = b'', *, buffer_size: int = 512, extended: bool
= False, timeout: Optional[float] = None, interval: float = 0.1, window: float = 0.1,
minimum_rssi: int = - 80, active: bool = True) → Iterable[ScanEntry]
Starts a BLE scan and returns an iterator of results. Advertisements and scan responses are filtered and
returned separately.
36 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Parameters
• prefixes (ReadableBuffer) – Sequence of byte string prefixes to filter advertising
packets with. A packet without an advertising structure that matches one of the prefixes is
ignored. Format is one byte for length (n) and n bytes of prefix and can be repeated.
• buffer_size (int) – the maximum number of advertising bytes to buffer.
• extended (bool) – When True, support extended advertising packets. Increasing
buffer_size is recommended when this is set.
• timeout (float) – the scan timeout in seconds. If None or zero, will scan until
stop_scan is called.
• interval (float) – the interval (in seconds) between the start of two consecutive scan
windows Must be in the range 0.0025 - 40.959375 seconds.
• window (float) – the duration (in seconds) to scan a single BLE channel. window must
be <= interval.
• minimum_rssi (int) – the minimum rssi of entries to return.
• active (bool) – retrieve scan responses for scannable advertisements.
Returns an iterable of _bleio.ScanEntry objects
Return type iterable
stop_scan(self ) → None
Stop the current scan.
connect(self, address: Address, *, timeout: float) → Connection
Attempts a connection to the device with the given address.
Parameters
• address (Address) – The address of the peripheral to connect to
• timeout (float/int) – Try to connect for timeout seconds.
erase_bonding(self ) → None
Erase all bonding information stored in flash memory.
class _bleio.Address(address: _typing.ReadableBuffer, address_type: int)
Encapsulates the address of a BLE device.
Create a new Address object encapsulating the address value. The value itself can be one of:
Parameters
• address (ReadableBuffer) – The address value to encapsulate. A buffer object
(bytearray, bytes) of 6 bytes.
• address_type (int) – one of the integer values: PUBLIC, RANDOM_STATIC,
RANDOM_PRIVATE_RESOLVABLE, or RANDOM_PRIVATE_NON_RESOLVABLE.
address_bytes :bytes
The bytes that make up the device address (read-only).
Note that the bytes object returned is in little-endian order: The least significant byte is
address_bytes[0]. So the address will appear to be reversed if you print the raw bytes object.
If you print or use str() on the Attribute object itself, the address will be printed in the expected
order. For example:
type :int
The address type (read-only).
One of the integer values: PUBLIC, RANDOM_STATIC, RANDOM_PRIVATE_RESOLVABLE, or
RANDOM_PRIVATE_NON_RESOLVABLE.
PUBLIC :int
A publicly known address, with a company ID (high 24 bits)and company-assigned part (low 24 bits).
RANDOM_STATIC :int
A randomly generated address that does not change often. It may never change or may change after a
power cycle.
RANDOM_PRIVATE_RESOLVABLE :int
An address that is usable when the peer knows the other device’s secret Identity Resolving Key (IRK).
RANDOM_PRIVATE_NON_RESOLVABLE :int
A randomly generated address that changes on every connection.
__eq__(self, other: object) → bool
Two Address objects are equal if their addresses and address types are equal.
__hash__(self ) → int
Returns a hash for the Address data.
class _bleio.Attribute
Definitions associated with all BLE attributes: characteristics, descriptors, etc.
Attribute is, notionally, a superclass of Characteristic and Descriptor, but is not defined as a
Python superclass of those classes.
You cannot create an instance of Attribute.
NO_ACCESS :int
security mode: access not allowed
OPEN :int
security_mode: no security (link is not encrypted)
ENCRYPT_NO_MITM :int
security_mode: unauthenticated encryption, without man-in-the-middle protection
ENCRYPT_WITH_MITM :int
security_mode: authenticated encryption, with man-in-the-middle protection
LESC_ENCRYPT_WITH_MITM :int
security_mode: LESC encryption, with man-in-the-middle protection
SIGNED_NO_MITM :int
security_mode: unauthenticated data signing, without man-in-the-middle protection
SIGNED_WITH_MITM :int
security_mode: authenticated data signing, without man-in-the-middle protection
class _bleio.Characteristic
Stores information about a BLE service characteristic and allows reading and writing of the characteristic’s
value.
38 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
There is no regular constructor for a Characteristic. A new local Characteristic can be created and attached
to a Service by calling add_to_service(). Remote Characteristic objects are created by Connection.
discover_remote_services() as part of remote Services.
properties :int
An int bitmask representing which properties are set, specified as bitwise or’ing of of these possible values.
BROADCAST, INDICATE, NOTIFY, READ, WRITE, WRITE_NO_RESPONSE.
uuid :Optional[UUID]
The UUID of this characteristic. (read-only)
Will be None if the 128-bit UUID for this characteristic is not known.
value :bytearray
The value of this characteristic.
descriptors :Descriptor
A tuple of Descriptor objects related to this characteristic. (read-only)
service :Service
The Service this Characteristic is a part of.
BROADCAST :int
property: allowed in advertising packets
INDICATE :int
property: server will indicate to the client when the value is set and wait for a response
NOTIFY :int
property: server will notify the client when the value is set
READ :int
property: clients may read this characteristic
WRITE :int
property: clients may write this characteristic; a response will be sent back
WRITE_NO_RESPONSE :int
property: clients may write this characteristic; no response will be sent back
add_to_service(self, service: Service, uuid: UUID, *, properties: int = 0, read_perm: int
= Attribute.OPEN, write_perm: int = Attribute.OPEN, max_length: int = 20,
fixed_length: bool = False, initial_value: Optional[_typing.ReadableBuffer] =
None) → Characteristic
Create a new Characteristic object, and add it to this Service.
Parameters
• service (Service) – The service that will provide this characteristic
• uuid (UUID) – The uuid of the characteristic
• properties (int) – The properties of the characteristic, specified as a bitmask of
these values bitwise-or’d together: BROADCAST, INDICATE, NOTIFY, READ, WRITE,
WRITE_NO_RESPONSE.
• read_perm (int) – Specifies whether the characteristic can be read by a
client, and if so, which security mode is required. Must be one of the in-
teger values Attribute.NO_ACCESS, Attribute.OPEN , Attribute.
ENCRYPT_NO_MITM , Attribute.ENCRYPT_WITH_MITM , Attribute.
LESC_ENCRYPT_WITH_MITM , Attribute.SIGNED_NO_MITM , or Attribute.
SIGNED_WITH_MITM .
• write_perm (int) – Specifies whether the characteristic can be written by a client, and
if so, which security mode is required. Values allowed are the same as read_perm.
• max_length (int) – Maximum length in bytes of the characteristic value. The maxi-
mum allowed is is 512, or possibly 510 if fixed_length is False. The default, 20, is
the maximum number of data bytes that fit in a single BLE 4.x ATT packet.
• fixed_length (bool) – True if the characteristic value is of fixed length.
• initial_value (ReadableBuffer) – The initial value for this characteristic. If not
given, will be filled with zeros.
Returns the new Characteristic.
set_cccd(self, *, notify: bool = False, indicate: bool = False) → None
Set the remote characteristic’s CCCD to enable or disable notification and indication.
Parameters
• notify (bool) – True if Characteristic should receive notifications of remote writes
• indicate (float) – True if Characteristic should receive indications of remote writes
class _bleio.CharacteristicBuffer(characteristic: Characteristic, *, timeout: int = 1,
buffer_size: int = 64)
Accumulates a Characteristic’s incoming values in a FIFO buffer.
Monitor the given Characteristic. Each time a new value is written to the Characteristic add the newly-written
bytes to a FIFO buffer.
Parameters
• characteristic (Characteristic) – The Characteristic to monitor. It may be a
local Characteristic provided by a Peripheral Service, or a remote Characteristic in a remote
Service that a Central has connected to.
• timeout (int) – the timeout in seconds to wait for the first character and between subse-
quent characters.
• buffer_size (int) – Size of ring buffer that stores incoming data coming from client.
Must be >= 1.
in_waiting :int
The number of bytes in the input buffer, available to be read
read(self, nbytes: Optional[int] = None) → Optional[bytes]
Read characters. If nbytes is specified then read at most that many bytes. Otherwise, read everything
that arrives until the connection times out. Providing the number of bytes expected is highly recommended
because it will be faster.
Returns Data read
Return type bytes or None
readinto(self, buf: _typing.WriteableBuffer) → Optional[int]
Read bytes into the buf. Read at most len(buf) bytes.
Returns number of bytes read and stored into buf
Return type int or None (on a non-blocking error)
readline(self ) → bytes
Read a line, ending in a newline character.
Returns the line read
40 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
import _bleio
my_entry = None
for entry in _bleio.adapter.scan(2.5):
if entry.name is not None and entry.name == 'InterestingPeripheral':
my_entry = entry
break
if not my_entry:
raise Exception("'InterestingPeripheral' not found")
Connections cannot be made directly. Instead, to initiate a connection use Adapter.connect. Connections
may also be made when another device initiates a connection. To use a Connection created by a peer, read the
Adapter.connections property.
connected :bool
True if connected to the remote peer.
paired :bool
True if paired to the remote peer.
connection_interval :float
Time between transmissions in milliseconds. Will be multiple of 1.25ms. Lower numbers increase speed
and decrease latency but increase power consumption.
When setting connection_interval, the peer may reject the new interval and connection_interval
will then remain the same.
Apple has additional guidelines that dictate should be a multiple of 15ms except if HID is available. When
HID is available Apple devices may accept 11.25ms intervals.
attribute :int
The maximum number of data bytes that can be sent in a single transmission, not including overhead bytes.
This is the maximum number of bytes that can be sent in a notification, which must be sent in a single
packet. But for a regular characteristic read or write, may be sent in multiple packets, so this limit does not
apply.
disconnect(self ) → None
Disconnects from the remote peripheral. Does nothing if already disconnected.
pair(self, *, bond: bool = True) → None
Pair to the peer to improve security.
discover_remote_services(self, service_uuids_whitelist: Optional[Iterable[UUID]] = None)
→ Tuple[Service, . . . ]
Do BLE discovery for all services or for the given service UUIDS, to find their handles and characteristics,
42 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
• max_length (int) – Maximum length in bytes of the descriptor value. The maximum
allowed is is 512, or possibly 510 if fixed_length is False. The default, 20, is the
maximum number of data bytes that fit in a single BLE 4.x ATT packet.
• fixed_length (bool) – True if the descriptor value is of fixed length.
• initial_value (ReadableBuffer) – The initial value for this descriptor.
Returns the new Descriptor.
class _bleio.PacketBuffer(characteristic: Characteristic, *, buffer_size: int)
Accumulates a Characteristic’s incoming packets in a FIFO buffer and facilitates packet aware outgoing
writes. A packet’s size is either the characteristic length or the maximum transmission unit (MTU) mi-
nus overhead, whichever is smaller. The MTU can change so check incoming_packet_length and
outgoing_packet_length before creating a buffer to store data.
When we’re the server, we ignore all connections besides the first to subscribe to notifications.
Monitor the given Characteristic. Each time a new value is written to the Characteristic add the newly-written
bytes to a FIFO buffer.
Monitor the given Characteristic. Each time a new value is written to the Characteristic add the newly-written
packet of bytes to a FIFO buffer.
Parameters
• characteristic (Characteristic) – The Characteristic to monitor. It may be a
local Characteristic provided by a Peripheral Service, or a remote Characteristic in a remote
Service that a Central has connected to.
• buffer_size (int) – Size of ring buffer (in packets of the Characteristic’s maximum
length) that stores incoming packets coming from the peer.
packet_size :int
packet_size is the same as incoming_packet_length. The name packet_size is deprecated
and will be removed in CircuitPython 6.0.0.
incoming_packet_length :int
Maximum length in bytes of a packet we are reading.
outgoing_packet_length :int
Maximum length in bytes of a packet we are writing.
readinto(self, buf: _typing.WriteableBuffer) → int
Reads a single BLE packet into the buf. Raises an exception if the next packet is longer than the given
buffer. Use packet_size to read the maximum length of a single packet.
Returns number of bytes read and stored into buf
Return type int
write(self, data: _typing.ReadableBuffer, *, header: Optional[bytes] = None) → int
Writes all bytes from data into the same outgoing packet. The bytes from header are included before data
when the pending packet is currently empty.
This does not block until the data is sent. It only blocks until the data is pending.
Returns number of bytes written. May include header bytes when packet is empty.
Return type int
deinit(self ) → None
Disable permanently.
class _bleio.ScanEntry
Encapsulates information about a device that was received during scanning. It can be advertisement or scan re-
sponse data. This object may only be created by a _bleio.ScanResults: it has no user-visible constructor.
Cannot be instantiated directly. Use _bleio.Adapter.start_scan.
address :Address
The address of the device (read-only), of type _bleio.Address.
advertisement_bytes :bytes
All the advertisement data present in the packet, returned as a bytes object. (read-only)
rssi :int
The signal strength of the device at the time of the scan, in integer dBm. (read-only)
connectable :bool
True if the device can be connected to. (read-only)
scan_response :bool
True if the entry was a scan response. (read-only)
matches(self, prefixes: ScanEntry, *, all: bool = True) → bool
Returns True if the ScanEntry matches all prefixes when all is True. This is stricter than the scan filtering
which accepts any advertisements that match any of the prefixes where all is False.
class _bleio.ScanResults
Iterates over advertising data received while scanning. This object is always created by a _bleio.Adapter:
it has no user-visible constructor.
Cannot be instantiated directly. Use _bleio.Adapter.start_scan.
__iter__(self ) → Iterator[ScanEntry]
Returns itself since it is the iterator.
__next__(self ) → ScanEntry
Returns the next _bleio.ScanEntry. Blocks if none have been received and scanning is still active.
Raises StopIteration if scanning is finished and no other results are available.
class _bleio.Service(uuid: UUID, *, secondary: bool = False)
Stores information about a BLE service and its characteristics.
Create a new Service identified by the specified UUID. It can be accessed by all connections. This is known as
a Service server. Client Service objects are created via Connection.discover_remote_services.
To mark the Service as secondary, pass True as secondary.
Parameters
• uuid (UUID) – The uuid of the service
• secondary (bool) – If the service is a secondary one
Returns the new Service
characteristics :Tuple[Characteristic, ...]
A tuple of Characteristic designating the characteristics that are offered by this service. (read-only)
remote :bool
True if this is a service provided by a remote device. (read-only)
secondary :bool
True if this is a secondary service. (read-only)
44 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
uuid :Optional[UUID]
The UUID of this service. (read-only)
Will be None if the 128-bit UUID for this service is not known.
class _bleio.UUID(value: Union[int, _typing.ReadableBuffer, str])
A 16-bit or 128-bit UUID. Can be used for services, characteristics, descriptors and more.
Create a new UUID or UUID object encapsulating the uuid value. The value can be one of:
• an int value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID)
• a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
• a string of hex digits of the form ‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx’
Creating a 128-bit UUID registers the UUID with the onboard BLE software, and provides a temporary 16-bit
UUID that can be used in place of the full 128-bit UUID.
Parameters value (int, ReadableBuffer or str) – The uuid value to encapsulate
uuid16 :int
The 16-bit part of the UUID. (read-only)
Type int
uuid128 :bytes
The 128-bit value of the UUID Raises AttributeError if this is a 16-bit UUID. (read-only)
Type bytes
size :int
128 if this UUID represents a 128-bit vendor-specific UUID. 16 if this UUID represents a 16-bit Bluetooth
SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported.
Type int
pack_into(self, buffer: _typing.WriteableBuffer, offset: int = 0) → None
Packs the UUID into the given buffer at the given offset.
__eq__(self, other: object) → bool
Two UUID objects are equal if their values match and they are both 128-bit or both 16-bit.
The _eve module provides a class _EVE which contains methods for constructing EVE command buffers and ap-
pending basic graphics commands.
class _eve._EVE
46 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Parameters
• filter (int) – bitmap filtering mode, one of NEAREST or BILINEAR. Range 0-1
• wrapx (int) – bitmap 𝑥 wrap mode, one of REPEAT or BORDER. Range 0-1
• wrapy (int) – bitmap 𝑦 wrap mode, one of REPEAT or BORDER. Range 0-1
• width (int) – drawn bitmap width, in pixels. Range 0-511
• height (int) – drawn bitmap height, in pixels. Range 0-511
BitmapSource(self, addr: int) → None
Set the source address for bitmap graphics
Parameters addr (int) – Bitmap start address, pixel-aligned. May be in SRAM or flash.
Range 0-16777215
BitmapSwizzle(self, r: int, g: int, b: int, a: int) → None
Set the source for the r,g,b and a channels of a bitmap
Parameters
• r (int) – red component source channel. Range 0-7
• g (int) – green component source channel. Range 0-7
• b (int) – blue component source channel. Range 0-7
• a (int) – alpha component source channel. Range 0-7
BitmapTransformA(self, p: int, v: int) → None
Set the 𝑎 component of the bitmap transform matrix
Parameters
• p (int) – precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0
• v (int) – The 𝑎 component of the bitmap transform matrix, in signed 8.8 or 1.15 bit
fixed-point form. Range 0-131071. The initial value is 256
The initial value is p = 0, v = 256. This represents the value 1.0.
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
BitmapTransformB(self, p: int, v: int) → None
Set the 𝑏 component of the bitmap transform matrix
Parameters
• p (int) – precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0
• v (int) – The 𝑏 component of the bitmap transform matrix, in signed 8.8 or 1.15 bit
fixed-point form. Range 0-131071. The initial value is 0
The initial value is p = 0, v = 0. This represents the value 0.0.
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
BitmapTransformC(self, v: int) → None
Set the 𝑐 component of the bitmap transform matrix
Parameters v (int) – The 𝑐 component of the bitmap transform matrix, in signed 15.8 bit
fixed-point form. Range 0-16777215. The initial value is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
BitmapTransformD(self, p: int, v: int) → None
Set the 𝑑 component of the bitmap transform matrix
Parameters
• p (int) – precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0
• v (int) – The 𝑑 component of the bitmap transform matrix, in signed 8.8 or 1.15 bit
fixed-point form. Range 0-131071. The initial value is 0
The initial value is p = 0, v = 0. This represents the value 0.0.
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
BitmapTransformE(self, p: int, v: int) → None
Set the 𝑒 component of the bitmap transform matrix
Parameters
• p (int) – precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0
• v (int) – The 𝑒 component of the bitmap transform matrix, in signed 8.8 or 1.15 bit
fixed-point form. Range 0-131071. The initial value is 256
The initial value is p = 0, v = 256. This represents the value 1.0.
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
BitmapTransformF(self, v: int) → None
Set the 𝑓 component of the bitmap transform matrix
Parameters v (int) – The 𝑓 component of the bitmap transform matrix, in signed 15.8 bit
fixed-point form. Range 0-16777215. The initial value is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
BlendFunc(self, src: int, dst: int) → None
Set pixel arithmetic
Parameters
• src (int) – specifies how the source blending factor is computed. One
of ZERO, ONE, SRC_ALPHA, DST_ALPHA, ONE_MINUS_SRC_ALPHA or
ONE_MINUS_DST_ALPHA. Range 0-7. The initial value is SRC_ALPHA(2)
• dst (int) – specifies how the destination blending factor is computed, one of the same
constants as src. Range 0-7. The initial value is ONE_MINUS_SRC_ALPHA(4)
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
Call(self, dest: int) → None
Execute a sequence of commands at another location in the display list
Parameters dest (int) – display list address. Range 0-65535
Cell(self, cell: int) → None
Set the bitmap cell number for the vertex2f command
Parameters cell (int) – bitmap cell number. Range 0-127. The initial value is 0
48 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
ClearColorA(self, alpha: int) → None
Set clear value for the alpha channel
Parameters alpha (int) – alpha value used when the color buffer is cleared. Range 0-255.
The initial value is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
ClearColorRGB(self, red: int, green: int, blue: int) → None
Set clear values for red, green and blue channels
Parameters
• red (int) – red value used when the color buffer is cleared. Range 0-255. The initial
value is 0
• green (int) – green value used when the color buffer is cleared. Range 0-255. The
initial value is 0
• blue (int) – blue value used when the color buffer is cleared. Range 0-255. The initial
value is 0
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
Clear(self, c: int, s: int, t: int) → None
Clear buffers to preset values
Parameters
• c (int) – clear color buffer. Range 0-1
• s (int) – clear stencil buffer. Range 0-1
• t (int) – clear tag buffer. Range 0-1
ClearStencil(self, s: int) → None
Set clear value for the stencil buffer
Parameters s (int) – value used when the stencil buffer is cleared. Range 0-255. The initial
value is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
ClearTag(self, s: int) → None
Set clear value for the tag buffer
Parameters s (int) – value used when the tag buffer is cleared. Range 0-255. The initial value
is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
ColorA(self, alpha: int) → None
Set the current color alpha
Parameters alpha (int) – alpha for the current color. Range 0-255. The initial value is 255
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
50 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Return(self ) → None
Return from a previous call command
SaveContext(self ) → None
Push the current graphics context on the context stack
ScissorSize(self, width: int, height: int) → None
Set the size of the scissor clip rectangle
Parameters
• width (int) – The width of the scissor clip rectangle, in pixels. Range 0-4095. The
initial value is hsize
• height (int) – The height of the scissor clip rectangle, in pixels. Range 0-4095. The
initial value is 2048
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
ScissorXY(self, x: int, y: int) → None
Set the top left corner of the scissor clip rectangle
Parameters
• x (int) – The 𝑥 coordinate of the scissor clip rectangle, in pixels. Range 0-2047. The
initial value is 0
• y (int) – The 𝑦 coordinate of the scissor clip rectangle, in pixels. Range 0-2047. The
initial value is 0
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
StencilFunc(self, func: int, ref: int, mask: int) → None
Set function and reference value for stencil testing
Parameters
• func (int) – specifies the test function, one of NEVER, LESS, LEQUAL, GREATER,
GEQUAL, EQUAL, NOTEQUAL, or ALWAYS. Range 0-7. The initial value is ALWAYS(7)
• ref (int) – specifies the reference value for the stencil test. Range 0-255. The initial
value is 0
• mask (int) – specifies a mask that is ANDed with the reference value and the stored
stencil value. Range 0-255. The initial value is 255
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
StencilMask(self, mask: int) → None
Control the writing of individual bits in the stencil planes
Parameters mask (int) – the mask used to enable writing stencil bits. Range 0-255. The
initial value is 255
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
StencilOp(self, sfail: int, spass: int) → None
Set stencil test actions
Parameters
• sfail (int) – specifies the action to take when the stencil test fails, one of KEEP, ZERO,
REPLACE, INCR, INCR_WRAP, DECR, DECR_WRAP, and INVERT. Range 0-7. The
initial value is KEEP(1)
• spass (int) – specifies the action to take when the stencil test passes, one of the same
constants as sfail. Range 0-7. The initial value is KEEP(1)
These values are part of the graphics context and are saved and restored by SaveContext() and
RestoreContext().
TagMask(self, mask: int) → None
Control the writing of the tag buffer
Parameters mask (int) – allow updates to the tag buffer. Range 0-1. The initial value is 1
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
Tag(self, s: int) → None
Set the current tag value
Parameters s (int) – tag value. Range 0-255. The initial value is 255
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
Vertex2ii(self, x: int, y: int, handle: int, cell: int) → None
Parameters
• x (int) – x-coordinate in pixels. Range 0-511
• y (int) – y-coordinate in pixels. Range 0-511
• handle (int) – bitmap handle. Range 0-31
• cell (int) – cell number. Range 0-127
This method is an alternative to Vertex2f().
Vertex2f(self, b: float) → None
Draw a point.
Parameters
• x (float) – pixel x-coordinate
• y (float) – pixel y-coordinate
LineWidth(self, width: float) → None
Set the width of rasterized lines
Parameters width (float) – line width in pixels. Range 0-511. The initial value is 1
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
PointSize(self, size: float) → None
Set the diameter of rasterized points
Parameters size (float) – point diameter in pixels. Range 0-1023. The initial value is 1
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
VertexTranslateX(self, x: float) → None
Set the vertex transformation’s x translation component
52 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Parameters x (float) – signed x-coordinate in pixels. Range ±4095. The initial value is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
VertexTranslateY(self, y: float) → None
Set the vertex transformation’s y translation component
Parameters y (float) – signed y-coordinate in pixels. Range ±4095. The initial value is 0
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
VertexFormat(self, frac: int) → None
Set the precision of vertex2f coordinates
Parameters frac (int) – Number of fractional bits in X,Y coordinates, 0-4. Range 0-7. The
initial value is 4
This value is part of the graphics context and is saved and restored by SaveContext() and
RestoreContext().
cmd0(self, n: int) → None
Append the command word n to the FIFO
Parameters n (int) – The command code
This method is used by the eve module to efficiently add commands to the FIFO.
cmd(self, n: int, fmt: str, args: Tuple[str, . . . ]) → None
Append a command packet to the FIFO.
Parameters
• n (int) – The command code
• fmt (str) – The command format struct layout
• args (tuple(str, ..)) – The command’s arguments
Supported format codes: h, H, i, I.
This method is used by the eve module to efficiently add commands to the FIFO.
_pixelbuf – A fast RGB(W) pixel buffer library for like NeoPixel and DotStar
The _pixelbuf module provides the PixelBuf class to accelerate RGB(W) strip/matrix manipulation, such as
DotStar and Neopixel.
Byteorders are configured with strings, such as “RGB” or “RGBD”.
_pixelbuf.colorwheel(n: float) → int
C implementation of the common wheel() function found in many examples. Returns the colorwheel RGB value
as an integer value for n (usable in PixelBuf, neopixel, and dotstar).
_pixelbuf.wheel(n: float) → int
Use of wheel() is deprecated. Please use colorwheel().
class _pixelbuf.PixelBuf(size: int, *, byteorder: str = 'BGR', brightness: float = 0, auto_write:
bool = False, header: _typing.ReadableBuffer = b'', trailer: _typ-
ing.ReadableBuffer = b'')
A fast RGB[W] pixel buffer for LED and similar devices.
Create a PixelBuf object of the specified size, byteorder, and bits per pixel.
When brightness is less than 1.0, a second buffer will be used to store the color values before they are adjusted
for brightness.
When P (PWM duration) is present as the 4th character of the byteorder string, the 4th value in the tuple/list for
a pixel is the individual pixel brightness (0.0-1.0) and will enable a Dotstar compatible 1st byte for each pixel.
Parameters
• size (int) – Number of pixels
• byteorder (str) – Byte order string (such as “RGB”, “RGBW” or “PBGR”)
• brightness (float) – Brightness (0 to 1.0, default 1.0)
• auto_write (bool) – Whether to automatically write pixels (Default False)
• header (ReadableBuffer) – Sequence of bytes to always send before pixel values.
• trailer (ReadableBuffer) – Sequence of bytes to always send after pixel values.
bpp :int
The number of bytes per pixel in the buffer (read-only)
brightness :float
Float value between 0 and 1. Output brightness.
When brightness is less than 1.0, a second buffer will be used to store the color values before they are
adjusted for brightness.
auto_write :bool
Whether to automatically write the pixels after each update.
byteorder :str
byteorder string for the buffer (read-only)
show(self ) → None
Transmits the color data to the pixels so that they are shown. This is done automatically when
auto_write is True.
fill(self, color: Union[int, Tuple[int, int, int], Tuple[int, int, int, float]]) → None
Fills the given pixelbuf with the given color.
__getitem__(self, index: slice) → Union[Tuple[Tuple[int, int, int], . . . ], Tuple[Tuple[int, int, int,
float], . . . ]]
54 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
__getitem__(self, index: int) → Union[Tuple[int, int, int], Tuple[int, int, int, float]]
Returns the pixel value at the given index as a tuple of (Red, Green, Blue[, White]) values between 0 and
255. When in PWM (DotStar) mode, the 4th tuple value is a float of the pixel intensity from 0-1.0.
__setitem__(self, index: slice, value: Tuple[Union[int, Tuple[float, . . . ], List[float]], . . . ]) → None
__setitem__(self, index: slice, value: List[Union[int, Tuple[float, . . . ], List[float]]]) → None
__setitem__(self, index: int, value: Union[int, Tuple[float, . . . ], List[float]]) → None
Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are The individual
(Red, Green, Blue[, White]) values between 0 and 255. If given an integer, the red, green and blue values
are packed into the lower three bytes (0xRRGGBB). For RGBW byteorders, if given only RGB values
either as an int or as a tuple, the white value is used instead when the red, green, and blue values are the
same.
The _stage module contains native code to speed-up the `stage Library <https://github.com/python-ugame/
circuitpython-stage>`_.
_stage.render(x0: int, y0: int, x1: int, y1: int, layers: List[Layer], buffer: _typing.WriteableBuffer,
display: displayio.Display, scale: int, background: int) → None
Render and send to the display a fragment of the screen.
Parameters
• x0 (int) – Left edge of the fragment.
• y0 (int) – Top edge of the fragment.
• x1 (int) – Right edge of the fragment.
• y1 (int) – Bottom edge of the fragment.
• layers (list[Layer]) – A list of the Layer objects.
• buffer (WriteableBuffer) – A buffer to use for rendering.
• display (Display) – The display to use.
• scale (int) – How many times should the image be scaled up.
• background (int) – What color to display when nothing is there.
There are also no sanity checks, outside of the basic overflow checking. The caller is responsible for making the
passed parameters valid.
This function is intended for internal use in the stage library and all the necessary checks are performed there.
class _stage.Layer(width: int, height: int, graphic: _typing.ReadableBuffer, palette: _typ-
ing.ReadableBuffer, grid: _typing.ReadableBuffer)
Keep information about a single layer of graphics
Keep internal information about a layer of graphics (either a Grid or a Sprite) in a format suitable for fast
rendering with the render() function.
Parameters
• width (int) – The width of the grid in tiles, or 1 for sprites.
• height (int) – The height of the grid in tiles, or 1 for sprites.
• graphic (ReadableBuffer) – The graphic data of the tiles.
• palette (ReadableBuffer) – The color palette to be used.
_typing.ReadableBuffer
Classes that implement the readable buffer protocol
• bytes
• bytearray
• memoryview
• array.array
• ulab.array
• rgbmatrix.RGBMatrix
_typing.WriteableBuffer
Classes that implement the writeable buffer protocol
• bytearray
• memoryview
• array.array
• ulab.array
• rgbmatrix.RGBMatrix
_typing.AudioSample
Classes that implement the audiosample protocol
56 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
• audiocore.WaveFile
• audiocore.RawSample
• audiomixer.Mixer
• audiomp3.MP3Decoder
You can play these back with audioio.AudioOut, audiobusio.I2SOut or audiopwmio.
PWMAudioOut.
_typing.FrameBuffer
Classes that implement the framebuffer protocol
• rgbmatrix.RGBMatrix
_typing.Alarm
Classes that implement alarms for sleeping and asynchronous notification.
• alarm.pin.PinAlarm
• alarm.time.TimeAlarm
You can use these alarms to wake up from light or deep sleep.
The I2CDevice and SPIDevice helper classes make managing transaction state on a bus easy. For example, they
manage locking the bus to prevent other concurrent access. For SPI devices, it manages the chip select and protocol
changes such as mode. For I2C, it manages the device address.
class adafruit_bus_device.I2CDevice(i2c: busio.I2C, device_address: int, probe: bool = True)
I2C Device Manager
Represents a single I2C device and manages locking the bus and the device address. :param ~busio.I2C i2c:
The I2C bus the device is on :param int device_address: The 7 bit device address :param bool probe: Probe for
the device upon object creation, default is true
Example:
import busio
from board import *
from adafruit_bus_device.i2c_device import I2CDevice
with busio.I2C(SCL, SDA) as i2c:
device = I2CDevice(i2c, 0x70)
bytes_read = bytearray(4)
with device:
device.readinto(bytes_read)
# A second transaction
with device:
device.write(bytes_read)
__enter__(self ) → I2CDevice
Context manager entry to lock bus.
__exit__(self ) → None
Automatically unlocks the bus on exit.
readinto(self, buf: _typing.WriteableBuffer, *, start: int = 0, end: Optional[int] = None) → None
Read into buf from the device. The number of bytes read will be the length of buf. If start or end
is provided, then the buffer will be sliced as if buf[start:end]. This will not cause an allocation like
buf[start:end] will so it saves memory. :param bytearray buf: buffer to write into :param int start:
Index to start writing at :param int end: Index to write up to but not include; if None, use len(buf)
write(self, buf: _typing.ReadableBuffer, *, start: int = 0, end: Optional[int] = None) → None
Write the bytes from buffer to the device, then transmit a stop bit. If start or end is provided,
then the buffer will be sliced as if buffer[start:end]. This will not cause an allocation like
buffer[start:end] will so it saves memory. :param bytearray buf: buffer containing the bytes to
write :param int start: Index to start writing from :param int end: Index to read up to but not include; if
None, use len(buf)
write_then_readinto(self, out_buffer: _typing.WriteableBuffer, in_buffer: _typ-
ing.ReadableBuffer, *, out_start: int = 0, out_end: Optional[int] =
None, in_start: int = 0, in_end: Optional[int] = None) → None
Write the bytes from out_buffer to the device, then immediately reads into in_buffer from the
device. The number of bytes read will be the length of in_buffer. If out_start or out_end is pro-
vided, then the output buffer will be sliced as if out_buffer[out_start:out_end]. This will not
cause an allocation like buffer[out_start:out_end] will so it saves memory. If in_start or
in_end is provided, then the input buffer will be sliced as if in_buffer[in_start:in_end]. This
will not cause an allocation like in_buffer[in_start:in_end] will so it saves memory. :param
bytearray out_buffer: buffer containing the bytes to write :param bytearray in_buffer: buffer containing
the bytes to read into :param int out_start: Index to start writing from :param int out_end: Index to read up
to but not include; if None, use len(out_buffer) :param int in_start: Index to start writing at :param
int in_end: Index to write up to but not include; if None, use len(in_buffer)
class adafruit_bus_device.SPIDevice(spi: busio.SPI, chip_select: microcontroller.Pin, *, bau-
drate: int = 100000, polarity: int = 0, phase: int = 0,
extra_clocks: int = 0)
SPI Device Manager
Represents a single SPI device and manages locking the bus and the device address. :param ~busio.SPI spi: The
SPI bus the device is on :param ~digitalio.DigitalInOut chip_select: The chip select pin object that implements
the DigitalInOut API. :param int extra_clocks: The minimum number of clock cycles to cycle the bus after CS
is high. (Used for SD cards.)
Example:
import busio
import digitalio
from board import *
from adafruit_bus_device.spi_device import SPIDevice
with busio.SPI(SCK, MOSI, MISO) as spi_bus:
cs = digitalio.DigitalInOut(D10)
device = SPIDevice(spi_bus, cs)
bytes_read = bytearray(4)
# The object assigned to spi in the with statements below
# is the original spi_bus object. We are using the busio.SPI
# operations busio.SPI.readinto() and busio.SPI.write().
with device as spi:
spi.readinto(bytes_read)
# A second transaction
with device as spi:
spi.write(bytes_read)
__enter__(self ) → busio.SPI
Starts a SPI transaction by configuring the SPI and asserting chip select.
__exit__(self ) → None
Ends a SPI transaction by deasserting chip select. See Lifetime and ContextManagers for more info.
58 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
The AES module contains classes used to implement encryption and decryption. It aims to be low overhead in terms
of memory.
class aesio.AES(key: _typing.ReadableBuffer, mode: int = 0, iv: Optional[_typing.ReadableBuffer] =
None, segment_size: int = 8)
Encrypt and decrypt AES streams
Create a new AES state with the given key.
Parameters
• key (ReadableBuffer) – A 16-, 24-, or 32-byte key
• mode (int) – AES mode to use. One of: AES.MODE_ECB, AES.MODE_CBC, or
AES.MODE_CTR
• iv (ReadableBuffer) – Initialization vector to use for CBC or CTR mode
Additional arguments are supported for legacy reasons.
Encrypting a string:
import aesio
from binascii import hexlify
Provides alarms that trigger based on time intervals or on external events, such as pin changes. The program can
simply wait for these alarms, or go to sleep and be awoken when they trigger.
There are two supported levels of sleep: light sleep and deep sleep.
Light sleep keeps sufficient state so the program can resume after sleeping. It does not shut down WiFi, BLE, or other
communications, or ongoing activities such as audio playback. It reduces power consumption to the extent possible
that leaves these continuing activities running. In some cases there may be no decrease in power consumption.
Deep sleep shuts down power to nearly all of the microcontroller including the CPU and RAM. This can save a more
significant amount of power, but CircuitPython must restart code.py from the beginning when awakened.
For both light sleep and deep sleep, if CircuitPython is connected to a host computer, maintaining the connection takes
priority and power consumption may not be reduced.
class alarm.pin.PinAlarm(pin: microcontroller.Pin, value: bool, edge: bool = False, pull: bool =
False)
Create an alarm triggered by a microcontroller.Pin level. The alarm is not active until it is
passed to an alarm-enabling function, such as alarm.light_sleep_until_alarms() or alarm.
exit_and_deep_sleep_until_alarms().
Parameters
• pin (microcontroller.Pin) – The pin to monitor. On some ports, the choice of pin
may be limited due to hardware restrictions, particularly for deep-sleep alarms.
• value (bool) – When active, trigger when the pin value is high (True) or low (False).
On some ports, multiple PinAlarm objects may need to have coordinated values for deep-
sleep alarms.
• edge (bool) – If True, trigger only when there is a transition to the specified value of
value. If True, if the alarm becomes active when the pin value already matches value,
the alarm is not triggered: the pin must transition from not value to value to trigger
the alarm. On some ports, edge-triggering may not be available, particularly for deep-sleep
alarms.
• pull (bool) – Enable a pull-up or pull-down which pulls the pin to the level opposite that
of value. For instance, if value is set to True, setting pull to True will enable a
pull-down, to hold the pin low normally until an outside signal pulls it high.
pin :microcontroller.Pin
The trigger pin.
value :bool
The value on which to trigger.
60 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
import alarm
import time
print("Waking up")
# Deep sleep until the alarm goes off. Then restart the program.
alarm.exit_and_deep_sleep_until_alarms(time_alarm)
class alarm.SleepMemory
Store raw bytes in RAM that persists during deep sleep. The class acts as a bytearray. If power is lost, the
memory contents are lost.
Note that this class can’t be imported and used directly. The sole instance of SleepMemory is available at
alarm.sleep_memory.
Usage:
import alarm
alarm.sleep_memory[0] = True
alarm.sleep_memory[1] = 12
The analogio module contains classes to provide access to analog IO typically implemented with digital-to-analog
(DAC) and analog-to-digital (ADC) converters.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
For example:
import analogio
from board import *
pin = analogio.AnalogIn(A0)
print(pin.value)
pin.deinit()
This example will initialize the the device, read value and then deinit() the hardware. The last step is optional
because CircuitPython will do it automatically after the program finishes.
class analogio.AnalogIn(pin: microcontroller.Pin)
Read analog voltage levels
Usage:
import analogio
from board import *
62 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Use the AnalogIn on the given pin. The reference voltage varies by platform so use reference_voltage to
read the configured setting.
Parameters pin (Pin) – the pin to read from
value :int
The value on the analog pin between 0 and 65535 inclusive (16-bit). (read-only)
Even if the underlying analog to digital converter (ADC) is lower resolution, the value is 16-bit.
reference_voltage :float
The maximum voltage measurable (also known as the reference voltage) as a float in Volts.
deinit(self ) → None
Turn off the AnalogIn and release the pin for other use.
__enter__(self ) → AnalogIn
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
class analogio.AnalogOut(pin: microcontroller.Pin)
Output analog values (a specific voltage).
Example usage:
import analogio
from board import *
audiobusio – Support for audio input and output over digital buses
The audiobusio module contains classes to provide access to audio IO over digital buses. These protocols are
used to communicate audio to other chips in the same circuit. It doesn’t include audio interconnect protocols such as
S/PDIF.
All libraries change hardware state and should be deinitialized when they are no longer needed. To do so, either call
deinit() or use a context manager.
class audiobusio.I2SOut(bit_clock: microcontroller.Pin, word_select: microcontroller.Pin, data: mi-
crocontroller.Pin, *, left_justified: bool)
Output an I2S audio signal
Create a I2SOut object associated with the given pins.
Parameters
• bit_clock (Pin) – The bit clock (or serial clock) pin
• word_select (Pin) – The word select (or left/right clock) pin
• data (Pin) – The data pin
• left_justified (bool) – True when data bits are aligned with the word select clock.
False when they are shifted by one to match classic I2S protocol.
Simple 8ksps 440 Hz sine wave on Metro M0 Express using UDA1334 Breakout:
import audiobusio
import audiocore
import board
import array
import time
import math
import board
import audioio
import audiocore
import audiobusio
import digitalio
f = open("cplay-5.1-16bit-16khz.wav", "rb")
wav = audiocore.WaveFile(f)
64 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
print("playing")
a.play(wav)
while a.playing:
pass
print("stopped")
playing :bool
True when the audio sample is being output. (read-only)
paused :bool
True when playback is paused. (read-only)
deinit(self ) → None
Deinitialises the I2SOut and releases any hardware resources for reuse.
__enter__(self ) → I2SOut
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
play(self, sample: _typing.AudioSample, *, loop: bool = False) → None
Plays the sample once when loop=False and continuously when loop=True. Does not block. Use
playing to block.
Sample must be an audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer or
audiomp3.MP3Decoder.
The sample itself should consist of 8 bit or 16 bit samples.
stop(self ) → None
Stops playback.
pause(self ) → None
Stops playback temporarily while remembering the position. Use resume to resume playback.
resume(self ) → None
Resumes sample playback after pause().
class audiobusio.PDMIn(clock_pin: microcontroller.Pin, data_pin: microcontroller.Pin, *, sam-
ple_rate: int = 16000, bit_depth: int = 8, mono: bool = True, oversample:
int = 64, startup_delay: float = 0.11)
Record an input PDM audio stream
Create a PDMIn object associated with the given pins. This allows you to record audio signals from the given
pins. Individual ports may put further restrictions on the recording parameters. The overall sample rate is
determined by sample_rate x oversample, and the total must be 1MHz or higher, so sample_rate
must be a minimum of 16000.
Parameters
• clock_pin (Pin) – The pin to output the clock to
• data_pin (Pin) – The pin to read the data from
• sample_rate (int) – Target sample_rate of the resulting samples. Check
sample_rate for actual value. Minimum sample_rate is about 16000 Hz.
• bit_depth (int) – Final number of bits per sample. Must be divisible by 8
• mono (bool) – True when capturing a single channel of audio, captures two channels
otherwise
• oversample (int) – Number of single bit samples to decimate into a final sample. Must
be divisible by 8
• startup_delay (float) – seconds to wait after starting microphone clock to allow
microphone to turn on. Most require only 0.01s; some require 0.1s. Longer is safer. Must
be in range 0.0-1.0 seconds.
sample_rate :int
The actual sample_rate of the recording. This may not match the constructed sample rate due to internal
clock limitations.
deinit(self ) → None
Deinitialises the PDMIn and releases any hardware resources for reuse.
__enter__(self ) → PDMIn
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context.
record(self, destination: _typing.WriteableBuffer, destination_length: int) → None
Records destination_length bytes of samples to destination. This is blocking.
An IOError may be raised when the destination is too slow to record the audio at the given rate. For internal
flash, writing all 1s to the file before recording is recommended to speed up writes.
Returns The number of samples recorded. If this is less than destination_length, some
samples were missed due to processing time.
66 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
dac = audioio.AudioOut(board.SPEAKER)
sine_wave = audiocore.RawSample(sine_wave)
dac.play(sine_wave, loop=True)
time.sleep(1)
dac.stop()
sample_rate :Optional[int]
32 bit value that dictates how quickly samples are played in Hertz (cycles per second). When the sample
is looped, this can change the pitch output without changing the underlying sample. This will not change
the sample rate of any active playback. Call play again to change it.
deinit(self ) → None
Deinitialises the AudioOut and releases any hardware resources for reuse.
__enter__(self ) → RawSample
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
class audiocore.WaveFile(file: BinaryIO, buffer: _typing.WriteableBuffer)
Load a wave file for audio playback
A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must be 8 bit
unsigned or 16 bit signed. If a buffer is provided, it will be used instead of allocating an internal buffer.
Load a .wav file for playback with audioio.AudioOut or audiobusio.I2SOut.
Parameters
• file (typing.BinaryIO) – Already opened wave file
• buffer (WriteableBuffer) – Optional pre-allocated buffer, that will be split in half
and used for double-buffering of the data. If not provided, two 512 byte buffers are allocated
internally.
Playing a wave file from flash:
import board
import audiocore
import audioio
import digitalio
print("playing")
a.play(wav)
while a.playing:
(continues on next page)
sample_rate :int
32 bit value that dictates how quickly samples are loaded into the DAC in Hertz (cycles per second). When
the sample is looped, this can change the pitch output without changing the underlying sample.
bits_per_sample :int
Bits per sample. (read only)
channel_count :int
Number of audio channels. (read only)
deinit(self ) → None
Deinitialises the WaveFile and releases all memory resources for reuse.
__enter__(self ) → WaveFile
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
import audiocore
import audioio
import board
import array
(continues on next page)
68 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
dac = audioio.AudioOut(board.SPEAKER)
sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
dac.play(sine_wave, loop=True)
time.sleep(1)
dac.stop()
import board
import audioio
import digitalio
print("playing")
a.play(wav)
while a.playing:
pass
print("stopped")
playing :bool
True when an audio sample is being output even if paused. (read-only)
paused :bool
True when playback is paused. (read-only)
deinit(self ) → None
Deinitialises the AudioOut and releases any hardware resources for reuse.
__enter__(self ) → AudioOut
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
play(self, sample: _typing.AudioSample, *, loop: bool = False) → None
Plays the sample once when loop=False and continuously when loop=True. Does not block. Use
playing to block.
Sample must be an audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer or
audiomp3.MP3Decoder.
The sample itself should consist of 16 bit samples. Microcontrollers with a lower output resolution will
use the highest order bits to output. For example, the SAMD21 has a 10 bit DAC that ignores the lowest 6
bits when playing 16 bit samples.
stop(self ) → None
Stops playback and resets to the start of the sample.
pause(self ) → None
Stops playback temporarily while remembering the position. Use resume to resume playback.
resume(self ) → None
Resumes sample playback after pause().
import board
import audioio
import audiocore
import audiomixer
import digitalio
a = audioio.AudioOut(board.A0)
music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb"))
drum = audiocore.WaveFile(open("drum.wav", "rb"))
mixer = audiomixer.Mixer(voice_count=2, sample_rate=16000, channel_count=1,
bits_per_sample=16, samples_signed=True)
print("playing")
# Have AudioOut play our Mixer source
a.play(mixer)
# Play the first sample voice
mixer.voice[0].play(music)
while mixer.playing:
# Play the second sample voice
mixer.voice[1].play(drum)
time.sleep(1)
print("stopped")
70 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
playing :bool
True when any voice is being output. (read-only)
sample_rate :int
32 bit value that dictates how quickly samples are played in Hertz (cycles per second).
voice :Tuple[MixerVoice, ...]
A tuple of the mixer’s audiomixer.MixerVoice object(s).
>>> mixer.voice
(<MixerVoice>,)
deinit(self ) → None
Deinitialises the Mixer and releases any hardware resources for reuse.
__enter__(self ) → Mixer
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
play(self, sample: _typing.AudioSample, *, voice: int = 0, loop: bool = False) → None
Plays the sample once when loop=False and continuously when loop=True. Does not block. Use
playing to block.
Sample must be an audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer or
audiomp3.MP3Decoder.
The sample must match the Mixer’s encoding settings given in the constructor.
stop_voice(self, voice: int = 0) → None
Stops playback of the sample on the given voice.
class audiomixer.MixerVoice
Voice objects used with Mixer
Used to access and control samples with audiomixer.Mixer.
MixerVoice instance object(s) created by audiomixer.Mixer.
level :float
The volume level of a voice, as a floating point number between 0 and 1.
playing :bool
True when this voice is being output. (read-only)
play(self, sample: _typing.AudioSample, *, loop: bool = False) → None
Plays the sample once when loop=False, and continuously when loop=True. Does not block. Use
playing to block.
Sample must be an audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer or
audiomp3.MP3Decoder.
The sample must match the audiomixer.Mixer’s encoding settings given in the constructor.
stop(self ) → None
Stops playback of the sample on this voice.
import board
import audiomp3
import audioio
import digitalio
print("playing")
a.play(mp3)
while a.playing:
pass
print("stopped")
file :BinaryIO
File to play back.
sample_rate :int
32 bit value that dictates how quickly samples are loaded into the DAC in Hertz (cycles per second). When
the sample is looped, this can change the pitch output without changing the underlying sample.
bits_per_sample :int
Bits per sample. (read only)
channel_count :int
Number of audio channels. (read only)
rms_level :float
The RMS audio level of a recently played moment of audio. (read only)
deinit(self ) → None
Deinitialises the MP3 and releases all memory resources for reuse.
__enter__(self ) → MP3Decoder
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
72 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
import audiocore
import audiopwmio
import board
import array
import time
import math
dac = audiopwmio.PWMAudioOut(board.SPEAKER)
sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000)
dac.play(sine_wave, loop=True)
time.sleep(1)
dac.stop()
import board
import audiocore
import audiopwmio
import digitalio
print("playing")
a.play(wav)
while a.playing:
pass
print("stopped")
playing :bool
True when an audio sample is being output even if paused. (read-only)
paused :bool
True when playback is paused. (read-only)
deinit(self ) → None
Deinitialises the PWMAudioOut and releases any hardware resources for reuse.
__enter__(self ) → PWMAudioOut
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
play(self, sample: _typing.AudioSample, *, loop: bool = False) → None
Plays the sample once when loop=False and continuously when loop=True. Does not block. Use
playing to block.
Sample must be an audiocore.WaveFile, audiocore.RawSample, audiomixer.Mixer or
audiomp3.MP3Decoder.
The sample itself should consist of 16 bit samples. Microcontrollers with a lower output resolution will
use the highest order bits to output. For example, the SAMD21 has a 10 bit DAC that ignores the lowest 6
bits when playing 16 bit samples.
stop(self ) → None
Stops playback and resets to the start of the sample.
pause(self ) → None
Stops playback temporarily while remembering the position. Use resume to resume playback.
resume(self ) → None
Resumes sample playback after pause().
The bitbangio module contains classes to provide digital bus protocol support regardless of whether the underlying
hardware exists to use the protocol.
First try to use busio module instead which may utilize peripheral hardware to implement the protocols. Native
implementations will be faster than bitbanged versions and have more capabilities.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
For example:
74 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
import bitbangio
from board import *
This example will initialize the the device, run scan() and then deinit() the hardware. The last step is optional
because CircuitPython automatically resets hardware after a program finishes.
class bitbangio.I2C(scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 400000,
timeout: int = 255)
Two wire serial protocol
I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL
and SDA, the clock and data lines respectively.
See also:
Using this class directly requires careful lock management. Instead, use I2CDevice to manage locks.
See also:
Using this class to directly read registers requires manual bit unpacking. Instead, use an existing driver or make
one with Register data descriptors.
Parameters
• scl (Pin) – The clock pin
• sda (Pin) – The data pin
• frequency (int) – The clock frequency of the bus
• timeout (int) – The maximum clock stretching timeout in microseconds
deinit(self ) → None
Releases control of the underlying hardware so other classes can use it.
__enter__(self ) → I2C
No-op used in Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware on context exit. See Lifetime and ContextManagers for more
info.
scan(self ) → List[int]
Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of those that respond. A device
responds if it pulls the SDA line low after its address (including a read bit) is sent on the bus.
try_lock(self ) → bool
Attempts to grab the I2C lock. Returns True on success.
unlock(self ) → None
Releases the I2C lock.
readfrom_into(self, address: int, buffer: _typing.WriteableBuffer, *, start: int = 0, end: Op-
tional[int] = None) → None
Read into buffer from the device selected by address. The number of bytes read will be the length of
buffer. At least one byte must be read.
If start or end is provided, then the buffer will be sliced as if buffer[start:end]. This will not
cause an allocation like buf[start:end] will so it saves memory.
Parameters
• address (int) – 7-bit device address
• buffer (WriteableBuffer) – buffer to write into
• start (int) – Index to start writing at
• end (int) – Index to write up to but not include
writeto(self, address: int, buffer: _typing.ReadableBuffer, *, start: int = 0, end: Optional[int] =
None, stop: bool = True) → None
Write the bytes from buffer to the device selected by address and then transmits a stop bit. Use
writeto_then_readfrom when needing a write, no stop and repeated start before a read.
If start or end is provided, then the buffer will be sliced as if buffer[start:end]. This will not
cause an allocation like buffer[start:end] will so it saves memory.
Writing a buffer or slice of length zero is permitted, as it can be used to poll for the existence of a device.
Parameters
• address (int) – 7-bit device address
• buffer (ReadableBuffer) – buffer containing the bytes to write
• start (int) – Index to start writing from
• end (int) – Index to read up to but not include
writeto_then_readfrom(self, address: int, out_buffer: _typing.ReadableBuffer, in_buffer: _typ-
ing.ReadableBuffer, *, out_start: int = 0, out_end: Optional[int] =
None, in_start: int = 0, in_end: Optional[int] = None) → None
Write the bytes from out_buffer to the device selected by address, generate no stop bit, generate
a repeated start and read into in_buffer. out_buffer and in_buffer can be the same buffer
because they are used sequentially.
If start or end is provided, then the corresponding buffer will be sliced as if buffer[start:end].
This will not cause an allocation like buf[start:end] will so it saves memory.
Parameters
• address (int) – 7-bit device address
• out_buffer (ReadableBuffer) – buffer containing the bytes to write
• in_buffer (WriteableBuffer) – buffer to write into
• out_start (int) – Index to start writing from
• out_end (int) – Index to read up to but not include. Defaults to len(buffer)
• in_start (int) – Index to start writing at
• in_end (int) – Index to write up to but not include. Defaults to len(buffer)
class bitbangio.OneWire(pin: microcontroller.Pin)
Lowest-level of the Maxim OneWire protocol
OneWire implements the timing-sensitive foundation of the Maxim (formerly Dallas Semi) OneWire protocol.
Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126
Create a OneWire object associated with the given pin. The object implements the lowest level timing-sensitive
bits of the protocol.
Parameters pin (Pin) – Pin to read pulses from.
76 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
import bitbangio
import board
onewire = bitbangio.OneWire(board.D7)
onewire.reset()
onewire.write_bit(True)
onewire.write_bit(False)
print(onewire.read_bit())
deinit(self ) → None
Deinitialize the OneWire bus and release any hardware resources for reuse.
__enter__(self ) → OneWire
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
reset(self ) → bool
Reset the OneWire bus
read_bit(self ) → bool
Read in a bit
Returns bit state read
Return type bool
write_bit(self, value: bool) → None
Write out a bit based on value.
class bitbangio.SPI(clock: microcontroller.Pin, MOSI: Optional[microcontroller.Pin] = None, MISO:
Optional[microcontroller.Pin] = None)
A 3-4 wire serial protocol
SPI is a serial protocol that has exclusive pins for data in and out of the main device. It is typically faster than
I2C because a separate pin is used to select a device rather than a transmitted address. This class only manages
three of the four SPI lines: clock, MOSI, MISO. Its up to the client to manage the appropriate select line, often
abbreviated CS or SS. (This is common because multiple secondaries can share the clock, MOSI and MISO
lines and therefore the hardware.)
Construct an SPI object on the given pins.
See also:
Using this class directly requires careful lock management. Instead, use SPIDevice to manage locks.
See also:
Using this class to directly read registers requires manual bit unpacking. Instead, use an existing driver or make
one with Register data descriptors.
Parameters
• clock (Pin) – the pin to use for the clock.
• MOSI (Pin) – the Main Out Selected In pin.
• MISO (Pin) – the Main In Selected Out pin.
deinit(self ) → None
Turn off the SPI bus.
__enter__(self ) → SPI
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
configure(self, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) → None
Configures the SPI bus. Only valid when locked.
Parameters
• baudrate (int) – the clock rate in Hertz
• polarity (int) – the base state of the clock line (0 or 1)
• phase (int) – the edge of the clock that data is captured. First (0) or second (1). Rising
or falling depends on clock polarity.
• bits (int) – the number of bits per word
try_lock(self ) → bool
Attempts to grab the SPI lock. Returns True on success.
Returns True when lock has been grabbed
Return type bool
unlock(self ) → None
Releases the SPI lock.
write(self, buf: _typing.ReadableBuffer) → None
Write the data contained in buf. Requires the SPI being locked. If the buffer is empty, nothing happens.
readinto(self, buffer: _typing.WriteableBuffer, *, start: int = 0, end: Optional[int] = None,
write_value: int = 0) → None
Read into buffer while writing write_value for each byte read. The SPI object must be locked. If
the number of bytes to read is 0, nothing happens.
Parameters
• buffer (bytearray) – Read data into this buffer
• start (int) – Start of the slice of buffer to read into: buffer[start:end]
• end (int) – End of the slice; this index is not included. Defaults to len(buffer)
• write_value (int) – Value to write while reading.
write_readinto(self, buffer_out: _typing.ReadableBuffer, buffer_in: _typing.ReadableBuffer, *,
out_start: int = 0, out_end: Optional[int] = None, in_start: int = 0, in_end: Op-
tional[int] = None) → None
Write out the data in buffer_out while simultaneously reading data into buffer_in. The SPI ob-
ject must be locked. The lengths of the slices defined by buffer_out[out_start:out_end] and
buffer_in[in_start:in_end] must be equal. If buffer slice lengths are both 0, nothing happens.
Parameters
• buffer_out (ReadableBuffer) – Write out the data in this buffer
• buffer_in (WriteableBuffer) – Read data into this buffer
78 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
bitmaptools.fill_region(dest_bitmap: displayio.Bitmap, x1: int, y1: int, x2: int, y2: int, value: int)
→ None
Draws the color value into the destination bitmap within the rectangular region bounded by (x1,y1) and (x2,y2),
exclusive.
Parameters
• dest_bitmap (bitmap) – Destination bitmap that will be written into
• x1 (int) – x-pixel position of the first corner of the rectangular fill region
• y1 (int) – y-pixel position of the first corner of the rectangular fill region
• x2 (int) – x-pixel position of the second corner of the rectangular fill region (exclusive)
• y2 (int) – y-pixel position of the second corner of the rectangular fill region (exclusive)
• value (int) – Bitmap palette index that will be written into the rectangular fill region in
the destination bitmap
bitmaptools.draw_line(dest_bitmap: displayio.Bitmap, x1: int, y1: int, x2: int, y2: int, value: int) →
None
Draws a line into a bitmap specified two endpoints (x1,y1) and (x2,y2).
Parameters
• dest_bitmap (bitmap) – Destination bitmap that will be written into
• x1 (int) – x-pixel position of the line’s first endpoint
• y1 (int) – y-pixel position of the line’s first endpoint
• x2 (int) – x-pixel position of the line’s second endpoint
• y2 (int) – y-pixel position of the line’s second endpoint
• value (int) – Bitmap palette index that will be written into the line in the destination
bitmap
bitmaptools.arrayblit(bitmap: displayio.Bitmap, data: _typing.ReadableBuffer, x1: int = 0, y1: int
= 0, x2: Optional[int] = None, y2: Optional[int] = None, skip_index: Op-
tional[int] = None) → None
Inserts pixels from data into the rectangle of width×height pixels with the upper left corner at (x,y)
The values from data are taken modulo the number of color values avalable in the destination bitmap.
If x1 or y1 are not specified, they are taken as 0. If x2 or y2 are not specified, or are given as -1, they are taken
as the width and height of the image.
The coordinates affected by the blit are x1 <= x < x2 and y1 <= y < y2.
data must contain at least as many elements as required. If it contains excess elements, they are ignored.
The blit takes place by rows, so the first elements of data go to the first row, the next elements to the next row,
and so on.
Parameters
• bitmap (displayio.Bitmap) – A writable bitmap
• data (ReadableBuffer) – Buffer containing the source pixel values
• x1 (int) – The left corner of the area to blit into (inclusive)
• y1 (int) – The top corner of the area to blit into (inclusive)
• x2 (int) – The right of the area to blit into (exclusive)
• y2 (int) – The bottom corner of the area to blit into (exclusive)
80 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
• skip_index (int) – Bitmap palette index in the source that will not be copied, set to
None to copy all pixels
bitmaptools.readinto(bitmap: displayio.Bitmap, file: BinaryIO, bits_per_pixel: int, element_size: int
= 1, reverse_pixels_in_element: bool = False, swap_bytes_in_element: bool =
False, reverse_rows: bool = False) → None
Reads from a binary file into a bitmap.
The file must be positioned so that it consists of bitmap.height rows of pixel data, where each row is the
smallest multiple of element_size bytes that can hold bitmap.width pixels.
The bytes in an element can be optionally swapped, and the pixels in an element can be reversed. Also, the row
loading direction can be reversed, which may be requires for loading certain bitmap files.
This function doesn’t parse image headers, but is useful to speed up loading of uncompressed image formats
such as PCF glyph data.
Parameters
• bitmap (displayio.Bitmap) – A writable bitmap
• file (typing.BinaryIO) – A file opened in binary mode
• bits_per_pixel (int) – Number of bits per pixel. Values 1, 2, 4, 8, 16, 24, and 32 are
supported;
• element_size (int) – Number of bytes per element. Values of 1, 2, and 4 are supported,
except that 24 bits_per_pixel requires 1 byte per element.
• reverse_pixels_in_element (bool) – If set, the first pixel in a word is taken from
the Most Signficant Bits; otherwise, it is taken from the Least Significant Bits.
• swap_bytes_in_element (bool) – If the element_size is not 1, then reverse the
byte order of each element read.
• reverse_rows (bool) – Reverse the direction of the row loading (required for some
bitmap images).
Common container for board base pin names. These will vary from board to board so don’t expect portability when
using this module.
Warning: The board module varies by board. The APIs documented here may or may not be available on a
specific board.
board.I2C() → busio.I2C
Returns the busio.I2C object for the board designated SDA and SCL pins. It is a singleton.
board.SPI() → busio.SPI
Returns the busio.SPI object for the board designated SCK, MOSI and MISO pins. It is a singleton.
board.UART() → busio.UART
Returns the busio.UART object for the board designated TX and RX pins. It is a singleton.
The object created uses the default parameter values for busio.UART. If you need to set parameters that
are not changeable after creation, such as receiver_buffer_size, do not use board.UART(); instead
create a busio.UART object explicitly with the desired parameters.
import busio
from board import *
This example will initialize the the device, run scan() and then deinit() the hardware. The last step is optional
because CircuitPython automatically resets hardware after a program finishes.
class busio.I2C(scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 100000, timeout:
int = 255)
Two wire serial protocol
I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL
and SDA, the clock and data lines respectively.
See also:
Using this class directly requires careful lock management. Instead, use I2CDevice to manage locks.
82 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
See also:
Using this class to directly read registers requires manual bit unpacking. Instead, use an existing driver or make
one with Register data descriptors.
Parameters
• scl (Pin) – The clock pin
• sda (Pin) – The data pin
• frequency (int) – The clock frequency in Hertz
• timeout (int) – The maximum clock stretching timeut - (used only for bitbangio.I2C;
ignored for busio.I2C)
Note: On the nRF52840, only one I2C object may be created, except on the Circuit Playground Bluefruit,
which allows two, one for the onboard accelerometer, and one for offboard use.
deinit(self ) → None
Releases control of the underlying hardware so other classes can use it.
__enter__(self ) → I2C
No-op used in Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware on context exit. See Lifetime and ContextManagers for more
info.
scan(self ) → List[int]
Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of those that respond.
Returns List of device ids on the I2C bus
Return type list
try_lock(self ) → bool
Attempts to grab the I2C lock. Returns True on success.
Returns True when lock has been grabbed
Return type bool
unlock(self ) → None
Releases the I2C lock.
readfrom_into(self, address: int, buffer: _typing.WriteableBuffer, *, start: int = 0, end: Op-
tional[int] = None) → None
Read into buffer from the device selected by address. The number of bytes read will be the length of
buffer. At least one byte must be read.
If start or end is provided, then the buffer will be sliced as if buffer[start:end]. This will not
cause an allocation like buf[start:end] will so it saves memory.
Parameters
• address (int) – 7-bit device address
• buffer (WriteableBuffer) – buffer to write into
• start (int) – Index to start writing at
• end (int) – Index to write up to but not include. Defaults to len(buffer)
onewire = busio.OneWire(board.D7)
onewire.reset()
onewire.write_bit(True)
(continues on next page)
84 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
deinit(self ) → None
Deinitialize the OneWire bus and release any hardware resources for reuse.
__enter__(self ) → OneWire
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
reset(self ) → bool
Reset the OneWire bus and read presence
Returns False when at least one device is present
Return type bool
read_bit(self ) → bool
Read in a bit
Returns bit state read
Return type bool
write_bit(self, value: bool) → None
Write out a bit based on value.
class busio.SPI(clock: microcontroller.Pin, MOSI: Optional[microcontroller.Pin] = None, MISO: Op-
tional[microcontroller.Pin] = None)
A 3-4 wire serial protocol
SPI is a serial protocol that has exclusive pins for data in and out of the main device. It is typically faster than
I2C because a separate pin is used to select a device rather than a transmitted address. This class only manages
three of the four SPI lines: clock, MOSI, MISO. Its up to the client to manage the appropriate select line, often
abbreviated CS or SS. (This is common because multiple secondaries can share the clock, MOSI and MISO
lines and therefore the hardware.)
Construct an SPI object on the given pins.
Note: The SPI peripherals allocated in order of desirability, if possible, such as highest speed and not shared use
first. For instance, on the nRF52840, there is a single 32MHz SPI peripheral, and multiple 8MHz peripherals,
some of which may also be used for I2C. The 32MHz SPI peripheral is returned first, then the exclusive 8MHz
SPI peripheral, and finally the shared 8MHz peripherals.
See also:
Using this class directly requires careful lock management. Instead, use SPIDevice to manage locks.
See also:
Using this class to directly read registers requires manual bit unpacking. Instead, use an existing driver or make
one with Register data descriptors.
Parameters
• clock (Pin) – the pin to use for the clock.
• MOSI (Pin) – the Main Out Selected In pin.
frequency :int
The actual SPI bus frequency. This may not match the frequency requested due to internal limitations.
deinit(self ) → None
Turn off the SPI bus.
__enter__(self ) → SPI
No-op used by Context Managers. Provided by context manager helper.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
configure(self, *, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) → None
Configures the SPI bus. The SPI object must be locked.
Parameters
• baudrate (int) – the desired clock rate in Hertz. The actual clock rate may be higher or
lower due to the granularity of available clock settings. Check the frequency attribute
for the actual clock rate.
• polarity (int) – the base state of the clock line (0 or 1)
• phase (int) – the edge of the clock that data is captured. First (0) or second (1). Rising
or falling depends on clock polarity.
• bits (int) – the number of bits per word
Note: On the SAMD21, it is possible to set the baudrate to 24 MHz, but that speed is not guaranteed to
work. 12 MHz is the next available lower speed, and is within spec for the SAMD21.
Note: On the nRF52840, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, and
8MHz. If you pick a a baudrate other than one of these, the nearest lower baudrate will be chosen, with a
minimum of 125kHz. Two SPI objects may be created, except on the Circuit Playground Bluefruit, which
allows only one (to allow for an additional I2C object).
try_lock(self ) → bool
Attempts to grab the SPI lock. Returns True on success.
Returns True when lock has been grabbed
Return type bool
unlock(self ) → None
Releases the SPI lock.
write(self, buffer: _typing.ReadableBuffer, *, start: int = 0, end: Optional[int] = None) → None
Write the data contained in buffer. The SPI object must be locked. If the buffer is empty, nothing
happens.
Parameters
• buffer (ReadableBuffer) – Write out the data in this buffer
• start (int) – Start of the slice of buffer to write out: buffer[start:end]
• end (int) – End of the slice; this index is not included. Defaults to len(buffer)
86 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
• timeout (float) – the timeout in seconds to wait for the first character and between
subsequent characters when reading. Raises ValueError if timeout >100 seconds.
• receiver_buffer_size (int) – the character length of the read buffer (0 to disable).
(When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
New in CircuitPython 4.0: timeout has incompatibly changed units from milliseconds to seconds. The new
upper limit on timeout is meant to catch mistaken use of milliseconds.
baudrate :int
The current baudrate.
in_waiting :int
The number of bytes in the input buffer, available to be read
timeout :float
The current timeout, in seconds (float).
deinit(self ) → None
Deinitialises the UART and releases any hardware resources for reuse.
__enter__(self ) → UART
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
read(self, nbytes: Optional[int] = None) → Optional[bytes]
Read characters. If nbytes is specified then read at most that many bytes. Otherwise, read everything
that arrives until the connection times out. Providing the number of bytes expected is highly recommended
because it will be faster.
Returns Data read
Return type bytes or None
readinto(self, buf: _typing.WriteableBuffer) → Optional[int]
Read bytes into the buf. Read at most len(buf) bytes.
Returns number of bytes read and stored into buf
Return type int or None (on a non-blocking error)
New in CircuitPython 4.0: No length parameter is permitted.
readline(self ) → bytes
Read a line, ending in a newline character, or return None if a timeout occurs sooner, or return every-
thing readable if no newline is found and timeout=0
88 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
reset_input_buffer(self ) → None
Discard any unread characters in the input buffer.
class busio.Parity
Enum-like class to define the parity used to verify correct data transfer.
ODD :int
Total number of ones should be odd.
EVEN :int
Total number of ones should be even.
The camera module contains classes to control the camera and take pictures.
class camera.Camera
The class to control camera.
Usage:
import board
import sdioio
import storage
import camera
sd = sdioio.SDCard(
clock=board.SDIO_CLOCK,
command=board.SDIO_COMMAND,
data=board.SDIO_DATA,
frequency=25000000)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
cam = camera.Camera()
file.write(buffer, size)
file.close()
Initialize camera.
deinit(self ) → None
De-initialize camera.
take_picture(self, buf: _typing.WriteableBuffer, format: ImageFormat) → int
Take picture and save to buf in the given format. The size of the picture taken is width by height
in pixels.
Returns the number of bytes written into buf
Return type int
class camera.ImageFormat
Image format
Enum-like class to define the image format.
JPG :ImageFormat
JPG format.
RGB565 :ImageFormat
RGB565 format.
The canio module contains low level classes to support the CAN bus protocol.
CAN and Listener classes change hardware state and should be deinitialized when they are no longer needed if the
program continues after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextMan-
agers for more info.
For example:
import canio
from board import *
This example will write the data ‘adafruit’ onto the CAN bus to any device listening for message id 0x0408.
A CAN bus involves a transceiver, which is often a separate chip with a “standby” pin. If your board has a
CAN_STANDBY pin, ensure to set it to an output with the value False to enable the transceiver.
Other implementations of the CAN device may exist (for instance, attached via an SPI bus). If so their constructor
arguments may differ, but otherwise we encourage implementors to follow the API that the core uses.
class canio.BusState
The state of the CAN bus
ERROR_ACTIVE :object
The bus is in the normal (active) state
ERROR_WARNING :object
The bus is in the normal (active) state, but a moderate number of errors have occurred recently.
NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ER-
ROR_WARNING before ERROR_PASSIVE.
ERROR_PASSIVE :object
The bus is in the passive state due to the number of errors that have occurred recently.
This device will acknowledge packets it receives, but cannot transmit messages. If additional errors occur,
this device may progress to BUS_OFF. If it successfully acknowledges other packets on the bus, it can
return to ERROR_WARNING or ERROR_ACTIVE and transmit packets.
BUS_OFF :object
The bus has turned off due to the number of errors that have occurred recently. It must be restarted before
it will send or receive packets. This device will neither send or acknowledge packets on the bus.
class canio.CAN(tx: microcontroller.Pin, rx: microcontroller.Pin, *, baudrate: int = 250000, loopback:
bool = False, silent: bool = False, auto_restart: bool = False)
CAN bus protocol
A common shared-bus protocol. The rx and tx pins are generally connected to a transceiver which controls the
H and L pins on a shared bus.
90 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
Parameters
• rx (Pin) – the pin to receive with
• tx (Pin) – the pin to transmit with
• baudrate (int) – The bit rate of the bus in Hz. All devices on the bus must agree on this
value.
• loopback (bool) – When True the rx pin’s value is ignored, and the device receives the
packets it sends.
• silent (bool) – When True the tx pin is always driven to the high logic level. This
mode can be used to “sniff” a CAN bus without interfering.
• auto_restart (bool) – If True, will restart communications after entering bus-off state
auto_restart :bool
If True, will restart communications after entering bus-off state
baudrate :int
The baud rate (read-only)
transmit_error_count :int
The number of transmit errors (read-only). Increased for a detected transmission error, decreased for
successful transmission. Limited to the range from 0 to 255 inclusive. Also called TEC.
receive_error_count :int
The number of receive errors (read-only). Increased for a detected reception error, decreased for successful
reception. Limited to the range from 0 to 255 inclusive. Also called REC.
state :BusState
The current state of the bus. (read-only)
loopback :bool
True if the device was created in loopback mode, False otherwise (read-only)
silent :bool
True if the device was created in silent mode, False otherwise (read-only)
restart(self ) → None
If the device is in the bus off state, restart it.
listen(self, matches: Optional[Sequence[Match]] = None, *, timeout: float = 10) → Listener
Start receiving messages that match any one of the filters.
Creating a listener is an expensive operation and can interfere with reception of messages by other listeners.
There is an implementation-defined maximum number of listeners and limit to the complexity of the filters.
If the hardware cannot support all the requested matches, a ValueError is raised. Note that generally there
are some number of hardware filters shared among all fifos.
A message can be received by at most one Listener. If more than one listener matches a message, it is
undefined which one actually receives it.
An empty filter list causes all messages to be accepted.
Timeout dictates how long receive() and next() will block.
Platform specific notes:
SAM E5x supports two Listeners. Filter blocks are shared between the two listeners. There are 4 standard
filter blocks and 4 extended filter blocks. Each block can either match 2 single addresses or a mask
of addresses. The number of filter blocks can be increased, up to a hardware maximum, by rebuilding
CircuitPython, but this decreases the CircuitPython free memory even if canio is not used.
STM32F405 supports two Listeners. Filter blocks are shared between the two listeners. There are 14 filter
blocks. Each block can match 2 standard addresses with mask or 1 extended address with mask.
ESP32S2 supports one Listener. There is a single filter block, which can either match a standard address
with mask or an extended address with mask.
send(self, message: Union[RemoteTransmissionRequest, Message]) → None
Send a message on the bus with the given data and id. If the message could not be sent due to a full fifo or
a bus error condition, RuntimeError is raised.
deinit(self ) → None
Deinitialize this object, freeing its hardware resources
__enter__(self ) → CAN
Returns self, to allow the object to be used in a The with statement statement for resource control
__exit__(self, unused1: Optional[Type[BaseException]], unused2: Optional[BaseException], un-
used3: Optional[types.TracebackType]) → None
Calls deinit()
class canio.Listener
Listens for CAN message
canio.Listener is not constructed directly, but instead by calling canio.CAN.listen.
In addition to using the receive method to retrieve a message or the in_waiting method to check for
an available message, a listener can be used as an iterable, yielding messages until no message arrives within
self.timeout seconds.
timeout :float
receive(self ) → Optional[Union[RemoteTransmissionRequest, Message]]
Reads a message, after waiting up to self.timeout seconds
If no message is received in time, None is returned. Otherwise, a Message or
RemoteTransmissionRequest is returned.
in_waiting(self ) → int
Returns the number of messages (including remote transmission requests) waiting
__iter__(self ) → Listener
Returns self
This method exists so that Listener can be used as an iterable
__next__(self ) → Union[RemoteTransmissionRequest, Message]
Reads a message, after waiting up to self.timeout seconds
If no message is received in time, raises StopIteration. Otherwise, a Message or is returned.
This method enables the Listener to be used as an iterable, for instance in a for-loop.
deinit(self ) → None
Deinitialize this object, freeing its hardware resources
__enter__(self ) → CAN
Returns self, to allow the object to be used in a The with statement statement for resource control
__exit__(self, unused1: Optional[Type[BaseException]], unused2: Optional[BaseException], un-
used3: Optional[types.TracebackType]) → None
Calls deinit()
92 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
The countio module contains logic to read and count edge transistions
Warning: This module is not available in some SAMD21 (aka M0) builds. See the Module Support Matrix -
Which Modules Are Available on Which Boards for more info.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
class countio.Counter(pin_a: microcontroller.Pin)
Counter will keep track of the number of falling edge transistions (pulses) on a given pin
Create a Counter object associated with the given pin. It tracks the number of falling pulses relative when the
object is constructed.
Parameters pin_a (Pin) – Pin to read pulses from.
For example:
import board
import countio
pin_counter = countio.Counter(board.D1)
#reset the count after 100 counts
while True:
if pin_counter.count == 100:
pin_counter.reset()
print(pin_counter.count)
count :int
The current count in terms of pulses.
deinit(self ) → None
Deinitializes the Counter and releases any hardware resources for reuse.
__enter__(self ) → Counter
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
reset(self ) → None
Resets the count back to 0.
94 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
The digitalio module contains classes to provide access to basic digital IO.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
For example:
import digitalio
from board import *
pin = digitalio.DigitalInOut(D13)
print(pin.value)
This example will initialize the the device, read value and then deinit() the hardware.
Here is blinky:
import digitalio
from board import *
import time
led = digitalio.DigitalInOut(D13)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(0.1)
led.value = False
time.sleep(0.1)
class digitalio.DriveMode
Defines the drive mode of a digital pin
Enum-like class to define the drive mode used when outputting digital values.
PUSH_PULL :DriveMode
Output both high and low digital values
OPEN_DRAIN :DriveMode
Output low digital values but go into high z for digital high. This is useful for i2c and other protocols that
share a digital line.
class digitalio.DigitalInOut(pin: microcontroller.Pin)
Digital input and output
A DigitalInOut is used to digitally control I/O pins. For analog control of a pin, see the analogio.AnalogIn
and analogio.AnalogOut classes.
Create a new DigitalInOut object associated with the pin. Defaults to input with no pull. Use
switch_to_input() and switch_to_output() to change the direction.
Parameters pin (Pin) – The pin to control
direction :Direction
The direction of the pin.
Setting this will use the defaults from the corresponding switch_to_input() or
switch_to_output() method. If you want to set pull, value or drive mode prior to switching,
then use those methods instead.
value :bool
The digital logic level of the pin.
drive_mode :DriveMode
The pin drive mode. One of:
• digitalio.DriveMode.PUSH_PULL
• digitalio.DriveMode.OPEN_DRAIN
pull :Optional[Pull]
The pin pull direction. One of:
• digitalio.Pull.UP
• digitalio.Pull.DOWN
• None
deinit(self ) → None
Turn off the DigitalInOut and release the pin for other use.
__enter__(self ) → DigitalInOut
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
switch_to_output(self, value: bool = False, drive_mode: DriveMode = DriveMode.PUSH_PULL)
→ None
Set the drive mode and value and then switch to writing out digital values.
Parameters
• value (bool) – default value to set upon switching
• drive_mode (DriveMode) – drive mode for the output
switch_to_input(self, pull: Optional[Pull] = None) → None
Set the pull and then switch to read in digital values.
Parameters pull (Pull) – pull configuration for the input
Example usage:
import digitalio
import board
switch = digitalio.DigitalInOut(board.SLIDE_SWITCH)
switch.switch_to_input(pull=digitalio.Pull.UP)
# Or, after switch_to_input
switch.pull = digitalio.Pull.UP
print(switch.value)
class digitalio.Direction
Defines the direction of a digital pin
Enum-like class to define which direction the digital values are going.
INPUT :Direction
Read digital data in
96 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
OUTPUT :Direction
Write digital data out
class digitalio.Pull
Defines the pull of a digital input pin
Enum-like class to define the pull value, if any, used while reading digital values in.
UP :Pull
When the input line isn’t being driven the pull up can pull the state of the line high so it reads as true.
DOWN :Pull
When the input line isn’t being driven the pull down can pull the state of the line low so it reads as false.
The displayio module contains classes to manage display output including synchronizing with refresh rates and
partial updating.
displayio.release_displays() → None
Releases any actively used displays so their busses and pins can be used again. This will also release the builtin
display on boards that have one. You will need to reinitialize it yourself afterwards. This may take seconds to
complete if an active EPaperDisplay is refreshing.
Use this once in your code.py if you initialize a display. Place it right before the initialization so the display is
active as long as possible.
class displayio.Bitmap(width: int, height: int, value_count: int)
Stores values of a certain size in a 2D array
Bitmaps can be treated as read-only buffers. If the number of bits in a pixel is 8, 16, or 32; and the number
of bytes per row is a multiple of 4, then the resulting memoryview will correspond directly with the bitmap’s
contents. Otherwise, the bitmap data is packed into the memoryview with unspecified padding.
A read-only buffer can be used e.g., with ulab.frombuffer to efficiently create an array with the same
content as a Bitmap; to move data efficiently from ulab back into a Bitmap, use bitmaptools.arrayblit.
Create a Bitmap object with the given fixed size. Each pixel stores a value that is used to index into a corre-
sponding palette. This enables differently colored sprites to share the underlying Bitmap. value_count is used
to minimize the memory used to store the Bitmap.
Parameters
• width (int) – The number of values wide
• height (int) – The number of values high
• value_count (int) – The number of possible pixel values.
width :int
Width of the bitmap. (read only)
height :int
Height of the bitmap. (read only)
__getitem__(self, index: Union[Tuple[int, int], int]) → int
Returns the value at the given index. The index can either be an x,y tuple or an int equal to y * width
+ x.
This allows you to:
print(bitmap[0,1])
bitmap[0,1] = 3
blit(self, x: int, y: int, source_bitmap: Bitmap, *, x1: int, y1: int, x2: int, y2: int, skip_index: int) →
None
Inserts the source_bitmap region defined by rectangular boundaries (x1,y1) and (x2,y2) into the
bitmap at the specified (x,y) location.
Parameters
• x (int) – Horizontal pixel location in bitmap where source_bitmap upper-left corner will
be placed
• y (int) – Vertical pixel location in bitmap where source_bitmap upper-left corner will be
placed
• source_bitmap (bitmap) – Source bitmap that contains the graphical region to be
copied
• x1 (int) – Minimum x-value for rectangular bounding box to be copied from the source
bitmap
• y1 (int) – Minimum y-value for rectangular bounding box to be copied from the source
bitmap
• x2 (int) – Maximum x-value (exclusive) for rectangular bounding box to be copied from
the source bitmap
• y2 (int) – Maximum y-value (exclusive) for rectangular bounding box to be copied from
the source bitmap
• skip_index (int) – bitmap palette index in the source that will not be copied, set to
None to copy all pixels
98 Chapter 1. CircuitPython
CircuitPython Documentation, Release 6.3.0
init_sequence = (b"\xe1\x0f\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\
˓→x36\x0F" # Set Gamma
The first command is 0xe1 with 15 (0xf) parameters following. The second is 0x11 with 0 parameters and a
120ms (0x78) delay. The third command is 0x29 with one parameter 0xaa and a 120ms delay (0x78). Multiple
byte literals (b””) are merged together on load. The parens are needed to allow byte literals on subsequent lines.
The initialization sequence should always leave the display memory access inline with the scan of the display to
minimize tearing artifacts.
Parameters
• display_bus – The bus that the display is connected to
• init_sequence (ReadableBuffer) – Byte-packed initialization sequence.
• width (int) – Width in pixels
• height (int) – Height in pixels
• colstart (int) – The index if the first visible column
• rowstart (int) – The index if the first visible row
• rotation (int) – The rotation of the display in degrees clockwise. Must be in 90 degree
increments (0, 90, 180, 270)
• color_depth (int) – The number of bits of color per pixel transmitted. (Some displays
support 18 bit but 16 is easier to transmit. The last bit is extrapolated.)
• grayscale (bool) – True if the display only shows a single color.
• pixels_in_byte_share_row (bool) – True when pixels are less than a byte and a
byte includes pixels from the same row of the display. When False, pixels share a column.
• bytes_per_cell (int) – Number of bytes per addressable memory location when
color_depth < 8. When greater than one, bytes share a row or column according to pix-
els_in_byte_share_row.
• reverse_pixels_in_byte (bool) – Reverses the pixel order within each byte when
color_depth < 8. Does not apply across multiple bytes even if there is more than one byte
per cell (bytes_per_cell.)
• reverse_bytes_in_word (bool) – Reverses the order of bytes within a word when
color_depth == 16
• set_column_command (int) – Command used to set the start and end columns to up-
date
• set_row_command (int) – Command used so set the start and end rows to update
• write_ram_command (int) – Command used to write pixels values into the update
region. Ignored if data_as_commands is set.
• set_vertical_scroll (int) – Command used to set the first row to show
• backlight_pin (microcontroller.Pin) – Pin connected to the display’s back-
light
• brightness_command (int) – Command to set display brightness. Usually available
in OLED controllers.
• brightness (float) – Initial display brightness. This value is ignored if
auto_brightness is True.
• auto_brightness (bool) – If True, brightness is controlled via an ambient light sensor
or other mechanism.
• single_byte_bounds (bool) – Display column and row commands use single bytes
• data_as_commands (bool) – Treat all init and boundary data as SPI commands. Cer-
tain displays require this.
• SH1107_addressing (bool) – Special quirk for SH1107, use upper/lower column set
and page set
• auto_refresh (bool) – Automatically refresh the screen
• native_frames_per_second (int) – Number of display refreshes per second that
occur with the given init_sequence.
• backlight_on_high (bool) – If True, pulling the backlight pin high turns the back-
light on.
auto_refresh :bool
True when the display is refreshed automatically.
brightness :float
The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When
auto_brightness is True, the value of brightness will change automatically. If brightness is
set, auto_brightness will be disabled and will be set to False.
auto_brightness :bool
True when the display brightness is adjusted automatically, based on an ambient light sensor or other
method. Note that some displays may have this set to True by default, but not actually implement automatic
brightness adjustment. auto_brightness is set to False if brightness is set manually.
width :int
Gets the width of the board
height :int
Gets the height of the board
rotation :int
The rotation of the display as an int in degrees.
bus :_DisplayBus
The bus being used by the display
show(self, group: Group) → None
Switches to displaying the given group of layers. When group is None, the default CircuitPython terminal
will be shown.
Parameters group (Group) – The group to show.
refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int
= 1) → bool
When auto refresh is off, waits for the target frame rate and then refreshes the display, returning True. If
the call has taken too long since the last refresh call for the given target frame rate, then the refresh returns
False immediately without updating the screen to hopefully help getting caught up.
If the time since the last successful refresh is below the minimum frame rate, then an exception will be
raised. Set minimum_frames_per_second to 0 to disable.
When auto refresh is off, display.refresh() or display.
refresh(target_frames_per_second=None) will update the display immediately.
When auto refresh is on, updates the display immediately. (The display will also update without calls to
this.)
Parameters
• target_frames_per_second (int) – How many times a second refresh should
be called and the screen updated. Set to None for immediate refresh.
• minimum_frames_per_second (int) – The minimum number of times the screen
should be updated per second.
fill_row(self, y: int, buffer: _typing.WriteableBuffer) → _typing.WriteableBuffer
Extract the pixels from a single row
Parameters
• y (int) – The top edge of the area
• buffer (WriteableBuffer) – The buffer in which to place the pixel data
y :int
Y position of the Group in the parent.
append(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) → None
Append a layer to the group. It will be drawn above other layers.
insert(self, index: int, layer: Union[vectorio.VectorShape, Group, TileGrid]) → None
Insert a layer into the group.
index(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) → int
Returns the index of the first copy of layer. Raises ValueError if not found.
pop(self, i: int = - 1) → Union[vectorio.VectorShape, Group, TileGrid]
Remove the ith item and return it.
remove(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) → None
Remove the first copy of layer. Raises ValueError if it is not present.
__bool__(self ) → bool
__len__(self ) → int
Returns the number of layers in a Group
__getitem__(self, index: int) → Union[vectorio.VectorShape, Group, TileGrid]
Returns the value at the given index.
This allows you to:
print(group[0])
group[0] = sprite
del group[0]
import board
import displayio
import time
import pulseio
board.DISPLAY.auto_brightness = False
board.DISPLAY.brightness = 0
splash = displayio.Group()
board.DISPLAY.show(splash)
# Wait forever
while True:
pass
__bool__(self ) → bool
__len__(self ) → int
Returns the number of colors in a Palette
__getitem__(self, index: int) → Optional[int]
Return the pixel color at the given index as an integer.
__setitem__(self, index: int, value: Union[int, _typing.ReadableBuffer, Tuple[int, int, int]]) → None
Sets the pixel color at the given index. The index should be an integer in the range 0 to color_count-1.
The value argument represents a color, and can be from 0x000000 to 0xFFFFFF (to represent an RGB
value). Value can be an int, bytes (3 bytes (RGB) or 4 bytes (RGB + pad byte)), bytearray, or a tuple or
list of 3 integers.
This allows you to:
y :int
Y position of the top edge in the parent.
flip_x :bool
If true, the left edge rendered will be the right edge of the right-most tile.
flip_y :bool
If true, the top edge rendered will be the bottom edge of the bottom-most tile.
transpose_xy :bool
If true, the TileGrid’s axis will be swapped. When combined with mirroring, any 90 degree rotation can
be achieved along with the corresponding mirrored version.
pixel_shader :Union[ColorConverter, Palette]
The pixel shader of the tilegrid.
__getitem__(self, index: Union[Tuple[int, int], int]) → int
Returns the tile index at the given index. The index can either be an x,y tuple or an int equal to y *
width + x.
This allows you to:
print(grid[0])
grid[0] = 10
or:
grid[0,0] = 10
The dualbank module adds ability to update and switch between the two app partitions.
There are two identical partitions, these contain different firmware versions. Having two partitions enables rollback
functionality.
The two partitions are defined as boot partition and next-update partition. Calling dualbank.flash() writes the
next-update partition.
After the next-update partition is written a validation check is performed and on a successful validation this partition
is set as the boot partition. On next reset, firmware will be loaded from this partition.
Here is the sequence of commands to follow:
import dualbank
dualbank.flash(buffer, offset)
dualbank.switch()
dualbank.switch() → None
Switches the boot partition.
On next reset, firmware will be loaded from the partition just switched over to.
class fontio.BuiltinFont
A font built into CircuitPython
Creation not supported. Available fonts are defined when CircuitPython is built. See the
Adafruit_CircuitPython_Bitmap_Font library for dynamically loaded fonts.
bitmap :displayio.Bitmap
Bitmap containing all font glyphs starting with ASCII and followed by unicode. Use get_glyph in most
cases. This is useful for use with displayio.TileGrid and terminalio.Terminal.
get_bounding_box(self ) → Tuple[int, int]
Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height.
get_glyph(self, codepoint: int) → Glyph
Returns a fontio.Glyph for the given codepoint or None if no glyph is available.
class fontio.Glyph(bitmap: displayio.Bitmap, tile_index: int, width: int, height: int, dx: int, dy: int,
shift_x: int, shift_y: int)
Storage of glyph info
Named tuple used to capture a single glyph and its attributes.
Parameters
• bitmap – the bitmap including the glyph
• tile_index – the tile index within the bitmap
• width – the width of the glyph’s bitmap
• height – the height of the glyph’s bitmap
• dx – x adjustment to the bitmap’s position
• dy – y adjustment to the bitmap’s position
• shift_x – the x difference to the next glyph
• shift_y – the y difference to the next glyph
The framebufferio module contains classes to manage display output including synchronizing with refresh rates
and partial updating. It is used in conjunction with classes from displayio to actually place items on the display;
and classes like RGBMatrix to actually drive the display.
class framebufferio.FramebufferDisplay(framebuffer: _typing.FrameBuffer, *, rotation: int =
0, auto_refresh: bool = True)
Manage updating a display with framebuffer in RAM
This initializes a display and connects it into CircuitPython. Unlike other objects in CircuitPython, Display
objects live until displayio.release_displays() is called. This is done so that CircuitPython can use
the display itself.
Create a Display object with the given framebuffer (a buffer, array, ulab.array, etc)
Parameters
• framebuffer (FrameBuffer) – The framebuffer that the display is connected to
• auto_refresh (bool) – Automatically refresh the screen
• rotation (int) – The rotation of the display in degrees clockwise. Must be in 90 degree
increments (0, 90, 180, 270)
auto_refresh :bool
True when the display is refreshed automatically.
brightness :float
The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When
auto_brightness is True, the value of brightness will change automatically. If brightness is
set, auto_brightness will be disabled and will be set to False.
auto_brightness :bool
True when the display brightness is adjusted automatically, based on an ambient light sensor or other
method. Note that some displays may have this set to True by default, but not actually implement automatic
brightness adjustment. auto_brightness is set to False if brightness is set manually.
width :int
Gets the width of the framebuffer
height :int
Gets the height of the framebuffer
rotation :int
The rotation of the display as an int in degrees.
framebuffer :_typing.FrameBuffer
The framebuffer being used by the display
show(self, group: displayio.Group) → None
Switches to displaying the given group of layers. When group is None, the default CircuitPython terminal
will be shown.
Parameters group (Group) – The group to show.
refresh(self, *, target_frames_per_second: int = 60, minimum_frames_per_second: int = 1) → bool
When auto refresh is off, waits for the target frame rate and then refreshes the display, returning True. If
the call has taken too long since the last refresh call for the given target frame rate, then the refresh returns
False immediately without updating the screen to hopefully help getting caught up.
If the time since the last successful refresh is below the minimum frame rate, then an exception will be
raised. Set minimum_frames_per_second to 0 to disable.
When auto refresh is on, updates the display immediately. (The display will also update without calls to
this.)
Parameters
• target_frames_per_second (int) – How many times a second refresh should
be called and the screen updated.
• minimum_frames_per_second (int) – The minimum number of times the screen
should be updated per second.
fill_row(self, y: int, buffer: _typing.WriteableBuffer) → _typing.WriteableBuffer
Extract the pixels from a single row
Parameters
Warning: This module is not available in SAMD21 builds. See the Module Support Matrix - Which Modules Are
Available on Which Boards for more info.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
For example:
import frequencyio
import time
from board import *
frequency = frequencyio.FrequencyIn(D13)
frequency.capture_period = 15
time.sleep(0.1)
This example will initialize the the device, set capture_period, and then sleep 0.1 seconds. CircuitPython will
automatically turn off FrequencyIn capture when it resets all hardware after program completion. Use deinit() or
a with statement to do it yourself.
class frequencyio.FrequencyIn(pin: microcontroller.Pin, capture_period: int = 10)
Read a frequency signal
FrequencyIn is used to measure the frequency, in hertz, of a digital signal on an incoming pin. Accuracy has
shown to be within 10%, if not better. It is recommended to utilize an average of multiple samples to smooth
out readings.
Frequencies below 1KHz are not currently detectable.
FrequencyIn will not determine pulse width (use PulseIn).
Create a FrequencyIn object associated with the given pin.
Parameters
• pin (Pin) – Pin to read frequency from.
• capture_period (int) – Keyword argument to set the measurement period, in mil-
liseconds. Default is 10ms; range is 1ms - 500ms.
Read the incoming frequency from a pin:
import frequencyio
import board
frequency = frequencyio.FrequencyIn(board.D11)
capture_period :int
The capture measurement period. Lower incoming frequencies will be measured more accurately with
longer capture periods. Higher frequencies are more accurate with shorter capture periods.
Note: When setting a new capture_period, all previous capture information is cleared with a call to
clear().
deinit(self ) → None
Deinitialises the FrequencyIn and releases any hardware resources for reuse.
__enter__(self ) → FrequencyIn
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
pause(self ) → None
Pause frequency capture.
resume(self ) → None
Resumes frequency capture.
clear(self ) → None
Clears the last detected frequency capture value.
__get__(self, index: int) → int
Returns the value of the last frequency captured.
import board
import digitalio
import gamepad
import time
B_UP = 1 << 0
B_DOWN = 1 << 1
pad = gamepad.GamePad(
digitalio.DigitalInOut(board.D10),
(continues on next page)
y = 0
while True:
buttons = pad.get_pressed()
if buttons & B_UP:
y -= 1
print(y)
elif buttons & B_DOWN:
y += 1
print(y)
time.sleep(0.1)
while buttons:
# Wait for all buttons to be released.
buttons = pad.get_pressed()
time.sleep(0.1)
get_pressed(self ) → int
Get the status of buttons pressed since the last call and clear it.
Returns an 8-bit number, with bits that correspond to buttons, which have been pressed (or held down)
since the last call to this function set to 1, and the remaining bits set to 0. Then it clears the button state, so
that new button presses (or buttons that are held down) can be recorded for the next call.
deinit(self ) → None
Disable button scanning.
The gnss module contains classes to control the GNSS and acquire positioning information.
class gnss.GNSS(system: Union[SatelliteSystem, List[SatelliteSystem]])
Get updated positioning information from Global Navigation Satellite System (GNSS)
Usage:
import gnss
import time
class gnss.PositionFix
Position fix mode
Enum-like class to define the position fix mode.
INVALID :PositionFix
No measurement.
FIX_2D :PositionFix
2D fix.
FIX_3D :PositionFix
3D fix.
class gnss.SatelliteSystem
Satellite system type
Enum-like class to define the satellite system type.
GPS :SatelliteSystem
Global Positioning System.
GLONASS :SatelliteSystem
GLObal NAvigation Satellite System.
SBAS :SatelliteSystem
Satellite Based Augmentation System.
QZSS_L1CA :SatelliteSystem
Quasi-Zenith Satellite System L1C/A.
QZSS_L1S :SatelliteSystem
Quasi-Zenith Satellite System L1S.
import board
from i2cperipheral import I2CPeripheral
regs = [0] * 16
index = 0
if r.address == 0x40:
if not r.is_read: # Main write which is Selected read
b = r.read(1)
if not b or b[0] > 15:
break
index = b[0]
(continues on next page)
This example sets up an I2C device that can be accessed from Linux like this:
Warning: I2CPeripheral makes use of clock stretching in order to slow down the host. Make sure the I2C host
supports this.
Raspberry Pi in particular does not support this with its I2C hw block. This can be worked around by using the
i2c-gpio bit banging driver. Since the RPi firmware uses the hw i2c, it’s not possible to emulate a HAT eeprom.
ipaddress
The ipaddress module provides types for IP addresses. It is a subset of CPython’s ipaddress module.
ipaddress.ip_address(obj: Union[int]) → IPv4Address
Return a corresponding IP address object or raise ValueError if not possible.
class ipaddress.IPv4Address(address: Union[int, str, bytes])
Encapsulates an IPv4 address.
Create a new IPv4Address object encapsulating the address value.
The value itself can either be bytes or a string formatted address.
packed :bytes
The bytes that make up the address (read-only).
version :int
4 for IPv4, 6 for IPv6
__eq__(self, other: object) → bool
Two Address objects are equal if their addresses and address types are equal.
__hash__(self ) → int
Returns a hash for the IPv4Address data.
The math module provides some basic mathematical functions for working with floating-point numbers.
math.e :float
base of the natural logarithm
math.pi :float
the ratio of a circle’s circumference to its diameter
math.acos(x: float) → float
Return the inverse cosine of x.
math.asin(x: float) → float
Return the inverse sine of x.
math.atan(x: float) → float
Return the inverse tangent of x.
math.atan2(y: float, x: float) → float
Return the principal value of the inverse tangent of y/x.
math.ceil(x: float) → int
Return an integer, being x rounded towards positive infinity.
math.copysign(x: float, y: float) → float
Return x with the sign of y.
math.cos(x: float) → float
Return the cosine of x.
math.degrees(x: float) → float
Return radians x converted to degrees.
math.exp(x: float) → float
Return the exponential of x.
exception memorymonitor.AllocationError
Bases: Exception
Catchall exception for allocation related errors.
Initialize self. See help(type(self)) for accurate signature.
class memorymonitor.AllocationAlarm(*, minimum_block_count: int = 1)
Throw an exception when an allocation of minimum_block_count or more blocks occurs while active.
Track allocations:
import memorymonitor
aa = memorymonitor.AllocationAlarm(minimum_block_count=2)
x = 2
# Should not allocate any blocks.
with aa:
x = 5
__enter__(self ) → AllocationAlarm
Enables the alarm.
__exit__(self ) → None
Automatically disables the allocation alarm when exiting a context. See Lifetime and ContextManagers
for more info.
class memorymonitor.AllocationSize
Tracks the number of allocations in power of two buckets.
It will have 16 16-bit buckets to track allocation counts. It is total allocations meaning frees are ignored.
Reallocated memory is counted twice, at allocation and when reallocated with the larger size.
The buckets are measured in terms of blocks which is the finest granularity of the heap. This means bucket 0
will count all allocations less than or equal to the number of bytes per block, typically 16. Bucket 2 will be less
than or equal to 4 blocks. See bytes_per_block to convert blocks to bytes.
Multiple AllocationSizes can be used to track different code boundaries.
Track allocations:
import memorymonitor
mm = memorymonitor.AllocationSize()
with mm:
print("hello world" * 3)
bytes_per_block :int
Number of bytes per block
__enter__(self ) → AllocationSize
Clears counts and resumes tracking.
__exit__(self ) → None
Automatically pauses allocation tracking when exiting a context. See Lifetime and ContextManagers for
more info.
__len__(self ) → int
Returns the number of allocation buckets.
This allows you to:
mm = memorymonitor.AllocationSize()
print(len(mm))
mm = memorymonitor.AllocationSize()
print(mm[0])
The microcontroller module defines the pins from the perspective of the microcontroller. See board for board-
specific pin mappings.
microcontroller.cpu :Processor
CPU information and control, such as cpu.temperature and cpu.frequency (clock frequency). This
object is an instance of microcontroller.Processor.
microcontroller.cpus :Processor
CPU information and control, such as cpus[0].temperature and cpus[1].frequency (clock fre-
quency) on chips with more than 1 cpu. The index selects which cpu. This object is an instance of
microcontroller.Processor.
microcontroller.delay_us(delay: int) → None
Dedicated delay method used for very short delays. Do not do long delays because this stops all other functions
from completing. Think of this as an empty while loop that runs for the specified (delay) time. If you have
other code or peripherals (e.g audio recording) that require specific timing or processing while you are waiting,
explore a different avenue such as using time.sleep().
microcontroller.disable_interrupts() → None
Disable all interrupts. Be very careful, this can stall everything.
microcontroller.enable_interrupts() → None
Enable the interrupts that were enabled at the last disable.
microcontroller.on_next_reset(run_mode: RunMode) → None
Configure the run mode used the next time the microcontroller is reset but not powered down.
Parameters run_mode (RunMode) – The next run mode
microcontroller.reset() → None
Reset the microcontroller. After reset, the microcontroller will enter the run mode last set by on_next_reset.
Warning: This may result in file system corruption when connected to a host computer. Be very careful
when calling this! Make sure the device “Safely removed” on Windows or “ejected” on Mac OSX and
Linux.
microcontroller.nvm :Optional[nvm.ByteArray]
Available non-volatile memory. This object is the sole instance of nvm.ByteArray when available or None
otherwise.
Type nvm.ByteArray or None
microcontroller.watchdog :Optional[watchdog.WatchDogTimer]
Available watchdog timer. This object is the sole instance of watchdog.WatchDogTimer when available
or None otherwise.
class microcontroller.Pin
Identifies an IO pin on the microcontroller.
Identifies an IO pin on the microcontroller. They are fixed by the hardware so they cannot be constructed on
demand. Instead, use board or microcontroller.pin to reference the desired pin.
class microcontroller.Processor
Microcontroller CPU information and control
Usage:
import microcontroller
print(microcontroller.cpu.frequency)
print(microcontroller.cpu.temperature)
Note that on chips with more than one cpu (such as the RP2040)
microcontroller.cpu will return the value for CPU 0.
To get values from other CPUs use microcontroller.cpus indexed by
the number of the desired cpu. i.e.
print(microcontroller.cpus[0].temperature)
print(microcontroller.cpus[1].frequency)
NORMAL :RunMode
Run CircuitPython as normal.
SAFE_MODE :RunMode
Run CircuitPython in safe mode. User code will not be run and the file system will be writeable over USB.
BOOTLOADER :RunMode
Run the bootloader.
The msgpack format is similar to json, except that the encoded data is binary. See https://msgpack.org for details. The
module implements a subset of the cpython module msgpack-python.
Not implemented: 64-bit int, uint, float.
Example 1:
import msgpack
from io import BytesIO
b = BytesIO()
msgpack.pack({'list': [True, False, None, 1, 3.14], 'str': 'blah'}, b)
b.seek(0)
print(msgpack.unpack(b))
class MyClass:
def __init__(self, val):
self.value = val
def __str__(self):
return str(self.value)
data = MyClass(b'my_value')
def encoder(obj):
if isinstance(obj, MyClass):
return ExtType(1, obj.value)
return f"no encoder for {obj}"
buffer = BytesIO()
pack(data, buffer, default=encoder)
buffer.seek(0)
(continues on next page)
The multiterminal module allows you to configure an additional serial terminal source. Incoming characters are
accepted from both the internal serial connection and the optional secondary connection.
multiterminal.get_secondary_terminal() → Optional[BinaryIO]
Returns the current secondary terminal.
multiterminal.set_secondary_terminal(stream: BinaryIO) → None
Read additional input from the given stream and write out back to it. This doesn’t replace the core stream
(usually UART or native USB) but is mixed in instead.
Parameters stream (stream) – secondary stream
multiterminal.clear_secondary_terminal() → None
Clears the secondary terminal.
multiterminal.schedule_secondary_terminal_read(socket: sched-
ule_secondary_terminal_read.socket)
→ None
In cases where the underlying OS is doing task scheduling, this notifies the OS when more data is available on
the socket to read. This is useful as a callback for lwip sockets.
The neopixel_write module contains a helper method to write out bytes in the 800khz neopixel protocol.
For example, to turn off a single neopixel (like the status pixel on Express boards.)
import board
import neopixel_write
import digitalio
pin = digitalio.DigitalInOut(board.NEOPIXEL)
pin.direction = digitalio.Direction.OUTPUT
pixel_off = bytearray([0, 0, 0])
neopixel_write.neopixel_write(pin, pixel_off)
Warning: This module is disabled in 6.x and will removed in 7.x. Please use networking libraries instead.
This module provides a registry of configured NICs. It is used by the ‘socket’ module to look up a suitable NIC when
a socket is created.
network.route() → List[object]
Returns a list of all configured NICs.
The nvm module allows you to store whatever raw bytes you wish in a reserved section non-volatile memory.
Note that this module can’t be imported and used directly. The sole instance of ByteArray is available at
microcontroller.nvm.
class nvm.ByteArray
Presents a stretch of non-volatile memory as a bytearray.
Non-volatile memory is available as a byte array that persists over reloads and power cycles. Each assignment
causes an erase and write cycle so its recommended to assign all values to change at once.
Usage:
import microcontroller
microcontroller.nvm[0:3] = b"\xcc\x10\x00"
Not currently dynamically supported. Access the sole instance through microcontroller.nvm.
__bool__(self ) → bool
__len__(self ) → int
Return the length. This is used by (len)
__getitem__(self, index: slice) → bytearray
__getitem__(self, index: int) → int
Returns the value at the given index.
__setitem__(self, index: slice, value: _typing.ReadableBuffer) → None
__setitem__(self, index: int, value: int) → None
Set the value at the given index.
The os module is a strict subset of the CPython os module. So, code written in CircuitPython will work in CPython
but not necessarily the other way around.
os.uname() → _Uname
Returns a named tuple of operating specific and CircuitPython port specific information.
class os._Uname
Bases: NamedTuple
The type of values that uname() returns
sysname :str
nodename :str
release :str
version :str
machine :str
os.chdir(path: str) → None
Change current directory.
os.getcwd() → str
Get the current directory.
os.listdir(dir: str) → str
With no argument, list the current directory. Otherwise list the given directory.
os.mkdir(path: str) → None
Create a new directory.
os.remove(path: str) → None
Remove a file.
os.rmdir(path: str) → None
Remove a directory.
os.rename(old_path: str, new_path: str) → str
Rename a file.
os.stat(path: str) → Tuple[int, int, int, int, int, int, int, int, int, int]
Get the status of a file or directory.
Note: On builds without long integers, the number of seconds for contemporary dates will not fit in a small
integer. So the time fields return 946684800, which is the number of seconds corresponding to 1999-12-31.
os.statvfs(path: str) → Tuple[int, int, int, int, int, int, int, int, int, int]
Get the status of a filesystem.
Returns a tuple with the filesystem information in the following order:
• f_bsize – file system block size
• f_frsize – fragment size
• f_blocks – size of fs in f_frsize units
• f_bfree – number of free blocks
• f_bavail – number of free blocks for unprivileged users
• f_files – number of inodes
• f_ffree – number of free inodes
• f_favail – number of free inodes for unprivileged users
• f_flag – mount flags
• f_namemax – maximum filename length
Parameters related to inodes: f_files, f_ffree, f_avail and the f_flags parameter may return 0 as
they can be unavailable in a port-specific implementation.
os.sync() → None
Sync all filesystems.
os.urandom(size: int) → str
Returns a string of size random bytes based on a hardware True Random Number Generator. When not available,
it will raise a NotImplementedError.
os.sep :str
Separator used to delineate path components such as folder and file names.
Warning: This module is not available in some SAMD21 builds. See the Module Support Matrix - Which
Modules Are Available on Which Boards for more info.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
class ps2io.Ps2(data_pin: microcontroller.Pin, clock_pin: microcontroller.Pin)
Communicate with a PS/2 keyboard or mouse
Ps2 implements the PS/2 keyboard/mouse serial protocol, used in legacy devices. It is similar to UART but
there are only two lines (Data and Clock). PS/2 devices are 5V, so bidirectional level converters must be used to
connect the I/O lines to pins of 3.3V boards.
Create a Ps2 object associated with the given pins.
Parameters
• data_pin (Pin) – Pin tied to data wire.
• clock_pin (Pin) – Pin tied to clock wire. This pin must support interrupts.
Read one byte from PS/2 keyboard and turn on Scroll Lock LED:
import ps2io
import board
while len(kbd) == 0:
pass
print(kbd.popleft())
print(kbd.sendcmd(0xed))
print(kbd.sendcmd(0x01))
deinit(self ) → None
Deinitialises the Ps2 and releases any hardware resources for reuse.
__enter__(self ) → Ps2
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
popleft(self ) → int
Removes and returns the oldest received byte. When buffer is empty, raises an IndexError exception.
sendcmd(self, byte: int) → int
Sends a command byte to PS/2. Returns the response byte, typically the general ack value (0xFA). Some
commands return additional data which is available through popleft().
Raises a RuntimeError in case of failure. The root cause can be found by calling clear_errors(). It
is advisable to call clear_errors() before sendcmd() to flush any previous errors.
Parameters byte (int) – byte value of the command
clear_errors(self ) → None
Returns and clears a bitmap with latest recorded communication errors.
Reception errors (arise asynchronously, as data is received):
0x01: start bit not 0
0x02: timeout
0x04: parity bit error
0x08: stop bit not 1
0x10: buffer overflow, newest data discarded
Transmission errors (can only arise in the course of sendcmd()):
The pulseio module contains classes to provide access to basic pulse IO. Individual pulses are commonly used in
infrared remotes and in DHT temperature sensors.
Warning: PWMOut is moving to pwmio and will be removed from pulseio in CircuitPython 7.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
class pulseio.PulseIn(pin: microcontroller.Pin, maxlen: int = 2, *, idle_state: bool = False)
Measure a series of active and idle pulses. This is commonly used in infrared receivers and low cost temperature
sensors (DHT). The pulsed signal consists of timed active and idle periods. Unlike PWM, there is no set duration
for active and idle pairs.
Create a PulseIn object associated with the given pin. The object acts as a read-only sequence of pulse lengths
with a given max length. When it is active, new pulse lengths are added to the end of the list. When there is no
more room (len() == maxlen) the oldest pulse length is removed to make room.
Parameters
• pin (Pin) – Pin to read pulses from.
• maxlen (int) – Maximum number of pulse durations to store at once
• idle_state (bool) – Idle state of the pin. At start and after resume the first recorded
pulse will the opposite state from idle.
Read a short series of pulses:
import pulseio
import board
pulses = pulseio.PulseIn(board.D7)
maxlen :int
The maximum length of the PulseIn. When len() is equal to maxlen, it is unclear which pulses are active
and which are idle.
paused :bool
True when pulse capture is paused as a result of pause() or an error during capture such as a signal that
is too fast.
deinit(self ) → None
Deinitialises the PulseIn and releases any hardware resources for reuse.
__enter__(self ) → PulseIn
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
pause(self ) → None
Pause pulse capture
resume(self, trigger_duration: int = 0) → None
Resumes pulse capture after an optional trigger pulse.
Warning: Using trigger pulse with a device that drives both high and low signals risks a short. Make
sure your device is open drain (only drives low) when using a trigger pulse. You most likely added a
“pull-up” resistor to your circuit to do this.
clear(self ) → None
Clears all captured pulses
popleft(self ) → int
Removes and returns the oldest read pulse.
__bool__(self ) → bool
__len__(self ) → int
Returns the current pulse length
This allows you to:
pulses = pulseio.PulseIn(pin)
print(len(pulses))
pulses = pulseio.PulseIn(pin)
print(pulses[0])
import array
import pulseio
import pwmio
import board
deinit(self ) → None
Deinitialises the PulseOut and releases any hardware resources for reuse.
__enter__(self ) → PulseOut
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
send(self, pulses: _typing.ReadableBuffer) → None
Pulse alternating on and off durations in microseconds starting with on. pulses must be an array.
array with data type ‘H’ for unsigned halfword (two bytes).
This method waits until the whole array of pulses has been sent and ensures the signal is off afterwards.
Parameters pulses (array.array) – pulse durations in microseconds
The pwmio module contains classes to provide access to basic pulse IO.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
For example:
import pwmio
import time
from board import *
pwm = pwmio.PWMOut(D13)
pwm.duty_cycle = 2 ** 15
time.sleep(0.1)
This example will initialize the the device, set duty_cycle, and then sleep 0.1 seconds. CircuitPython will automat-
ically turn off the PWM when it resets all hardware after program completion. Use deinit() or a with statement
to do it yourself.
class pwmio.PWMOut(pin: microcontroller.Pin, *, duty_cycle: int = 0, frequency: int = 500, vari-
able_frequency: bool = False)
Output a Pulse Width Modulated signal on a given pin.
Create a PWM object associated with the given pin. This allows you to write PWM signals out on the given pin.
Frequency is fixed after init unless variable_frequency is True.
Note: When variable_frequency is True, further PWM outputs may be limited because it may take
more internal resources to be flexible. So, when outputting both fixed and flexible frequency signals construct
the fixed outputs first.
Parameters
• pin (Pin) – The pin to output to
• duty_cycle (int) – The fraction of each pulse which is high. 16-bit
• frequency (int) – The target frequency in Hertz (32-bit)
• variable_frequency (bool) – True if the frequency will change over time
import pwmio
import board
import pwmio
import board
import pwmio
import board
import time
time.sleep(0.2)
pwm.frequency = 880
time.sleep(0.1)
duty_cycle :int
16 bit value that dictates how much of one cycle is high (1) versus low (0). 0xffff will always be high, 0
will always be low and 0x7fff will be half high and then half low.
Depending on how PWM is implemented on a specific board, the internal representation for duty cycle
might have less than 16 bits of resolution. Reading this property will return the value from the internal
representation, so it may differ from the value set.
frequency :int
32 bit value that dictates the PWM frequency in Hertz (cycles per second). Only writeable when con-
structed with variable_frequency=True.
Depending on how PWM is implemented on a specific board, the internal value for the PWM’s duty cycle
may need to be recalculated when the frequency changes. In these cases, the duty cycle is automatically
recalculated from the original duty cycle value. This should happen without any need to manually re-set
the duty cycle.
deinit(self ) → None
Deinitialises the PWMOut and releases any hardware resources for reuse.
__enter__(self ) → PWMOut
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
The random module is a strict subset of the CPython random module. So, code written in CircuitPython will work
in CPython but not necessarily the other way around.
Like its CPython cousin, CircuitPython’s random seeds itself on first use with a true random from os.urandom() when
available or the uptime otherwise. Once seeded, it will be deterministic, which is why its bad for cryptography.
Warning: Numbers from this module are not cryptographically strong! Use bytes from os.urandom directly
for true randomness.
random._T
width :int
The width of the display, in pixels
height :int
The height of the display, in pixels
deinit(self ) → None
Free the resources (pins, timers, etc.) associated with this rgbmatrix instance. After deinitialization, no
further operations may be performed.
refresh(self ) → None
Transmits the color data in the buffer to the pixels so that they are shown.
The rotaryio module contains classes to read different rotation encoding schemes. See Wikipedia’s Rotary Encoder
page for more background.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
class rotaryio.IncrementalEncoder(pin_a: microcontroller.Pin, pin_b: microcontroller.Pin)
IncrementalEncoder determines the relative rotational position based on two series of pulses.
Create an IncrementalEncoder object associated with the given pins. It tracks the positional state of an incre-
mental rotary encoder (also known as a quadrature encoder.) Position is relative to the position when the object
is contructed.
Parameters
• pin_a (Pin) – First pin to read pulses from.
• pin_b (Pin) – Second pin to read pulses from.
For example:
import rotaryio
import time
from board import *
position :int
The current position in terms of pulses. The number of pulses per rotation is defined by the specific
hardware.
deinit(self ) → None
Deinitializes the IncrementalEncoder and releases any hardware resources for reuse.
__enter__(self ) → IncrementalEncoder
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
rxstall :bool
True when the state machine has stalled due to a full RX FIFO since the last clear_rxfifo call.
in_waiting :int
The number of words available to readinto
deinit(self ) → None
Turn off the state machine and release its resources.
__enter__(self ) → StateMachine
No-op used by Context Managers. Provided by context manager helper.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
restart(self ) → None
Resets this state machine, runs any init and enables the clock.
run(self, instructions: _typing.ReadableBuffer) → None
Runs all given instructions. They will likely be interleaved with in-memory instructions. Make sure this
doesn’t wait for input!
This can be used to output internal state to the RX FIFO and then read with readinto.
stop(self ) → None
Stops the state machine clock. Use restart to enable it.
write(self, buffer: _typing.ReadableBuffer, *, start: int = 0, end: Optional[int] = None) → None
Write the data contained in buffer to the state machine. If the buffer is empty, nothing happens.
Parameters
• buffer (ReadableBuffer) – Write out the data in this buffer
• start (int) – Start of the slice of buffer to write out: buffer[start:end]
• end (int) – End of the slice; this index is not included. Defaults to len(buffer)
readinto(self, buffer: _typing.WriteableBuffer, *, start: int = 0, end: Optional[int] = None) → None
Read into buffer. If the number of bytes to read is 0, nothing happens. The buffer include any
data added to the fifo even if it was added before this was called.
Parameters
• buffer (WriteableBuffer) – Read data into this buffer
• start (int) – Start of the slice of buffer to read into: buffer[start:end]
• end (int) – End of the slice; this index is not included. Defaults to len(buffer)
The rtc module provides support for a Real Time Clock. You can access and manage the RTC using rtc.RTC. It
also backs the time.time() and time.localtime() functions using the onboard RTC if present.
rtc.set_time_source(rtc: RTC) → None
Sets the RTC time source used by time.localtime(). The default is rtc.RTC, but it’s useful to use this
to override the time source for testing purposes. For example:
import rtc
import time
class RTC(object):
@property
def datetime(self):
return time.struct_time((2018, 3, 17, 21, 1, 47, 0, 0, 0))
r = RTC()
rtc.set_time_source(r)
class rtc.RTC
Real Time Clock
This class represents the onboard Real Time Clock. It is a singleton and will always return the same instance.
datetime :time.struct_time
The current date and time of the RTC as a time.struct_time.
This must be set to the current date and time whenever the board loses power:
import rtc
import time
r = rtc.RTC()
r.datetime = time.struct_time((2019, 5, 29, 15, 14, 15, 0, -1, -1))
Once set, the RTC will automatically update this value as time passes. You can read this property to get a
snapshot of the current time:
current_time = r.datetime
print(current_time)
# struct_time(tm_year=2019, tm_month=5, ...)
calibration :int
The RTC calibration value as an int.
A positive value speeds up the clock and a negative value slows it down. Range and value is hardware
specific, but one step is often approximately 1 ppm:
import rtc
import time
r = rtc.RTC()
r.calibration = 1
class samd.Clock
Identifies a clock on the microcontroller.
They are fixed by the hardware so they cannot be constructed on demand. Instead, use samd.clock to refer-
ence the desired clock.
enabled :bool
Is the clock enabled? (read-only)
parent :Union[Clock, None]
Clock parent. (read-only)
frequency :int
Clock frequency in Herz. (read-only)
calibration :int
Clock calibration. Not all clocks can be calibrated.
Important: If the same SPI bus is shared with other peripherals, it is important that the SD card be initialized
before accessing any other peripheral on the bus. Failure to do so can prevent the SD card from being recognized
until it is powered off or re-inserted.
Example usage:
import os
import board
import sdcardio
import storage
sd = sdcardio.SDCard(board.SPI(), board.SD_CS)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
os.listdir('/sd')
count(self ) → int
Returns the total number of sectors
Due to technical limitations, this is a function and not a property.
Returns The number of 512-byte blocks, as a number
deinit(self ) → None
Disable permanently.
Returns None
readblocks(self, start_block: int, buf: _typing.WriteableBuffer) → None
Read one or more blocks from the card
Parameters
• start_block (int) – The block to start reading from
• buf (WriteableBuffer) – The buffer to write into. Length must be multiple of 512.
Returns None
writeblocks(self, start_block: int, buf: _typing.ReadableBuffer) → None
Write one or more blocks to the card
Parameters
• start_block (int) – The block to start writing from
• buf (ReadableBuffer) – The buffer to read from. Length must be multiple of 512.
Returns None
import os
import board
import sdioio
import storage
sd = sdioio.SDCard(
clock=board.SDIO_CLOCK,
command=board.SDIO_COMMAND,
data=board.SDIO_DATA,
frequency=25000000)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
os.listdir('/sd')
count(self ) → int
Returns the total number of sectors
Due to technical limitations, this is a function and not a property.
Returns The number of 512-byte blocks, as a number
readblocks(self, start_block: int, buf: _typing.WriteableBuffer) → None
Read one or more blocks from the card
Parameters
• start_block (int) – The block to start reading from
• buf (WriteableBuffer) – The buffer to write into. Length must be multiple of 512.
Returns None
writeblocks(self, start_block: int, buf: _typing.ReadableBuffer) → None
Write one or more blocks to the card
Parameters
• start_block (int) – The block to start writing from
• buf (ReadableBuffer) – The buffer to read from. Length must be multiple of 512.
Returns None
Warning: This module is disabled in 6.x and will removed in 7.x. Please use networking libraries instead. (Native
networking will provide a socket compatible class.)
Create TCP, UDP and RAW sockets for communicating over the Internet.
class socket.socket(family: int = AF_INET, type: int = SOCK_STREAM, proto: int = IP-
PROTO_TCP)
Create a new socket
Parameters
• family (int) – AF_INET or AF_INET6
• type (int) – SOCK_STREAM, SOCK_DGRAM or SOCK_RAW
• proto (int) – IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)
AF_INET :int
AF_INET6 :int
SOCK_STREAM :int
SOCK_DGRAM :int
SOCK_RAW :int
IPPROTO_TCP :int
bind(self, address: Tuple[str, int]) → None
Bind a socket to an address
Parameters address (tuple(str, int)) – tuple of (remote_address, remote_port)
listen(self, backlog: int) → None
Set socket to listen for incoming connections
Parameters backlog (int) – length of backlog queue for waiting connetions
socketpool
The socketpool module provides sockets through a pool. The pools themselves act like CPython’s socket
module.
class socketpool.Socket
TCP, UDP and RAW socket. Cannot be created directly. Instead, call SocketPool.socket().
Provides a subset of CPython’s socket.socket API. It only implements the versions of recv that do not
allocate bytes objects.
__enter__(self ) → Socket
No-op used by Context Managers.
__exit__(self ) → None
Automatically closes the Socket when exiting a context. See Lifetime and ContextManagers for more info.
accept(self ) → Tuple[Socket, Tuple[str, int]]
Accept a connection on a listening socket of type SOCK_STREAM, creating a new socket of type
SOCK_STREAM. Returns a tuple of (new_socket, remote_address)
bind(self, address: Tuple[str, int]) → None
Bind a socket to an address
Parameters address (~tuple) – tuple of (remote_address, remote_port)
close(self ) → None
Closes this Socket and makes its resources available to its SocketPool.
connect(self, address: Tuple[str, int]) → None
Connect a socket to a remote address
Parameters address (~tuple) – tuple of (remote_address, remote_port)
listen(self, backlog: int) → None
Set socket to listen for incoming connections
Parameters backlog (~int) – length of backlog queue for waiting connetions
recvfrom_into(self, buffer: _typing.WriteableBuffer) → Tuple[int, Tuple[str, int]]
Reads some bytes from a remote address.
Returns a tuple containing * the number of bytes received into the given buffer * a remote_address, which
is a tuple of ip address and port number
Parameters buffer (object) – buffer to read into
recv_into(self, buffer: _typing.WriteableBuffer, bufsize: int) → int
Reads some bytes from the connected remote address, writing into the provided buffer. If bufsize <=
len(buffer) is given, a maximum of bufsize bytes will be read into the buffer. If no valid value is given for
bufsize, the default is the length of the given buffer.
Suits sockets of type SOCK_STREAM Returns an int of number of bytes read.
Parameters
• buffer (bytearray) – buffer to receive into
ssl
The storage provides storage management functionality such as mounting and unmounting which is typically han-
dled by the operating system hosting Python. CircuitPython does not have an OS, so this module provides this func-
tionality directly.
storage.mount(filesystem: VfsFat, mount_path: str, *, readonly: bool = False) → None
Mounts the given filesystem object at the given path.
This is the CircuitPython analog to the UNIX mount command.
Parameters readonly (bool) – True when the filesystem should be readonly to CircuitPython.
storage.umount(mount: Union[str, VfsFat]) → None
Unmounts the given filesystem object or if mount is a path, then unmount the filesystem mounted at that location.
This is the CircuitPython analog to the UNIX umount command.
storage.remount(mount_path: str, readonly: bool = False, *, disable_concurrent_write_protection: bool
= False) → None
Remounts the given path with new parameters.
Parameters
• readonly (bool) – True when the filesystem should be readonly to CircuitPython.
• disable_concurrent_write_protection (bool) – When True, the check that
makes sure the underlying filesystem data is written by one computer is disabled. Disabling
the protection allows CircuitPython and a host to write to the same filesystem with the risk
that the filesystem will be corrupted.
storage.getmount(mount_path: str) → VfsFat
Retrieves the mount object associated with the mount path
storage.erase_filesystem() → None
Erase and re-create the CIRCUITPY filesystem.
On boards that present USB-visible CIRCUITPY drive (e.g., SAMD21 and SAMD51), then call
microcontroller.reset() to restart CircuitPython and have the host computer remount CIRCUITPY.
This function can be called from the REPL when CIRCUITPY has become corrupted.
Warning: All the data on CIRCUITPY will be lost, and CircuitPython will restart on certain boards.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: struct.
Supported size/byte order prefixes: @, <, >, !.
Supported format codes: b, B, x, h, H, i, I, l, L, q, Q, s, P, f, d (the latter 2 depending on the floating-point support).
struct.calcsize(fmt: str) → int
Return the number of bytes needed to store the given fmt.
struct.pack(fmt: str, *values: Any) → bytes
Pack the values according to the format string fmt. The return value is a bytes object encoding the values.
struct.pack_into(fmt: str, buffer: _typing.WriteableBuffer, offset: int, *values: Any) → None
Pack the values according to the format string fmt into a buffer starting at offset. offset may be negative to count
from the end of buffer.
struct.unpack(fmt: str, data: _typing.ReadableBuffer) → Tuple[Any, . . . ]
Unpack from the data according to the format string fmt. The return value is a tuple of the unpacked values.
The buffer size must match the size required by the format.
supervisor.runtime :Runtime
Runtime information, such as runtime.serial_connected (USB serial connection status). This object
is the sole instance of supervisor.Runtime.
supervisor.enable_autoreload() → None
Enable autoreload based on USB file write activity.
supervisor.disable_autoreload() → None
Disable autoreload based on USB file write activity until enable_autoreload is called.
supervisor.set_rgb_status_brightness(brightness: int) → None
Set brightness of status neopixel from 0-255 set_rgb_status_brightness is called.
supervisor.reload() → None
Reload the main Python code and run it (equivalent to hitting Ctrl-D at the REPL).
supervisor.set_next_stack_limit(size: int) → None
Set the size of the stack for the next vm run. If its too large, the default will be used.
class supervisor.RunReason
The reason that CircuitPython started running.
STARTUP :object
CircuitPython started the microcontroller started up. See microcontroller.Processor.
reset_reason for more detail on why the microcontroller was started.
AUTO_RELOAD :object
CircuitPython restarted due to an external write to the filesystem.
SUPERVISOR_RELOAD :object
CircuitPython restarted due to a call to supervisor.reload().
REPL_RELOAD :object
CircuitPython started due to the user typing CTRL-D in the REPL.
class supervisor.Runtime
Current status of runtime objects.
Usage:
import supervisor
if supervisor.runtime.serial_connected:
print("Hello World!")
You cannot create an instance of supervisor.Runtime. Use supervisor.runtime to access the sole
instance available.
usb_connected :bool
Returns the USB enumeration status (read-only).
serial_connected :bool
Returns the USB serial communication status (read-only).
serial_bytes_available :int
Returns the whether any bytes are available to read on the USB serial input. Allows for polling to see
whether to call the built-in input() or wait. (read-only)
run_reason :RunReason
Returns why CircuitPython started running this particular time.
The terminalio module contains classes to display a character stream on a display. The built in font is available as
terminalio.FONT.
terminalio.FONT :fontio.BuiltinFont
The built in font
class terminalio.Terminal(tilegrid: displayio.TileGrid, font: fontio.BuiltinFont)
Display a character stream with a TileGrid
Terminal manages tile indices and cursor position based on VT100 commands. The font should be a fontio.
BuiltinFont and the TileGrid’s bitmap should match the font’s bitmap.
write(self, buf: _typing.ReadableBuffer) → Optional[int]
Write the buffer of bytes to the bus.
Returns the number of bytes written
Return type int or None
The time module is a strict subset of the CPython time module. So, code written in MicroPython will work in
CPython but not necessarily the other way around.
time.monotonic() → float
Returns an always increasing value of time with an unknown reference point. Only use it to compare against
other values from monotonic.
Returns the current monotonic time
Return type float
time.sleep(seconds: float) → None
Sleep for a given number of seconds.
Parameters seconds (float) – the time to sleep in fractional seconds
class time.struct_time(time_tuple: Tuple[int, int, int, int, int, int, int, int, int])
Structure used to capture a date and time. Note that it takes a tuple!
Parameters time_tuple (tuple) – Tuple of time info: (tm_year, tm_mon, tm_mday,
tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)
• tm_year: the year, 2017 for example
• tm_month: the month, range [1, 12]
• tm_mday: the day of the month, range [1, 31]
• tm_hour: the hour, range [0, 23]
• tm_min: the minute, range [0, 59]
The touchio module contains classes to provide access to touch IO typically accelerated by hardware on the onboard
microcontroller.
All classes change hardware state and should be deinitialized when they are no longer needed if the program continues
after use. To do so, either call deinit() or use a context manager. See Lifetime and ContextManagers for more
info.
For example:
import touchio
from board import *
touch_pin = touchio.TouchIn(D6)
print(touch_pin.value)
This example will initialize the the device, and print the value.
class touchio.TouchIn(pin: microcontroller.Pin)
Read the state of a capacitive touch sensor
Usage:
import touchio
from board import *
touch = touchio.TouchIn(A1)
while True:
if touch.value:
print("touched!")
import board
import touchio
touch = touchio.TouchIn(board.A1)
touch.threshold = 7300
deinit(self ) → None
Deinitialises the TouchIn and releases any hardware resources for reuse.
__enter__(self ) → TouchIn
No-op used by Context Managers.
__exit__(self ) → None
Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for
more info.
ulab is a numpy-like module for micropython, meant to simplify and speed up common mathematical operations
on arrays. The primary goal was to implement a small subset of numpy that might be useful in the context of a
microcontroller. This means low-level data processing of linear (array) and two-dimensional (matrix) data.
ulab is adapted from micropython-ulab, and the original project’s documentation can be found at https://
micropython-ulab.readthedocs.io/en/latest/
ulab is modeled after numpy, and aims to be a compatible subset where possible. Numpy’s documentation can be
found at https://docs.scipy.org/doc/numpy/index.html
ulab.approx.bisect(fun: Callable[[float], float], a: float, b: float, *, xtol: float = 2.4e-07, maxiter: int
= 100) → float
Parameters
• f (callable) – The function to bisect
• a (float) – The left side of the interval
• b (float) – The right side of the interval
• xtol (float) – The tolerance value
• maxiter (float) – The maximum number of iterations to perform
Find a solution (zero) of the function f(x) on the interval (a..``b``) using the bisection method. The result is
accurate to within xtol unless more than maxiter steps are required.
ulab.approx.fmin(fun: Callable[[float], float], x0: float, *, xatol: float = 2.4e-07, fatol: float = 2.4e-07,
maxiter: int = 200) → float
Parameters
• f (callable) – The function to bisect
• x0 (float) – The initial x value
• xatol (float) – The absolute tolerance value
• fatol (float) – The relative tolerance value
Find a minimum of the function f(x) using the downhill simplex method. The located x is within fxtol of
the actual minimum, and f(x) is within fatol of the actual minimum unless more than maxiter steps are
requried.
ulab.approx.interp(x: ulab.array, xp: ulab.array, fp: ulab.array, *, left: Optional[float] = None, right:
Optional[float] = None) → ulab.array
Parameters
• x (ulab.array) – The x-coordinates at which to evaluate the interpolated values.
• xp (ulab.array) – The x-coordinates of the data points, must be increasing
• fp (ulab.array) – The y-coordinates of the data points, same length as xp
• left – Value to return for x < xp[0], default is fp[0].
• right – Value to return for x > xp[-1], default is fp[-1].
Returns the one-dimensional piecewise linear interpolant to a function with given discrete data points (xp, fp),
evaluated at x.
ulab.approx.newton(fun: Callable[[float], float], x0: float, *, xtol: float = 2.4e-07, rtol: float = 0.0,
maxiter: int = 50) → float
Parameters
• f (callable) – The function to bisect
• x0 (float) – The initial x value
• xtol (float) – The absolute tolerance value
• rtol (float) – The relative tolerance value
• maxiter (float) – The maximum number of iterations to perform
Find a solution (zero) of the function f(x) using Newton’s Method. The result is accurate to within xtol *
rtol * |f(x)| unless more than maxiter steps are requried.
ulab.approx.trapz(y: ulab.array, x: Optional[ulab.array] = None, dx: float = 1.0) → float
Parameters
• ulab.array y (1D) – the values of the dependent variable
• ulab.array x (1D) – optional, the coordinates of the independent variable. Defaults to
uniformly spaced values.
• dx (float) – the spacing between sample points, if x=None
Returns the integral of y(x) using the trapezoidal rule.
Most of these functions take an “axis” argument, which indicates whether to operate over the flattened array (None),
or a particular axis (integer).
ulab.numerical.argmax(array: ulab._ArrayLike, *, axis: Optional[int] = None) → int
Return the index of the maximum element of the 1D array
ulab.numerical.argmin(array: ulab._ArrayLike, *, axis: Optional[int] = None) → int
Return the index of the minimum element of the 1D array
ulab.numerical.argsort(array: ulab.array, *, axis: int = - 1) → ulab.array
Returns an array which gives indices into the input array from least to greatest.
ulab.numerical.cross(a: ulab.array, b: ulab.array) → ulab.array
Return the cross product of two vectors of length 3
ulab.numerical.diff(array: ulab.array, *, n: int = 1, axis: int = - 1) → ulab.array
Return the numerical derivative of successive elements of the array, as an array. axis=None is not supported.
ulab.numerical.flip(array: ulab.array, *, axis: Optional[int] = None) → ulab.array
Returns a new array that reverses the order of the elements along the given axis, or along all axes if axis is None.
ulab.numerical.max(array: ulab._ArrayLike, *, axis: Optional[int] = None) → float
Return the maximum element of the 1D array
ulab.numerical.mean(array: ulab._ArrayLike, *, axis: Optional[int] = None) → float
Return the mean element of the 1D array, as a number if axis is None, otherwise as an array.
ulab.numerical.median(array: ulab.array, *, axis: int = - 1) → ulab.array
Find the median value in an array along the given axis, or along all axes if axis is None.
ulab.numerical.min(array: ulab._ArrayLike, *, axis: Optional[int] = None) → float
Return the minimum element of the 1D array
ulab.numerical.roll(array: ulab.array, distance: int, *, axis: Optional[int] = None) → None
Shift the content of a vector by the positions given as the second argument. If the axis keyword is supplied,
the shift is applied to the given axis. The array is modified in place.
ulab.numerical.sort(array: ulab.array, *, axis: int = - 1) → ulab.array
Sort the array along the given axis, or along all axes if axis is None. The array is modified in place.
ulab.numerical.std(array: ulab._ArrayLike, *, axis: Optional[int] = None, ddof: int = 0) → float
Return the standard deviation of the array, as a number if axis is None, otherwise as an array.
ulab.numerical.sum(array: ulab._ArrayLike, *, axis: Optional[int] = None) → Union[float, int,
ulab.array]
Return the sum of the array, as a number if axis is None, otherwise as an array.
These functions can operate on numbers, 1-D iterables, 1-D arrays, or 2-D arrays by applying the function to every
element in the array. This is typically much more efficient than expressing the same operation as a Python loop.
ulab.vector.acos(a: ulab._ArrayLike) → ulab.array
Computes the inverse cosine function
ulab.vector.acosh(a: ulab._ArrayLike) → ulab.array
Computes the inverse hyperbolic cosine function
ulab.vector.asin(a: ulab._ArrayLike) → ulab.array
Computes the inverse sine function
ulab.vector.asinh(a: ulab._ArrayLike) → ulab.array
Computes the inverse hyperbolic sine function
ulab.vector.around(a: ulab._ArrayLike, *, decimals: int = 0) → ulab.array
Returns a new float array in which each element is rounded to decimals places.
ulab.vector.atan(a: ulab._ArrayLike) → ulab.array
Computes the inverse tangent function; the return values are in the range [-pi/2,pi/2].
ulab.vector.arctan2(ya: ulab._ArrayLike, xa: ulab._ArrayLike) → ulab.array
Computes the inverse tangent function of y/x; the return values are in the range [-pi, pi].
ulab.vector.atanh(a: ulab._ArrayLike) → ulab.array
Computes the inverse hyperbolic tangent function
ulab.vector.ceil(a: ulab._ArrayLike) → ulab.array
Rounds numbers up to the next whole number
ulab.vector.cos(a: ulab._ArrayLike) → ulab.array
Computes the cosine function
ulab.vector.cosh(a: ulab._ArrayLike) → ulab.array
Computes the hyperbolic cosine function
ulab.vector.degrees(a: ulab._ArrayLike) → ulab.array
Converts angles from radians to degrees
ulab.vector.erf(a: ulab._ArrayLike) → ulab.array
Computes the error function, which has applications in statistics
ulab.vector.erfc(a: ulab._ArrayLike) → ulab.array
Computes the complementary error function, which has applications in statistics
ulab._Index
class ulab.array(values: Union[array, Iterable[Union[_float, _bool, Iterable[Any]]]], *, dtype:
_DType = ulab.float)
1- and 2- dimensional array
Parameters
• values (sequence) – Sequence giving the initial content of the array.
• dtype (_DType) – The type of array values, ulab.int8, ulab.uint8, ulab.
int16, ulab.uint16, ulab.float or ulab.bool
The values sequence can either be another ~ulab.array, sequence of numbers (in which case a 1-dimensional
array is created), or a sequence where each subsequence has the same length (in which case a 2-dimensional
array is created).
Passing a ulab.array and a different dtype can be used to convert an array from one dtype to another.
In many cases, it is more convenient to create an array from a function like zeros or linspace.
ulab.array implements the buffer protocol, so it can be used in many places an array.array can be
used.
shape :Tuple[int, ...]
The size of the array, a tuple of length 1 or 2
size :int
The number of elements in the array
itemsize :int
The size of a single item in the array
strides :Tuple[int, ...]
Tuple of bytes to step in each dimension, a tuple of length 1 or 2
copy(self ) → array
Return a copy of the array
dtype(self ) → _DType
Returns the dtype of the array
flatten(self, *, order: str = 'C') → array
Parameters order – Whether to flatten by rows (‘C’) or columns (‘F’)
Returns a new ulab.array object which is always 1 dimensional. If order is ‘C’ (the default”, then the
data is ordered in rows; If it is ‘F’, then the data is ordered in columns. “C” and “F” refer to the typical
storage organization of the C and Fortran languages.
reshape(self, shape: Tuple[int, . . . ]) → array
Returns an array containing the same data with a new shape.
sort(self, *, axis: Optional[int] = 1) → None
Parameters axis – Whether to sort elements within rows (0), columns (1), or elements (None)
tobytes(self ) → bytearray
Return the raw data bytes in the array
transpose(self ) → array
Swap the rows and columns of a 2-dimensional array
__add__(self, other: Union[array, _float]) → array
Adds corresponding elements of the two arrays, or adds a number to all elements of the array. If both
arguments are arrays, their sizes must match.
ulab.float :_DType
Type code for floating point values, like the ‘f’ typecode of array.array
ulab.uint8 :_DType
Type code for unsigned integers in the range 0 .. 255 inclusive, like the ‘H’ typecode of array.array
ulab.uint16 :_DType
Type code for unsigned integers in the range 0 .. 65535 inclusive, like the ‘h’ typecode of array.array
ulab.bool :_DType
Type code for boolean values
ulab.get_printoptions() → Dict[str, int]
Get printing options
ulab.set_printoptions(threshold: Optional[int] = None, edgeitems: Optional[int] = None) → None
Set printing options
ulab.ndinfo(array: array) → None
ulab.arange(stop: _float, step: _float = 1, *, dtype: _DType = ulab.float) → array
ulab.arange(start: _float, stop: _float, step: _float = 1, *, dtype: _DType = ulab.float) → array
Return a new 1-D array with elements ranging from start to stop, with step size step.
ulab.concatenate(arrays: Tuple[array], *, axis: int = 0) → array
Join a sequence of arrays along an existing axis.
ulab.diag(a: array, *, k: int = 0) → array
Return specified diagonals.
ulab.eye(size: int, *, M: Optional[int] = None, k: int = 0, dtype: _DType = ulab.float) → array
Return a new square array of size, with the diagonal elements set to 1 and the other elements set to 0.
ulab.full(shape: Union[int, Tuple[int, . . . ]], fill_value: Union[_float, _bool], *, dtype: _DType =
ulab.float) → array
Return a new array of the given shape with all elements set to 0.
ulab.linspace(start: _float, stop: _float, *, dtype: _DType = ulab.float, num: int = 50, endpoint: _bool =
True, retstep: _bool = False) → array
Return a new 1-D array with num elements ranging from start to stop linearly.
ulab.logspace(start: _float, stop: _float, *, dtype: _DType = ulab.float, num: int = 50, endpoint: _bool =
True, base: _float = 10.0) → array
Return a new 1-D array with num evenly spaced elements on a log scale. The sequence starts at base **
start, and ends with base ** stop.
ulab.ones(shape: Union[int, Tuple[int, . . . ]], *, dtype: _DType = ulab.float) → array
Return a new array of the given shape with all elements set to 1.
ulab.zeros(shape: Union[int, Tuple[int, . . . ]], *, dtype: _DType = ulab.float) → array
Return a new array of the given shape with all elements set to 0.
ulab.frombuffer(buffer: _typing.ReadableBuffer, dtype: _DType = ulab.float, count: int = - 1, offset: int
= 0) → array
Interpret a buffer as a 1-dimensional array.
Note: The host is considered to be connected if it is asserting DTR (Data Terminal Ready). Most terminal
programs and pyserial assert DTR when opening a serial connection. However, the C# SerialPort
API does not. You must set SerialPort.DtrEnable.
in_waiting :int
Returns the number of bytes waiting to be read on the USB serial input. (read-only)
out_waiting :int
Returns the number of bytes waiting to be written on the USB serial output. (read-only)
timeout :Optional[float]
The initial value of timeout is None. If None, wait indefinitely to satisfy the conditions of a read
operation. If 0, do not wait. If > 0, wait only timeout seconds.
write_timeout :Optional[float]
The initial value of write_timeout is None. If None, wait indefinitely to finish writing all the bytes
passed to write().If 0, do not wait. If > 0, wait only write_timeout seconds.
read(self, size: int = 1) → bytes
Read at most size bytes. If size exceeds the internal buffer size only the bytes in the buffer will be
read. If timeout is > 0 or None, and fewer than size bytes are available, keep waiting until the timeout
expires or size bytes are available.
Returns Data read
Return type bytes
readinto(self, buf: _typing.WriteableBuffer) → int
Read bytes into the buf. If nbytes is specified then read at most that many bytes, subject to timeout.
Otherwise, read at most len(buf) bytes.
Returns number of bytes read and stored into buf
Return type bytes
readline(self, size: int = - 1) → Optional[bytes]
Read a line ending in a newline character (“\n”), including the newline. Return everything readable if no
newline is found and timeout is 0. Return None in case of error.
This is a binary stream: the newline character “\n” cannot be changed. If the host computer transmits “\r”
it will also be included as part of the line.
Parameters size (int) – maximum number of characters to read. -1 means as many as
possible.
Warning: If timeout is None, readlines() will never return, because there is no way to
indicate end of stream.
import usb_hid
mouse = usb_hid.devices[0]
mouse.send_report()
For example, Keyboard is 0x06 within the generic desktop usage page 0x01. Mouse is 0x02 within the
same usage page.
send_report(self, buf: _typing.ReadableBuffer) → None
Send a HID report.
The usb_midi module contains classes to transmit and receive MIDI messages over USB.
usb_midi.ports :Tuple[Union[PortIn, PortOut], ...]
Tuple of all MIDI ports. Each item is ether PortIn or PortOut.
class usb_midi.PortIn
Receives midi commands over USB
You cannot create an instance of usb_midi.PortIn.
PortIn objects are constructed for every corresponding entry in the USB descriptor and added to the
usb_midi.ports tuple.
read(self, nbytes: Optional[int] = None) → Optional[bytes]
Read characters. If nbytes is specified then read at most that many bytes. Otherwise, read everything
that arrives until the connection times out. Providing the number of bytes expected is highly recommended
because it will be faster.
Returns Data read
Return type bytes or None
readinto(self, buf: _typing.WriteableBuffer, nbytes: Optional[int] = None) → Optional[bytes]
Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at
most len(buf) bytes.
Returns number of bytes read and stored into buf
Return type bytes or None
class usb_midi.PortOut
Sends midi messages to a computer over USB
You cannot create an instance of usb_midi.PortOut.
PortOut objects are constructed for every corresponding entry in the USB descriptor and added to the
usb_midi.ports tuple.
write(self, buf: _typing.ReadableBuffer) → Optional[int]
Write the buffer of bytes to the bus.
Returns the number of bytes written
Return type int or None
ustack.max_stack_usage() → int
Return the maximum excursion of the stack so far.
ustack.stack_size() → int
Return the size of the entire stack. Same as in micropython.mem_info(), but returns a value instead of just
printing it.
ustack.stack_usage() → int
Return how much stack is currently in use. Same as micropython.stack_use(); duplicated here for convenience.
The watchdog module provides support for a Watchdog Timer. This timer will reset the device if it hasn’t been fed
after a specified amount of time. This is useful to ensure the board has not crashed or locked up. Note that on some
platforms the watchdog timer cannot be disabled once it has been enabled.
The WatchDogTimer is used to restart the system when the application crashes and ends up into a non recoverable
state. Once started it cannot be stopped or reconfigured in any way. After enabling, the application must “feed” the
watchdog periodically to prevent it from expiring and resetting the system.
Example usage:
class watchdog.WatchDogMode
run state of the watchdog timer
Enum-like class to define the run mode of the watchdog timer.
RAISE :WatchDogMode
Raise an exception when the WatchDogTimer expires.
RESET :WatchDogMode
Reset the system if the WatchDogTimer expires.
class watchdog.WatchDogTimer
Timer that is used to detect code lock ups and automatically reset the microcontroller when one is detected.
A lock up is detected when the watchdog hasn’t been fed after a given duration. So, make sure to call feed
within the timeout.
Not currently dynamically supported. Access the sole instance through microcontroller.watchdog.
timeout :float
The maximum number of seconds that can elapse between calls to feed()
mode :WatchDogMode
The current operating mode of the WatchDogTimer watchdog.WatchDogMode.
Setting a WatchDogMode activates the WatchDog:
import microcontroller
import watchdog
w = microcontroller.watchdog
w.timeout = 5
w.mode = watchdog.WatchDogMode.RAISE
Once set, the WatchDogTimer will perform the specified action if the timer expires.
feed(self ) → None
Feed the watchdog timer. This must be called regularly, otherwise the timer will expire.
deinit(self ) → None
Stop the watchdog timer. This may raise an error if the watchdog timer cannot be disabled on this platform.
wifi
The wifi module provides necessary low-level functionality for managing wifi wifi connections. Use socketpool
for communicating over the network.
wifi.radio :Radio
Wifi radio used to manage both station and AP modes. This object is the sole instance of wifi.Radio.
class wifi.Network
A wifi network provided by a nearby access point.
You cannot create an instance of wifi.Network. They are returned by wifi.Radio.
start_scanning_networks.
ssid :str
String id of the network
bssid :bytes
BSSID of the network (usually the AP’s MAC address)
rssi :int
Signal strength of the network
channel :int
Channel number the network is operating on
country :str
String id of the country code
authmode :str
String id of the authmode
class wifi.Radio
Native wifi radio.
This class manages the station and access point functionality of the native Wifi radio.
You cannot create an instance of wifi.Radio. Use wifi.radio to access the sole instance available.
enabled :bool
True when the wifi radio is enabled. If you set the value to False, any open sockets will be closed.
mac_address :bytes
MAC address of the wifi radio. (read-only)
hostname :_typing.ReadableBuffer
Hostname for wifi interface. When the hostname is altered after interface started/connected the changes
would only be reflected once the interface restarts/reconnects.
ipv4_gateway :Optional[ipaddress.IPv4Address]
IP v4 Address of the gateway when connected to an access point. None otherwise.
ipv4_subnet :Optional[ipaddress.IPv4Address]
IP v4 Address of the subnet when connected to an access point. None otherwise.
ipv4_address :Optional[ipaddress.IPv4Address]
IP v4 Address of the radio when connected to an access point. None otherwise.
ipv4_dns :Optional[ipaddress.IPv4Address]
IP v4 Address of the DNS server in use when connected to an access point. None otherwise.
ap_info :Optional[Network]
Network object containing BSSID, SSID, authmode, channel, country and RSSI when connected to an
access point. None otherwise.
start_scanning_networks(self, *, start_channel: int = 1, stop_channel: int = 11) → Iter-
able[Network]
Scans for available wifi networks over the given channel range. Make sure the channels are allowed in
your country.
stop_scanning_networks(self ) → None
Stop scanning for Wifi networks and free any resources used to do it.
connect(self, ssid: _typing.ReadableBuffer, password: _typing.ReadableBuffer = b'', *, channel: Op-
tional[int] = 0, bssid: Optional[_typing.ReadableBuffer] = b'', timeout: Optional[float] =
None) → bool
Connects to the given ssid and waits for an ip address. Reconnections are handled automatically once one
connection succeeds.
By default, this will scan all channels and connect to the access point (AP) with the given ssid and
greatest signal strength (rssi).
If channel is given, the scan will begin with the given channel and connect to the first AP with the given
ssid. This can speed up the connection time significantly because a full scan doesn’t occur.
If bssid is given, the scan will start at the first channel or the one given and connect to the AP with the
given bssid and ssid.
ping(self, ip: ipaddress.IPv4Address, *, timeout: Optional[float] = 0.5) → float
Ping an IP to test connectivity. Returns echo time in seconds. Returns None when it times out.
class wifi.ScannedNetworks
Iterates over all wifi.Network objects found while scanning. This object is always created by a wifi.
Radio: it has no user-visible constructor.
Cannot be instantiated directly. Use wifi.Radio.start_scanning_networks.
__iter__(self ) → Iterator[Network]
Returns itself since it is the iterator.
__next__(self ) → Network
Returns the next wifi.Network. Raises StopIteration if scanning is finished and no other results
are available.
wiznet – Support for WizNet hardware, including the WizNet 5500 Ethernet adaptor.
Warning: This module is disabled in 6.x and will removed in 7.x. Please use networking libraries instead.
• The reset pin is optional: if supplied it is used to reset the wiznet board before initialization.
• The SPI bus will be initialized appropriately by this library.
• At present, the WIZNET5K object is a singleton, so only one WizNet interface is supported at a time.
connected :bool
(boolean, readonly) is this device physically connected?
dhcp :bool
(boolean, readwrite) is DHCP active on this device?
• set to True to activate DHCP, False to turn it off
ifconfig(self, params: Optional[Tuple[str, str, str, str]] = None) → Optional[Tuple[str, str, str, str]]
Called without parameters, returns a tuple of (ip_address, subnet_mask, gateway_address, dns_server)
Or can be called with the same tuple to set those parameters. Setting ifconfig parameters turns DHCP off,
if it was on.
help(object=None)
Prints a help method about the given object. When object is none, prints general port information.
CircuitPython supports a number of microcontroller families. Support quality for each varies depending on the active
contributors for each port.
Adafruit sponsored developers are actively contributing to atmel-samd, mimxrt10xx, nrf and stm ports. They also
maintain the other ports in order to ensure the boards build. Additional testing is limited.
This port supports many development boards that utilize SAMD21 and SAMD51 chips. See https://circuitpython.org/
downloads for all supported boards.
Building
Debugging
This directory contains the port of CircuitPython to Spresense. It is a compact development board based on Sony’s
power-efficient multicore microcontroller CXD5602.
Board features:
• Integrated GPS
– The embedded GNSS with support for GPS, QZSS and GLONASS enables applications where tracking is
required.
• Hi-res audio output and multi mic inputs
– Advanced 192kHz/24 bit audio codec and amplifier for audio output, and support for up to 8 mic input
channels.
• Multicore microcontroller
– Spresense is powered by Sony’s CXD5602 microcontroller (ARM® Cortex®-M4F × 6 cores), with a clock
speed of 156 MHz.
Currently, Spresense port does not support Audio and Multicore.
Refer to developer.sony.com/develop/spresense/ for further information about this board.
Prerequisites
Linux
Windows
macOS
Build instructions
$ make -C mpy-cross
$ cd ports/cxd56
$ make BOARD=spresense
USB connection
Connect the Spresense main board to the PC via the USB cable.
Connect the Spresense extension board to the PC via the USB cable.
Once built and deployed, access the CircuitPython REPL (the Python prompt) via USB. You can run:
Circuitpython on ESP32-S2
This port adds the ESP32-S2 line of modules from Espressif to Circuitpython. ESP32-S2 modules are low power,
single-core Wi-Fi microcontroller SoCs designed for IoT applications.
• bindings/ contains some required bindings to the ESP-IDF for exceptions and memory.
• boards/ contains the configuration files for each development board and breakout available on the port.
• common-hal/ contains the port-specific module implementations, used by shared-module and shared-bindings.
• esp-idf/ contains the Espressif IoT development framework installation, including all the drivers for the port.
• modules/ contains information specific to certain ESP32-S2 hardware modules, such as the pins used for flash
and RAM on the WROVER and WROOM.
• peripherals/ contains peripheral setup files and peripheral mapping information, sorted by family and sub-
variant. Most files in this directory can be generated with the python scripts in tools/.
• supervisor/ contains port-specific implementations of internal flash, serial and USB, as well as the port.c file,
which initializes the port at startup.
• tools/ includes useful python scripts for debugging and other purposes.
At the root level, refer to mpconfigboard.h and mpconfigport.mk for port specific settings and a list of enabled
circuitpython modules.
The USB port built into ESP32-S2 boards such as the Saola is not the native USB of the board, but a debugging and
programming interface. The actual ESP32-S2 native USB which exposes the Circuitpython drive and CDC connection
is located on IO pins 19 and 20:
GPIO USB
20 D+ (green)
19 D- (white)
GND GND (black)
5V +5V (red)
Connect these pins using a USB adapter or breakout cable to access the Circuitpython drive.
Before building or flashing the ESP32-S2, you must install the esp-idf. This must be re-done every time the esp-idf is
updated, but not every time you build. Run cd ports/esp32s2 from circuitpython/ to move to the esp32s2
port root, and run:
./esp-idf/install.sh
After this initial installation, you must add the esp-idf tools to your path. You must also do this any time you open a
new bash environment for building or flashing:
. esp-idf/export.sh
When Circuitpython updates the ESP-IDF to a new release, you may need to run this installation process again. The
exact commands used may also vary based on your bash environment.
Building boards such as the Saola is typically done through make flash. The default port is tty.
SLAB_USBtoUART, which will only work on certain Mac setups. On most machines, both Mac and Linux, you
will need to set the port yourself by running ls /dev/tty.usb* and selecting the one that only appears when
your development board is plugged in. An example make command with the port setting is as follows:
Debugging
The ESP32-S2 supports JTAG debugging over OpenOCD using a JLink or other probe hardware. The official tutorials
can be found on the Espressif website here, but they are mostly for the ESP32-S2 Kaluga, which has built-in debugging.
OpenOCD is automatically installed and added to your bash environment during the esp-idf installation and setup
process. You can double check that it is installed by using openocd --version, as per the tutorial. Attach
the JTAG probe pins according to the instructions for JTAG debugging on boards that do not contain an integrated
debugger.
Once the debugger is connected physically, you must run OpenOCD with attached configuration files specifying
the interface (your debugger probe) and either a target or a board (targets are for SoCs only, and can be used
when a full board configuration file doesn’t exist). You can find the path location of these files by checking the
OPENOCD_SCRIPTS environmental variable by running echo $OPENOCD_SCRIPTS in bash. Interfaces will be
in the interface/ directory, and targets and boards in the target/ and board/ directories, respectively.
Note: Unfortunately, there are no board files for the esp32-s2 other than the Kaluga, and the included target/
esp32s2.cfg target file will not work by default on the Jlink for boards like the Saola 1, as the default speed is
incorrect. In addition, these files are covered under the GPL and cannot be included in Circuitpython. Thus, you
must make a copy of the esp32s2.cfg file yourself and add the following line manually, under transport select
jtag at the start of the file:
adapter_khz 1000
Once this is complete, your final OpenOCD command may look something like this:
Where SOMEPATH is the location of your copied configuration file (this can be placed in the port/boards directory
with a prefix to ignore it with .gitignore, for instance). Interface, target and board config files sourced from
espressif only need their paths from the $OPENOCD_SCRIPTS location, you don’t need to include their full path.
Once OpenOCD is running, connect to GDB with:
xtensa-esp32s2-elf-gdb build-espressif_saola_1_wrover/firmware.elf
And follow the Espressif GDB tutorial instructions for connecting, or add them to your gdbinit:
LiteX (FPGA)
LiteX is a Python-based System on a Chip (SoC) designer for open source supported Field Programmable Gate Array
(FPGA) chips. This means that the CPU core(s) and peripherals are not defined by the physical chip. Instead, they
are loaded as separate “gateware”. Once this gateware is loaded, CircuitPython can be loaded on top of it to work as
expected.
Installation
dfu-util -D adafruit-circuitpython-fomu-en_US-<version>.dfu
It will install and then restart. CIRCUITPY should appear as it usually does and work the same.
Flash
Some boards have UF2 bootloaders and can simply be flashed in the normal way, by copying firmware.uf2 to the
BOOT drive.
For some boards, you can use the flash target:
Segger Targets
DFU Targets
make flash and make sd will not work with DFU targets. Hence, dfu-gen and dfu-flash must be used instead.
• dfu-gen: Generates a Firmware zip to be used by the DFU flash application.
• dfu-flash: Triggers the DFU flash application to upload the firmware from the generated Firmware zip file.
When enabled you have different options to test it:
• NUS Console for Linux (recommended)
• WebBluetooth REPL (experimental)
RP2040
This port supports many development boards that utilize RP2040 chips. See https://circuitpython.org/downloads for
all supported boards.
Building
Circuitpython on STM32
This port brings the ST Microelectronics STM32 series of MCUs to Circuitpython. STM32 chips have a wide range
of capability, from <$1 low power STM32F0s to dual-core STM32H7s running at 400+ MHz. Currently, only the F4,
F7, and H7 families are supported, powered by the ARM Cortex M4 and M7 processors.
Refer to the ST Microelectronics website for more information on features sorted by family and individual chip lines:
st.com/en/microcontrollers-microprocessors/stm32-high-performance-mcus.html
STM32 SoCs vary product-by-product in clock speed, peripheral capability, pin assignments, and their support within
this port. Refer to mpconfigport.mk for a full list of enabled modules sorted by family.
• boards/ contains the configuration files for each development board and breakout available on the port, as well
as system files and both shared and SoC-specific linker files. Board configuration includes a pin mapping of the
board, oscillator information, board-specific build flags, and setup for OLED or TFT screens where applicable.
• common-hal/ contains the port-specific module implementations, used by shared-module and shared-bindings.
• packages/ contains package-specific pin bindings (LQFP100, BGA216, etc)
• peripherals/ contains peripheral setup files and peripheral mapping information, sorted by family and sub-
variant. Most files in this directory can be generated with the python scripts in tools/.
• st-driver/ submodule for ST HAL and LL files generated via CubeMX. Shared with TinyUSB.
• supervisor/ contains port-specific implementations of internal flash, serial and USB, as well as the port.c file,
which initializes the port at startup.
• tools/ python scripts for generating peripheral and pin mapping files in peripherals/ and board/.
At the root level, refer to mpconfigboard.h and mpconfigport.mk for port specific settings and a list of enabled
modules.
Build instructions
Ensure your clone of Circuitpython is ready to build by following the guide on the Adafruit Website. This includes
installing the toolchain, synchronizing submodules, and running mpy-cross.
Once the one-time build tasks are complete, you can build at any time by navigating to the port directory:
$ cd ports/stm
$ make BOARD=feather_stm32f405_express
You may also build with certain flags available in the makefile, depending on your board and development goals. The
following flags would enable debug information and correct flash locations for a pre-flashed UF2 bootloader:
USB connection
Connect your development board of choice to the host PC via the USB cable. Note that for most ST development
boards such as the Nucleo and Discovery series, you must use a secondary OTG USB connector to access circuit-
python, as the primary USB connector will be connected to a built-in ST-Link debugger rather than the chip itself.
In many cases, this ST-Link USB connector will still need to be connected to power for the chip to turn on - refer to
your specific product manual for details.
Most ST development boards come with a built-in STLink programming and debugging probe accessible via USB.
This programmer may show up as an MBED drive on the host PC, enabling simple drag and drop programming with a
.bin file, or they may require a tool like OpenOCD or StLink-org/stlink to run flashing and debugging commands.
Many hobbyist and 3rd party development boards also expose SWD pins. These can be used with a cheap stlink
debugger or other common programmers.
For non-ST products or users without a debugger, all STM32 boards in the high performance families (F4, F7 and H7)
include a built-in DFU bootloader stored in ROM. This bootloader is accessed by ensuring the BOOT0 pin is held to a
logic 1 and the BOOT1 pin is held to a logic 0 when the chip is reset (ST Appnote AN2606). Most chips hold BOOT
low by default, so this can usually be achieved by running a jumper wire from 3.3V power to the BOOT0 pin, if it is
exposed, or by flipping the appropriate switch or button as the chip is reset. Once the chip is started in DFU mode,
BOOT0 no longer needs to be held high and can be released. An example is available in the Feather STM32F405
guide.
Windows users will need to install stm32cubeprog, while Mac and Linux users will need to install dfu-util
with brew install dfu-util or sudo apt-get install dfu-util. More details are available in the
Feather F405 guide.
Ensure the board is in dfu mode by following the steps in the previous section. Then run:
Alternatively, you can navigate to the build directory and run the raw dfu-util command:
dfu-util -a 0 --dfuse-address 0x08000000 -D firmware.bin
Connecting the board to the PC via the USB cable will allow code to be uploaded to the CIRCUITPY volume.
Circuitpython exposes a CDC virtual serial connection for REPL access and debugging. Connecting to it from OSX
will look something like this:
You may also use a program like mu to assist with REPL access.
1.8.3 Troubleshooting
From time to time, an error occurs when working with CircuitPython. Here are a variety of errors that can happen,
what they mean and how to fix them.
If your host computer starts complaining that your CIRCUITPY drive is corrupted or files cannot be overwritten
or deleted, then you will have to erase it completely. When CircuitPython restarts it will create a fresh empty
CIRCUITPY filesystem.
This often happens on Windows when the CIRCUITPY disk is not safely ejected before being reset by the button or
being disconnected from USB. This can also happen on Linux and Mac OSX but it’s less likely.
Caution: To erase and re-create CIRCUITPY (for example, to correct a corrupted filesystem), follow one of the
procedures below. It’s important to note that any files stored on the CIRCUITPY drive will be erased.
For boards with CIRCUITPY stored on a separate SPI flash chip, such as Feather M0 Express, Metro M0
Express and Circuit Playground Express:
1. Download the appropriate flash .erase uf2 from the Adafruit_SPIFlash repo.
2. Double-click the reset button.
3. Copy the appropriate .uf2 to the xxxBOOT drive.
4. The on-board NeoPixel will turn blue, indicating the erase has started.
5. After about 15 seconds, the NexoPixel will start flashing green. If it flashes red, the erase failed.
6. Double-click again and load the appropriate CircuitPython .uf2.
For boards without SPI flash, such as Feather M0 Proto, Gemma M0 and, Trinket M0:
1. Download the appropriate erase .uf2 from the Learn repo.
2. Double-click the reset button.
3. Copy the appropriate .uf2 to the xxxBOOT drive.
4. The boot LED will start pulsing again, and the xxxBOOT drive will appear again.
5. Load the appropriate CircuitPython .uf2.
This error occurs when importing a module that is stored as a mpy binary file (rather than a py text file) that was
generated by a different version of CircuitPython than the one it’s being loaded into. Most versions are compatible
but, rarely they aren’t. In particular, the mpy binary format changed between CircuitPython versions 1.x and 2.x, and
will change again between 2.x and 3.x.
So, for instance, if you just upgraded to CircuitPython 2.x from 1.x you’ll need to download a newer version of the
library that triggered the error on import. They are all available in the Adafruit bundle and the Community bundle.
Make sure to download a version with 2.0.0 or higher in the filename.
These are libraries and drivers available in separate GitHub repos. They are designed for use with CircuitPython and
may or may not work with MicroPython.
We provide a bundle of all our libraries to ease installation of drivers and their dependencies. The bundle is primarily
geared to the Adafruit Express line of boards which feature a relatively large external flash. With Express boards, it’s
easy to copy them all onto the filesystem. However, if you don’t have enough space simply copy things over as they
are needed.
• The Adafruit bundles are available on GitHub: <https://github.com/adafruit/Adafruit_CircuitPython_Bundle/
releases>.
• Documentation for the bundle, which includes links to documentation for all libraries, is available here: <https:
//circuitpython.readthedocs.io/projects/bundle/en/latest/>.
This bundle contains non-Adafruit sponsored libraries, that are written and submitted by members of the community.
• The Community bundles are available on GitHub: <https://github.com/adafruit/CircuitPython_Community_
Bundle/releases>.
• Documentation is not available on ReadTheDocs at this time. See each library for any included documentation.
This guide covers a variety of development practices for CircuitPython core and library APIs. These APIs are both
built-into CircuitPython and those that are distributed on GitHub and in the Adafruit and Community bundles. Con-
sistency with these practices ensures that beginners can learn a pattern once and apply it throughout the CircuitPython
ecosystem.
Cookiecutter is a tool that lets you bootstrap a new repo based on another repo. We’ve made one here for CircuitPython
libraries that include configs for Travis CI and ReadTheDocs along with a setup.py, license, code of conduct and
readme.
Cookiecutter will provide a series of prompts relating to the library and then create a new directory with all of the files.
See the CircuitPython cookiecutter README for more details.
Module Naming
Adafruit funded libraries should be under the adafruit organization and have the format
Adafruit_CircuitPython_<name> and have a corresponding adafruit_<name> directory (aka package)
or adafruit_<name>.py file (aka module).
If the name would normally have a space, such as “Thermal Printer”, use an underscore instead (“Thermal_Printer”).
This underscore will be used everywhere even when the separation between “adafruit” and “circuitpython” is done
with a -. Use the underscore in the cookiecutter prompts.
Community created libraries should have the repo format CircuitPython_<name> and not have the adafruit_
module or package prefix.
Both should have the CircuitPython repository topic on GitHub.
Terminology
As our Code of Conduct states, we strive to use “welcoming and inclusive language.” Whether it is in documentation
or in code, the words we use matter. This means we disfavor language that due to historical and social context can
make community members and potential community members feel unwelcome.
There are specific terms to avoid except where technical limitations require it. While specific cases may call for other
terms, consider using these suggested terms first:
Preferred Deprecated
Main (device) Master
Peripheral Slave
Sensor
Secondary (device)
Denylist Blacklist
Allowlist Whitelist
Note that “technical limitations” refers e.g., to the situation where an upstream library or URL has to contain those
substrings in order to work. However, when it comes to documentation and the names of parameters and properties in
CircuitPython, we will use alternate terms even if this breaks tradition with past practice.
A driver should be initialized and ready to use after construction. If the device requires deinitialization, then provide
it through deinit() and also provide __enter__ and __exit__ to create a context manager usable with with.
For example, a user can then use deinit()`:
import digitalio
import board
import time
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
for i in range(10):
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
led.deinit()
This will deinit the underlying hardware at the end of the program as long as no exceptions occur.
Alternatively, using a with statement ensures that the hardware is deinitialized:
import digitalio
import board
import time
(continues on next page)
for i in range(10):
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
Python’s with statement ensures that the deinit code is run regardless of whether the code within the with statement
executes without exceptions.
For small programs like the examples this isn’t a major concern because all user usable hardware is reset after programs
are run or the REPL is run. However, for more complex programs that may use hardware intermittently and may also
handle exceptions on their own, deinitializing the hardware using a with statement will ensure hardware isn’t enabled
longer than needed.
Whenever possible, make sure device you are talking to is the device you expect. If not, raise a RuntimeError. Beware
that I2C addresses can be identical on different devices so read registers you know to make sure they match your
expectation. Validating this upfront will help catch mistakes.
Getters/Setters
When designing a driver for a device, use properties for device state and use methods for sequences of abstract actions
that the device performs. State is a property of the device as a whole that exists regardless of what the code is doing.
This includes things like temperature, time, sound, light and the state of a switch. For a more complete list see the
sensor properties bullet below.
Another way to separate state from actions is that state is usually something the user can sense themselves by sight or
feel for example. Actions are something the user can watch. The device does this and then this.
Making this separation clear to the user will help beginners understand when to use what.
Here is more info on properties from Python.
Raise an appropriate Exception, along with a useful message, whenever a critical test or other condition fails.
Example:
If memory is constrained and a more compact method is needed, use The assert statement instead.
Example:
CircuitPython is aimed to be one’s first experience with code. It will be the first step into the world of hardware and
software. To ease one’s exploration out from this first step, make sure that functionality shared with CPython shares
the same API. It doesn’t need to be the full API it can be a subset. However, do not add non-CPython APIs to the same
modules. Instead, use separate non-CPython modules to add extra functionality. By distinguishing API boundaries at
modules you increase the likelihood that incorrect expectations are found on import and not randomly during runtime.
When adding a new module for additional functionality related to a CPython module do NOT simply prefix it with u.
This is not a large enough differentiation from CPython. This is the MicroPython convention and they use u* modules
interchangeably with the CPython name. This is confusing. Instead, think up a new name that is related to the extra
functionality you are adding.
For example, storage mounting and unmounting related functions were moved from uos into a new storage module.
Terminal related functions were moved into multiterminal. These names better match their functionality and do
not conflict with CPython names. Make sure to check that you don’t conflict with CPython libraries too. That way we
can port the API to CPython in the future.
Example
When adding extra functionality to CircuitPython to mimic what a normal operating system would do, either copy an
existing CPython API (for example file writing) or create a separate module to achieve what you want. For example,
mounting and unmount drives is not a part of CPython so it should be done in a module, such as a new storage
module, that is only available in CircuitPython. That way when someone moves the code to CPython they know what
parts need to be adapted.
Document inline
Whenever possible, document your code right next to the code that implements it. This makes it more likely to stay
up to date with the implementation itself. Use Sphinx’s automodule to format these all nicely in ReadTheDocs. The
cookiecutter helps set these up.
Use Sphinx flavor rST for markup.
Lots of documentation is a good thing but it can take a lot of space. To minimize the space used on disk and on load,
distribute the library as both .py and .mpy, MicroPython and CircuitPython’s bytecode format that omits comments.
Module description
"""
`<module name>` - <Short description>
=================================================
<Longer description.>
"""
Class description
At the class level document what class does and how to initialize it:
class DS3231:
"""DS3231 real-time clock.
:param ~busio.I2C i2c_bus: The I2C bus the DS3231 is connected to.
:param int address: The I2C address of the device.
"""
Renders as:
class DS3231(i2c_bus, address=64)
DS3231 real-time clock.
Parameters
• i2c_bus (I2C) – The I2C bus the DS3231 is connected to.
• address (int) – The I2C address of the device.
Attributes
Attributes are state on objects. (See Getters/Setters above for more discussion about when to use them.) They can be
defined internally in a number of different ways. Each approach is enumerated below with an explanation of where
the comment goes.
Regardless of how the attribute is implemented, it should have a short description of what state it represents including
the type, possible values and/or units. It should be marked as (read-only) or (write-only) at the end of the
first line for attributes that are not both readable and writable.
Instance attributes
- `digitalio.DriveMode.PUSH_PULL`
- `digitalio.DriveMode.OPEN_DRAIN`
"""
Renders as:
drive_mode
The pin drive mode. One of:
• digitalio.DriveMode.PUSH_PULL
• digitalio.DriveMode.OPEN_DRAIN
Property description
@property
def datetime(self):
"""The current date and time as a `time.struct_time`."""
return self.datetime_register
@datetime.setter
def datetime(self, value):
pass
Renders as:
datetime
The current date and time as a time.struct_time.
Read-only example:
@property
def temperature(self):
"""
The current temperature in degrees Celsius. (read-only)
Renders as:
temperature
The current temperature in degrees Celsius. (read-only)
The device may require calibration to get accurate readings.
lost_power = i2c_bit.RWBit(0x0f, 7)
"""True if the device has lost power since the time was set."""
Renders as:
lost_power
True if the device has lost power since the time was set.
Method description
Renders as:
turn_right(degrees)
Turns the bot degrees right.
Parameters degrees (float) – Degrees to turn right
Use BusDevice
BusDevice is an awesome foundational library that manages talking on a shared I2C or SPI device for you. The devices
manage locking which ensures that a transfer is done as a single unit despite CircuitPython internals and, in the future,
other Python threads. For I2C, the device also manages the device address. The SPI device, manages baudrate settings,
chip select line and extra post-transaction clock cycles.
I2C Example
DEVICE_DEFAULT_I2C_ADDR = 0x42
class Widget:
"""A generic widget."""
@property
def register(self):
"""Widget's one register."""
with self.i2c_device as i2c:
i2c.writeto(b'0x00')
i2c.readfrom_into(self.buf)
return self.buf[0]
SPI Example
class SPIWidget:
"""A generic widget with a weird baudrate."""
@property
def register(self):
"""Widget's one register."""
with self.spi_device as spi:
spi.write(b'0x00')
spi.readinto(self.buf)
return self.buf[0]
Use composition
When writing a driver, take in objects that provide the functionality you need rather than taking their arguments and
constructing them yourself or subclassing a parent class with functionality. This technique is known as composition
and leads to code that is more flexible and testable than traditional inheritance.
See also:
Wikipedia has more information on “dependency inversion”.
For example, if you are writing a driver for an I2C device, then take in an I2C object instead of the pins themselves.
This allows the calling code to provide any object with the appropriate methods such as an I2C expansion board.
Another example is to expect a DigitalInOut for a pin to toggle instead of a Pin from board. Taking in the Pin
object alone would limit the driver to pins on the actual microcontroller instead of pins provided by another driver
such as an IO expander.
CircuitPython boards tend to have a small amount of internal flash and a small amount of ram but large amounts of
external flash for the file system. So, create many small libraries that can be loaded as needed instead of one large file
that does everything.
Speed second
Speed isn’t as important as API clarity and code size. So, prefer simple APIs like properties for state even if it sacrifices
a bit of speed.
Although Python doesn’t require managing memory, it’s still a good practice for library writers to think about memory
allocations. Avoid them in drivers if you can because you never know how much something will be called. Fewer allo-
cations means less time spent cleaning up. So, where you can, prefer bytearray buffers that are created in __init__
and used throughout the object with methods that read or write into the buffer instead of creating new objects. Unified
hardware API classes such as busio.SPI are design to read and write to subsections of buffers.
It’s ok to allocate an object to return to the user. Just beware of causing more than one allocation per call due to internal
logic.
However, this is a memory tradeoff so do not do it for large or rarely used buffers.
Examples
struct.pack
The MicroPython const() feature, as discussed in this forum post, and in this issue thread, provides some optimiza-
tions that can be useful on smaller, memory constrained devices. However, when using const(), keep in mind these
general guide lines:
• Always use via an import, ex: from micropython import const
• Limit use to global (module level) variables only.
• If user will not need access to variable, prefix name with a leading underscore, ex: _SOME_CONST.
The Adafruit Unified Sensor Driver Arduino library has a great list of measurements and their units. Use the same ones
including the property name itself so that drivers can be used interchangeably when they have the same properties.
The Python API for a new module should be defined and documented in shared-bindings and define an under-
lying C API. If the implementation is port-agnostic or relies on underlying APIs of another module, the code should
live in shared-module. If it is port specific then it should live in common-hal within the port’s folder. In either
case, the file and folder structure should mimic the structure in shared-bindings.
To test your native modules or core enhancements, follow these Adafruit Learning Guides for building local firmware
to flash onto your device(s):
SAMD21 - Build Firmware Learning Guide
ESP8266 - Build Firmware Learning Guide
MicroPython compatibility
Keeping compatibility with MicroPython isn’t a high priority. It should be done when it’s not in conflict with any of
the above goals.
We love CircuitPython and would love to see it come to more microcontroller platforms. Since 3.0 we’ve reworked
CircuitPython to make it easier than ever to add support. While there are some major differences between ports, this
page covers the similarities that make CircuitPython what it is and how that core fits into a variety of microcontrollers.
1.8.6 Architecture
1.8.7 Porting
The first step to porting to a new microcontroller is getting a build running. The primary goal of it should be to get
main.c compiling with the assistance of the supervisor/supervisor.mk file. Port specific code should be
isolated to the port’s directory (in the top level until the ports directory is present). This includes the Makefile and
any C library resources. Make sure these resources are compatible with the MIT License of the rest of the code!
Circuitpython has a number of modules enabled by default in py/circuitpy_mpconfig.mk. Most of these
modules will need to be disabled in mpconfigboard.mk during the early stages of a port in order for it to compile.
As the port progresses in module support, this list can be pruned down as a natural “TODO” list. An example minimal
build list is shown below:
Step 2: Init
Once your build is setup, the next step should be to get your clocks going as you expect from the supervisor. The
supervisor calls port_init to allow for initialization at the beginning of main. This function also has the ability
to request a safe mode state which prevents the supervisor from running user code while still allowing access to the
REPL and other resources.
The core port initialization and reset methods are defined in supervisor/port.c and should be the first to be
implemented. It’s required that they be implemented in the supervisor directory within the port directory. That
way, they are always in the expected place.
The supervisor also uses three linker variables, _ezero, _estack and _ebss to determine memory layout for stack
overflow checking.
Step 3: REPL
Getting the REPL going is a huge step. It involves a bunch of initialization to be done correctly and is a good sign
you are well on your porting way. To get the REPL going you must implement the functions and definitions from
supervisor/serial.h with a corresponding supervisor/serial.c in the port directory. This involves
sending and receiving characters over some sort of serial connection. It could be UART or USB for example.
digitalio provides a well-defined, cross-port hardware abstraction layer built to support different devices and their
drivers. It’s backed by the Common HAL, a C api suitable for supporting different hardware in a similar manner. By
sharing this C api, developers can support new hardware easily and cross-port functionality to the new hardware.
These instructions also apply to analogio, busio, pulseio and touchio. Most drivers depend on analogio,
digitalio and busio so start with those.
File layout
Adding support
The first step is to hook the shared-bindings into your build for the modules you wish to support. Here’s an
example of this step for the atmel-samd/Makefile:
SRC_BINDINGS = \
board/__init__.c \
microcontroller/__init__.c \
microcontroller/Pin.c \
analogio/__init__.c \
analogio/AnalogIn.c \
analogio/AnalogOut.c \
digitalio/__init__.c \
digitalio/DigitalInOut.c \
pulseio/__init__.c \
pulseio/PulseIn.c \
pulseio/PulseOut.c \
pulseio/PWMOut.c \
busio/__init__.c \
busio/I2C.c \
busio/SPI.c \
busio/UART.c \
(continues on next page)
The Makefile defines the modules to build and adds the sources to include the shared-bindings version and
the common-hal version within the port specific directory. You may comment out certain subfolders to reduce the
number of modules to add but don’t comment out individual classes. It won’t compile then.
Built in modules are typically defined in mpconfigport.h. To add support you should have something like:
#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module } \
At this point in the port, nothing will compile yet, because there’s still work to be done to fix missing sources, compile
issues, and link issues. I suggest start with a common-hal directory from another port that implements it such as
atmel-samd or esp8266, deleting the function contents and stubbing out any return statements. Once that is done,
you should be able to compile cleanly and import the modules, but nothing will work (though you are getting closer).
The last step is actually implementing each function in a port specific way. I can’t help you with this. :-) If you have
any questions how a Common HAL function should work then see the corresponding .h file in shared-bindings.
Testing
Woohoo! You are almost done. After you implement everything, lots of drivers and sample code should just work.
There are a number of drivers and examples written for Adafruit’s Feather ecosystem. Here are places to start:
• Adafruit repos with CircuitPython topic
• Adafruit driver bundle
The libraries below are inherited from MicroPython. They are similar to the standard Python libraries with the same
name. They implement a subset of or a variant of the corresponding standard Python library.
CircuitPython’s long-term goal is that code written in CircuitPython using Python standard libraries will be runnable
on CPython without changes.
These libraries are not enabled on CircuitPython builds with limited flash memory, usually on non-Express builds:
binascii, errno, json, re.
These libraries are not currently enabled in any CircuitPython build, but may be in the future, with the u prefix dropped:
uctypes, uhashlib, uzlib.
All builtin functions and exceptions are described here. They are also available via builtins module.
Not all of these functions and types are turned on in all CircuitPython ports, for space reasons.
abs()
all()
any()
bin()
class bool
class bytearray
class bytes
See CPython documentation: bytes.
callable()
chr()
classmethod()
compile()
class complex
delattr(obj, name)
The argument name should be a string, and this function deletes the named attribute from the object given by
obj.
class dict
dir()
divmod()
enumerate()
eval()
exec()
filter()
class float
class frozenset
frozenset() is not enabled on non-Express CircuitPython boards.
getattr()
globals()
hasattr()
hash()
hex()
id()
input()
class int
oct()
open()
ord()
pow()
print()
property()
range()
repr()
reversed()
reversed() is not enabled on non-Express CircuitPython boards.
round()
class set
setattr()
class slice
The slice builtin is the type that slice objects have.
sorted()
staticmethod()
class str
sum()
super()
class tuple
type()
zip()
Exceptions
exception AssertionError
exception AttributeError
exception Exception
exception ImportError
exception IndexError
exception KeyboardInterrupt
exception KeyError
exception MemoryError
exception NameError
exception NotImplementedError
exception OSError
See CPython documentation: OSError. CircuitPython doesn’t implement the errno attribute, instead use the
standard way to access exception arguments: exc.args[0].
exception RuntimeError
exception ReloadException
ReloadException is used internally to deal with soft restarts.
exception StopIteration
exception SyntaxError
exception SystemExit
See CPython documentation: SystemExit.
exception TypeError
See CPython documentation: TypeError.
exception ValueError
exception ZeroDivisionError
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: heapq.
This module implements the heap queue algorithm.
A heap queue is simply a list that has its elements stored in a certain way.
Functions
uheapq.heappush(heap, item)
Push the item onto the heap.
uheapq.heappop(heap)
Pop the first item from the heap, and return it. Raises IndexError if heap is empty.
uheapq.heapify(x)
Convert the list x into a heap. This is an in-place operation.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: array.
Supported format codes: b, B, h, H, i, I, l, L, q, Q, f, d (the latter 2 depending on the floating-point support).
Classes
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: binascii.
This module implements conversions between binary data and various encodings of it in ASCII form (in both direc-
tions).
Functions
binascii.hexlify(data[, sep ])
Convert binary data to hexadecimal representation. Returns bytes string.
Difference to CPython
If additional argument, sep is supplied, it is used as a separator between hexadecimal values.
binascii.unhexlify(data)
Convert hexadecimal data to binary representation. Returns bytes string. (i.e. inverse of hexlify)
binascii.a2b_base64(data)
Decode base64-encoded data, ignoring invalid characters in the input. Conforms to RFC 2045 s.6.8. Returns a
bytes object.
binascii.b2a_base64(data)
Encode binary data in base64 format, as in RFC 3548. Returns the encoded data followed by a newline character,
as a bytes object.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: collections.
This module implements advanced collection and container types to hold/accumulate various objects.
Classes
collections.namedtuple(name, fields)
This is factory function to create a new namedtuple type with a specific name and set of fields. A namedtuple is
a subclass of tuple which allows to access its fields not just by numeric index, but also with an attribute access
syntax using symbolic field names. Fields is a sequence of strings specifying field names. For compatibility
with CPython it can also be a a string with space-separated field named (but this is less efficient). Example of
use:
collections.OrderedDict(...)
dict type subclass which remembers and preserves the order of keys added. When ordered dict is iterated over,
keys/items are returned in the order they were added:
Output:
z 1
a 2
w 5
b 3
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: errno.
This module provides access to symbolic error codes for OSError exception.
Constants
try:
os.mkdir("my_dir")
except OSError as exc:
if exc.args[0] == errno.EEXIST:
print("Directory already exists")
errno.errorcode
Dictionary mapping numeric error codes to strings with symbolic error code (see above):
>>> print(errno.errorcode[uerrno.EEXIST])
EEXIST
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: gc.
Functions
gc.enable()
Enable automatic garbage collection.
gc.disable()
Disable automatic garbage collection. Heap memory can still be allocated, and garbage collection can still be
initiated manually using gc.collect().
gc.collect()
Run a garbage collection.
gc.mem_alloc()
Return the number of bytes of heap RAM that are allocated.
Difference to CPython
gc.mem_free()
Return the number of bytes of available heap RAM, or -1 if this amount is not known.
Difference to CPython
This function is a MicroPython extension.
gc.threshold([amount ])
Set or query the additional GC allocation threshold. Normally, a collection is triggered only when a new allo-
cation cannot be satisfied, i.e. on an out-of-memory (OOM) condition. If this function is called, in addition to
OOM, a collection will be triggered each time after amount bytes have been allocated (in total, since the pre-
vious time such an amount of bytes have been allocated). amount is usually specified as less than the full heap
size, with the intention to trigger a collection earlier than when the heap becomes exhausted, and in the hope
that an early collection will prevent excessive memory fragmentation. This is a heuristic measure, the effect of
which will vary from application to application, as well as the optimal value of the amount parameter.
Calling the function without argument will return the current value of the threshold. A value of -1 means a
disabled allocation threshold.
Difference to CPython
This function is a a MicroPython extension. CPython has a similar function - set_threshold(), but due to
different GC implementations, its signature and semantics are different.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: hashlib.
This module implements binary data hashing algorithms. The exact inventory of available algorithms depends on a
board. Among the algorithms which may be implemented:
• SHA256 - The current generation, modern hashing algorithm (of SHA2 series). It is suitable for
cryptographically-secure purposes. Included in the MicroPython core and any board is recommended to provide
this, unless it has particular code size constraints.
• SHA1 - A previous generation algorithm. Not recommended for new usages, but SHA1 is a part of number of
Internet standards and existing applications, so boards targeting network connectivity and interoperability will
try to provide this.
• MD5 - A legacy algorithm, not considered cryptographically secure. Only selected boards, targeting interoper-
ability with legacy applications, will offer this.
Constructors
class hashlib.sha256([data ])
Create an SHA256 hasher object and optionally feed data into it.
class hashlib.sha1([data ])
Create an SHA1 hasher object and optionally feed data into it.
class hashlib.md5([data ])
Create an MD5 hasher object and optionally feed data into it.
Methods
hash.update(data)
Feed more binary data into hash.
hash.digest()
Return hash for all data passed through hash, as a bytes object. After this method is called, more data cannot be
fed into the hash any longer.
hash.hexdigest()
This method is NOT implemented. Use binascii.hexlify(hash.digest()) to achieve a similar ef-
fect.
io – input/output streams
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: io.
This module contains additional types of stream (file-like) objects and helper functions.
Conceptual hierarchy
Difference to CPython
Conceptual hierarchy of stream base classes is simplified in MicroPython, as described in this section.
(Abstract) base stream classes, which serve as a foundation for behavior of all the concrete classes, adhere to few
dichotomies (pair-wise classifications) in CPython. In MicroPython, they are somewhat simplified and made implicit
to achieve higher efficiencies and save resources.
An important dichotomy in CPython is unbuffered vs buffered streams. In MicroPython, all streams are currently
unbuffered. This is because all modern OSes, and even many RTOSes and filesystem drivers already perform buffering
on their side. Adding another layer of buffering is counter- productive (an issue known as “bufferbloat”) and takes
precious memory. Note that there still cases where buffering may be useful, so we may introduce optional buffering
support at a later time.
But in CPython, another important dichotomy is tied with “bufferedness” - it’s whether a stream may incur short
read/writes or not. A short read is when a user asks e.g. 10 bytes from a stream, but gets less, similarly for writes. In
CPython, unbuffered streams are automatically short operation susceptible, while buffered are guarantee against them.
The no short read/writes is an important trait, as it allows to develop more concise and efficient programs - something
which is highly desirable for MicroPython. So, while MicroPython doesn’t support buffered streams, it still provides
for no-short-operations streams. Whether there will be short operations or not depends on each particular class’ needs,
but developers are strongly advised to favor no-short-operations behavior for the reasons stated above. For example,
MicroPython sockets are guaranteed to avoid short read/writes. Actually, at this time, there is no example of a short-
operations stream class in the core, and one would be a port-specific class, where such a need is governed by hardware
peculiarities.
The no-short-operations behavior gets tricky in case of non-blocking streams, blocking vs non-blocking behavior
being another CPython dichotomy, fully supported by MicroPython. Non-blocking streams never wait for data either
to arrive or be written - they read/write whatever possible, or signal lack of data (or ability to write data). Clearly,
this conflicts with “no-short-operations” policy, and indeed, a case of non-blocking buffered (and this no-short-ops)
streams is convoluted in CPython - in some places, such combination is prohibited, in some it’s undefined or just not
documented, in some cases it raises verbose exceptions. The matter is much simpler in MicroPython: non-blocking
stream are important for efficient asynchronous operations, so this property prevails on the “no-short-ops” one. So,
while blocking streams will avoid short reads/writes whenever possible (the only case to get a short read is if end of
file is reached, or in case of error (but errors don’t return short data, but raise exceptions)), non-blocking streams may
produce short data to avoid blocking the operation.
The final dichotomy is binary vs text streams. MicroPython of course supports these, but while in CPython text
streams are inherently buffered, they aren’t in MicroPython. (Indeed, that’s one of the cases for which we may
introduce buffering support.)
Note that for efficiency, MicroPython doesn’t provide abstract base classes corresponding to the hierarchy above, and
it’s not possible to implement, or subclass, a stream class in pure Python.
Functions
Classes
class io.FileIO(...)
This is type of a file open in binary mode, e.g. using open(name, "rb"). You should not instantiate this
class directly.
class io.TextIOWrapper(...)
This is type of a file open in text mode, e.g. using open(name, "rt"). You should not instantiate this class
directly.
class io.StringIO([string ])
class io.BytesIO([string ])
In-memory file-like objects for input/output. StringIO is used for text-mode I/O (similar to a normal file
opened with “t” modifier). BytesIO is used for binary-mode I/O (similar to a normal file opened with “b”
modifier). Initial contents of file-like objects can be specified with string parameter (should be normal string
for StringIO or bytes object for BytesIO). All the usual file methods like read(), write(), seek(),
flush(), close() are available on these objects, and additionally, a following method:
getvalue()
Get the current contents of the underlying buffer which holds data.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: json.
This modules allows to convert between Python objects and the JSON data format.
Functions
json.dump(obj, stream)
Serialise obj to a JSON string, writing it to the given stream.
json.dumps(obj)
Return obj represented as a JSON string.
json.load(stream)
Parse the given stream, interpreting it as a JSON string and deserialising the data to a Python object. The
resulting object is returned.
Parsing continues until end-of-file is encountered. A ValueError is raised if the data in stream is not
correctly formed.
json.loads(str)
Parse the JSON str and return an object. Raises ValueError if the string is not correctly formed.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: re.
This module implements regular expression operations. Regular expression syntax supported is a subset of CPython
re module (and actually is a subset of POSIX extended regular expressions).
Supported operators are:
'.' Match any character.
'[...]' Match set of characters. Individual characters and ranges are supported, including negated sets (e.g.
[^a-c]).
'^'
'$'
'?'
'*'
'+'
'??'
'*?'
'+?'
'|'
'(...)' Grouping. Each group is capturing (a substring it captures can be accessed with match.group()
method).
NOT SUPPORTED: Counted repetitions ({m,n}), more advanced assertions (\b, \B), named groups ((?
P<name>...)), non-capturing groups ((?:...)), etc.
Functions
re.compile(regex_str[, flags ])
Compile regular expression, return regex object.
re.match(regex_str, string)
Compile regex_str and match against string. Match always happens from starting position in a string.
re.search(regex_str, string)
Compile regex_str and search it in a string. Unlike match, this will search string for first position which
matches regex (which still may be 0 if regex is anchored).
re.DEBUG
Flag value, display debug information about compiled expression.
Regex objects
Compiled regular expression. Instances of this class are created using re.compile().
regex.match(string)
regex.search(string)
Similar to the module-level functions match() and search(). Using methods is (much) more efficient if
the same regex is applied to multiple strings.
regex.split(string, max_split=- 1)
Split a string using regex. If max_split is given, it specifies maximum number of splits to perform. Returns list
of strings (there may be up to max_split+1 elements if it’s specified).
Match objects
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: sys.
Functions
sys.exit(retval=0)
Terminate current program with a given exit code. Underlyingly, this function raise as SystemExit exception.
If an argument is given, its value given as an argument to SystemExit.
sys.print_exception(exc, file=sys.stdout)
Print exception with a traceback to a file-like object file (or sys.stdout by default).
Difference to CPython
This is simplified version of a function which appears in the traceback module in CPython. Unlike
traceback.print_exception(), this function takes just exception value instead of exception type, ex-
ception value, and traceback object; file argument should be positional; further arguments are not supported.
Constants
sys.argv
A mutable list of arguments the current program was started with.
sys.byteorder
The byte order of the system ("little" or "big").
sys.implementation
Object with information about the current Python implementation. For CircuitPython, it has following attributes:
• name - string “circuitpython”
• version - tuple (major, minor, micro), e.g. (1, 7, 0)
This object is the recommended way to distinguish CircuitPython from other Python implementations (note that
it still may not exist in the very minimal ports).
Difference to CPython
CPython mandates more attributes for this object, but the actual useful bare minimum is implemented in Cir-
cuitPython.
sys.maxsize
Maximum value which a native integer type can hold on the current platform, or maximum value representable
by CircuitPython integer type, if it’s smaller than platform max value (that is the case for CircuitPython ports
without long int support).
This attribute is useful for detecting “bitness” of a platform (32-bit vs 64-bit, etc.). It’s recommended to not
compare this attribute to some value directly, but instead count number of bits in it:
bits = 0
v = sys.maxsize
while v:
bits += 1
v >>= 1
if bits > 32:
# 64-bit (or more) platform
...
else:
(continues on next page)
sys.modules
Dictionary of loaded modules. On some ports, it may not include builtin modules.
sys.path
A mutable list of directories to search for imported modules.
sys.platform
The platform that CircuitPython is running on. For OS/RTOS ports, this is usually an identifier of the OS, e.g.
"linux". For baremetal ports it is an identifier of the chip on a board, e.g. "MicroChip SAMD51". It
thus can be used to distinguish one board from another. If you need to check whether your program runs on
CircuitPython (vs other Python implementation), use sys.implementation instead.
sys.stderr
Standard error stream.
sys.stdin
Standard input stream.
sys.stdout
Standard output stream.
sys.version
Python language version that this implementation conforms to, as a string.
sys.version_info
Python language version that this implementation conforms to, as a tuple of ints.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements “foreign data interface” for MicroPython. The idea behind it is similar to CPython’s ctypes
modules, but the actual API is different, streamlined and optimized for small size. The basic idea of the module is
to define data structure layout with about the same power as the C language allows, and then access it using familiar
dot-syntax to reference sub-fields.
See also:
Module struct Standard Python way to access binary data structures (doesn’t scale well to large and complex
structures).
Structure layout is defined by a “descriptor” - a Python dictionary which encodes field names as keys and other
properties required to access them as associated values. Currently, uctypes requires explicit specification of offsets for
each field. Offset are given in bytes from a structure start.
Following are encoding examples for various field types:
• Scalar types:
in other words, value is scalar type identifier ORed with field offset (in bytes) from the start of the structure.
• Recursive structures:
"sub": (offset, {
"b0": 0 | uctypes.UINT8,
"b1": 1 | uctypes.UINT8,
})
i.e. value is a 2-tuple, first element of which is offset, and second is a structure descriptor dictionary (note:
offsets in recursive descriptors are relative to the structure it defines).
• Arrays of primitive types:
i.e. value is a 2-tuple, first element of which is ARRAY flag ORed with offset, and second is scalar element type
ORed number of elements in array.
• Arrays of aggregate types:
i.e. value is a 3-tuple, first element of which is ARRAY flag ORed with offset, second is a number of elements
in array, and third is descriptor of element type.
• Pointer to a primitive type:
i.e. value is a 2-tuple, first element of which is PTR flag ORed with offset, and second is scalar element type.
• Pointer to an aggregate type:
i.e. value is a 2-tuple, first element of which is PTR flag ORed with offset, second is descriptor of type pointed
to.
• Bitfields:
i.e. value is type of scalar value containing given bitfield (typenames are similar to scalar types, but prefixes with
“BF”), ORed with offset for scalar value containing the bitfield, and further ORed with values for bit offset and
bit length of the bitfield within scalar value, shifted by BF_POS and BF_LEN positions, respectively. Bitfield
position is counted from the least significant bit, and is the number of right-most bit of a field (in other words,
it’s a number of bits a scalar needs to be shifted right to extract the bitfield).
In the example above, first a UINT16 value will be extracted at offset 0 (this detail may be important when
accessing hardware registers, where particular access size and alignment are required), and then bitfield whose
rightmost bit is lsbit bit of this UINT16, and length is bitsize bits, will be extracted. For example, if lsbit is 0
and bitsize is 8, then effectively it will access least-significant byte of UINT16.
Note that bitfield operations are independent of target byte endianness, in particular, example above will access
least-significant byte of UINT16 in both little- and big-endian structures. But it depends on the least significant
bit being numbered 0. Some targets may use different numbering in their native ABI, but uctypes always uses
the normalized numbering described above.
Module contents
Given a structure descriptor dictionary and its layout type, you can instantiate a specific structure instance at a given
memory address using uctypes.struct() constructor. Memory address usually comes from following sources:
• Predefined address, when accessing hardware registers on a baremetal system. Lookup these addresses in
datasheet for a particular MCU/SoC.
• As a return value from a call to some FFI (Foreign Function Interface) function.
• From uctypes.addressof(), when you want to pass arguments to an FFI function, or alternatively, to access some
data for I/O (for example, data read from a file or network socket).
Structure objects
Structure objects allow accessing individual fields using standard dot notation: my_struct.substruct1.
field1. If a field is of scalar type, getting it will produce a primitive value (Python integer or float) corresponding
to the value contained in a field. A scalar field can also be assigned to.
If a field is an array, its individual elements can be accessed with the standard subscript operator [] - both read and
assigned to.
If a field is a pointer, it can be dereferenced using [0] syntax (corresponding to C * operator, though [0] works in C
too). Subscripting a pointer with other integer values but 0 are supported too, with the same semantics as in C.
Summing up, accessing structure fields generally follows C syntax, except for pointer dereference, when you need to
use [0] operator instead of *.
Limitations
Accessing non-scalar fields leads to allocation of intermediate objects to represent them. This means that special care
should be taken to layout a structure which needs to be accessed when memory allocation is disabled (e.g. from an
interrupt). The recommendations are:
• Avoid nested structures. For example, instead of mcu_registers.peripheral_a.register1, define
separate layout descriptors for each peripheral, to be accessed as peripheral_a.register1.
• Avoid other non-scalar data, like array. For example, instead of peripheral_a.register[0] use
peripheral_a.register0.
Note that these recommendations will lead to decreased readability and conciseness of layouts, so they should be used
only if the need to access structure fields without allocation is anticipated (it’s even possible to define 2 parallel layouts
- one for normal usage, and a restricted one to use when memory allocation is prohibited).
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: select.
This module provides functions to efficiently wait for events on multiple stream objects (select streams which are
ready for operations).
Functions
uselect.poll()
Create an instance of the Poll class.
uselect.select(rlist, wlist, xlist[, timeout ])
Wait for activity on a set of objects.
This function is provided by some MicroPython ports for compatibility and is not efficient. Usage of Poll is
recommended instead.
class Poll
Methods
poll.register(obj[, eventmask ])
Register stream obj for polling. eventmask is logical OR of:
• uselect.POLLIN - data available for reading
• uselect.POLLOUT - more data can be written
Note that flags like uselect.POLLHUP and uselect.POLLERR are not valid as input eventmask (these
are unsolicited events which will be returned from poll() regardless of whether they are asked for). This
semantics is per POSIX.
eventmask defaults to uselect.POLLIN | uselect.POLLOUT.
poll.unregister(obj)
Unregister obj from polling.
poll.modify(obj, eventmask)
Modify the eventmask for obj.
poll.poll(timeout=- 1)
Wait for at least one of the registered objects to become ready or have an exceptional condition, with optional
timeout in milliseconds (if timeout arg is not specified or -1, there is no timeout).
Returns list of (obj, event, . . . ) tuples. There may be other elements in tuple, depending on a platform and
version, so don’t assume that its size is 2. The event element specifies which events happened with a stream
and is a combination of uselect.POLL* constants described above. Note that flags uselect.POLLHUP
and uselect.POLLERR can be returned at any time (even if were not asked for), and must be acted on
accordingly (the corresponding stream unregistered from poll and likely closed), because otherwise all further
invocations of poll() may return immediately with these flags set for this stream again.
In case of timeout, an empty list is returned.
Difference to CPython
Tuples returned may contain more than 2 elements as described above.
poll.ipoll(timeout=- 1, flags=0)
Like poll.poll(), but instead returns an iterator which yields a callee-owned tuples. This function
provides efficient, allocation-free way to poll on streams.
If flags is 1, one-shot behavior for events is employed: streams for which events happened will have their event
masks automatically reset (equivalent to poll.modify(obj, 0)), so new events for such a stream won’t
be processed until new mask is set with poll.modify(). This behavior is useful for asynchronous I/O
schedulers.
Difference to CPython
This function is a MicroPython extension.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: socket.
This module provides access to the BSD socket interface.
Difference to CPython
For efficiency and consistency, socket objects in MicroPython implement a stream (file-like) interface directly. In
CPython, you need to convert a socket to a file-like object using makefile() method. This method is still supported
by MicroPython (but is a no-op), so where compatibility with CPython matters, be sure to use it.
The native socket address format of the usocket module is an opaque data type returned by getaddrinfo func-
tion, which must be used to resolve textual address (including numeric addresses):
Using getaddrinfo is the most efficient (both in terms of memory and processing power) and portable way to work
with addresses.
However, socket module (note the difference with native MicroPython usocket module described here) provides
CPython-compatible way to specify addresses using tuples, as described below.
Summing up:
• Always use getaddrinfo when writing portable applications.
• Tuple addresses described below can be used as a shortcut for quick hacks and interactive use, if your port
supports them.
Tuple address format for socket module:
• IPv4: (ipv4_address, port), where ipv4_address is a string with dot-notation numeric IPv4 address, e.g. "8.8.
8.8", and port is and integer port number in the range 1-65535. Note the domain names are not accepted as
ipv4_address, they should be resolved first using usocket.getaddrinfo().
• IPv6: (ipv6_address, port, flowinfo, scopeid), where ipv6_address is a string with colon-notation numeric IPv6
address, e.g. "2001:db8::1", and port is an integer port number in the range 1-65535. flowinfo must be
0. scopeid is the interface scope identifier for link-local addresses. Note the domain names are not accepted as
ipv6_address, they should be resolved first using usocket.getaddrinfo().
Functions
usocket.getaddrinfo(host, port)
Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating
a socket connected to that service. The list of 5-tuples has following structure:
s = usocket.socket()
s.connect(usocket.getaddrinfo('www.micropython.org', 80)[0][-1])
Difference to CPython
CPython raises a socket.gaierror exception (OSError subclass) in case of error in this function.
MicroPython doesn’t have socket.gaierror and raises OSError directly. Note that error numbers of
getaddrinfo() form a separate namespace and may not match error numbers from uerrno module. To
distinguish getaddrinfo() errors, they are represented by negative numbers, whereas standard system er-
rors are positive numbers (error numbers are accessible using e.args[0] property from an exception object).
The use of negative values is a provisional detail which may change in the future.
usocket.inet_ntop(af, bin_addr)
Convert a binary network address bin_addr of the given address family af to a textual representation:
usocket.inet_pton(af, txt_addr)
Convert a textual network address txt_addr of the given address family af to a binary representation:
Constants
usocket.AF_INET
usocket.AF_INET6
Address family types. Availability depends on a particular MicroPython port.
usocket.SOCK_STREAM
usocket.SOCK_DGRAM
Socket types.
usocket.IPPROTO_UDP
usocket.IPPROTO_TCP
IP protocol numbers. Availability depends on a particular MicroPython port. Note that you don’t need
to specify these in a call to usocket.socket(), because SOCK_STREAM socket type automatically selects
IPPROTO_TCP, and SOCK_DGRAM - IPPROTO_UDP. Thus, the only real use of these constants is as an
argument to usocket.socket.setsockopt().
usocket.SOL_*
Socket option levels (an argument to usocket.socket.setsockopt()). The exact inventory depends on
a MicroPython port.
usocket.SO_*
Socket options (an argument to usocket.socket.setsockopt()). The exact inventory depends on a
MicroPython port.
Constants specific to WiPy:
usocket.IPPROTO_SEC
Special protocol value to create SSL-compatible socket.
class socket
Methods
socket.close()
Mark the socket closed and release all resources. Once that happens, all future operations on the socket object
will fail. The remote end will receive EOF indication if supported by protocol.
Sockets are automatically closed when they are garbage-collected, but it is recommended to close() them
explicitly as soon you finished working with them.
socket.bind(address)
Bind the socket to address. The socket must not already be bound.
socket.listen([backlog ])
Enable a server to accept connections. If backlog is specified, it must be at least 0 (if it’s lower, it will be set to 0);
and specifies the number of unaccepted connections that the system will allow before refusing new connections.
If not specified, a default reasonable value is chosen.
socket.accept()
Accept a connection. The socket must be bound to an address and listening for connections. The return value is
a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and
address is the address bound to the socket on the other end of the connection.
socket.connect(address)
Connect to a remote socket at address.
socket.send(bytes)
Send data to the socket. The socket must be connected to a remote socket. Returns number of bytes sent, which
may be smaller than the length of data (“short write”).
socket.sendall(bytes)
Send all data to the socket. The socket must be connected to a remote socket. Unlike send(), this method will
try to send all of data, by sending data chunk by chunk consecutively.
The behavior of this method on non-blocking sockets is undefined. Due to this, on MicroPython, it’s recom-
mended to use write() method instead, which has the same “no short writes” policy for blocking sockets, and
will return number of bytes sent on non-blocking sockets.
socket.recv(bufsize)
Receive data from the socket. The return value is a bytes object representing the data received. The maximum
amount of data to be received at once is specified by bufsize.
socket.sendto(bytes, address)
Send data to the socket. The socket should not be connected to a remote socket, since the destination socket is
specified by address.
socket.recvfrom(bufsize)
Receive data from the socket. The return value is a pair (bytes, address) where bytes is a bytes object representing
the data received and address is the address of the socket sending the data.
socket.setsockopt(level, optname, value)
Set the value of the given socket option. The needed symbolic constants are defined in the socket module (SO_*
etc.). The value can be an integer or a bytes-like object representing a buffer.
socket.settimeout(value)
Note: Not every port supports this method, see below.
Set a timeout on blocking socket operations. The value argument can be a nonnegative floating point number
expressing seconds, or None. If a non-zero value is given, subsequent socket operations will raise an OSError
exception if the timeout period value has elapsed before the operation has completed. If zero is given, the socket
is put in non-blocking mode. If None is given, the socket is put in blocking mode.
Not every MicroPython port supports this method. A more portable and generic solution is to use
uselect.poll object. This allows to wait on multiple objects at the same time (and not just on sockets,
but on generic stream objects which support polling). Example:
# Instead of:
s.settimeout(1.0) # time in seconds
s.read(10) # may timeout
# Use:
poller = uselect.poll()
poller.register(s, uselect.POLLIN)
res = poller.poll(1000) # time in milliseconds
if not res:
# s is still not ready for input, i.e. operation timed out
Difference to CPython
CPython raises a socket.timeout exception in case of timeout, which is an OSError subclass. MicroPy-
thon raises an OSError directly instead. If you use except OSError: to catch the exception, your code will
socket.setblocking(flag)
Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking, else to
blocking mode.
This method is a shorthand for certain settimeout() calls:
• sock.setblocking(True) is equivalent to sock.settimeout(None)
• sock.setblocking(False) is equivalent to sock.settimeout(0)
socket.makefile(mode='rb', buffering=0)
Return a file object associated with the socket. The exact returned type depends on the arguments given to
makefile(). The support is limited to binary modes only (‘rb’, ‘wb’, and ‘rwb’). CPython’s arguments: encoding,
errors and newline are not supported.
Difference to CPython
As MicroPython doesn’t support buffered streams, values of buffering parameter is ignored and treated as if it
was 0 (unbuffered).
Difference to CPython
Closing the file object returned by makefile() WILL close the original socket as well.
socket.read([size ])
Read up to size bytes from the socket. Return a bytes object. If size is not given, it reads all data available from
the socket until EOF; as such the method will not return until the socket is closed. This function tries to read as
much data as requested (no “short reads”). This may be not possible with non-blocking socket though, and then
less data will be returned.
socket.readinto(buf [, nbytes ])
Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at most len(buf)
bytes. Just as read(), this method follows “no short reads” policy.
Return value: number of bytes read and stored into buf.
socket.readline()
Read a line, ending in a newline character.
Return value: the line read.
socket.write(buf )
Write the buffer of bytes to the socket. This function will try to write all data to a socket (no “short writes”).
This may be not possible with a non-blocking socket though, and returned value will be less than the length of
buf.
Return value: number of bytes written.
exception usocket.error
MicroPython does NOT have this exception.
Difference to CPython
CPython used to have a socket.error exception which is now deprecated, and is an alias of OSError. In
MicroPython, use OSError directly.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: ssl.
This module provides access to Transport Layer Security (previously and widely known as “Secure Sockets Layer”)
encryption and peer authentication facilities for network sockets, both client-side and server-side.
Functions
Warning: Some implementations of ussl module do NOT validate server certificates, which makes an SSL
connection established prone to man-in-the-middle attacks.
Exceptions
ssl.SSLError
This exception does NOT exist. Instead its base class, OSError, is used.
Constants
ussl.CERT_NONE
ussl.CERT_OPTIONAL
ussl.CERT_REQUIRED
Supported values for cert_reqs parameter.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module implements a subset of the corresponding CPython module, as described below. For more information,
refer to the original CPython documentation: zlib.
This module allows to decompress binary data compressed with DEFLATE algorithm (commonly used in zlib library
and gzip archiver). Compression is not yet implemented.
Functions
Difference to CPython
This class is MicroPython extension. It’s included on provisional basis and may be changed considerably or
removed in later versions.
A few string operations are not enabled on small builds (usually non-Express), due to limited flash memory: string.
center(), string.partition(), string.splitlines(), string.reversed().
CircuitPython/MicroPython-specific libraries
Functionality specific to the CircuitPython/MicroPython implementation is available in the following libraries. These
libraries may change significantly or be removed in future versions of CircuitPython.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
The btree module implements a simple key-value database using external storage (disk files, or in general case,
a random-access stream). Keys are stored sorted in the database, and besides efficient retrieval by a key value,
a database also supports efficient ordered range scans (retrieval of values with the keys in a given range). On the
application interface side, BTree database work as close a possible to a way standard dict type works, one notable
difference is that both keys and values must be bytes objects (so, if you want to store objects of other types, you
need to serialize them to bytes first).
The module is based on the well-known BerkelyDB library, version 1.xx.
Example:
import btree
# Prints b'two'
print(db[b"2"])
del db[b"2"]
# Prints:
# b"1"
# b"3"
for key in db:
print(key)
db.close()
Functions
Methods
btree.close()
Close the database. It’s mandatory to close the database at the end of processing, as some unwritten data may be
still in the cache. Note that this does not close underlying stream with which the database was opened, it should
be closed separately (which is also mandatory to make sure that data flushed from buffer to the underlying
storage).
btree.flush()
Flush any data in cache to the underlying stream.
btree.__getitem__(key)
btree.get(key, default=None)
btree.__setitem__(key, val)
btree.__detitem__(key)
btree.__contains__(key)
Standard dictionary methods.
btree.__iter__()
A BTree object can be iterated over directly (similar to a dictionary) to get access to all keys in order.
btree.keys([start_key[, end_key[, flags ]]])
btree.values([start_key[, end_key[, flags ]]])
btree.items([start_key[, end_key[, flags ]]])
These methods are similar to standard dictionary methods, but also can take optional parameters to iterate over
a key sub-range, instead of the entire database. Note that for all 3 methods, start_key and end_key arguments
represent key values. For example, values() method will iterate over values corresponding to they key range
given. None values for start_key means “from the first key”, no end_key or its value of None means “until the
end of database”. By default, range is inclusive of start_key and exclusive of end_key, you can include end_key
in iteration by passing flags of btree.INCL. You can iterate in descending key direction by passing flags of
btree.DESC. The flags values can be ORed together.
Constants
btree.INCL
A flag for keys(), values(), items() methods to specify that scanning should be inclusive of the end
key.
btree.DESC
A flag for keys(), values(), items() methods to specify that scanning should be in descending direction
of keys.
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
This module provides a general frame buffer which can be used to create bitmap images, which can then be sent to a
display.
class FrameBuffer
The FrameBuffer class provides a pixel buffer which can be drawn upon with pixels, lines, rectangles, text and even
other FrameBuffer’s. It is useful when generating output for displays.
For example:
import framebuf
fbuf.fill(0)
(continues on next page)
Constructors
Drawing text
FrameBuffer.text(s, x, y[, c ])
Write text to the FrameBuffer using the the coordinates as the upper-left corner of the text. The color of the text
can be defined by the optional argument but is otherwise a default value of 1. All characters have dimensions of
8x8 pixels and there is currently no way to change the font.
Other methods
FrameBuffer.scroll(xstep, ystep)
Shift the contents of the FrameBuffer by the given vector. This may leave a footprint of the previous colors in
the FrameBuffer.
FrameBuffer.blit(fbuf, x, y[, key ])
Draw another FrameBuffer on top of the current one at the given coordinates. If key is specified then it should
be a color integer and the corresponding color will be considered transparent: all pixels with that color value
will not be drawn.
This method works between FrameBuffer instances utilising different formats, but the resulting colors may be
unexpected due to the mismatch in color formats.
Constants
framebuf.MONO_VLSB
Monochrome (1-bit) color format This defines a mapping where the bits in a byte are vertically mapped with
bit 0 being nearest the top of the screen. Consequently each byte occupies 8 vertical pixels. Subsequent bytes
appear at successive horizontal locations until the rightmost edge is reached. Further bytes are rendered at
locations starting at the leftmost edge, 8 pixels lower.
framebuf.MONO_HLSB
Monochrome (1-bit) color format This defines a mapping where the bits in a byte are horizontally mapped. Each
byte occupies 8 horizontal pixels with bit 0 being the leftmost. Subsequent bytes appear at successive horizontal
locations until the rightmost edge is reached. Further bytes are rendered on the next row, one pixel lower.
framebuf.MONO_HMSB
Monochrome (1-bit) color format This defines a mapping where the bits in a byte are horizontally mapped. Each
byte occupies 8 horizontal pixels with bit 7 being the leftmost. Subsequent bytes appear at successive horizontal
locations until the rightmost edge is reached. Further bytes are rendered on the next row, one pixel lower.
framebuf.RGB565
Red Green Blue (16-bit, 5+6+5) color format
framebuf.GS2_HMSB
Grayscale (2-bit) color format
framebuf.GS4_HMSB
Grayscale (4-bit) color format
framebuf.GS8
Grayscale (8-bit) color format
Warning: Though this MicroPython-based library may be available for use in some builds of CircuitPython, it
is unsupported and its functionality may change in the future, perhaps significantly. As CircuitPython continues
to develop, it may be changed to comply more closely with the corresponding standard Python library. You will
likely need to change your code later if you rely on any non-standard functionality it currently provides.
Functions
micropython.const(expr)
Used to declare that the expression is a constant so that the compile can optimise it. The use of this function
should be as follows:
CONST_X = const(123)
CONST_Y = const(2 * CONST_X + 1)
Constants declared this way are still accessible as global variables from outside the module they are declared
in. On the other hand, if a constant begins with an underscore then it is hidden, it is not available as a global
variable, and does not take up any memory during execution.
This const function is recognised directly by the MicroPython parser and is provided as part of the
micropython module mainly so that scripts can be written which run under both CPython and MicroPy-
thon, by following the above pattern.
micropython.opt_level([level ])
If level is given then this function sets the optimisation level for subsequent compilation of scripts, and returns
None. Otherwise it returns the current optimisation level.
The optimisation level controls the following compilation features:
• Assertions: at level 0 assertion statements are enabled and compiled into the bytecode; at levels 1 and
higher assertions are not compiled.
• Built-in __debug__ variable: at level 0 this variable expands to True; at levels 1 and higher it expands
to False.
• Source-code line numbers: at levels 0, 1 and 2 source-code line number are stored along with the bytecode
so that exceptions can report the line number they occurred at; at levels 3 and higher line numbers are not
stored.
The default optimisation level is usually level 0.
micropython.mem_info([verbose ])
Print information about currently used memory. If the verbose argument is given then extra information is
printed.
The information that is printed is implementation dependent, but currently includes the amount of stack and
heap used. In verbose mode it prints out the entire heap indicating which blocks are used and which are free.
micropython.qstr_info([verbose ])
Print information about currently interned strings. If the verbose argument is given then extra information is
printed.
The information that is printed is implementation dependent, but currently includes the number of interned
strings and the amount of RAM they use. In verbose mode it prints out the names of all RAM-interned strings.
micropython.stack_use()
Return an integer representing the current amount of stack that is being used. The absolute value of this is not
particularly useful, rather it should be used to compute differences in stack usage at different points.
micropython.heap_lock()
micropython.heap_unlock()
Lock or unlock the heap. When locked no memory allocation can occur and a MemoryError will be raised if
any heap allocation is attempted.
These functions can be nested, ie heap_lock() can be called multiple times in a row and the lock-depth
will increase, and then heap_unlock() must be called the same number of times to make the heap available
again.
micropython.kbd_intr(chr)
Set the character that will raise a KeyboardInterrupt exception. By default this is set to 3 during script
execution, corresponding to Ctrl-C. Passing -1 to this function will disable capture of Ctrl-C, and passing 3 will
restore it.
This function can be used to prevent the capturing of Ctrl-C on the incoming stream of characters that is usually
used for the REPL, in case that stream is used for other purposes.
1.8.10 CircuitPython
Get CircuitPython
Official binaries for all supported boards are available through circuitpython.org/downloads. The site includes stable,
unstable and continuous builds. Full release notes and assets are available through GitHub releases as well.
Documentation
Guides and videos are available through the Adafruit Learning System under the CircuitPython category. An API
reference is also available on Read the Docs. A collection of awesome resources can be found at Awesome Circuit-
Python.
Specifically useful documentation when starting out:
• Welcome to CircuitPython
• CircuitPython Essentials
• Example Code
Code Search
GitHub doesn’t currently support code search on forks. Therefore, CircuitPython doesn’t have code search through
GitHub because it is a fork of MicroPython. Luckily, SourceGraph has free code search for public repos like Circuit-
Python. So, visit sourcegraph.com/github.com/adafruit/circuitpython to search the CircuitPython codebase online.
Contributing
See CONTRIBUTING.md for full guidelines but please be aware that by contributing to this project you are agreeing
to the Code of Conduct. Contributors who follow the Code of Conduct are welcome to submit pull requests and they
will be promptly reviewed by project admins. Please join the Discord too.
Branding
While we are happy to see CircuitPython forked and modified, we’d appreciate it if forked releases not use the name
“CircuitPython” or the Blinka logo. “CircuitPython” means something special to us and those who learn about it. As
a result, we’d like to make sure products referring to it meet a common set of requirements.
If you’d like to use the term “CircuitPython” and Blinka for your product here is what we ask:
• Your product is supported by the primary “adafruit/circuitpython” repo. This way we can update any custom
code as we update the CircuitPython internals.
• Your product is listed on circuitpython.org (source here). This is to ensure that a user of your product can always
download the latest version of CircuitPython from the standard place.
• Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
If you choose not to meet these requirements, then we ask you call your version of CircuitPython something else
(for example, SuperDuperPython) and not use the Blinka logo. You can say it is “CircuitPython-compatible” if most
CircuitPython drivers will work with it.
CircuitPython:
• Supports native USB on all boards, allowing file editing without special tools.
• Floats (aka decimals) are enabled for all builds.
• Error messages are translated into 10+ languages.
• Does not support concurrency within Python (including interrupts and threading). Some concurrency is achieved
with native modules for tasks that require it such as audio file playback.
Behavior
• The order that files are run and the state that is shared between them. CircuitPython’s goal is to clarify the role
of each file and make each file independent from each other.
• boot.py (or settings.py) runs only once on start up before USB is initialized. This lays the ground
work for configuring USB at startup rather than it being fixed. Since serial is not available, output is written to
boot_out.txt.
• code.py (or main.py) is run after every reload until it finishes or is interrupted. After it is done running, the
vm and hardware is reinitialized. This means you cannot read state from code.py in the REPL anymore,
as the REPL is a fresh vm. CircuitPython’s goal for this change includes reducing confusion about pins and
memory being used.
• After the main code is finished the REPL can be entered by pressing any key.
• Autoreload state will be maintained across reload.
• Adds a safe mode that does not run user code after a hard crash or brown out. The hope is that this will make it
easier to fix code that causes nasty crashes by making it available through mass storage after the crash. A reset
(the button) is needed after it’s fixed to get back into normal mode.
• RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes.
• Re-runs code.py or other main file after file system writes over USB mass storage. (Disable with
supervisor.disable_autoreload())
• Autoreload is disabled while the REPL is active.
• Main is one of these: code.txt, code.py, main.py, main.txt
• Boot is one of these: settings.txt, settings.py, boot.py, boot.txt
API
Modules
• No module aliasing. (uos and utime are not available as os and time respectively.) Instead os, time, and
random are CPython compatible.
• New storage module which manages file system mounts. (Functionality from uos in MicroPython.)
• Modules with a CPython counterpart, such as time, os and random, are strict subsets of their CPython
version. Therefore, code from CircuitPython is runnable on CPython but not necessarily the reverse.
• tick count is available as time.monotonic()
Project Structure
Core
Ports
Ports include the code unique to a microcontroller line and also variations based on the board.
1.8.11 Contributing
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree
to abide by its terms. Participation covers any forum used to converse about CircuitPython including unofficial and
official spaces. Failure to do so will result in corrective actions such as time out or ban from the project.
Licensing
By contributing to this repository you are certifying that you have all necessary permissions to license the code under
an MIT License. You still retain the copyright but are granting many permissions under the MIT License.
If you have an employment contract with your employer please make sure that they don’t automatically own your work
product. Make sure to get any necessary approvals before contributing. Another term for this contribution off-hours is
moonlighting.
Ways to contribute
As CircuitPython grows, there are more and more ways to contribute. Here are some ideas:
• Build a project with CircuitPython and share how to do it online.
• Test the latest libraries and CircuitPython versions with your projects and file issues for any bugs you find.
• Contribute Python code to CircuitPython libraries that support new devices or features of an existing device.
• Contribute C code to CircuitPython which fixes an open issue or adds a new feature.
CircuitPython developer Dan Halbert (@dhalbert) has written up build instructions using native build tools here.
For SAMD21 debugging workflow tips check out this learn guide from Scott (@tannewt).
Developer contacts
Scott Shawcroft (@tannewt) is the lead developer of CircuitPython and is sponsored by Adafruit Industries LLC. Scott
is usually available during US West Coast working hours. Dan Halbert (@dhalbert) and Kattni Rembor (@kattni) are
also sponsored by Adafruit Industries LLC and are usually available during US East Coast daytime hours including
some weekends.
They are all reachable on Discord, GitHub issues and the Adafruit support forum.
Code guidelines
We aim to keep our code and commit style compatible with MicroPython upstream. Please review their code conven-
tions to do so. Familiarity with their design philosophy is also useful though not always applicable to CircuitPython.
Furthermore, CircuitPython has a design guide that covers a variety of different topics. Please read it as well.
Welcome to CircuitPython!
This document is a quick-start guide only.
Detailed guides on how to build CircuitPython can be found in the Adafruit Learn system at
https://learn.adafruit.com/building-circuitpython/
Setup
Please ensure you setup your build environment appropriately, as per the guide. You will need:
• Linux: https://learn.adafruit.com/building-circuitpython/linux
• MacOS: https://learn.adafruit.com/building-circuitpython/macos
• Windows Subsystem for Linux (WSL): https://learn.adafruit.com/building-circuitpython/windows-subsystem-
for-linux
Submodules
This project has a bunch of git submodules. You will need to update them regularly.
mpy-cross
As part of the build process, mpy-cross is needed to compile .py files into .mpy files. To compile (or recompile)
mpy-cross:
make -C mpy-cross
1.8.13 Building
There a number of ports of CircuitPython! To build for your board, change to the appropriate ports directory and build.
Examples:
cd ports/atmel-samd
make BOARD=circuitplayground_express
cd ports/nrf
make BOARD=circuitplayground_bluefruit
If you aren’t sure what boards exist, have a peek in the boards subdirectory of your port. If you have a fast computer
with many cores, consider adding -j to your build flags, such as -j17 on a 6-core 12-thread machine.
1.8.14 Testing
If you are working on changes to the core language, you might find it useful to run the test suite. The test suite in the
top level tests directory. It needs the unix port to run.
cd ports/unix
make axtls
make micropython
cd ../../tests
./run-tests
˓→vfs_fat_ramdisk vfs_userfs
1.8.15 Debugging
The easiest way to debug CircuitPython on hardware is with a JLink device, JLinkGDBServer, and an appropriate
GDB. Instructions can be found at https://learn.adafruit.com/debugging-the-samd21-with-gdb
If using JLink, you’ll need both the JLinkGDBServer and arm-none-eabi-gdb running.
Example:
If your port/build includes arm-none-eabi-gdb-py, consider using it instead, as it can be used for better register
debugging with https://github.com/bnahill/PyCortexMDebug
We apply code quality checks using pre-commit. Install pre-commit once per system with
pre-commit --install
Pre-commit also requires some additional programs to be installed through your package manager:
• Standard Unix tools such as make, find, etc
• The gettext package, any modern version
• uncrustify version 0.71 (0.72 is also tested)
Each time you create a git commit, the pre-commit quality checks will be run. You can also run them e.g., with
pre-commit run foo.c or pre-commit run --all to run on all files whether modified or not.
Some pre-commit quality checks require your active attention to resolve, others (such as the formatting checks of
uncrustify) are made automatically and must simply be incorporated into your code changes by committing them.
Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and leaders pledge to making
participation in our project and our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level or type of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity and orientation.
Our Standards
We are committed to providing a friendly, safe and welcoming environment for all.
Examples of behavior that contributes to creating a positive environment include:
• Be kind and courteous to others
• Using welcoming and inclusive language
• Being respectful of differing viewpoints and experiences
• Collaborating with other community members
• Gracefully accepting constructive criticism
• Focusing on what is best for the community
• Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
• The use of sexualized language or imagery and sexual attention or advances
• The use of inappropriate images, including in a community member’s avatar
• The use of inappropriate language, including in a community member’s nickname
• Any spamming, flaming, baiting or other attention-stealing behavior
• Excessive or unwelcome helping; answering outside the scope of the question asked
• Trolling, insulting/derogatory comments, and personal or political attacks
• Promoting or spreading disinformation, lies, or conspiracy theories against a person, group, organisation,
project, or community
• Public or private harassment
• Publishing others’ private information, such as a physical or electronic address, without explicit permission
• Other conduct which could reasonably be considered inappropriate
The goal of the standards and moderation guidelines outlined here is to build and maintain a respectful community.
We ask that you don’t just aim to be “technically unimpeachable”, but rather try to be your best self.
We value many things beyond technical expertise, including collaboration and supporting others within our commu-
nity. Providing a positive experience for other community members can have a much more significant impact than
simply providing the correct answer.
Our Responsibilities
Project leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate
and fair corrective action in response to any instances of unacceptable behavior.
Project leaders have the right and responsibility to remove, edit, or reject messages, comments, commits, code, is-
sues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any
community member for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
Moderation
Instances of behaviors that violate the Adafruit Community Code of Conduct may be reported by any member of
the community. Community members are encouraged to report these situations, including situations they witness
involving other community members.
You may report in the following ways:
In any situation, you may send an email to [email protected].
On the Adafruit Discord, you may send an open message from any channel to all Community Moderators by tag-
ging @community moderators. You may also send an open message from any channel, or a direct message to
@kattni#1507, @tannewt#4653, @danh#1614, @cater#2442, @sommersoft#0222, @Mr. Certainly#0472 or @An-
don#8175.
Email and direct message reports will be kept confidential.
In situations on Discord where the issue is particularly egregious, possibly illegal, requires immediate action, or
violates the Discord terms of service, you should also report the message directly to Discord.
These are the steps for upholding our community’s standards of conduct.
1. Any member of the community may report any situation that violates the Adafruit Community Code of Conduct.
All reports will be reviewed and investigated.
2. If the behavior is an egregious violation, the community member who committed the violation may be banned
immediately, without warning.
3. Otherwise, moderators will first respond to such behavior with a warning.
4. Moderators follow a soft “three strikes” policy - the community member may be given another chance, if they
are receptive to the warning and change their behavior.
5. If the community member is unreceptive or unreasonable when warned by a moderator, or the warning goes
unheeded, they may be banned for a first or second offense. Repeated offenses will result in the community
member being banned.
Scope
This Code of Conduct and the enforcement policies listed above apply to all Adafruit Community venues. This
includes but is not limited to any community spaces (both public and private), the entire Adafruit Discord server, and
Adafruit GitHub repositories. Examples of Adafruit Community spaces include but are not limited to meet-ups, audio
chats on the Adafruit Discord, or interaction at a conference.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the
project or its community. As a community member, you are representing our community, and are expected to behave
accordingly.
Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.
contributor-covenant.org/version/1/4/code-of-conduct.html, and the Rust Code of Conduct.
For other projects adopting the Adafruit Community Code of Conduct, please contact the maintainers of those projects
for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your
moderation policy or making a copy with your own moderation policy so as to avoid confusion.
To date, this has only been tested on one port (esp32s2), on one board (espressif_kaluga_1).
What it does
If you have ever used CircuitPython on a platform with a graphical LCD display, you have probably already seen
multiple “consoles” in use (although the LCD console is “output only”).
New compile-time option CIRCUITPY_USB_VENDOR enables an additional “console” that can be used in parallel
with the original (CDC) serial console.
Web pages that support the WebUSB standard can connect to the “vendor” interface and activate this WebUSB serial
console at any time.
You can type into either console, and CircuitPython output is sent to all active consoles.
One example of a web page you can use to test drive this feature can be found at:
https://adafruit.github.io/Adafruit_TinyUSB_Arduino/examples/webusb-serial/index.html
How to enable
Update your platform’s mpconfigboard.mk file to enable and disable specific types of USB interfaces.
CIRCUITPY_USB_HID = xxx CIRCUITPY_USB_MIDI = xxx CIRCUITPY_USB_VENDOR = xxx
On at least some of the hardware platforms, the maximum number of USB endpoints is fixed. For example, on the
ESP32S2, you must pick only one of the above 3 interfaces to be enabled.
Original espressif_kaluga_1 mpconfigboard.mk settings:
CIRCUITPY_USB_HID = 1 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_USB_VENDOR = 0
Settings to enable WebUSB instead:
CIRCUITPY_USB_HID = 0 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_USB_VENDOR = 1
Notice that to enable VENDOR on ESP32-S2, we had to give up HID. There may be platforms that can have both, or
even all three.
Implementation Notes
Sidenote - The use of the term "vendor" instead of "WebUSB" was done to match tinyusb.
Basically, this feature was ported into CircuitPython by pulling code snippets out of the tinyusb example, and putting
them where they best belonged in the CircuitPython codebase.
There was one complication:
tinyusb uses C preprocessor macros to define things like USB descriptors.
CircuitPython uses a Python program (tools/gen_usb_descriptor.py) to create USB descriptors (etc.) using “helper
objects” from another repo (adafruit_usb_descriptor). This means some of the example code had to be adapted to the
new programing model, and gen_usb_descriptor gained new command-line options to control the generated code.
The generated files go into the “build” directory, look for autogen_usb_descriptor.c and gen-
hdr/autogen_usb_descriptor.h.
Also worth pointing out - the re-use of the CDC connect/disconnect mechanism is not actually part of the WebUSB
standard, it’s more of “common idiom”. We make use of it here because we need to know when we should be paying
attention to the WebUSB serial interface, and when we should ignore it..
The current code uses the existing Python infrastructure to create the Interface descriptor, but simply outputs the code
snippets from the original tinyusb demo code to create the WEBUSB_URL, BOS, and MS_OS_20 descriptors. I sup-
pose additional work could be done to add these to the adafruit_usb_descriptor project, and then gen_usb_descriptor.py
could be modified to make use of them.
Program gen_usb_descriptor.py creates objects for most interface types, regardless of whether or not they are actually
enabled. This increases the size of a generated string table. I made the new vendor-interface-related code not do this
(because some of the ARM platforms would no longer build), but I did not go back and do this for the other interface
types (CDC, MIDI, HID, etc.) Some FLASH savings are probably possible if this is done.
TWO
• genindex
• modindex
• search
241
CircuitPython Documentation, Release 6.3.0
_ dualbank, 109
_bleio, 35
_eve, 45
e
_pew, 53 errno, 203
_pixelbuf, 54
_stage, 55
f
_typing, 56 fontio, 110
framebuf, 224
a framebufferio, 110
adafruit_bus_device, 57 frequencyio, 112
aesio, 59 g
alarm, 59
alarm.pin, 60 gamepad, 113
alarm.time, 60 gamepadshift, 114
alarm.touch, 61 gc, 203
analogio, 62 gnss, 115
array, 201 h
audiobusio, 64
hashlib, 204
audiocore, 66
audioio, 68 i
audiomixer, 70
i2cperipheral, 116
audiomp3, 72
io, 205
audiopwmio, 73
ipaddress, 119
b j
binascii, 201 json, 207
bitbangio, 74
bitmaptools, 79 m
bitops, 81 math, 119
board, 82 memorymonitor, 121
btree, 222 microcontroller, 123
busio, 82 micropython, 227
msgpack, 125
c multiterminal, 126
camera, 89
canio, 90 n
collections, 202 neopixel_write, 127
countio, 94 network, 127
nvm, 127
d
digitalio, 95 o
displayio, 97 os, 128
243
CircuitPython Documentation, Release 6.3.0
p v
ps2io, 129 vectorio, 169
pulseio, 131
pwmio, 134 w
watchdog, 170
r wifi, 171
random, 135 wiznet, 172
re, 207
rgbmatrix, 136
rotaryio, 137
rp2pio, 138
rtc, 141
s
samd, 142
sdcardio, 142
sdioio, 143
sharpdisplay, 145
socket, 145
socketpool, 147
ssl, 149
storage, 150
struct, 151
supervisor, 152
sys, 208
t
terminalio, 153
time, 153
touchio, 154
u
uctypes, 210
uheap, 155
uheapq, 200
ulab, 156
ulab.approx, 156
ulab.compare, 157
ulab.fft, 158
ulab.filter, 158
ulab.linalg, 159
ulab.numerical, 160
ulab.poly, 161
ulab.user, 161
ulab.vector, 161
usb_cdc, 166
usb_hid, 167
usb_midi, 168
uselect, 213
usocket, 215
ussl, 220
ustack, 169
uzlib, 221
245
CircuitPython Documentation, Release 6.3.0
246 Index
CircuitPython Documentation, Release 6.3.0
Index 247
CircuitPython Documentation, Release 6.3.0
248 Index
CircuitPython Documentation, Release 6.3.0
Index 249
CircuitPython Documentation, Release 6.3.0
250 Index
CircuitPython Documentation, Release 6.3.0
Index 251
CircuitPython Documentation, Release 6.3.0
252 Index
CircuitPython Documentation, Release 6.3.0
Index 253
CircuitPython Documentation, Release 6.3.0
254 Index
CircuitPython Documentation, Release 6.3.0
Index 255
CircuitPython Documentation, Release 6.3.0
256 Index
CircuitPython Documentation, Release 6.3.0
Index 257
CircuitPython Documentation, Release 6.3.0
258 Index
CircuitPython Documentation, Release 6.3.0
Index 259
CircuitPython Documentation, Release 6.3.0
260 Index
CircuitPython Documentation, Release 6.3.0
Index 261
CircuitPython Documentation, Release 6.3.0
262 Index