canio – CAN bus access

The canio module contains low level classes to support the CAN bus protocol on microcontrollers that have built-in CAN peripherals.

Boards like the Adafruit RP2040 CAN Bus Feather that use an MCP2515 or compatible chip use the adafruit_mcp2515 module instead.

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 ContextManagers for more info.

For example:

import canio
from board import *

can = canio.CAN(board.CAN_RX, board.CAN_TX, baudrate=1000000)
message = canio.Message(id=0x0408, data=b"adafruit")
can.send(message)
can.deinit()

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.

For more information on working with this module, refer to this Learn Guide on using it.

Available on these boards
  • 01Space 0.42 OLED ESP32C3
  • AITHinker ESP32-C3S_Kit
  • AITHinker ESP32-C3S_Kit_2M
  • ATMegaZero ESP32-S2
  • Adafruit Feather ESP32 V2
  • Adafruit Feather ESP32-C6 4MB Flash No PSRAM
  • Adafruit Feather ESP32-S2 Reverse TFT
  • Adafruit Feather ESP32-S2 TFT
  • Adafruit Feather ESP32-S3 Reverse TFT
  • Adafruit Feather ESP32-S3 TFT
  • Adafruit Feather ESP32S2
  • Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM
  • Adafruit Feather ESP32S3 No PSRAM
  • Adafruit Feather HUZZAH32
  • Adafruit Feather M4 CAN
  • Adafruit Feather STM32F405 Express
  • Adafruit FunHouse
  • Adafruit HUZZAH32 Breakout
  • Adafruit ItsyBitsy ESP32
  • Adafruit MagTag
  • Adafruit MatrixPortal S3
  • Adafruit Metro ESP32S2
  • Adafruit Metro ESP32S3
  • Adafruit QT Py ESP32 PICO
  • Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM
  • Adafruit QT Py ESP32-S3 no psram
  • Adafruit QT Py ESP32C3
  • Adafruit QT Py ESP32S2
  • Adafruit-Qualia-S3-RGB666
  • Arduino Nano ESP32
  • Artisense Reference Design RD00
  • BLING!
  • BPI-Bit-S2
  • BPI-Leaf-S3
  • BPI-PicoW-S3
  • BastWiFi
  • Bee-Data-Logger
  • Bee-Motion-S3
  • Bee-S3
  • BlizzardS3
  • CRCibernetica IdeaBoard
  • ColumbiaDSL-Sensor-Board-V1
  • CrumpS2
  • Cytron Maker Feather AIoT S3
  • DFRobot Beetle ESP32-C3
  • DFRobot FireBeetle 2 ESP32-S3
  • Deneyap Kart
  • Deneyap Kart 1A
  • Deneyap Kart 1A v2
  • Deneyap Kart G
  • Deneyap Mini
  • Deneyap Mini v2
  • ES3ink
  • ESP 12k NodeMCU
  • ESP32 Devkit V1
  • ESP32-C3-DevKitM-1
  • ESP32-C6-DevKitC-1-N8
  • ESP32-C6-DevKitM-1
  • ESP32-H2-DevKitM-1
  • ESP32-S2-DevKitC-1-N4
  • ESP32-S2-DevKitC-1-N4R2
  • ESP32-S2-DevKitC-1-N8R2
  • ESP32-S3-Box-2.5
  • ESP32-S3-Box-Lite
  • ESP32-S3-DevKitC-1-N32R8
  • ESP32-S3-DevKitC-1-N8
  • ESP32-S3-DevKitC-1-N8R2
  • ESP32-S3-DevKitC-1-N8R8
  • ESP32-S3-DevKitC-1-N8R8-with-HACKTABLET
  • ESP32-S3-DevKitM-1-N8
  • ESP32-S3-EYE
  • ESP32-S3-USB-OTG-N8
  • Espressif ESP32 DevKitc V4 WROOM-32E
  • Espressif ESP32 DevKitc V4 WROVER
  • Espressif ESP32-LyraT
  • Espressif-ESP32-S3-LCD-EV-Board
  • FeatherS2
  • FeatherS2 Neo
  • FeatherS2 PreRelease
  • FeatherS3
  • Flipper Zero Wi-Fi Dev
  • Franzininho WIFI w/Wroom
  • Franzininho WIFI w/Wrover
  • Gravitech Cucumber M
  • Gravitech Cucumber MS
  • Gravitech Cucumber R
  • Gravitech Cucumber RS
  • HMI-DevKit-1.1
  • Hardkernel Odroid Go
  • Heltec ESP32-S3-WIFI-LoRa-V3
  • HexKyS2
  • IoTs2
  • Kaluga 1
  • LILYGO T-DECK
  • LILYGO T-DISPLAY S3 v1.2
  • LILYGO TEMBED ESP32S3
  • LILYGO TTGO T-01C3
  • LILYGO TTGO T-DISPLAY v1.1
  • LILYGO TTGO T-DISPLAY v1.1 4M
  • LILYGO TTGO T-OI PLUS
  • LILYGO TTGO T8 ESP32-S2
  • LILYGO TTGO T8 ESP32-S2 w/Display
  • LOLIN S3 16MB Flash 8MB PSRAM
  • LOLIN S3 MINI 4MB Flash 2MB PSRAM
  • LOLIN S3 PRO 16MB Flash 8MB PSRAM
  • Lilygo T-watch 2020 V3
  • Luatos Core-ESP32C3
  • M5 Stack Cardputer
  • M5STACK STAMP-C3
  • M5Stack Atom Echo
  • M5Stack Atom Lite
  • M5Stack Atom Matrix
  • M5Stack Atom U
  • M5Stack AtomS3
  • M5Stack AtomS3 Lite
  • M5Stack AtomS3U
  • M5Stack Core Basic
  • M5Stack Core Fire
  • M5Stack Core2
  • M5Stack Dial
  • M5Stack M5Paper
  • M5Stack Stick C
  • M5Stack Stick C Plus
  • M5Stack Timer Camera X
  • MORPHEANS MorphESP-240
  • MagiClick S3 N4R2
  • Maker badge by Czech maker
  • MakerFabs-ESP32-S3-Parallel-TFT-With-Touch-7inch
  • MicroDev microC3
  • MicroDev microS2
  • MixGo CE
  • NanoS3
  • Neuron
  • Oak Dev Tech PixelWing ESP32S2
  • Oxocard Artwork
  • Oxocard Connect
  • Oxocard Galaxy
  • Oxocard Science
  • ProS3
  • PyboardV1_1
  • S2Mini
  • S2Pico
  • SAM E54 Xplained Pro
  • STM32F4_DISCO
  • Saola 1 w/Wroom
  • Saola 1 w/Wrover
  • Seeed Studio XIAO ESP32C3
  • SparkFun STM32 MicroMod Processor
  • SparkFun Thing Plus - STM32
  • TTGO T8 ESP32-S2-WROOM
  • Targett Module Clip w/Wroom
  • Targett Module Clip w/Wrover
  • TinyC6
  • TinyPICO
  • TinyPICO Nano
  • TinyS2
  • TinyS3
  • TinyWATCH S3
  • VCC-GND YD-ESP32-S3 (N16R8)
  • VCC-GND YD-ESP32-S3 (N8R8)
  • Waveshare ESP32-S2-Pico
  • Waveshare ESP32-S2-Pico-LCD
  • Waveshare ESP32-S3-Pico
  • Waveshare ESP32-S3-Zero
  • WeAct ESP32-C6 (4MB)
  • WeAct ESP32-C6 (8MB)
  • Wemos Lolin C3 Mini" // from Wemos MP
  • Wemos Lolin C3 Pico" // from Wemos MP
  • nanoESP32-S2 w/Wrover
  • nanoESP32-S2 w/Wroom
  • senseBox MCU-S2 ESP32S2

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 ERROR_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.

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() None

If the device is in the bus off state, restart it.

listen(matches: Sequence[Match] | None = 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(message: 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() None

Deinitialize this object, freeing its hardware resources

__enter__() CAN

Returns self, to allow the object to be used in a The with statement statement for resource control

__exit__(unused1: Type[BaseException] | None, unused2: BaseException | None, unused3: types.TracebackType | None) 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() RemoteTransmissionRequest | Message | None

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() int

Returns the number of messages (including remote transmission requests) waiting

__iter__() Listener

Returns self

This method exists so that Listener can be used as an iterable

__next__() 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() None

Deinitialize this object, freeing its hardware resources

__enter__() CAN

Returns self, to allow the object to be used in a The with statement statement for resource control

__exit__(unused1: Type[BaseException] | None, unused2: BaseException | None, unused3: types.TracebackType | None) None

Calls deinit()

class canio.Match(id: int, *, mask: int | None = None, extended: bool = False)

Describe CAN bus messages to match

Construct a Match with the given properties.

If mask is not None, then the filter is for any id which matches all the nonzero bits in mask. Otherwise, it matches exactly the given id. If extended is true then only extended ids are matched, otherwise only standard ids are matched.

id: int

The id to match

mask: int

The optional mask of ids to match

extended: bool

True to match extended ids, False to match standard ides

class canio.Message(id: int, data: bytes, *, extended: bool = False)

Construct a Message to send on a CAN bus.

Parameters:
  • id (int) – The numeric ID of the message

  • data (bytes) – The content of the message

  • extended (bool) – True if the message has an extended identifier, False if it has a standard identifier

In CAN, messages can have a length from 0 to 8 bytes.

id: int

The numeric ID of the message

data: bytes

The content of the message

extended: bool

True if the message’s id is an extended id

class canio.RemoteTransmissionRequest(id: int, length: int, *, extended: bool = False)

Construct a RemoteTransmissionRequest to send on a CAN bus.

Parameters:
  • id (int) – The numeric ID of the requested message

  • length (int) – The length of the requested message

  • extended (bool) – True if the message has an extended identifier, False if it has a standard identifier

In CAN, messages can have a length from 0 to 8 bytes.

id: int

The numeric ID of the message

extended: bool

True if the message’s id is an extended id

length: int

The length of the requested message.