Bei meinem HomePi ist der CAN-Bus über einen IC vom Typ MCP2515 direkt an einen Raspberry Pi angebunden. In diesem Beitrage zeige ich, wie der CAN-Bus hard- und softwaremäßig an den Raspberry Pi angebunden wird.

Hardware

Für die Hardware werden der CAN-Controller MCP2515 und der CAN-Transceiver MCP2562 eingesetzt. Der MCP2515 kümmert sich dabei um das Senden und Empfangen der Nachrichten im CAN-Protokoll. Der MCP2562 ist ein Treiber, welcher (einfach ausgedrückt) die Signale des MCP2515 für die Übertragung verstärkt.

Unter Verwendung dieser beiden ICs sind Datenraten von bis zu 1 Mb/s auf dem CAN-Bus möglich.

Die Beschaltung erfolgt gemäß dem folgenden Schaltplan:

Der CAN-Controller MCP2515 wird mit +3,3 V als Betriebsspannung versorgt. Somit ist eine direkte Verbindung der Datenleitungen des SPI-Bus zum Raspberry Pi möglich.

Der Treiber MCP2562 wird mit +5 V als Betriebsspannung versorgt. Zusätzlich wird er mit +3,3 V versorgt, welche er als Basis für seine RXD und TXD Leitungen verwendet. Hier erfolgt somit automatisch durch den IC die Pegelanpassung zwischen +5 V und den +3,3 V, die für den Raspberry Pi erforderlich sind.

Als Taktquelle für den MCP2515 dient ein 16 MHz Quarz. Alternativ kann hier auch ein 8 MHz Quarz verwendet werden.

Der Widerstand R2 dient als Abschlusswiderstand zur Terminierung des CAN-Bus. Dieser sollte nur jeweils einmal am Anfang und am Ende des gesamten CAN-Bus vorhanden sein. Bei Busteilnehmern “in der Mitte” darf dieser Widerstand nicht vorhanden sein!

Installation der Software

Als Basissystem dient hier ein normales Raspbian Buster (oder neuer).

Die nötige Software ist in den Standard-Repositories von Raspbian bereits enthalten und muss nur noch installiert werden.

sudo apt update
sudo apt install can-utils

Aktivieren der Hardware

Damit die Hardware verwendet wird, müssen die entsprechenden Overlays in der Datei /boot/config.txt konfiguriert werden. Hierfür werden am Ende der Datei die folgenden Zeilen hinzugefügt:

dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=6
dtoverlay=spi-bcm2835-overlay

Die 16000000 steht in dem Fall dafür, dass der MCP2515 mit einem Takt von 16 MHz arbeitet. Dies ist abhängig von dem verwendeten Quarz und muss gegebenenfalls angepasst werden.

Die 6 steht für den GPIO-Pin (BCM), an dem die Interrupt-Leitung des MCP2515 angeschlossen ist und muss ebenfalls an die eigene Hardware angepasst werden.

Zum Übernehmen der Änderungen ist ein Neustart das Raspberry Pis erforderlich.

Prüfen ob die Hardware erkannt wurde

Ob die Hardware korrekt erkannt wurde kann wie folgt überprüft werden:

pi@raspberrypi:~ $ ls /sys/bus/spi/devices/spi0.0
driver  modalias  net  of_node  power  statistics  subsystem  uevent
pi@raspberrypi:~ $ ls /sys/bus/spi/devices/spi0.0/net
can0
pi@raspberrypi:~ $ ls /sys/bus/spi/devices/spi0.0/net/can0
addr_assign_type    carrier_up_count  gro_flush_timeout  netdev_group    queues
address             device            ifalias            operstate       speed
addr_len            dev_id            ifindex            phys_port_id    statistics
broadcast           dev_port          iflink             phys_port_name  subsystem
carrier             dormant           link_mode          phys_switch_id  tx_queue_len
carrier_changes     duplex            mtu                power           type
carrier_down_count  flags             name_assign_type   proto_down      uevent
pi@raspberrypi:~ $ ls /sys/class/net
can0  eth0  lo

Sieht die Ausgabe so aus, wie hier dargestellt, dann ist alles in Ordnung und der Raspberry Pi kann mit dem MCP2515 kommunizieren. Sollte ein Problem vorliegen, dann liefert mindestens einer der Befehle einen Fehler zurück.

Einrichtung des CAN-Interfaces

Der CAN-Bus erscheint auf dem Raspberry Pi als Netzwerkinterface. Ein Aufruf von ip addr sollte das Interface can0 anzeigen, wobei es jedoch noch als DOWN markiert ist.

...
3: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN group default qlen 10
    link/can

Über den folgenden Befehl kann das Interface manuell aktiviert werden:

sudo ip link set can0 up type can bitrate 500000

Hierbei wird eine Bitrate von 500 kb/s verwendet. Diese Bitrate kann bei Bedarf natürlich angepasst werden und sollte bei allen Busteilnehmern gleich sein.

Ein erneuter Aufruf von ip addr zeigt nun, dass das Interface aktiv ist.

...
3: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN group default qlen 10
    link/can

Automatisches Aktivieren des Interfaces beim Systemstart

Damit das can0 Interface beim Systemstart automatisch aktiviert wird, müssen die folgenden Einträge in der Datei /etc/network/interfaces hinzugefügt werden. Dies funktioniert auch dann, wenn die “normalen” Netzwerkinterfaces vom dhcpcd verwaltet werden.

# CAN-Bus
auto can0
iface can0 can static
  bitrate 500000

Die 500000 ist hierbei wieder die zu verwendende Bitrate.

Testen des CAN-Bus

Zum Testen des CAN-Bus können nun über ein Terminal Nachrichten gesendet oder empfangen werden.

Senden von CAN-Nachrichten

Zum Senden von Nachrichten kann das Tool cansend verwendet werden, wobei Standard Frames mit 11-Bit Nachrichten-IDs und Extended Frames mit 29-Bit Nachrichten-IDs unterstützt werden.

Für Standard Frames sieht der Aufruf wie folgt aus:

cansend can0 123#42ff

123 ist in diesem Fall die ID der Nachricht in Hex-Schreibweise und muss immer 3 Zeichen lang sein. 42ff sind die Daten, wiederum in Hex, mit einer Länge von 0 bis 8 Byte.

Bei Extended Frames besteht die ID aus 8 Zeichen. Der Rest verhält sich analog zu den Standard Frames.

cansend can0 012EA567#42ff

Eine kurze Hilfe zu cansend erhält man über die Befehle cansend --help oder man cansend.

Empfangen von CAN-Nachrichten

Über den Befehl candump könne empfange Nachrichten angezeigt werden.

pi@raspberrypi:~ $ candump can0
  can0  123   [2]  42 FF
  can0  012EA567   [2]  42 FF
  can0  1FFFFFFF   [8]  00 11 22 33 44 55 66 77
  can0       001   [0] 
  can0  00001337   [4]  DE AD BE EF