Brug denne robuste serielle kommunikationsprotokol til at forbinde to Arduino-kort sammen og sende data til hinanden.

Controller Area Network (CAN)-bussen er en robust og pålidelig kommunikationsprotokol, der er meget udbredt i forskellige industri-, bil- og rumfartsapplikationer. Den er designet til transmission af data mellem mikrocontrollere og enheder over et CAN-bus-netværk. Du ved det måske ikke endnu, men det er tingen bag de skøre bil-dashboard-mods, du ser på sociale medier.

Vi vil guide dig gennem, hvordan du bygger en CAN-bus med MCP2515 CAN-modulet ved hjælp af en Arduino og breadboard. Vi vil også gennemgå Arduino CAN-biblioteket og demonstrere, hvordan man sender og modtager data over CAN-bussen.

Hvad er en CAN-bus?

CAN-bussen er en seriel kommunikationsprotokol, der blev udviklet af Bosch i 1980'erne. Det er meget udbredt i forskellige applikationer på grund af dets høje pålidelighed og robusthed. Det giver mulighed for overførsel af data mellem enheder ved høje hastigheder med minimal latenstid over kun to linjer: CAN High og CAN Low.

instagram viewer

I 1994 blev CAN-bussen en international standard (ISO 11898), der var designet specifikt til hurtig seriel dataudveksling mellem elektroniske controllere i bilapplikationer. Se vores omfattende guide vedr hvad en CAN-bus er, og hvilken rolle den spiller i bilsystemer for flere detaljer.

En af grundene til, at CAN-bussen er så populær, er på grund af dens fejlfindings- og korrektionsfunktioner. Protokollen kan opdage og rette fejl i transmissionen af ​​data. Dette gør den ideel til applikationer, hvor dataintegritet er kritisk, såsom inden for industriel automatisering.

At kende MCP2515 CAN-modulet

MCP2515 CAN Bus Controller-modulet er en enhed, der giver enestående support til den udbredte CAN Protocol version 2.0B. Dette modul er ideelt til kommunikation ved høje datahastigheder på op til 1 Mbps.

MCP2515 IC er en uafhængig CAN-controller med et SPI-interface, der muliggør kommunikation med en bred vifte af mikrocontrollere. TJA1050 IC fungerer på den anden side som en grænseflade mellem MCP2515 CAN controller IC og den fysiske CAN bus.

For ekstra bekvemmelighed er der en jumper, der gør det muligt at tilslutte 120 ohm terminering, hvilket gør det endnu nemmere at forbinde dine ledninger til CAN_H & CAN_L skruer til kommunikation med andre CAN-moduler.

Feature

Specifikation

Transceiver

TJA1050

Mikrocontroller interface

SPI (tillader Multi CAN bus integration)

Krystal oscillator

8 MHz

Afslutning

120Ω

Fart

1 Mbps

Strømforbrug

Lavstrøm standby drift

Dimension

40 x 28 mm

Node kapacitet

Understøtter op til 112 noder

Du kan få yderligere information fra MCP2515 datablad hvis du har brug for dette modul til et mere avanceret projekt.

CAN-meddelelsesstruktur

CAN-meddelelsesstrukturen består af flere segmenter, men de mest kritiske segmenter for dette projekt er identifikator og data. Identifikationen, også kendt som CAN ID eller Parameter Group Number (PGN), identificerer enhederne på CAN'et netværk, og længden af ​​identifikatoren kan være enten 11 eller 29 bit, afhængigt af typen af ​​CAN-protokol Brugt.

I mellemtiden repræsenterer dataene de faktiske sensor-/kontroldata, der transmitteres. Dataene kan være alt fra 0 til 8 bytes lange, og Data Length Code (DLC) angiver antallet af tilstedeværende databytes.

Arduino MCP2515 CAN Bus bibliotek

Dette bibliotek implementerer CAN V2.0B protokol, som kan fungere med hastigheder på op til 1 Mbps. Det giver et SPI-interface, der kan fungere ved hastigheder på op til 10MHz, mens det understøtter både standard (11-bit) og udvidet (29-bit) data. Hvad mere er, kommer den med to modtagebuffere, som giver mulighed for prioriteret beskedlagring.

Initialisering af CAN-bussen

Her er den opsætningskode, du skal bruge for at initialisere CAN-bussen:

#omfatte
#omfatte

MCP2515 mcp2515(10); // Indstil CS pin

ugyldigOpsætning(){
mens (!Seriel);
Seriel.begynde(9600);
SPI.begynde(); //Begynder SPI-kommunikation

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

Dette initialiserer MCP2515 med en CAN-bithastighed på 500Kbps og en oscillatorfrekvens på 8MHz.

MCP2515 CAN driftstilstande

Der er tre driftstilstande, der bruges med MCP2515 CAN-bus-controlleren:

  • setNormalMode(): indstiller controlleren til at sende og modtage beskeder.
  • setLoopbackMode(): indstiller controlleren til at sende og modtage beskeder, men de beskeder den sender vil også blive modtaget af sig selv.
  • setListenOnlyMode(): indstiller controlleren til kun at modtage beskeder.

Disse er funktionskald, der bruges til at indstille driftstilstanden for MCP2515 CAN-bus-controlleren.

mcp2515.setNormalMode();

mcp2515.setLoopbackMode();

mcp2515.setListenOnlyMode();

Afsendelse af data over CAN-bussen

For at sende en besked over CAN-bussen skal du bruge sendMsgBuf() metode:

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

Dette sender en besked med ID 0x01 og en datanyttelast på {0x01, 0x02, 0x03, 0x04}. Den første parameter er CAN ID, den anden er meddelelsesprioriteten, den tredje er længden af ​​datanyttelasten, og den fjerde er selve datanyttelasten.

Det sendMsgBuf() metode returnerer en værdi, der angiver, om meddelelsen blev sendt med succes eller ej. Du kan kontrollere denne værdi ved at ringe til checkError() metode:

hvis (CAN.checkError()) {
Seriel.println("Fejl ved afsendelse af besked.");
}

Dette kontrollerer, om der opstod en fejl under transmissionen af ​​meddelelsen, og udskriver en fejlmeddelelse, hvis det er nødvendigt.

Modtagelse af data fra CAN-bussen

For at modtage en besked over CAN-bussen kan du bruge readMsgBuf() metode:

usigneretchar len = 0;
usigneretchar buff[8];
usigneretchar canID = 0;

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

Dette kontrollerer, om en besked er tilgængelig på CAN-bussen, og læser derefter beskeden ind i buf array. Længden af ​​beskeden gemmes i len variabel, og meddelelsens ID er gemt i canID variabel.

Når du har modtaget en besked, kan du behandle datanyttelasten efter behov. For eksempel kan du udskrive datanyttelasten til den serielle monitor:

Seriel.Print("Modtaget besked med ID");
Seriel.Print(canID, HEX);
Seriel.Print(" og data: ");

til (int i = 0; i < len; i++) {
Seriel.Print(buff[i], HEX);
Seriel.Print(" ");
}

Seriel.println();

Dette udskriver ID'et for den modtagne besked og datanyttelasten til den serielle monitor.

Sådan tilsluttes en CAN-bus-transceiver til et breadboard

For at bygge en CAN-bus til at forbinde to enheder i dette eksempelprojekt, skal du bruge:

  • To mikrocontrollere (to Arduino Nano-kort til dette eksempel)
  • To MCP2515 CAN-moduler
  • Et brødbræt
  • Jumper ledninger
  • Et I2C 16x2 LCD-skærmmodul
  • HC-SR04 ultralydssensor

Til dette projekteksempel bruges fire biblioteker i Arduino-skitsen. Der er NewPing bibliotek, som giver en brugervenlig grænseflade til ultralydssensoren, såvel som SPI bibliotek, som letter kommunikationen mellem Arduino-kortet og MCP2515 CAN-bus-controlleren. Det LiquidCrystal_I2C bibliotek bruges til displaymodulet.

Til sidst er der mcp2515 bibliotek at interface med MCP2515-chippen, så vi nemt kan overføre data over CAN-bus-netværket.

Hardwareopsætning (HC-SR04 eksempel)

I dette projekt, der bruger en HC-SR04-sensor og LCD, vil det ene Arduino Nano-kort fungere som modtager, mens det andet Arduino fungerer som afsender. Tilslut dine senderkomponenter i henhold til ledningsdiagrammet nedenfor:

Her er diagrammet for modtagerkredsløbet:

Til sidst skal du forbinde de to noder sammen ved hjælp af CAN_H og CAN_L linjer som vist:

Når du tilslutter modulerne, er det vigtigt at sikre, at strømforsyningsspændingen er inden for det specificerede område, og at KAN H og KAN L benene er korrekt forbundet til bussen.

Programmering af MCP2515 CAN-busmodulet

Bemærk, at når du programmerer MCP2515-modulet, er det vigtigt at bruge den korrekte bithastighed for at sikre vellykket kommunikation med andre CAN-enheder på netværket.

Afsenderkode:

#omfatte
#omfatte
#omfatte

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

strukturkan_rammecanBesked;

ugyldigOpsætning(){
Seriel.begynde(9600);
mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}

ugyldigsløjfe(){
usigneretint afstand = sonar.ping_cm();
canMsg.can_id = 0x036; //CAN id som 0x036
canMsg.can_dlc = 8; //CAN-datalængde som 8
canMsg.data[0] = afstand; //Opdater fugtværdi i [0]
canMsg.data[1] = 0x00; //Hvil alle 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);//Sender CAN-meddelelsen
forsinke(100);
}

Modtager kode:

#omfatte
#omfatte
#omfatte

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

ugyldigOpsætning(){
Seriel.begynde(9600);

mcp2515.reset();
mcp2515.setBitrate (CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
lcd.init();
lcd.baggrundslys();
lcd.sætMarkør(0, 0);
lcd.Print("MUO CAN TUTORIAL");
forsinke(3000);
lcd.klar();
}

ugyldigsløjfe(){
hvis (mcp2515.læs besked(&canMsg) == MCP2515::FEJL_OK) // At modtage data
{
int distance = canMsg.data[0];
lcd.sætMarkør(0,0);
lcd.Print("Afstand: ");
lcd.Print(afstand);
lcd.Print("cm");
}
}

Tag dine Arduino-projekter til det næste niveau

Kombinationen af ​​CAN-bussen og Arduino giver en kraftfuld platform til at bygge eller lære sofistikerede kommunikationsnetværk, der bruges i forskellige applikationer. Selvom det kan synes at være en stejl indlæringskurve, er det at have din egen opsætning på et brødbræt en ret praktisk måde at lære rebet ved at bruge et CAN-bus-netværk i komplekse DIY-projekter.