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.
Inhalt
- Hardware
- Installation der Software
- Aktivieren der Hardware
- Prüfen ob die Hardware erkannt wurde
- Einrichtung des CAN-Interfaces
- Automatisches Aktivieren des Interfaces beim Systemstart
- Testen des CAN-Bus
- Senden von CAN-Nachrichten
- Empfangen von CAN-Nachrichten
- Details zum Status des CAN-Interfaces anzeigen
- Mögliche Zustände der Bus-Teilnehmer
- Loopback-Modus
- Mögliche Leitungslängen
- Andere Hardwarekonfigurationen
- Waveshare RS485 CAN HAT
- Zwei CAN-Controller (z.B. PiCAN Duo)
- Fehlersuche
- Weitere Informationen
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.
Achtung
Es dürfen keine Leitungen mit +5 V direkt mit dem Raspi verbunden werden, da dieser sonst beschädigt wird.
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 aktuelles Raspberry Pi OS.
Die nötige Software ist in den Standard-Repositories vom OS bereits enthalten und muss nur noch installiert werden.
1 | sudo apt update |
Aktivieren der Hardware
Damit die Hardware verwendet wird, müssen die entsprechenden Overlays in der Datei /boot/firmware/config.txt
konfiguriert werden. Hierfür werden am Ende der Datei die folgenden Zeilen hinzugefügt:
1 | dtparam=spi=on |
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.
Hinweis
Ein paar Informationen zu anderen Hardwarekonfigurationen habe ich am Ende dieses Beitrags aufgelistet.
Prüfen ob die Hardware erkannt wurde
Ob die Hardware korrekt erkannt wurde kann wie folgt überprüft werden:
1 | pi@raspberrypi:~ $ ls /sys/bus/spi/devices/spi0.0 |
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.
1 | ip link show type can |
Über den folgenden Befehl kann das Interface manuell aktiviert werden:
1 | 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.
1 | ip link show type 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 NetworkManager oder dhcpcd verwaltet werden.
1 | # CAN-Bus |
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.
Achtung
Es muss mindestens ein weiterer Teilnehmer am Bus sein. Sonst bleiben vom CAN-Controller erwartete Rückmeldungen auf dem Bus aus und der Controller geht somit in einen Fehlerzustand. Alternativ kann zum Testen der Loopback-Modus aktiviert 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:
1 | 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.
1 | 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.
1 | pi@raspberrypi:~ $ candump can0 |
Optional können über die Angabe von beispielsweise -tA -x
zusätzliche Informationen angezeigt werden:
1 | pi@raspberrypi:~ $ candump -tA -x can0 |
Dabei sind gesendete Nachrichten dann mit TX
und empfangene mit RX
gekennzeichnet. Dahinter folgen das BRS und das ESI Bit.
Ist das ESI Bit gesetzt, bedeutet dies, dass der Sender der Nachricht im Error Passive Zustand ist.
Details zum Status des CAN-Interfaces anzeigen
Genaue Details zu dem can0
Interface können wie folgt angezeigt werden:
1 | pi@raspberrypi:~ $ ip -details -statistics link show can0 |
Interessant sind hier vor allem der aktuelle Zustand in Zeile 4 (hier ERROR-ACTIVE), sowie die Anzahl der empfangenen und gesendeten Pakete in den letzten 4 Zeilen.
Über die Anzahl der empfangenen und gesendeten Pakete, besonders dabei den errors und dropped lässt sich schnell ein Überblick über eventuelle Probleme auf dem Bus gewinnen.
Tipp
Nicht von clock 8000000
verwirren lassen. Ich nutze beispielsweise einen 16 MHz Quarz, sowie die passenden Einträge in der config.txt
und es werden hier trotzdem 8 MHz angezeigt.
Mögliche Zustände der Bus-Teilnehmer
Grundsätzlich gibt es beim CAN-Bus drei mögliche (Fehler-) Zustände für einen Teilnehmer:
- Error-active
Der Teilnehmer nimmt aktiv am Bus teil und kann Nachrichten und aktive Fehlernachrichten (active error frames) senden. Dies sollte der Normalzustand sein. - Error-passive
Der Teilnehmer nimmt am Bus teil, aber sendet keine aktiven Fehlernachrichten mehr, sondern nur noch passive (passive error frames). Dieser Zustand tritt ein, wenn der Teilnehmer Fehler auf dem Bus erkannt hat und soll verhindern, dass er den Bus mit möglichweise falschen Nachrichten stört. - Bus-off
Bei zu vielen Fehlern koppelt sich der Teilnehmer selbstständig vom Bus ab, um den Bus nicht zu stören. In diesem Zustand können keine Nachrichten empfangen oder gesendet werden.
Loopback-Modus
Normalerweise sendet der CAN-Controller die Nachrichten an den Bus und erwartet eine entsprechende Rückmeldung. Bleibt diese aus, so geht der Controller von einem Fehler aus.
Möchte man nur lokal etwas testen so kann man den Lookback-Modus aktivieren. Dieser leitet die zu sendenden Nachrichten direkt wieder an den Controller zurück. Der Controller spricht quasi mit sich selbst, ohne etwas wirklich zu senden.
Aktiviert werden kann der Loopback-Modus durch Erweiterung des Befehls um loopback on
. War das Interface bereits aktiv, so muss es zuvor gestoppt werden.
1 | sudo ip link set can0 down |
In den Details zum Interface ist dies dann auch durch den Zusatz <LOOPBACK>
deutlich gekennzeichnet:
1 | pi@raspberrypi:~ $ ip -details -statistics link show can0 |
Wieder deaktivieren lässt sich der Loopback-Modus durch loopback off
am Ende des Befehls.
Mögliche Leitungslängen
Die maximal mögliche Leitungslänge beim CAN-Bus hängt vor allem von der verwendeten Bitrate ab. Je höher die Bitrate, desto geringer die maximale Leitungslänge.
Selbstverständlich sollten bei größeren Längen immer entsprechend qualitativ hochwertige und geschirmte Kabel verwendet werden.
Die hier angegebenen Längen sind Richtwerte. Die tatsächlich erreichbare Länge hängt von vielen Faktoren ab.
Bitrate | Leitungslänge |
---|---|
10 kb/s | 6,7 km |
20 kb/s | 3,3 km |
50 kb/s | 1,0 km |
125 kb/s | 500 m |
250 kb/s | 250 m |
500 kb/s | 125 m |
1 Mb/s | 25 m |
Andere Hardwarekonfigurationen
Grundsätzlich ist zu beachten, welcher GPIO und was für ein Quarz von der Hardware verwendet werden. Beides muss entsprechend in der config.txt
angepasst werden.
Hier noch eine kurze Zusammenstellung der Einträge für andere Hardwarekonfigurationen und kaufbaren Module.
Waveshare RS485 CAN HAT
Hier gibt es zwei Versionen, die über den aufgelöteten Quarz unterschieden werden können. Die ältere Version vor August 2019 hat einen 8 MHz Quarz (Aufschrift 8.000) und die neuere Version einen 12 MHz Quarz (Aufschrift 12.000).
Beide Version nutzen den GPIO 25 (BCM) als Interrupt.
1 | dtparam=spi=on |
1 | dtparam=spi=on |
Zwei CAN-Controller (z.B. PiCAN Duo)
Für die gleichzeitige Nutzung von zwei MCP2515 CAN-Controllern an einem SPI-Bus könnten die Einträge in /boot/config.txt
so aussehen:
1 | dtparam=spi=on |
Die erzeugt dann die Interfaces can0
und can1
im System.
Die letzte Zeile aktiviert die Unterstützung von zwei CS-Leitungen für den SPI-Bus.
Fehlersuche
Wenn die Datei /boot/firmware/config.txt
nicht vorhanden ist, dann wird noch die alte Variante /boot/config.txt
verwendet. Alle Overlay Einstellungen müssen dann dort hinein.
Bei Fehlern hilft oftmals in Blick in das Kernel Log.
1 | sudo dmesg | grep mcp2515 |
Im Idealfall sollte hier mcp251x spi0.0 can0: MCP2515 successfully initialized
stehen. Andernfalls gibt es Probleme bei der Kommunikation mit dem MCP2515 CAN-Controller.
Bei älteren Installationen wird teilweise folgende Zeile zusätzlich in der config.txt
benötigt:
1 | dtoverlay=spi-bcm2835-overlay |
Bei Problemen kann es teilweise helfen die Geschwindigkeit vom SPI-Bus zu reduzieren, indem dem man bei dtoverlay=mcp2515-can0,...
am Ende noch ,spimaxfrequency=500000
hinzufügt.
Weitere Informationen
Hier noch ein paar Links zu Hardware- und Softwarekomponenten von mir zum CAN-Bus:
- CAN-Shield - CAN-Bus Platine mit MCP2515 für Raspberry Pi und Arduino
- MCP-CAN-Boot - CAN-Bus Bootloader für AVR Mikrocontroller
- ioBroker.canbus - ioBroker Adapter zur Einbindung vom CAN-Bus