Verwenden Sie dieses robuste serielle Kommunikationsprotokoll, um zwei Arduino-Boards miteinander zu verbinden und Daten miteinander zu senden.

Der Controller Area Network (CAN)-Bus ist ein robustes und zuverlässiges Kommunikationsprotokoll, das in verschiedenen Industrie-, Automobil- und Luft- und Raumfahrtanwendungen weit verbreitet ist. Es ist für die Übertragung von Daten zwischen Mikrocontrollern und Geräten über ein CAN-Bus-Netzwerk ausgelegt. Sie wissen das vielleicht noch nicht, aber es ist das Ding hinter diesen verrückten Auto-Dashboard-Mods, die Sie in den sozialen Medien sehen.

Wir führen Sie durch den Aufbau eines CAN-Busses mit dem CAN-Modul MCP2515 unter Verwendung eines Arduino und einer Steckplatine. Wir werden auch die Arduino CAN-Bibliothek durchgehen und demonstrieren, wie Daten über den CAN-Bus gesendet und empfangen werden.

Was ist ein CAN-Bus?

Der CAN-Bus ist ein serielles Kommunikationsprotokoll, das von Bosch in den 1980er Jahren entwickelt wurde. Es wird aufgrund seiner hohen Zuverlässigkeit und Robustheit in verschiedenen Anwendungen eingesetzt. Es ermöglicht die Übertragung von Daten zwischen Geräten mit hoher Geschwindigkeit und minimaler Latenz über nur zwei Leitungen: CAN High und CAN Low.

1994 wurde der CAN-Bus zu einem internationalen Standard (ISO 11898), der speziell für den schnellen seriellen Datenaustausch zwischen elektronischen Steuergeräten in Automobilanwendungen entwickelt wurde. Sehen Sie sich unseren umfassenden Leitfaden an was ein CAN-Bus ist und welche Rolle er in Automotive-Systemen spielt für mehr Details.

Einer der Gründe, warum der CAN-Bus so beliebt ist, sind seine Fehlererkennungs- und Korrekturfunktionen. Das Protokoll kann Fehler bei der Datenübertragung erkennen und korrigieren. Dies macht es ideal für Anwendungen, bei denen die Datenintegrität kritisch ist, wie z. B. in der industriellen Automatisierung.

Kenntnis des MCP2515 CAN-Moduls

Das CAN-Bus-Controller-Modul MCP2515 ist ein Gerät, das eine außergewöhnliche Unterstützung für das weit verbreitete CAN-Protokoll Version 2.0B bietet. Dieses Modul ist ideal für die Kommunikation mit hohen Datenraten von bis zu 1Mbps.

Der MCP2515 IC ist ein unabhängiger CAN-Controller mit einer SPI-Schnittstelle, die die Kommunikation mit einer Vielzahl von Mikrocontrollern ermöglicht. Der IC TJA1050 hingegen fungiert als Schnittstelle zwischen dem CAN-Controller-IC MCP2515 und dem physikalischen CAN-Bus.

Für zusätzlichen Komfort gibt es einen Jumper, mit dem Sie einen 120-Ohm-Abschluss anbringen können, wodurch es noch einfacher wird, Ihre Kabel an den anzuschließen CAN_H & KANN ICH Schrauben für die Kommunikation mit anderen CAN-Modulen.

Besonderheit

Spezifikation

Transceiver

TJA1050

Mikrocontroller-Schnittstelle

SPI (ermöglicht Multi-CAN-Bus-Integration)

Kristalloszillator

8MHz

Beendigung

120Ω

Geschwindigkeit

1 Mbps

Energieverbrauch

Stromarmer Standby-Betrieb

Abmessungen

40 x 28 mm

Knotenkapazität

Unterstützt bis zu 112 Knoten

Weitere Informationen erhalten Sie bei der MCP2515 Datenblatt falls Sie dieses Modul für ein fortgeschritteneres Projekt benötigen.

CAN-Nachrichtenstruktur

Die CAN-Nachrichtenstruktur besteht aus mehreren Segmenten, aber die kritischsten Segmente für dieses Projekt sind die Kennung und die Daten. Der Identifier, auch CAN-ID oder Parameter Group Number (PGN) genannt, identifiziert die Geräte am CAN Netzwerk, und die Länge des Identifiers kann je nach Art des CAN-Protokolls entweder 11 oder 29 Bit betragen gebraucht.

In der Zwischenzeit stellen die Daten die tatsächlich übertragenen Sensor-/Steuerungsdaten dar. Die Daten können zwischen 0 und 8 Bytes lang sein, und der Datenlängencode (DLC) gibt die Anzahl der vorhandenen Datenbytes an.

Die Arduino MCP2515 CAN-Bus-Bibliothek

Diese Bibliothek implementiert die CAN V2.0B-Protokoll, die mit Geschwindigkeiten von bis zu 1 Mbit / s arbeiten können. Es bietet eine SPI-Schnittstelle, die mit Geschwindigkeiten von bis zu 10 MHz betrieben werden kann und dabei sowohl Standarddaten (11 Bit) als auch erweiterte Daten (29 Bit) unterstützt. Darüber hinaus verfügt es über zwei Empfangspuffer, die eine priorisierte Nachrichtenspeicherung ermöglichen.

Initialisierung des CAN-Bus

Hier ist der Setup-Code, den Sie benötigen, um den CAN-Bus zu initialisieren:

#enthalten
#enthalten

MCP2515 mcp2515(10); // CS-Pin setzen

Leereaufstellen(){
während (!Seriell);
Seriell.Start(9600);
SPI.Start(); // Beginnt die SPI-Kommunikation

mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}

Dadurch wird der MCP2515 mit einer CAN-Bitrate von 500 Kbps und einer Oszillatorfrequenz von 8 MHz initialisiert.

MCP2515 CAN-Betriebsmodi

Es gibt drei Betriebsmodi, die mit dem CAN-Bus-Controller MCP2515 verwendet werden:

  • setNormalMode(): Stellt den Controller so ein, dass er Nachrichten sendet und empfängt.
  • setLoopbackMode(): stellt den Controller so ein, dass er Nachrichten sendet und empfängt, aber die gesendeten Nachrichten werden auch von ihm selbst empfangen.
  • setListenOnlyMode(): Stellt den Controller so ein, dass er nur Nachrichten empfängt.

Dies sind Funktionsaufrufe, mit denen der Betriebsmodus des CAN-Bus-Controllers MCP2515 eingestellt wird.

mcp2515.setNormalMode();

mcp2515.setLoopbackMode();

mcp2515.setListenOnlyMode();

Senden von Daten über den CAN-Bus

Um eine Nachricht über den CAN-Bus zu senden, verwenden Sie die sendMsgBuf() Methode:

ohne Vorzeichenverkohlen Daten[] = {0x01, 0x02, 0x03, 0x04};
CAN.sendMsgBuf(0x01, 0, 4, Daten);

Dieser sendet eine Nachricht mit der ID 0x01 und eine Datennutzlast von {0x01, 0x02, 0x03, 0x04}. Der erste Parameter ist die CAN-ID, der zweite die Nachrichtenpriorität, der dritte die Länge der Nutzdaten und der vierte die Nutzdaten selbst.

Der sendMsgBuf() -Methode gibt einen Wert zurück, der angibt, ob die Nachricht erfolgreich gesendet wurde oder nicht. Sie können diesen Wert überprüfen, indem Sie die aufrufen checkError() Methode:

Wenn (CAN.checkError()) {
Seriell.println("Fehler beim Senden der Nachricht.");
}

Dieser prüft, ob bei der Übertragung der Nachricht ein Fehler aufgetreten ist und druckt ggf. eine Fehlermeldung aus.

Empfangen von Daten vom CAN-Bus

Um eine Nachricht über den CAN-Bus zu empfangen, können Sie die verwenden readMsgBuf() Methode:

ohne Vorzeichenverkohlen len = 0;
ohne Vorzeichenverkohlen buf[8];
ohne Vorzeichenverkohlen canID = 0;

Wenn (CAN.checkReceive()) {
CAN.readMsgBuf(&len, buf);
canID = CAN.getCanId();
}

Dieser prüft, ob eine Botschaft auf dem CAN-Bus vorhanden ist und liest die Botschaft dann in den ein buf Reihe. Die Länge der Nachricht wird in gespeichert len Variable, und die ID der Nachricht wird in der gespeichert canID Variable.

Sobald Sie eine Nachricht erhalten haben, können Sie die Datennutzlast nach Bedarf verarbeiten. Sie könnten beispielsweise die Datennutzlast auf dem seriellen Monitor drucken:

Seriell.drucken("Nachricht mit ID erhalten");
Seriell.drucken(canID, HEX);
Seriell.drucken(" und Daten: ");

für (int ich = 0; ich < len; i++) {
Seriell.drucken(buf[i], HEX);
Seriell.drucken(" ");
}

Seriell.println();

Dies gibt die ID der empfangenen Nachricht und die Datennutzlast an den seriellen Monitor aus.

So schließen Sie einen CAN-Bus-Transceiver an ein Steckbrett an

Um in diesem Beispielprojekt einen CAN-Bus zur Verbindung zweier Geräte aufzubauen, benötigen Sie:

  • Zwei Mikrocontroller (zwei Arduino Nano Boards für dieses Beispiel)
  • Zwei MCP2515 CAN-Module
  • Ein Steckbrett
  • Überbrückungsdrähte
  • Ein I2C 16x2 LCD-Bildschirmmodul
  • Ultraschallsensor HC-SR04

Für dieses Projektbeispiel werden im Arduino-Sketch vier Bibliotheken verwendet. Da ist die NewPing Bibliothek, die eine benutzerfreundliche Oberfläche für den Ultraschallsensor bietet, sowie die SPI-Bibliothek, was die Kommunikation zwischen dem Arduino-Board und dem CAN-Bus-Controller MCP2515 erleichtert. Der LiquidCrystal_I2C Bibliothek wird für das Anzeigemodul verwendet.

Schließlich gibt es die mcp2515-Bibliothek mit dem MCP2515-Chip zu verbinden, was es uns ermöglicht, Daten einfach über das CAN-Bus-Netzwerk zu übertragen.

Hardware-Setup (Beispiel HC-SR04)

In diesem Projekt mit einem HC-SR04-Sensor und einem LCD fungiert ein Arduino Nano-Board als Empfänger, während das andere Arduino als Sender fungiert. Schließen Sie Ihre Senderkomponenten gemäß folgendem Anschlussplan an:

Hier ist das Diagramm für die Empfängerschaltung:

Verbinden Sie abschließend die beiden Knoten mit dem CAN_H Und KANN ICH Linien wie gezeigt:

Beim Verkabeln der Module ist darauf zu achten, dass die Versorgungsspannung im angegebenen Bereich liegt und die KANN H Und KANN ICH Pins richtig mit dem Bus verbunden sind.

Programmierung des CAN-Bus-Moduls MCP2515

Beachten Sie, dass es beim Programmieren des MCP2515-Moduls wichtig ist, die richtige Bitrate zu verwenden, um eine erfolgreiche Kommunikation mit anderen CAN-Geräten im Netzwerk sicherzustellen.

Absendercode:

#enthalten
#enthalten
#enthalten

MCP2515 mcp2515(10);
konstByte TrigPin = 3;
konstByte echopin = 4;
NewPing Sonar(trigPin, echoPin, 200);

Strukturcan_framecanMsg;

Leereaufstellen(){
Seriell.Start(9600);
mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}

LeereSchleife(){
ohne Vorzeichenint Abstand = sonar.ping_cm ();
canMsg.can_id = 0x036; //CAN-ID als 0x036
canMsg.can_dlc = 8; //CAN-Datenlänge als 8
canMsg.data[0] = Entfernung; //Feuchtigkeitswert in [0] aktualisieren
canMsg.data[1] = 0x00; //Alles mit 0 ausruhen
canMsg.data[2] = 0x00;
canMsg.data[3] = 0x00;
canMsg.data[4] = 0x00;
canMsg.data[5] = 0x00;
canMsg.data[6] = 0x00;
canMsg.data[7] = 0x00;

mcp2515.sendMessage(&canMsg);//Sendet die CAN-Nachricht
Verzögerung(100);
}

Empfängercode:

#enthalten
#enthalten
#enthalten

MCP2515 mcp2515(10);
LiquidCrystal_I2C lcd(0x27,16,2);
Strukturcan_framecanMsg;

Leereaufstellen(){
Seriell.Start(9600);

mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
lcd.init();
LCD-Rücklicht();
lcd.setCursor(0, 0);
lcd.drucken("MUO KANN TUTORIAL");
Verzögerung(3000);
lcd.klar();
}

LeereSchleife(){
Wenn (mcp2515.lies die Nachricht(&canMsg) == MCP2515::ERROR_OK) // Um ​​Daten zu empfangen
{
int Distanz = canMsg.data[0];
lcd.setCursor(0,0);
lcd.drucken("Distanz: ");
lcd.drucken(Distanz);
lcd.drucken("cm ");
}
}

Bringen Sie Ihre Arduino-Projekte auf die nächste Stufe

Die Kombination aus CAN-Bus und Arduino bietet eine leistungsstarke Plattform zum Erstellen oder Erlernen anspruchsvoller Kommunikationsnetzwerke, die in verschiedenen Anwendungen verwendet werden. Es mag zwar wie eine steile Lernkurve erscheinen, aber ein eigenes Setup auf einem Steckbrett zu haben, ist eine ziemlich praktische Möglichkeit, die Grundlagen der Verwendung eines CAN-Bus-Netzwerks in komplexen DIY-Projekten zu erlernen.