Adafruit CircuitPython BusDevice

Documentation Status Discord Build Status

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.

Installation

This library is NOT built into CircuitPython to make it easy to update. To install it either follow the directions below or install the library bundle.

To install:

  1. Download and unzip the latest release zip.
  2. Copy the unzipped adafruit_bus_device to the lib directory on the CIRCUITPY drive.

Usage Example

See examples/read_register_i2c.py and examples/read_register_spi.py for examples of the module’s usage.

Contributing

Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.

Building locally

To build this library locally you’ll need to install the circuitpython-build-tools package.

python3 -m venv .env
source .env/bin/activate
pip install circuitpython-build-tools

Once installed, make sure you are in the virtual environment:

source .env/bin/activate

Then run the build:

circuitpython-build-bundles --filename_prefix adafruit-circuitpython-busdevice --library_location .

Sphinx documentation

Sphinx is used to build the documentation based on rST files and comments in the code. First, install dependencies (feel free to reuse the virtual environment from above):

python3 -m venv .env
source .env/bin/activate
pip install Sphinx sphinx-rtd-theme

Now, once you have the virtual environment activated:

cd docs
sphinx-build -E -W -b html . _build/html

This will output the documentation to docs/_build/html. Open the index.html in your browser to view them. It will also (due to -W) error out on any warning like Travis will. This is a good way to locally verify it will pass.

Table of Contents

Simple test

Ensure your device works with this simple test.

examples/read_register_i2c.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import busio
import board
from adafruit_bus_device.i2c_device import I2CDevice

DEVICE_ADDRESS = 0x68 # device address of DS3231 board
A_DEVICE_REGISTER = 0x0E # device id register on the DS3231 board

# The follow is for I2C communications
comm_port = busio.I2C(board.SCL, board.SDA)
device = I2CDevice(comm_port, DEVICE_ADDRESS)

with device as bus_device:
    bus_device.write(bytes([A_DEVICE_REGISTER]))
    result = bytearray(1)
    bus_device.readinto(result)

print(''.join('{:02x}'.format(x) for x in result))
examples/read_register_spi.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import busio
import board
import digitalio
from adafruit_bus_device.spi_device import SPIDevice

DEVICE_ADDRESS = 0x68 # device address of BMP280 board
A_DEVICE_REGISTER = 0xD0 # device id register on the BMP280 board

# The follow is for SPI communications
cs = digitalio.DigitalInOut(board.A2)
comm_port = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
device = SPIDevice(comm_port, cs)

#pylint: disable-msg=no-member
with device as bus_device:
    bus_device.write(bytes([A_DEVICE_REGISTER]))
    result = bytearray(1)
    bus_device.readinto(result)

print(''.join('{:02x}'.format(x) for x in result))

adafruit_bus_device.i2c_device - I2C Bus Device

class adafruit_bus_device.i2c_device.I2CDevice(i2c, device_address)[source]

Represents a single I2C device and manages locking the bus and the device address.

Parameters:
  • i2c (I2C) – The I2C bus the device is on
  • device_address (int) – The 7 bit device address

Note

This class is NOT built into CircuitPython. See here for install instructions.

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)
readinto(buf, **kwargs)[source]

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.

Parameters:
  • buffer (bytearray) – buffer to write into
  • start (int) – Index to start writing at
  • end (int) – Index to write up to but not include
write(buf, **kwargs)[source]

Write the bytes from buffer to the device. Transmits a stop bit if stop is set.

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.

Parameters:
  • buffer (bytearray) – buffer containing the bytes to write
  • start (int) – Index to start writing from
  • end (int) – Index to read up to but not include
  • stop (bool) – If true, output an I2C stop condition after the buffer is written

adafruit_bus_device.spi_device - SPI Bus Device

class adafruit_bus_device.spi_device.SPIDevice(spi, chip_select=None, *, baudrate=100000, polarity=0, phase=0, extra_clocks=0)[source]

Represents a single SPI device and manages locking the bus and the device address.

Parameters:
  • spi (SPI) – The SPI bus the device is on
  • chip_select (DigitalInOut) – The chip select pin object that implements the DigitalInOut API.
  • extra_clocks (int) – The minimum number of clock cycles to cycle the bus after CS is high. (Used for SD cards.)

Note

This class is NOT built into CircuitPython. See here for install instructions.

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)

Indices and tables