1 Communicatie via de CAN-bus met Arduino-shield

Vergelijkbare documenten
De AT90CAN microprocessor van ATMEL in de motorvoertuigentechniek (8)

Workshop Arduino voor beginners deel 2

De Arduino-microcontroller in de motorvoertuigentechniek (6)

Tweede workshop Arduino

De Arduino-microcontroller in de motorvoertuigentechniek (4)

Opgave Tussentijdse Oefeningen Jaarproject I Reeks 4: Lcd Interface & Files

Oefening 1 - Seriële communicatie via USB

Arduino : Morse Voltmeter

De Arduino-microcontroller in de motorvoertuigentechniek (7)

Arduino CURSUS. door Willy - 09-juni-2017

Werkbladen voor Arduino workshop 1

De Arduino-microcontroller in de motorvoertuigentechniek (2)

De AT90CAN microprocessor van ATMEL in de motorvoertuigentechniek (4)

De Arduino-microcontroller in de motorvoertuigentechniek (8)

Besturingspaneel v Raam E-systeem functie omschrijving v109

In- en uitgangssignalen van microprocessoren

AVR-DOPER MINI ASSEMBLAGE HANDLEIDING + LAYOUT. Geschreven door: Tom Vocke

De AT90CAN microprocessor van ATMEL in de motorvoertuigentechniek (2)

Arduino Workshop 1 Zuid-Limburg

De Arduino-microcontroller in de motorvoertuigentechniek (3)

2 Algemene opbouw van een computersysteem

De AT90CAN microprocessor van ATMEL in de motorvoertuigentechniek (3)

RCL Arduino Workshop 1

MAKERKLAS WORKSHOP ARDUINO. Maandag 7 december 2015

Veiligheid,comfort en communicatie (1)

INHOUD SPI : SERIAL PERIPHERAL INTERFACE ALGEMEEN. Videolessen Deel 3 DATACOMMUNICATIE SPI

APPINVENTOR is een 100% gratis online tool waarmee je zelf apps kan maken voor Android devices (niet voor Apple).

B3C 70cm converter besturing. v PE5PVB bar.net bar.net

Les 8 23 april 2019 arrays bool lampenaan[5]; Serial Serial Serial Serial if(!lampenaan[3]) { int index nummer index nummer nul

led 0 aan Opdracht: 1 Opdracht: 4

Microcontrollers. Bart Kardinaal E Verslag microcontrollers Rev 1.0 Status definitief.

Arduino en APRS EZHE Workshop April 2017, PD1DDK

Motormanagement simulatie MegaSquirt Hoofdstuk 3

Seriële bluetooth verbinding ATmega128

- Dé internetsite voor de Automotive Professional

Espa 443 Converter. Beschrijving van de Espa 444 naar Espa 443 Converter.

Naam + Klas: Laptop Nr: Cijfer:

MiniPlex-41 NMEA-0184 multiplexer Handleiding

Locobuffer Handleiding

Arduino Zuid-Limburg Workshop 2

TECHNISCHE UNIVERSITEIT EINDHOVEN FACULTEIT DER TECHNISCHE NATUURKUNDE

MegaSquirt motormanagement-simulatie Hoofdstuk: Inleiding

Constructie van het klokcircuit voor de processor en het spanningsdetectie circuit

Accelerometer project 2010 Microcontroller printje op basis van de NXP-LPC2368

17 Operaties op bits Bitoperatoren en bitexpressies

ES1 Project 1: Microcontrollers

WZ FS 2-2-FFSK 12.5kHz. Korte handleiding

Hoofdstuk 7. Computerarchitectuur

CAN-tester Met uitgebreide mogelijkheden

MBUS-64 TCP. VF64 over MODBUS / TCP

Technische specificatie PRIS Dataverzamel Protocol

Arduino. HCC Vlaanderen - Mechelen 7 februari Luc De Cock

Arduino Cursus, Deel 2 Programmeren. Simon Pauw, ZB45, Amsterdam

Tinyserir-RC5. Datasheet. Tinyserir-RC5 Page: 1 of 8

S88XPressNetLI v1.0. Installatie- en gebruikershandleiding en naslagwerk KDesign Electronics, PCB ontwerp door RoSoft

Inhoudsopgave. SNI handleiding. Inhoudsopgave

Weerstation. Weerstation met Arduino C.G.N. van Veen. HiSPARC. 1 Weerstation. 2 Arduino. 2.1 Werking van Arduino

Handleiding HCS VB5118

Microcontrollers Week 4 Introductie microcontroller Jesse op den Brouw (met dank aan Ben Kuiper) INLMIC/

Technisch ontwerp positiebepaling Smart Blocks

De FOR lus: // terug naar waar je vandaan kwam Serial.begin(115200); // communicatie snelheid met de PC

FORTH op de 80C535 processor met het ATS535 board.

Besturing van de Miniatuurwereld RM-U. Gebruik van de Bootloader

Montagevoorschriften

Voorblad tentamen ENG

// hier wordt de functie: ZegHallo aangeroepen

Het koppelen van de Wago aan de AC500-eco via Modbus RTU. A quick start guide. Jaap Ruiten

Voeler ingang van de ilog recorder. Stop de temperatuurvoeler

Automatische spoel installatie voor legionella preventie. NTKC - Bennie ten Haken 27 Mrt

PIC Callgever Door PA1RUM

Het µclab voor Arduino UNO, NANO en Arduino UNO pincompatible

Infographic De infographic geeft in grove lijnen het overkoepelend concept weer Your home remotely controlled Zie de infographic hier naast.

GEÏNTEGREERDE PROEF. VTI Sint-Laurentius. Pakketweegschaal. Industriële informatie & communicatietechnologie SCHOOLJAAR

Programmeren met Arduino-software

- Dé internetsite voor de Automotive Professional

DDS chips. DDS = Direct Digital (frequency) Synthesis. Output = sinusvormig signaal. Maximum frequentie = ½ klokfrequentie

ATtiny13. Versie 01 : augustus Many van Krieken Page 1

PROJECT 5: PLANT MONITOR

Velbus DIN-rail RS232 & USB interface

Inhoud vandaag. Interrupts. Algemeen ARM7 AIC

A R D U I N O. addendum bij: Leren programmeren, meten en sturen met de Arduino. 3 e druk INHOUD

Sumo-robotcompetitie. Uitlegsessie 15 maart 2011

Voeler ingang van de ilog recorder. Stop de temperatuurvoeler

Deel 8: stappenmotoren en interrupts

16F877A development board cursus deel 1

HD44780 compatibele LCD-displays begrijpen

Goedkope RS232. MSX Computer Magazine nummer 53- april Scanned, ocr ed and converted to PDF by HansO, 2001

G. Schottert Handleiding Freekie 1. Nederlandse handleiding. Freekie DMX ADRES INSTELLINGEN 1

Handleiding HCS VB5248

1-poorts RS232 seriële adapter kaart met UART

MULTIMEDIABOX.nl Custom made solutions hardware & software. Advanced Menu

Beknopte informatie voor GBS leverancier t.b.v. NIBE warmtepomp 1145/1245/1155/1255/1345

Werkingsspanning: Uitgangsformaten: 1 tot 5 cijfers + fabriekscode, 26 bit Wiegand 30 bit Wiegand Clock en data Werkingstemperatuur: -31 C tot 63 C

THEORIE TALSTELSELS. 1 x 10 0 = 1 (een getal tot de macht 0 = 1) 8 x 10 1 = 80 2 x 10 2 = x 10 3 = Opgeteld: 9281d(ecimaal)

INHOUD. dankbetuiging inleiding DE ARDUINO REVOLUTIE...16 OVER DIT BOEK...17 OPZET VAN DIT BOEK...18

Microcontrollers. Robert Langenhuysen, PA0RYL

Snel aan de slag met de Mini Squirrel datalogger

Bouw je eigen minicomputer

Handleiding HCS VB5224

Transcriptie:

Hoofdstuk CAN-shield E. Gernaat (ISBN 978-90-79302-11-6) 1 Communicatie via de CAN-bus met Arduino-shield 1.1 Toelichting bij de Arduino CAN-opdrachten Aan het einde van dit hoofdstuk en in het laatste hoofdstuk is het benodigde materiaal te vinden. Voorbereidende werkzaamheden Solderen van de aansluitpinnen op de CAN-shield; USB-connector isoleren met stukje isolatieband. 1.2 Overzicht van de bijbehorende Arduino oefen-software We onderscheiden zendende en ontvangende programma s. Het ontvangen van de CAN-boodschappen kan op verschillende manieren gebeuren. Oefenprogramma s zijn te vinden op de Timloto site (www.timloto.org) maar kunnen ook worden opgevraagd bij de auteur. Mail naar: e.gernaat@timloto.org In dit hoofdstuk behandelen we vier programma s. Te weten: 1. Potmeter-data verzenden en ontvangen zendpotmeter1 ontvangst potmeter1 2. Maskeren en filteren set mask filter zend set mask filter ontvangst 2 Inleiding CAN-communicatie Bij moderne auto s maken vrijwel alle computers gebruik van de CAN-bus om gegevens met elkaar uit te wisselen. De CAN-bus staat bekend om zijn grote mate van betrouwbaarheid. De betrouwbaarheid heeft niet alleen betrekking op het elektrische signaal maar ook op de inhoud van de eigenlijke CANboodschap. Op de auto is de diagnose-connector via pin 6 en 14 verbonden 1

met de CAN-bus in het voertuig. De Arduino controller heeft de mogelijkheden om CAN-boodschappen te ontvangen en te verzenden met behulp van een aparte CAN-interface. 2.1 Globale werking CAN-controller Arduino spreekt over een shield wanneer we een interface-print rechtstreeks op de pinnen van de Arduino kunnen drukken. De Arduino CAN-Shield is gebaseerd op de MCP2515 CAN-controller en een MCP2551 level-shifter (een levelshifter IC zet de TTL-spanning van 0-5V om in de CAN-spanning). De print bevat behalve een twee-draads CAN-uitgang ook een 9-polige DB9 connector als CAN-aansluiting. De communicatie tussen de Arduino en de MCP2515 op de CAN-print verloopt via het seriële SPI-protocol. De CAN-shield van fig. 1 heeft een klok-kristal van 16 MHz. De aansluiting van de 9-pins DB9 connector is als volgt: 1. GND 2. GND 3. CAN-H 5. CAN-L 9. V-OBD (Vin) Figuur 1: De CAN-shield kan op de pinnen van de Arduino worden gedrukt en bestaat uit een MCP2515 CAN-controller en een MCP2551 level-shifter. De CAN-controller is voorzien van een 16 MHz klok. Behalve een Arduino CAN-shield is er ook een CAN-moduul op de markt. Deze moduul dient met losse draadjes aan de Arduino te worden verbonden. Beide 2

systemen hebben hun voor- en nadelen. In fig. 2 is een dergelijke moduul afgebeeld. De moduul maakt gebruik van dezelfde CAN-controller (U2) maar een ander merk level-shifter nl. een TJA1050 (U1). Dit maakt echter geen verschil. De aansluitingen van de moduul op de Arduino Uno zijn als volgt: INT aan Arduino pin 2 (Interrupt); SCK aan Arduino pin 13 (Serial Clock); SI aan Arduino pin 11 (MOSI, I(C)SP); SO aan Arduino pin 12 (MISO, I(C)SP); CS aan Arduino pin 10 (soms 9) (Chip Select); GND aan Arduino GND; VCC aan Arduino +5V. Figuur 2: Deze CAN-moduul maakt gebruik van losse draad verbindingen en wordt aangestuurd door een 8 MHz klok. Om de CAN-modulen te programmeren maken we gebruik van een CAN-library. De functies in de library maken het eenvoudiger om de CAN-controller te programmeren. Een 16 MHz klok op de CAN-controller is te prefereren omdat dan de baudrate van de CAN-controller in overeenstemming is met de baudrates van de library. Globaal verloopt de data-overdracht voor het zenden als volgt. De programmeur programmeert de Arduino met: de baudrate van de CAN-bus; de identifier van de CAN-boodschap; de data behorend bij de identifier. Deze data wordt via het SPI-protocol seriëel naar de CAN-controller op de print gestuurd. De CAN-controller stelt de baudrate van de CAN-bus in en voegt allerlei controle bytes toe aan de CAN-boodschap. Vervolgens stuurt de CANcontroller de complete CAN-boodschap naar de level-shifter. Het level-shifter 3

IC zet het seriële één-draads TTL-signaal om in het typische tweedraads CAN spanningsverschil signaal. ARDUINO UNO GND GND CAN Controller MCP 2515 2 13 11 12 9/10 +5 V GND 12 13 14 15 16 17 18 INT SCK MOSI MISO CS RST VDD 8 7 2 1 RxCAN TxCAN Level shifter TJA 1050 RxD 4 VCC 6 GND 7 1 TxD CAN l CAN h Figuur 3: De Arduino-controller zendt de CAN-boodschap seriëel door naar de CANcontroller. Vervolgens zet het level-shifter IC het CAN-TTL signaal om in het tweedraad CANspanningsverschil niveau. 2.2 De CAN-boodschap De CAN-boodschap bestaat uit een identifier en de eigenlijke data. De CANcontroller voegt hieraan een groot aantal controle bytes toe waarvan de CRC de belangrijkste is. Een identifier zegt iets over de informatie die volgt. Men data frame 0000 1111 0000 1111 0000 1111 0000 1111 0000 1111 0000 1111 0000 1111 0 8 bytes 0000 1111 1 11 6 15 2 7 aantal bits begin frame einde frame bevestiging (ACK) CRC (fout detectie) data (boodschap) controle identifier Figuur 4: De opbouw van een CAN-boodschap. De programmeur bepaalt de baudrate, de identifier en de data, De controle bytes worden door de CAN-controller berekend en toegevoegd. spreekt van een standaard CAN-frame wanneer de identifier 11 bits groot is. Bij een 29 bits grote identifier spreekt men van extended CAN. 2.3 De CAN-bedrading De CAN-bus zelf bestaat uit twee -meestal in elkaar gevlochten draden- die aan beide zijden wordt afgesloten door een weerstand van 120 Ω. De op de CAN-bus aangesloten computers lezen de verschilspanning tussen de CAN-h en CAN-l uit. Op deze wijze worden elektrische storingen van buitenaf voorkomen. Zie fig. 5 Een spanningmeting op de CAN-bus kan met een oscilloscoop plaats vinden door te meten tussen: 4

Figuur 5: Voorbeeld van een CAN-auto-netwerk. Ook de diagnose-connector is hierop aangesloten. De draden zijn in elkaar gevlochten. De communicatie-snelheid bedraagt meestal 500 kbits/sec CAN-l en CAN-h CAN-l en de massa CAN-h en de massa Figuur 6: Spanning gemeten tussen CAN-h en CAN-l. Op deze wijze worden ook door de controllers de spanning gemeten. De ontvangende CAN-controller meet het spanningsverschil tussen de CAN-h en CAN-l draad. Deze verschilspanning wordt in de level-shifter weer omgezet in een TTL-signaal. De CAN-controller haalt alle controle bytes er weer uit en geeft de CAN-boodschap door aan de Arduino-controller. De ontvangende controller leest dan de identifier en de data uit. Wanneer we de CAN-bus spanningen meten t.o.v. de massa of GND dan kunnen we zien dat de CAN-bus 5

spanning 2,5 V bedraagt als er geen boodschap wordt verzonden. Een logische 1 ontstaat door de CAN-h lijn omhoog te trekken en de CAN-l lijn naar beneden. Het spanningsverschil wordt gemeten. Vanuit het oscilloscoopbeeld kan Figuur 7: De CAN-spanningen gemeten ten opzichte van de massa. Een CAN-bus in rust (zonder signaal) meet 2,5 V t.o.v. de massa. Is er sprake van een signaal dan trekt CAN-h de spanning omhoog t.o.v de 2,5 V en CAN-l omlaag t.o.v de 2,5 V. ook de communicatiesnelheid worden vastgesteld. We meten hiervoor de tijd van de kleinste bit. De baudrate laat zich dan berekenen door de formule: baudrate (bits/sec) = 1000 ms/bittijd in ms. Bij dit hoofdstuk behoren een aantal programma s. We onderscheiden hierin: programma s die zenden; programma s die ontvangen; programma s die ontvangen, maskeren en filteren; Bij het ontvangen wordt onderscheid gemaakt tussen de pol- en de interruptmethode. Bij het pollen wordt er net zo lang gewacht totdat de boodschap binnen is en bij een interrupt springt, wanneer de CAN-boodschap binnen is, het programma naar een apart stukje programmatuur (een interrupt service routine of ISR) dat dan de boodschap ophaalt. Het nu volgende Arduino-programma leest een potentiometer uit en zet de potmeter-stand op de CAN-bus. We zijn uitgegaan van de kennis zoals die in de eerdere hoofdstukken is opgedaan. 3 CAN-programmatuur 3.1 Programma: Zend data potentiometer Programma naam: zend potmeter1.ino De Arduino CAN-BUS Shield wordt gebruikt. Een 10k potmeter is aangesloten op A0 (de loper), + 5V en de GND. De potmeter-stand wordt via de CAN-bus naar buitengebracht. Het CAN-bericht wordt tevens op de console weergegeven. De identifier is willekeurig. Voor de potmeter-data (0 tot 255) wordt 1 data-byte gebruikt. Een 120 Ω weerstand is gemonteerd tussen CAN-h en CAN-l. 1. # include <mcp can.h> //CAN-library 6

2. # include <SPI.h> //SPI-library 3. # define sensorpin A0 4. # define SPI CS PIN 10 5. MCP CAN CAN(SPI CS PIN); //library aktief, Chip Select: pin 10 6. unsigned int sensorvalue = 0; 7. unsigned int cantxvalue = 0; 8. unsigned int canid = 0; 9. byte canmsg[8]=0xff,0x02,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f; //bytes in array willekeurig 10. void setup() 11. { 12. Serial.begin(9600); //om boodschap naar console te sturen 13. CAN.begin(CAN 100KBPS); // 100 kb/s bij 16 MHz kristal 14. } 15. void loop() 16. { 17. sensorvalue=analogread(sensorpin); 18. cantxvalue = sensorvalue / 4; //om van 1024 naar 256 te gaan 19. cantxvalue=(byte)cantxvalue; //van integer naar byte 20. canmsg[0]=cantxvalue; // zend data: identifier = 0x07B, standaard frame = 0, data lengte = 8, canmsg=data buffer 21. CAN.sendMsgBuf (0x0FB,0,8,canMsg); //uitlezing naar console 22. canid = CAN.getCanId(); //lees eigen ID uit 23. Serial.print(canId,HEX); 24. Serial.print( \t ); //geef tapafstand 25. Serial.print(canMsg[0]); //lees buffer uit 26. Serial.print( \t ); 27. Serial.print(canMsg[1]); 28. Serial.print( \t ); 29. Serial.print(canMsg[2]); 30. Serial.print ( \t ); 31. Serial.print(canMsg[3]); 32. Serial.print( \t ); 33. Serial.print(canMsg[4]); 34. Serial.print( \t ); 35. Serial.print(canMsg[5]); 36. Serial.print ( \t ); 7

37. Serial.print(canMsg[6],HEX); 38. Serial.print( \t ); 39. Serial.print(canMsg[7],HEX); 40. Serial.println( \t ); 41. } 3.1.1 Vragen en opgaven (zie ook toelichting) 1. Upload het programma en controleer de werking met behulp van de seriële monitor. 2. Verander nu de uitlezing van de potmeter in een hexadecimale waarde. 3. Zet nu de potmeter-uitlezing op databyte 7 (de laatste) en controleer dit met de seriële monitor. 4. Controleer het spanningsniveau van het signaal met behulp van een oscilloscoop. Meet tussen CAN-h en CAN-l, CAN-h en de GND en CAN-l en de GND. 5. Controleer met de oscilloscoop of enige verandering in het beeld te zien is wanneer we aan de potmeter draaien. 6. Stel m.b.v. de oscilloscoop de baudrate van het signaal vast. 7. Monteer nu een tweede potmeter en geef de stand weer op de eerste data byte en schrijf het programma weg onder de naam zend potmeter1b. 3.1.2 Toelichting In regel 1 en 2 zien we dat er gebruik wordt gemaakt van twee bibliotheken (library s), een CAN- en een SPI-library. Door het toevoegen van bibliotheken kunnen speciale programmeer-opdrachten worden aangeroepen die buiten de standaard C-instructies vallen. De meeste van deze speciale bibliotheken moeten aan de Arduino IDE worden toegevoegd. Een aantal library s echter zitten al standaard in de IDE. De CAN-library met de naam CAN BUS Shield-master kan van internet worden gdownload en moet dan aan de Arduino IDE worden toegevoegd. De.ZIP file kan via Schets, bibliotheek gebruik en.zip bibliotheek toevoegen geactiveerd worden. In regel 3 wordt aangegeven op welke pin de potmeter wordt aangesloten. In regel 4 wordt vermeld op welke Arduino-pin de CS (Chip Select) van de CAN-controller wordt aangesloten. In regel 5 wordt een instance van de library aangemaakt met de naam CAN en wordt het pinnummer van de CS-pin doorgegeven. Met een logische nul vanuit de Arduino op de CS-pin 10 wordt de CAN-controller geactiveerd. In regel 6,7 en 8 worden de variabelen gedeclareerd. In regel 9 wordt de CAN-boodschap-array gedefiniëerd en gevuld met willekeurige hexadecimale waarden. Deze buffer is 8 bytes groot, van het type byte en heeft de naam canmsg meegekregen. In regel 12 van de setup wordt de baudrate ingesteld om met de console (het scherm) te kunnen 8

communiceren. In regel 13 wordt de CAN-communicatie geactiveerd en wordt de baudrate van de CAN-bus op 100 kb/s ingesteld. De nu volgende baudrates worden door de library ondersteund. #define CAN 5KBPS 1 #define CAN 10KBPS 2 #define CAN 20KBPS 3 #define CAN 25KBPS 4 #define CAN 31K25BPS 5 #define CAN 33KBPS 6 #define CAN 40KBPS 7 #define CAN 50KBPS 8 #define CAN 80KBPS 9 #define CAN 83K3BPS 10 #define CAN 95KBPS 11 #define CAN 100KBPS 12 #define CAN 125KBPS 13 #define CAN 200KBPS 14 #define CAN 250KBPS 15 #define CAN 500KBPS 16 #define CAN 666KBPS 17 #define CAN 1000KBPS 18 Voor de auto is de CAN 500KBPS het meest voorkomend. De genoemde baudrates gelden voor een kloksnelheid van 16 MHz van de CAN-controller. Vanuit de 10 bits ADC leest regel 17 de potmeter uit en door de uitlezing door vier te delen verandert de potmeter uitlezing in waarden tussen de 0 en 255 (Regel 18). De 10 bits vanuit de ADC hebben we teruggebracht tot 8 bits (1024/4). De variabele CanxValue was aanvankelijk van het type unsigned integer en we maken in regel 19 hier een variabele van het type byte van. Dan past hij in de array. In regel 20 vullen we de de eerste geheugenplaats van de array (plaats 0) met de stand van de potmeter. In regel 21 verzenden we de gehele CANboodschap in één keer met de programmaregel CAN.sendMsgBuf(). Binnen de haakjes staat de identifier 0x0FB (hexadecimaal), gevolgd door een 0 om aan te geven dat het hier om een standaard CAN-boodschap gaat en gevolgd door een 8 om aan te geven dat de data-buffer 8 bytes groot is. Met canmsg wordt vervolgens de gehele buffer verzonden. In regel 22 halen we onze identifier op en sturen deze naar de console gevolgd door de data die in de array (buffer) is opgeslagen. De inhoud van elke geheugenplaats van de array kan individueel worden opgeroepen door tussen de haakjes het gewenste nummer te zetten. Dit gebeurt in regel 25 t/m 40. De Serial print ( \t ) opdracht geeft een tap tussen de verschillende data bytes. 9

3.2 Programma: Ontvangst data potentiometer Het ontvangen van de CAN-boodschap kan op twee manieren gebeuren. Pollen, d.w.z. het programma is voortdurend bezig om te kijken of de boodschap al binnen is, is één methode. De andere methode is op interrupt-basis. Op het moment dat de boodschap binnen is wordt het hoofdprogramma door middel van een interrupt gewaarschuwd dat de boodschap ontvangen is. De CANcontroller maakt dan de interrupt-pin (INT) laag wanneer de CAN-boodschap is ontvangen. De INT-pin van de CAN controller is verbonden met pin 2 van de Arduino. Wanneer pin 2 in de interrupt-mode staat (attachinterrupt) zal iedere keer wanneer de CAN-boodschap ontvangen wordt het programma naar een zgn. Interrupt Service Routine springen. Na het uitvoeren van deze ISR gaat het programma weer verder waar het was gebleven. Het eenvoudigst is de pol-methode en het nu volgende programma maakt hiervan gebruik om de verzonden potmeterstand op de lcd weer te geven. Programma naam: ontvangst potmeter1.ino Arduino Uno met CAN-BUS Shield, potmeter-data wordt ontvangen m.b.v. de polmethode en de CAN-boodschap wordt weergegeven op de lcd. 1. #include <mcp can.h> 2. #include <SPI.h> 3. #include <LiquidCrystal.h> 4. # define SPI CS PIN 10 5. MCP CAN CAN(SPI CS PIN); // Maak instance CAN van de klas en selecteer CS-pin 6. LiquidCrystal lcd(9, 8, 7, 6, 5, 4);// LCD-klas, LCD-aansluiting voor de CAN-shield 7. byte buf[8]; 8. unsigned int canid; 9. void setup() 10. { 11. lcd.begin(16, 2); //initieer lcd 12. CAN.begin(CAN 100KBPS); // init can bus baudrate = 100k bij 16MHz crystal CAN-controller 13. Serial.begin(9600); // voor weergave console 14. } 15. void loop() 16.{ 17. if(can MSGAVAIL == CAN.checkReceive()) 18. { 19. CAN.readMsgBuf(8, buf); // lees data in buffer-array 20. canid = CAN.getCanId(); // lees identifier uit 21. } 10

//ID op de lcd 22. lcd.setcursor(0, 0); 23. lcd.print( ID: ); 24. lcd.setcursor(3, 0); 25. lcd.print(canid,hex); //buffer op lcd 26. lcd.setcursor(7, 0); 27. lcd.print(buf[0],hex); 28. lcd.setcursor(10, 0); 29. lcd.print(buf[1],hex); 30. lcd.setcursor(13, 0); 31. lcd.print(buf[2],hex); 32. lcd.setcursor(0, 1); 33. lcd.print(buf[3],hex); 34. lcd.setcursor(3, 1); 35. lcd.print(buf[4],hex); 36. lcd.setcursor(6, 1); 37. lcd.print(buf[5],hex); 38. lcd.setcursor(9, 1); 39. lcd.print(buf[6],hex); 40. lcd.setcursor(12, 1); 41. lcd.print(buf[7],hex); 42. } 3.2.1 Vragen en opgaven 1. Upload het programma, draai aan de potmeter en zie dat de veranderende data op de lcd wordt weergegeven. 3.2.2 Toelichting In regel 1 t/m 3 wordt aangegeven welke library s worden gebruikt. Aangezien we hier de CAN-boodschap op de lcd willen weergeven wordt ook de Liquid- Crystal library naar binnen gehaald. In regel 4 en 5 wordt een kopie van de CAN-library opgehaald en wordt de library verteld dat pin 10 wordt gebruikt als Chip Select. In regel 6 wordt een kopie van de lcd-library opgehaald en wordt de library verteld welke aansluitpinnen worden gebruikt. Let er op dat deze verschillen met de eerder gebruikte aansluiting. Zie het betreffende hoofdstuk en verder fig. 8. Zo n kopie van de library class wordt een instance genoemd en heeft de naam gekregen van CAN resp. lcd. In regel 7 en 8 worden de variabelen gedeklareerd. Een buffer variabele van 8 geheugen plaatsen elk 1 byte groot. De canid variabele maken we van het type unsigned int en wordt dan 16 11

220 1 8 10 16 0 16 x 2 LCD 15 0 1 LCD aansluiting 1= Vss 2 = VDD 3 = V0 4 = RS 5 = RW 6 = E 7 = D0 8 = D1 9 = D2 10= D3 11 = D4 12 = D5 13 = D6 14 = D7 15 = A 16 = K CAN BUS SHIELD 7 6 5 4 9 8 GND helderheid 13 12 11 10 9 8 7 6 5 4 3 2 1 0 10k UART GND + CAN BUS Shield I 2 C GND + CAN 5VGND A0 A1 A2 A3 A4 A5 D4 D5 D6 D7 RS E aansluitdraadjes met label Figuur 8: Lcd-aansluiting voor de CAN-BUS Shield. Deze verschilt van de eerdere aansluiting omdat sommige pinnen al door de CAN-shield worden gebruikt. bits groot. Groot genoeg voor de 11-bit grote CAN identifier. Bij extented CAN zullen voor een long unsigned integer moeten kiezen. In de setup() kiezen we de lcd (regel 11) en initiëren de CAN-module en zetten de baudrate op 100 kb/s (regel 12). Als we gebruik willen maken van de weergave op de console dan kunnen we de communicatie met de pc op 9600 bits/s zetten (regel 13). Wordt hier echter niet gebruikt. In de loop bekijken we in regel 17 of de CANboodschap al ontvangen is en zo ja dan slaan we de CAN-data op in de buffer en de identifier in de canid variabele. Regel 19 en 20. Dit voortdurend afvragen of er al een nieuwe boodschap binnen is noemt men dus pollen. Nu rest ons nog de CAN-boodschap op de lcd weer te geven. Dat gebeurt in regel 22 t/m 41. Eerst wordt de positie op de lcd weergegeven met setcursor gevolgd door de weergave van de variabelen op de lcd met lcd.print(). 4 Filteren en maskeren van de CAN-identifier De standaard CAN-boodschap bestaat uit een 11-bit identifier (ID), hexadecimaal van 000h tot 7FFh, gevolgd door maximaal 8 data bytes. We dan laten alle controle-bits buiten beschouwing. Een ontvangende CAN-controller kan de binnenkomende indentifiers onderzoeken om te bepalen of de CAN-boodschap relevant is voor het programma. De controller wacht bijv. op een boodschap met ID 3FFh welke data bevat om bijv. een elektromotor in- of uit te schakelen. 12

De CAN-controller bevat hiervoor filter- en maskeerregisters. Niet relevante CAN-boodschappen kunnen worden genegeerd. Het maskeerregister (MASK) wordt gebruikt om te bepalen welke bits van de identifier worden vergeleken met de bits in het filter. Als een bit in het maskeerregister op 0 wordt gezet dan wordt het overeenkomstige ID-bit automatisch geaccepteerd ongeacht de waarde van het filter-bit. Als een maskeerbit op 1 wordt gezet dan wordt de corresponderend ID-bit vergeleken met de waarde van het filter-bit. Wanneer deze gelijk zijn dan wordt de bit gaccepteerd, in het andere geval wordt de boodschap geweigerd. Een paar voorbeelden maken de functie van het maskeer- en filterregister duidelijk. Voorbeeld 1 We willen alleen identifier 567h of 0101 0110 0111b accepteren. Zet dan de filter-bits op 567h of 0101 0110 0111b en zet de maskeerbits op FFFh of 1111 1111 1111b Wanneer nu een CAN-boodschap arriveert worden de bits aangegeven in het maskeerregister (hier dus allemaal) vergeleken met het filter. Als deze bits identiek zijn wordt de boodschap geaccepteerd. Zo niet dan wordt de boodschap genegeerd. Voorbeeld 2 We willen alleen CAN-boodschappen accepteren met een identifier vanaf 560h tot en met 56Fh of 0101 0110 0000b tot 0101 0110 1111b Zet de filter-bits op 560h of 0101 0110 0000b Zet de maskeerbits op FF0h of 1111 1111 0000b Nu worden alleen de eerste 8 bits vergeleken en de laatste 4 zijn altijd correct. Wanneer nu een CAN-boodschap arriveert moeten alle bits behalve de laatste 4 corresponderen. Voorbeeld 3. We willen alleen boodschappen accepteren met een identifier vanaf 560h tot en met 567h of 0101 0110 000b tot 0101 0110 0111b Zet hiervoor de filter-bits weer op 560h of 0101 0110 0000b Zet de maskeerbits op FF8h of 1111 1111 1000b Wanneer nu een CAN-boodschap arriveert moeten -om de boodschap te accepteren- alle bits behalve de laatste 3 corresponderen. Nu heeft de MCP2515 CAN-controller 2 maskeerregisters en 6 filters. De rangschikking is volgens fig. 9. We willen het allemaal niet te ingewikkeld maken en laten het maskeren buiten beschouwing, d.w.z we zetten alle bits van de maskeerregisters op 1. Het nu volgende programma verzendt een 6-tal identifiers met 8 data bytes. In het bijbehorende ontvangende programma willen we -als voorbeeld- een aantal identifiers door het filteren niet ontvangen. 13

Mask RXM1 Filter RXF2 Mask RxM0 Filter RXF3 Filter RXF0 Filter RXF4 Accept Accept Filter RXF1 Filter RXF5 RXB0 identifier data veld MAB identifier data veld RXB1 Receive RxD Figuur 9: Twee maskeerregisters, Mask 0 en 1 voor resp. filter 0 en 1 en filter 2 t/m 5. 4.1 Programma: Zenden van een te filteren CAN-bericht Program naam: set mask filter zend.ino Deze demo laat het gebruik van maskeren en filteren zien. 6 identifiers met data worden over de CAN-bus verstuurd maar we willen ze niet allemaal ontvangen, We maken een selectie. Zie programma mask filter ontvangst. 1 #include <mcp can.h> 2. #include <SPI.h> 3. #define SPI CS PIN 10 4. MCP CAN CAN(SPI CS PIN); // Set CS pin op pin 10 5. byte buffera [8] = {1,2,0xA, 3, 4, 5, 6, 0x8}; 6. byte bufferb [8] = {1,2,0xB, 3, 4, 5, 6, 0x8}; 7. byte bufferc [8] = {1,2,0xC, 3, 4, 5, 6, 0x8}; 8. byte bufferd [8] = {1,2,0xD, 3, 4, 5, 6, 0x8}; 9. byte buffere [8] = {1,2,0xE, 3, 4, 5, 6, 0x8}; 10. byte bufferf [8] = {1,2,0xF, 3, 4, 5, 6, 0x8}; 11. unsigned int IDA =0x77; 14

12. unsigned int IDB =0x0B; 13. unsigned int IDC =0xA7; 14. unsigned int IDD =0x55; 15. unsigned int IDE =0x02; 16. unsigned int IDF =0xFF; 17. void setup() 18. { 19. Serial.begin(9600); 20. CAN.begin(CAN 100KBPS); 21. } 22. void loop() //weergave op console 23. { 24. CAN.sendMsgBuf(IDA, 0, 8, buffera); 25. Serial.print (IDA,HEX); 26. Serial.print ( \t ); 27. for (int i=0; i<8; i++) 28. { 29. Serial.print(bufferA[i],HEX); 30. Serial.print( \t ); 31. } 32. Serial.println(); 33. delay (500); 34. CAN.sendMsgBuf(IDB, 0, 8, bufferb); 35. Serial.print (IDB,HEX); 36. Serial.print ( \t ); 37. for (int i=0; i<8; i++) 38. { 39. Serial.print(bufferB[i],HEX); 40. Serial.print( \t ); 41. } 42. Serial.println(); 43. delay (500); 44. CAN.sendMsgBuf(IDC, 0, 8, bufferc); 45. Serial.print (IDC,HEX); 46. Serial.print ( \t ); 47. for (int i=0; i<8; i++) 48. { 15

49. Serial.print(bufferC[i],HEX); 50. Serial.print( \t ); 51. } 52. Serial.println(); 53. delay (500); 54. CAN.sendMsgBuf(IDD, 0, 8, bufferd); 55. Serial.print (IDD,HEX); 56. Serial.print ( \t ); 57. for (int i=0; i<8; i++) 58. { 59. Serial.print(bufferD[i],HEX); 60. Serial.print( \t ); 61. } 62. Serial.println(); 63. delay (500); 64. CAN.sendMsgBuf(IDE, 0, 8, buffere); 65. Serial.print (IDE,HEX); 66. Serial.print ( \t ); 67. for (int i=0; i<8; i++) 68. { 69. Serial.print(bufferE[i],HEX); 70. Serial.print( \t ); 71. } 72. Serial.println(); 73. delay (500); 74. CAN.sendMsgBuf(IDF, 0, 8, bufferf); 75. Serial.print (IDF,HEX); 76. Serial.print ( \t ); 77. for (int i=0; i<8; i++) 78. { 79. Serial.print(bufferF[i],HEX); 80. Serial.print( \t ); 81. } 82. Serial.println(); 83. delay (500); 84. } 16

Vragen en opgaven 1. Bekijk via hulpmiddelen en seriële plotter of de CAN-boodschappen op de console verschijnen. 4.1.1 Toelichting Er worden in dit programma 6 CAN-boodschappen verzonden. In de eerste twee regels worden weer de CAN en de SPI library opgeroepen. In regel 4 wordt een instance (kopie) van de library-klas gemaakt waarbij wordt aangegeven dat de Chip Select op pin 10 is aangesloten. In regel 5 t/m 10 worden de boodschapbuffers geïnitialiseerd en gevuld met min of meer willekeurige waarden. 6 identifiers krijgen een variabele naam IDA t/m IDF en worden gevuld met een willekeurig ID-mummer. Regel 11 t/m 16. In de setup wordt de baudrate voor de console alsmede de baudrate voor de CAN-controller vastgelegd. Regel 19 en 20. In de loop worden de 6 verschillende identifiers met de bijbehorende data verzonden en weergegeven op de console. De inhoud van elke buffer wordt met behulp van een for lus op de console weergegeven. Met Serial.print ( \t ) wordt de inhoud van de buffer met tab-afstanden weergegeven. Regel 24 t/m 83. Het nu volgende programma ontvangt de verschillende CAN-boodschappen en biedt de mogelijkheid om naar keuze identifiers te filteren. Bijzonder is dat we in het programma de maskers en filters moeten behandelen alsof we met extended CAN werken. 4.2 Programma: ontvangen met behulp van maskeren en filteren Programma naam: set mask filter ontvangst.ino Hoewel we hier het standaard frame gebruiken, moeten de maskers en filters als 29 bits (extended) worden behandeld. Dit heeft te maken met het aantal registers dat gevuld moet worden. Plaatsen we een 1 als tweede byte dan wordt er gefilterd. 1. #include <mcp can.h> 2. #include < SPI.h > 3. #include < LiquidCrystal.h> 4. long unsigned int Id; 5. byte buf[8]; 6. MCP CAN CAN(10); // CS pin wordt 10 7. LiquidCrystal lcd(9, 8, 7, 6, 5, 4);// aangepaste pinbezetting 8. void setup() 9. { 17

10. lcd.begin(20, 2); 11. CAN.begin(CAN 100KBPS); // init CAN bus: baudrate = 100kb/s // set mask, vergelijk alle 29 bits 12. CAN.init Mask(0,0, 0x1FFFFFFF); // Er zijn 2 mask-registers in de mcp2515 (0 en 1, beiden moeten met 1-nen worden gevuld) 13. CAN.init Mask(1,0, 0x1FFFFFFF); // 7FF = 11 bits identifier en 1FFF FFFF 29 bits identifier // set filter, 2e byte; 0 filter voor standaard frame laat dan door. //0 = standard; 1 = extended frame laat niet door 14. CAN.init Filt(0, 1, 0x00000077);// 0x77 2 filters voor mask 0 15. CAN.init Filt(1, 0, 0x00000002);// 0x02 16. CAN.init Filt(2, 0, 0x000000A7);// 0xA7 4 filters voor mask 1 17. CAN.init Filt(3, 1, 0x00000055);// 0x55 18. CAN.init Filt(4, 1, 0x0000000B);// 0x0B 19. CAN.init Filt(5, 0, 0x000000FF);// 0xFF 20. } 21. void loop() 22.{ // controleer of boodschap wordt ontvangen 23. if(can MSGAVAIL == CAN.checkReceive()) 24. { 25. CAN.readMsgBuf(8, buf); // lees data in buffer-array 26. Id= CAN.getCanId(); // lees identifier uit op lcd 27. lcd.setcursor(0, 0); 28. lcd.print ( ); // wis oude tekst 29. lcd.setcursor(0, 0); 30. lcd.print(id, HEX); 31. for(int i = 0; i< 16; i=i+2) // print de data 32. { 33. lcd.setcursor(i,1); 34. lcd.print(buf[i], HEX); 35. } 36. delay (50); 37 } 38 } 18

4.2.1 Vragen en opgaven 1. Verander het programma zodanig dat alleen de Identifiers 0x02, 0x0B en A7 worden doorgelaten. 4.2.2 Toelichting In regel 1 t/m 3 halen we de drie library s weer binnen. Aangezien we hier werken met extended identifiers maken we de variabele van het type long unsigned int en uiteraard hebben we weer een buffer variabele. Regel 5. In regel 6 maken we een instance (kopie) van de CAN-library en laten de class weten dat de Chip Select aan pin 10 zit. De lcd die we gaan gebruiken gebruikt de aangegeven data-pinnen in regel 7. In regel 10 geven we aan dat we weer te maken hebben met een 20 x 2 lcd en we zetten in regel 11 de CAN-controller op 100 kbits/sec. In regel 12 en 13 vullen we de twee maskeerregisters met enen. In regel 14 t/m 19 geven we de identifiers aan die we (eventueel) willen filteren. Het eerste bit genummerd van 0 t/m 5 geven de filters weer en het tweede bit geeft aan of de identifier al dan niet gefilterd wordt. In de loop (vanaf regel 21) worden de CAN-boodschappen binnengehaald en weergegeven op de lcd. In regel 28 wordt de oude tekst gewist. Het aantal spaties tussen de aanhalingstekens geeft het aantal te wissen tekens aan. In de for loop (regel 21) zien we dat de variabele i steeds met 2 wordt verhoogd. Dit is gedaan om een teken over te slaan. 4.2.3 Aanvullend materiaal 1x Arduino Uno 2x Arduino CAN-shield 3x 10k lineaire potmeter 1 x LCD 16 x2 set draadjes, male-male, female-female, female-male (20 cm) 19