Använd detta robusta seriella kommunikationsprotokoll för att koppla ihop två Arduino-kort och skicka data till varandra.

Controller Area Network (CAN)-bussen är ett robust och tillförlitligt kommunikationsprotokoll som används flitigt i olika industri-, bil- och flygtillämpningar. Den är designad för överföring av data mellan mikrokontroller och enheter över ett CAN-bussnätverk. Du kanske inte vet det här ännu, men det är grejen bakom de där galna bilinstrumentbrädorna du ser på sociala medier.

Vi kommer att gå igenom hur du bygger en CAN-buss med MCP2515 CAN-modulen med hjälp av en Arduino och breadboard. Vi kommer också att gå igenom Arduino CAN-biblioteket och demonstrera hur man skickar och tar emot data över CAN-bussen.

Vad är en CAN-buss?

CAN-bussen är ett seriellt kommunikationsprotokoll som utvecklades av Bosch på 1980-talet. Den används ofta i olika applikationer på grund av dess höga tillförlitlighet och robusthet. Det möjliggör överföring av data mellan enheter med höga hastigheter med minimal latens över endast två linjer: CAN High och CAN Low.

instagram viewer

1994 blev CAN-bussen en internationell standard (ISO 11898) som designades specifikt för snabbt seriellt datautbyte mellan elektroniska styrenheter i biltillämpningar. Kolla in vår omfattande guide om vad en CAN-buss är och vilken roll den spelar i fordonssystem för mer information.

En av anledningarna till att CAN-bussen är så populär är på grund av dess feldetekterings- och korrigeringsfunktioner. Protokollet kan upptäcka och korrigera fel i överföringen av data. Detta gör den idealisk för applikationer där dataintegritet är avgörande, till exempel inom industriell automation.

Att känna till MCP2515 CAN-modulen

MCP2515 CAN Bus Controller-modulen är en enhet som ger exceptionellt stöd för den mycket använda CAN Protocol version 2.0B. Denna modul är idealisk för kommunikation med höga datahastigheter på upp till 1 Mbps.

MCP2515 IC är en oberoende CAN-styrenhet med ett SPI-gränssnitt som möjliggör kommunikation med ett brett utbud av mikrokontroller. TJA1050 IC, å andra sidan, fungerar som ett gränssnitt mellan MCP2515 CAN-styrenhetens IC och den fysiska CAN-bussen.

För extra bekvämlighet finns det en bygel som gör att du kan ansluta 120 ohm avslutning, vilket gör det ännu enklare att ansluta dina kablar till CAN_H & KAN JAG skruvar för kommunikation med andra CAN-moduler.

Funktion

Specifikation

Transceiver

TJA1050

Mikrokontroller gränssnitt

SPI (möjliggör Multi CAN-bussintegration)

Kristalloscillator

8 MHz

Uppsägning

120Ω

Fart

1 Mbps

Energiförbrukning

Standby-drift med låg ström

Dimensionera

40 x 28 mm

Nodkapacitet

Stöder upp till 112 noder

Du kan få ytterligare information från MCP2515 datablad om du behöver den här modulen för ett mer avancerat projekt.

CAN-meddelandestruktur

CAN-meddelandestrukturen består av flera segment, men de mest kritiska segmenten för detta projekt är identifieraren och data. Identifieraren, även känd som CAN ID eller Parameter Group Number (PGN), identifierar enheterna på CAN: n nätverk, och längden på identifieraren kan vara antingen 11 eller 29 bitar, beroende på typen av CAN-protokoll Begagnade.

Samtidigt representerar data den faktiska sensor/kontrolldata som överförs. Data kan vara allt från 0 till 8 byte långa, och Data Length Code (DLC) indikerar antalet databyte som finns.

Arduino MCP2515 CAN Bus Library

Detta bibliotek implementerar CAN V2.0B-protokoll, som kan arbeta med hastigheter på upp till 1 Mbps. Den tillhandahåller ett SPI-gränssnitt som kan arbeta i hastigheter på upp till 10MHz samtidigt som det stöder både standarddata (11-bitars) och utökade (29-bitars). Dessutom kommer den med två mottagningsbuffertar, som möjliggör prioriterad meddelandelagring.

Initiering av CAN-bussen

Här är inställningskoden du behöver för att initiera CAN-bussen:

#omfatta
#omfatta

MCP2515 mcp2515(10); // Sätt CS-stift

tomhetuppstart(){
medan (!Serie);
Serie.Börja(9600);
SPI.Börja(); //Börjar SPI-kommunikation

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

Detta initierar MCP2515 med en CAN-bithastighet på 500Kbps och en oscillatorfrekvens på 8MHz.

MCP2515 CAN-driftlägen

Det finns tre driftlägen som används med MCP2515 CAN bus-styrenheten:

  • setNormalMode(): ställer in kontrollenheten för att skicka och ta emot meddelanden.
  • setLoopbackMode(): ställer in kontrollenheten för att skicka och ta emot meddelanden, men meddelandena som den skickar kommer också att tas emot av sig själv.
  • setListenOnlyMode(): ställer in styrenheten att endast ta emot meddelanden.

Dessa är funktionsanrop som används för att ställa in driftsläget för MCP2515 CAN-bussstyrenheten.

mcp2515.setNormalMode();

mcp2515.setLoopbackMode();

mcp2515.setListenOnlyMode();

Skickar data över CAN-bussen

För att skicka ett meddelande över CAN-bussen, använd sendMsgBuf() metod:

osigneradröding data[] = {0x01, 0x02, 0x03, 0x04};
CAN.sendMsgBuf(0x01, 0, 4, data);

Detta skickar ett meddelande med ID 0x01 och en datanyttolast på {0x01, 0x02, 0x03, 0x04}. Den första parametern är CAN ID, den andra är meddelandeprioriteten, den tredje är längden på datanyttolasten och den fjärde är själva datanyttolasten.

De sendMsgBuf() metod returnerar ett värde som anger om meddelandet skickades framgångsrikt eller inte. Du kan kontrollera detta värde genom att anropa checkError() metod:

om (CAN.checkError()) {
Serie.println("Det gick inte att skicka meddelande.");
}

Detta kontrollerar om ett fel inträffade under överföringen av meddelandet och skriver ut ett felmeddelande om det behövs.

Ta emot data från CAN-bussen

För att ta emot ett meddelande via CAN-bussen kan du använda readMsgBuf() metod:

osigneradröding len = 0;
osigneradröding buff[8];
osigneradröding canID = 0;

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

Detta kontrollerar om ett meddelande är tillgängligt på CAN-bussen och läser sedan in meddelandet i buff array. Meddelandets längd lagras i len variabel, och meddelandets ID lagras i canID variabel.

När du har fått ett meddelande kan du behandla datanyttolasten efter behov. Du kan till exempel skriva ut datanyttolasten till den seriella monitorn:

Serie.skriva ut("Mottaget meddelande med ID");
Serie.skriva ut(canID, HEX);
Serie.skriva ut(" och data: ");

för (int jag = 0; i < len; i++) {
Serie.skriva ut(buff[i], HEX);
Serie.skriva ut(" ");
}

Serie.println();

Detta skriver ut ID: t för det mottagna meddelandet och datanyttolasten till den seriella monitorn.

Hur man ansluter en CAN Bus Transceiver till en Breadboard

För att bygga en CAN-buss för att ansluta två enheter i detta exempelprojekt behöver du:

  • Två mikrokontroller (två Arduino Nano-kort för detta exempel)
  • Två MCP2515 CAN-moduler
  • En brödbräda
  • Bygeltrådar
  • En I2C 16x2 LCD-skärmmodul
  • HC-SR04 ultraljudssensor

För detta projektexempel används fyra bibliotek i Arduino-skissen. Där finns NewPing bibliotek, som ger ett lättanvänt gränssnitt för ultraljudssensorn, såväl som SPI bibliotek, vilket underlättar kommunikationen mellan Arduino-kortet och MCP2515 CAN-busskontrollern. De LiquidCrystal_I2C biblioteket används för displaymodulen.

Till sist finns det mcp2515 bibliotek för gränssnitt med MCP2515-chippet, vilket gör att vi enkelt kan överföra data över CAN-bussnätverket.

Hårdvaruinställning (HC-SR04 exempel)

I det här projektet använder en HC-SR04-sensor och LCD, ett Arduino Nano-kort kommer att fungera som en mottagare, medan det andra Arduino kommer att fungera som en avsändare. Anslut dina avsändarkomponenter enligt kopplingsschemat nedan:

Här är diagrammet för mottagarkretsen:

Slutligen, koppla ihop de två noderna med hjälp av CAN_H och KAN JAG linjer som visas:

När du ansluter modulerna är det viktigt att se till att strömförsörjningsspänningen ligger inom det specificerade området och att KAN H och KAN JAG stiften är korrekt anslutna till bussen.

Programmering av MCP2515 CAN Bus Module

Observera att vid programmering av MCP2515-modulen är det viktigt att använda rätt bithastighet för att säkerställa framgångsrik kommunikation med andra CAN-enheter i nätverket.

Avsändarkod:

#omfatta
#omfatta
#omfatta

MCP2515 mcp2515(10);
konstbyte trigPin = 3;
konstbyte echoPin = 4;
NewPing ekolod(trigPin, echoPin, 200);

strukturcan_framekanMsg;

tomhetuppstart(){
Serie.Börja(9600);
mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}

tomhetslinga(){
osigneradint avstånd = sonar.ping_cm();
canMsg.can_id = 0x036; //CAN-id som 0x036
canMsg.can_dlc = 8; //CAN-datalängd som 8
canMsg.data[0] = avstånd; //Uppdatera fuktighetsvärde i [0]
canMsg.data[1] = 0x00; //Vila alla med 0
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);//Sänder CAN-meddelandet
dröjsmål(100);
}

Mottagarens kod:

#omfatta
#omfatta
#omfatta

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

tomhetuppstart(){
Serie.Börja(9600);

mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.skriva ut("MUO CAN TUTORIAL");
dröjsmål(3000);
lcd.klar();
}

tomhetslinga(){
om (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) // För att ta emot data
{
int distans = canMsg.data[0];
lcd.setCursor(0,0);
lcd.skriva ut("Distans: ");
lcd.skriva ut(distans);
lcd.skriva ut("centimeter ");
}
}

Ta dina Arduino-projekt till nästa nivå

Kombinationen av CAN-bussen och Arduino ger en kraftfull plattform för att bygga eller lära sofistikerade kommunikationsnätverk som används i olika applikationer. Även om det kan tyckas vara en brant inlärningskurva, är det ett ganska praktiskt sätt att ha en egen installation på en brödbräda för att lära sig hur man använder ett CAN-bussnätverk i komplexa gör-det-själv-projekt.