CircuitPython APIs for non-CircuitPython versions of Python such as CPython on Linux and MicroPython.
npx @tessl/cli install tessl/pypi-adafruit-blinka@8.66.0A comprehensive CircuitPython API emulation library that enables CircuitPython code to run on devices running CPython or MicroPython. Blinka provides hardware abstraction for GPIO operations, communication protocols, and peripheral interfaces across 100+ supported development boards and single-board computers.
pip install adafruit-blinkaimport board
import digitalio
import analogio
import busioFor specific modules:
from adafruit_blinka import ContextManaged, Lockable
import microcontrollerimport board
import digitalio
import time
# Configure a digital output pin
led = digitalio.DigitalInOut(board.D18)
led.direction = digitalio.Direction.OUTPUT
# Blink the LED
for i in range(10):
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
# Cleanup
led.deinit()Adafruit-Blinka uses a layered architecture to provide CircuitPython compatibility:
adafruit_blinka.agnosticThis design enables seamless migration of CircuitPython code to CPython environments while maintaining hardware portability across diverse platforms from Raspberry Pi to FTDI USB adapters.
GPIO pin control with direction, pull resistors, and drive modes. Provides CircuitPython-compatible digital I/O operations with automatic resource management.
class DigitalInOut(ContextManaged):
def __init__(self, pin):
"""Initialize digital I/O pin"""
@property
def direction(self) -> Direction:
"""Pin direction (INPUT or OUTPUT)"""
@direction.setter
def direction(self, value: Direction) -> None:
"""Set pin direction"""
@property
def value(self) -> bool:
"""Pin logic level (True=HIGH, False=LOW)"""
@value.setter
def value(self, val: bool) -> None:
"""Set pin logic level"""
@property
def pull(self) -> Pull:
"""Pull resistor configuration"""
@pull.setter
def pull(self, val: Pull) -> None:
"""Configure pull resistor"""
def switch_to_output(self, value: bool = False, drive_mode: DriveMode = DriveMode.PUSH_PULL) -> None:
"""Switch pin to output mode"""
def switch_to_input(self, pull: Pull = None) -> None:
"""Switch pin to input mode"""
class Direction:
INPUT: Direction
OUTPUT: Direction
class Pull:
UP: Pull
DOWN: Pull
class DriveMode:
PUSH_PULL: DriveMode
OPEN_DRAIN: DriveModeAnalog-to-digital conversion and digital-to-analog output with platform-specific implementations. Supports reading sensor values and generating analog signals.
class AnalogIn:
def __init__(self, pin):
"""Initialize analog input pin"""
@property
def value(self) -> int:
"""Raw ADC value (0-65535)"""
@property
def voltage(self) -> float:
"""Voltage reading in volts"""
class AnalogOut:
def __init__(self, pin):
"""Initialize analog output pin (DAC)"""
@property
def value(self) -> int:
"""DAC output value (0-65535)"""
@value.setter
def value(self, val: int) -> None:
"""Set DAC output value"""Hardware and software implementations of I2C, SPI, and UART communication protocols with automatic resource locking and CircuitPython compatibility.
class I2C(Lockable):
def __init__(self, scl, sda, frequency: int = 100000):
"""Initialize I2C bus"""
def scan(self) -> list[int]:
"""Scan for I2C devices, return list of addresses"""
def readfrom_into(self, address: int, buffer: bytearray, start: int = 0, end: int = None) -> None:
"""Read from device into buffer"""
def writeto(self, address: int, buffer: bytes, start: int = 0, end: int = None) -> None:
"""Write buffer to device"""
class SPI(Lockable):
def __init__(self, clock, MOSI=None, MISO=None):
"""Initialize SPI bus"""
def configure(self, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) -> None:
"""Configure SPI parameters"""
def write(self, buf: bytes) -> None:
"""Write data to SPI bus"""
def readinto(self, buf: bytearray) -> None:
"""Read data from SPI bus into buffer"""
class UART:
def __init__(self, tx, rx, baudrate: int = 9600, bits: int = 8, parity=None, stop: int = 1, timeout: float = 1.0):
"""Initialize UART interface"""
def read(self, nbytes: int = None) -> bytes:
"""Read data from UART"""
def write(self, buf: bytes) -> int:
"""Write data to UART, return bytes written"""Pulse Width Modulation output and pulse measurement capabilities for motor control, servo positioning, and signal generation.
class PWMOut:
def __init__(self, pin, duty_cycle: int = 0, frequency: int = 500, variable_frequency: bool = False):
"""Initialize PWM output pin"""
@property
def duty_cycle(self) -> int:
"""PWM duty cycle (0-65535)"""
@duty_cycle.setter
def duty_cycle(self, val: int) -> None:
"""Set PWM duty cycle"""
@property
def frequency(self) -> int:
"""PWM frequency in Hz"""
@frequency.setter
def frequency(self, val: int) -> None:
"""Set PWM frequency"""
class PulseIn:
def __init__(self, pin, maxlen: int = 100, idle_state: bool = False):
"""Initialize pulse input measurement"""
def __len__(self) -> int:
"""Number of pulses captured"""
def __getitem__(self, index: int) -> int:
"""Get pulse duration in microseconds"""Platform-specific pin mappings and hardware interfaces with automatic detection and configuration for 100+ supported development boards.
# Board-specific pin constants (examples)
D0: Pin # Digital pin 0
D1: Pin # Digital pin 1
SDA: Pin # I2C data pin
SCL: Pin # I2C clock pin
MOSI: Pin # SPI data out
MISO: Pin # SPI data in
SCLK: Pin # SPI clock
def I2C() -> busio.I2C:
"""Return default I2C interface if available"""
def SPI() -> busio.SPI:
"""Return default SPI interface if available"""
# Version information
__version__: str # Blinka version
__repo__: str # Repository URL
__blinka__: bool # Always True for identificationSupport for advanced peripherals including NeoPixel LED strips, rotary encoders, keypads, and USB HID devices.
def neopixel_write(gpio, buf: bytes) -> None:
"""Write color buffer to NeoPixel LED strip"""
class IncrementalEncoder:
def __init__(self, pin_a, pin_b):
"""Initialize rotary encoder"""
@property
def position(self) -> int:
"""Current encoder position"""
class Keys:
def __init__(self, pins, value_when_pressed: bool = False, pull_up: bool = True):
"""Initialize key scanner"""
@property
def events(self) -> EventQueue:
"""Key event queue"""
class Device:
def __init__(self, descriptor: bytes, usage_page: int, usage: int, report_ids: tuple, in_report_lengths: tuple, out_report_lengths: tuple):
"""Initialize USB HID device"""
def send_report(self, report: bytes, report_id: int = None) -> None:
"""Send HID report"""Base classes and utilities that provide resource management, platform detection, and CircuitPython compatibility features.
class ContextManaged:
def deinit(self) -> None:
"""Release hardware resources"""
def __enter__(self):
"""Context manager entry"""
def __exit__(self, exc_type, exc_val, exc_tb):
"""Context manager exit with automatic cleanup"""
class Lockable(ContextManaged):
def try_lock(self) -> bool:
"""Attempt to acquire exclusive lock"""
def unlock(self) -> None:
"""Release exclusive lock"""
def load_settings_toml() -> None:
"""Load settings from settings.toml into environment"""
def patch_system() -> None:
"""Apply platform-specific system patches"""
def delay_us(delay: int) -> None:
"""Microsecond precision delay"""
# Platform detection
detector: object # Platform detection instance
chip_id: str # Detected chip identifier
board_id: str # Detected board identifier
implementation: str # Python implementation nameSoftware implementations of I2C and SPI communication protocols for platforms without dedicated hardware peripherals or when hardware resources are already in use.
class I2C(Lockable):
def __init__(self, scl, sda, frequency: int = 400000):
"""Initialize software I2C interface"""
def scan(self) -> list[int]:
"""Scan I2C bus for connected devices"""
def readfrom_into(self, address: int, buffer: bytearray, start: int = 0, end: int = None) -> None:
"""Read data from I2C device into buffer"""
def writeto(self, address: int, buffer: bytes, start: int = 0, end: int = None, stop: bool = True) -> int:
"""Write data to I2C device from buffer"""
class SPI(Lockable):
def __init__(self, clock, MOSI=None, MISO=None):
"""Initialize software SPI interface"""
def configure(self, baudrate: int = 100000, polarity: int = 0, phase: int = 0, bits: int = 8) -> None:
"""Configure SPI communication parameters"""
def write(self, buf: bytes) -> None:
"""Write data to SPI device"""
def readinto(self, buf: bytearray) -> None:
"""Read data from SPI device into buffer"""Color generation and MicroPython compatibility utilities that enhance the CircuitPython API emulation.
# Color utilities (rainbowio module)
def colorwheel(color_value: int) -> int:
"""Generate rainbow colors from 0-255 input value"""
# MicroPython compatibility decorators (micropython module)
def const(x):
"""Emulate making a constant (MicroPython compatibility)"""
def native(f):
"""Emulate native decorator (MicroPython compatibility)"""
def viper(f):
"""MicroPython viper decorator - not supported (raises SyntaxError)"""
def asm_thumb(f):
"""MicroPython inline assembler decorator - not supported (raises SyntaxError)"""class Pin:
"""Hardware pin reference"""
id: int
class Enum:
"""CircuitPython-style enum base class"""
def iteritems(self):
"""Iterate over enum items"""__version__: str # Package version string
VERSION: str # Alias for __version__