dinsdag 28 januari 2020

Software - Who am I

Waarom één microcontroller gebruiken als het er ook méér kunnen zijn. Da's natuurlijk geen doel op zich, maar wel een resultaat van de gemaakte keuzes. Elke node op de CAN-bus wordt gevormd door een gelijke DevKit voorzien van een microcontroller van het type ESP32:

ESP32 DevKit

De pinnen van de node worden gebruikt voor het aansluiten van Inputs en Outputs (I/O). Eenvoudige I/O van het type GPIO (General Purpose Inputs/Outputs), maar ook I/O voor de CAN-bus en pinnen voor de stroomvoorziening. Veel van de pinnen hebben speciale functies die deels te configureren zijn, maar ook deels ongewijzigd moeten blijven. Nader onderzoek resulteert in het volgende schema:

Fysieke I/O

Van de 30 pinnen blijven er relatief weinig over om vrij te gebruiken. In de kolommen met de naam Functie staat <spare> vermeld als de pin vrij is. Enkele pinnen hebben al een vaste functie gekregen die voor élke node gelijk is:
  • PIN34, PIN35, PIN36 en PIN39 zijn pinnen die alleen als Input te gebruiken zijn. Drie van deze pinnen worden ingezet om de node te identificeren. Hierover zometeen meer.
  • PIN04, PIN05, PIN12 en PIN15 zijn zogenaamde strapping-IO's en hebben tijdens het opstarten een speciale functie. Er wordt geadviseerd om ze met rust te laten (floating).
  • GND (2x), VIN en 3V3 dienen voor de voeding.
  • PIN01 en PIN03 (resp. TXD0 en RXD0) zijn in gebruik voor het programmeren van de node.
  • PIN16 en PIN17 worden ingezet voor de koppeling met de CAN-bus.
  • PIN02 is intern verbonden met de blauwe LED op de DevKit. Deze zal gebruikt worden om activiteit op de CAN-bus te signaleren.
Uiteindelijk blijven er dertien pinnen over om ingezet te worden voor diverse functies zoals het uitlezen van schakelaars of het aansturen van lampen. Dat lijkt best nog veel, maar zeker bij het dashboard red je het daar niet (zomaar) mee. Denk maar eens aan alle schakelaars en indicatielampjes en je gaat al snel over de dertien heen. Dat betekent dat een list bedacht moet worden of dat er een node bijgeplaatst moet worden. In een later bericht meer over dit dilemma.

Hierboven werden al de drie identificatiepinnen (PIN34, PIN36 en PIN39) genoemd. Die worden gebruikt om de node te identificeren. Alle nodes zijn namelijk gelijk. Niet alleen hardwarematig, maar ook softwarematig wil ik ze gelijk houden. Alle nodes krijgen dus dezelfde software, maar moeten wel verschillende functies uitvoeren. Bij het opstarten worden de drie pinnen uitgelezen en op basis hiervan worden sommige functies in de software wel of niet geactiveerd. De drie pinnen kunnen elk aan 0 volt of 3.3 volt gekoppeld worden en zo ontstaan er acht verschillende identificatiecodes (binair: 000, 001, 010, 011, 100, 101, 110 en 111). Dat betekent dus dat er op deze manier maximaal acht nodes mogelijk zijn. Lijkt me genoeg voor een Burton.

Voor de liefhebbers een stukje C-code waarmee de drie identificatiepinnen uitgelezen worden:

Functie "whoAmI".

De software wordt ontwikkeld in Visual Studio Code met de plug-in PlatformIO. Een prachtige combinatie waarmee vrij eenvoudig software voor diverse microcontrollers ontwikkeld kan worden. Voor diegene die al eens met de Arduino IDE gewerkt hebben, stap gerust over op PlatformIO. Daar ga je geen spijt van krijgen. Om de softwarefuncties te testen zijn twee nodes op een breadboard geplaatst. Hieronder een testopstelling met de verlichtingsschakelaar aan de ene node en de lampen (hier blauwe LED's) aan de andere node. Lijkt al snel een onoverzichtelijke spaghetti op zo'n breadboard.


Testopstelling. Het geel/oranje kabeltje is de CAN-bus.

Inmiddels is er al heel wat meer software geschreven waarover nog wel wat berichtjes gaan volgen. De basisopzet is gereed maar het is nog lang niet klaar. Morgen komt - als het goed is - de hoge voorruit binnen. Fijn, want die heeft wel even op zich laten wachten.

donderdag 9 januari 2020

CAN-bus - Deel 2

Mijn enthousiasme voor de CAN-bus heb ik in het vorige blogbericht niet onder stoelen of banken geschoven. De conclusie is dat het hier om een efficiënte en zeer betrouwbare communicatieverbinding gaat. Maar hoe gaat deze bus ingezet worden in mijn Burton. Hiervoor zijn in ieder geval twee belangrijke vragen te beantwoorden:
  1. Wat voor berichten ga ik versturen?
  2. Wat voor apparatuur ga ik toepassen?
De eerste vraag heeft natuurlijk alles te maken met de onderdelen binnen de Burton die via de CAN-bus aangestuurd gaan worden. In eerste instantie denk ik dan aan de verlichting en de bediening hiervan. Er zijn dus CAN-berichten nodig om alle lampen aan en uit te schakelen en hier misschien nog wel wat andere dingen mee uit te halen (spoiler alert).

Een CAN-bericht bevat naast de zaken uitgelegd in het vorige blogbericht o.a. nog een datablok. Hierin kan maximaal 8 bytes aan data verstuurd worden. Hoeveel data-bytes in het uiteindelijke bericht zitten wordt bepaald door de controle-bits. Met vier van de vijf controle-bits (het vijfde bit wordt niet gebruikt) wordt de lengte van het datablok (in aantal bytes) bepaald.


Het volledig standaard CAN-bericht op schaal (klik op het plaatje om het te vergroten).

Wat duidelijk wordt is dat het datablok het grootste deel van het CAN-bericht uitmaakt. Maar zoals in het plaatje aangegeven wordt, kan het datablok ook lengte 0 hebben. Da's fijn want om lampen aan en uit te zetten is niet zoveel data nodig. Maar hoe gebruiken autofabrikanten de CAN-berichten? Er zijn aardig wat pogingen ondernomen om de CAN-berichten van diverse automerken te reverse engineeren, omdat die fabrikanten hier niet mee te koop lopen. Wat mij daarbij steeds weer opvalt is dat er niet zo heel veel structuur zit in die berichten. Vaak worden maar relatief weinig berichten (lees: identificatiecodes) ingezet, maar wel met grote datablokken. Dit terwijl er méér dan 2000 identificatiecodes mogelijk zijn. In die datablokken worden veel bits gebruikt om zaken aan en uit te zetten of te monitoren. Zou ik dezelfde strategie volgen, dan heb ik met slechts één CAN-bericht de beschikking over 8 x 8 = 64 bits; méér dan genoeg bits om alle lampen van een Burton aan en uit te schakelen.

Ik moet dus een keuze maken: weinig berichten met relatief veel data, of relatief veel berichten met weinig data. Voorbeeld: het aansturen van het groot licht. Ik kan hiervoor één berichtidentificatie reserveren. Laten we zeggen berichtnummer 100. Dit bericht krijgt één databyte waarvan het eerste bit gebruikt wordt om de lamp aan (bit = 1) of uit (bit = 0) te schakelen. De alternatieve opzet zou zijn om gebruik te maken van twéé berichtnummers - 100 en 101 - beide zonder databytes. Berichtnummer 100 schakelt het groot licht aan en berichtnummer 101 schakelt het groot licht uit. Dat is toch om het even zou je zeggen, en dat is natuurlijk ook zo. Ik neig er trouwens naar om voor de alternatieve opzet te kiezen. Elke 'discrete opdracht' (lees: aan/uit) krijgt zijn eigen berichtnummer zonder datablok. Alleen als iets analoog aangestuurd of uitgelezen wordt, zal het bericht ook één of meerdere bytes bevatten voor de gewenste of actuele waarde.

Nu deze principiële keuze gemaakt is kan ik een lijst met berichtindentificatienummers (3 x woordwaarde) en bijbehorende functies gaan maken, rekening houdend met het feit dat lage nummers voorrang hebben op hoge nummers. Spreadsheetje vullen dus:

Eerste berichten in de lijst.

Het lijstje hierboven is nog heel prematuur. De 16 laagste berichtnummers heb ik nog even open gelaten. Verder zijn er nog wat nummers die niet gebruikt mogen worden:
  • 2032..2047: beginnen binair allemaal met zeven enen (111 1111 xxxx). Heeft vast iets te maken met de zeven recessieve stopbits.
  • 2015..2031: OBD (On Board Diagnostics) requests en responses. Heb ik niet echt mee te maken, maar toch maar vrij houden.
Blijven er nog ruim 2000 berichtnummers over. Méééér dan genoeg.


De tweede vraag (wat voor apparatuur ga ik toepassen) sluit wel een beetje aan op het vorige. Een van de hoofddoelen van CAN-bus is het reduceren van de hoeveelheid koperdraad in de auto. Het lijkt erop dat vooral de verlichting aangestuurd gaat worden en die zit zo'n beetje op elke hoek van de auto. Verder zitten er veel knoppen en lampjes e.d. bij het dashboard. Een mooie centrale plek. Dus op de volgende locaties komen CAN-nodes:
  • Vóórin, onder de motorkap. Misschien eentje rechts en eentje links, of is dat overkill?
  • Achterin, in de achterbak. Misschien ook wel eentje rechts en eentje links.
  • Centraal, achter het dashboard.
  • Mogelijk nog eentje bij het schutbord, onder de motorkap.
Maximaal zes nodes op de bus. En dan een mooi kabeltje daartussen. Bijvoorbeeld de speciale buskabel van Lapp:

Buskabel, maar dan tweedraads.


Doorsnede van de buskabel.

En dan de nodes zelf. Die spreken natuurlijk het meest tot de verbeelding. Een microcontroller is hier op zijn plek. Liefst eentje met een CAN-interface aan boord. Zo is er de PIC18F26K83 van Microchip, een 8-bits controller. Of - aan de andere kant van het spectrum - de ESP32 van Espressif. Zoals de naam al doet vermoeden, een 32-bits controller.

Een van de ESP32-modules.

Deze module wordt aangeboden in veel verschillende varianten en is voor de zelfbouw-hobbyist beschikbaar op een ontwikkelbord. De ESP32 heeft aardig wat mogelijkheden onder de motorkap. Zo is deze microcontroller standaard voorzien van bijvoorbeeld wifi, bluetooth, CAN-bus, I2C, een groot aantal GPIO's en nog enkele interfaces. Het is een dual-core processor met een real-time besturingssyteem (FreeRTOS) aan boord. Multi threaded programmeren wordt zo wel heel 'gemakkelijk'. Hoewel ook hier weer het woord overkill op zijn plaats is, wordt dit 'm. In de volgende variant:

ESP32 DevKit

Zo, de hoofdonderdelen van het CAN-bus-systeem zijn bepaald. In volgende blogberichten komen nog de software en bijbehorende tools aan bod. En misschien ook nog wel wat over de bouw van de Burton zelf, want die is nog lang niet klaar ;-).

dinsdag 7 januari 2020

CAN-bus - Deel 1

Een tijdje terug heb ik mezelf voorgenomen om de Burton te gaan voorzien van een CAN-bus. Niet omdat het moet, maar omdat het can dus... Zo, de eerste foute woordgrap is alweer gemaakt dit nieuwe jaar.

Nee, niet zo'n bus (bron: www.volkswagen.nl).

CAN staat voor Controller Area Network en is door Bosch ontwikkeld om elektronische systemen in een voertuig aan elkaar te koppelen en de hoeveelheid bedrading te verminderen. CAN maakt gebruik van een tweedraads bus-systeem en is als eerste door Mercedes gebruikt in een productie-auto. In de automobielindustrie is de CAN-bus niet meer weg te denken, maar inmiddels heeft de CAN-bus zich ook bewezen in de industriële automatisering, medische apparatuur, elektrische fietsen en volgens een enkele website ook in het elektronische schakelsysteem van Shimano.

Een CAN-bus is vooral nuttig als de complexiteit van de elektronische systemen toeneemt. Bij een Burton is dat toch niet echt (euh, echt niet) het geval hoor ik je denken... En dat is natuurlijk ook zo. Voor de eenvoudige systemen in een Burton is een CAN-bus behoorlijk overkill. Maar omdat de Burton voor mij het ultieme over-the-top hobbyproject is, kan de elektronica natuurlijk niet achter blijven. Dat moet iets speciaals worden. Bovendien: adel verplicht!

Een auto is voor elektronica zo'n beetje de meest vuile omgeving die je je kunt voorstellen. Dus het wordt een hele uitdaging om hier op een goede manier mee om te gaan. De betrouwbaarheid van het geheel moet natuurlijk hoog worden. Iets waar in het ontwerp vanaf het begin rekening gehouden moet worden. De CAN-bus heeft het in zich om zich in zo'n vuile omgeving goed staande te houden. Op verschillende manieren wordt de foutgevoeligheid van het systeem gereduceerd. Enkele elektrische eigenschappen waardoor storingen worden voorkomen:
  • De bus bestaat uit twee draden - CAN-H en CAN-L. De digitale nullen en enen van het protocol worden vertaald naar een spanningsverschil tussen de twee draden. Een storingspuls die opgepikt wordt door de ene draad, wordt naar alle waarschijnlijkheid óók opgepikt door de tweede draad. Het spanningsverschil tussen de draden blijft nu gelijk hetgeen een storing op de bus voorkomt.
  • De twee draden worden getwist (twisted-pair) waardoor magnetische invloeden (en de resulterende stroompjes) zichzelf uitdoven.
  • De bus wordt aan twee zijden afgesloten met een weerstand (afsluitweerstand) van 120 ohm, passend bij de impedantie van de (juist gekozen!) kabel. De kabel wordt nu schijnbaar oneindig lang wat reflecties van signalen aan het eind van de kabel voorkomt.

Schematische voorstelling CAN-bus.


Niet alleen elektrisch worden storingen voorkomen, ook het protocol zelf heeft enkele mooie foutcontroles en foutreducerende eigenschappen aan boord. Het CAN-busprotocol is trouwens anders dan heel veel andere communicatieprotocollen niet gebaseerd op berichtverkeer tussen een specifieke zender en een geadresseerde ontvanger. Nee, op de CAN-bus heeft een node géén adres. Elke node kan in principe berichten op de bus plaatsen. Alle node's luisteren naar de berichten die langs komen en doen hier iets mee als zij ze interessant vinden. Maar wat nu als twee nodes tegelijkertijd een bericht gaan plaatsen? Dan gebeurt er iets wat in mijn ogen het meest geniale is van het hele protocol. Er wordt een prioriteitsgevecht gehouden. De node die dit gevecht wint, mag zijn bericht afmaken; de node die het gevecht verliest moet even zijn mond houden.

Om te begrijpen hoe dit gevecht in zijn werk gaat moet je weten dat elk bericht een identificatiecode heeft. Een getal van 11 bits *) waarmee het bericht geïdentificeerd wordt. De node die het bericht met getalsmatig de laagste identificatiecode op de bus probeert te zetten wint het gevecht van een node die een bericht met een hogere identificatiecode probeert te versturen. Maar dan zonder dat ze beide de identificatiecode eerst in zijn geheel kenbaar maken. Hoe dat kan heeft te maken met de manier waarop bits (nullen en enen) op de bus geplaatst worden:
  • Als een node een 1 (één) wil plaatsen laat hij de CAN-H en CAN-L als het waren vrij zweven. De spanning op de twee draden zal dan ergens in het midden tussen de 0 volt en 5 volt gaan hangen. Op zowel de CAN-H- als de CAN-L-draad staat dan een ongeveer gelijke spanning. De spanning tussen CAN-H en CAN-L is dan nagenoeg 0 volt.
  • Als een node een 0 (nul) wil plaatsen zal hij de CAN-H (via een weerstand) aan de 5 volt, en de CAN-L (via een weerstand) aan de 0 volt hangen. Er ontstaat een spanning tussen de CAN-L- en CAN-H-draad van ongeveer 2 volt.

Dominante en recessieve bits op de CAN-bus.


Stel dat twee CAN-nodes (node A en node B) gelijktijdig beginnen met het plaatsen van een eigen bericht op de bus. Dan zijn er in principe bij elke achtereenvolgend bit vier mogelijkheden:
  • Als node A een 0 plaatst en node B een 0, dan zal er een resulterende 0 op de bus verschijnen. 
  • Als node A een 1 plaatst en node B een 1, dan zal dit resulteren in een 1 op de bus. Tot dusver niets vreemds.
  • Als node A een 1 plaatst en node B een 0, dan gebeurt er iets anders. Node A zal met de 1 de bus vrij laten zweven, maar node B trekt met de 0 de twee buslijnen uit elkaar. Resulterend in een 0 op de bus. De 0 overheerst over de 1. In mooie woorden: de 0 van node B is dominant, de 1 van node A is recessief
  • Als node A een 0 plaatst en node B een 1, gebeurt precies het omgekeerde.
Als beide nodes dus gelijktijdig een eigen bericht met nullen en enen op de bus proberen te plaatsen, zal er een moment aanbreken waarbij het bericht van één van beide nodes niet meer gelijk zal zijn aan wat er daadwerkelijk op de bus verschijnt. Nu is het zo dat een node elk bit dat er op de bus verschijnt ook gelijktijdig terugleest. En nu komt het geniale: op het moment dat een node ziet dat het bit op de bus anders is dan hij zelf wilde plaatsen, dan stopt die node met 'praten' en heeft als het ware het gevecht verloren. De winnende node gaat gewoon verder met het plaatsen van de rest van zijn bericht op de bus. En het mooie is, er wordt geen moment tijd verloren.

Samenvattend:
  • Er zal altijd maar één node op een bepaald moment een volledig bericht op de bus plaatsen.
  • Berichten met een lage identificatiecode hebben voorrang op berichten met een hogere identificatiecode (een 0 is namelijk dominant t.o.v. een 1).
Omdat er geen geldende afspraken zijn vastgelegd over de identificatiecodes (elk automerk heeft zo zijn eigen indeling), kun je zelf een indeling maken. Hierover in een volgend blogbericht meer. Een CAN-bericht bestaat trouwens uit méér dan alleen een identificatiecode. Zo bevat het bericht ook een CRC (Cyclic Redundancy Checksum) van 15 bits (plus één afsluitend bit) die door de zender berekend wordt op basis van alle voorgaande bits in het bericht. De ontvangende node doet hetzelfde en vergelijkt zijn resultaat met de CRC die berekend is door de zender. Zijn ze gelijk, dan wordt het bericht geaccepteerd. Is er ergens een bit veranderd tijdens het versturen, dan zullen de CRC's van zender en ontvanger niet gelijk zijn en wordt het bericht niet geaccepteerd door de ontvanger.

Aansluitend aan de CRC zet de zender een 1 op de bus. Het acknowledge-bit. Als er een ontvangende node aanwezig is die het bericht tot en met de CRC correct heeft ontvangen, zal deze het recessieve bit naar 0 veranderen. Zo vertelt hij de zendende node dat het bericht (in ieder geval bij één node) succesvol is gearriveerd. Blijft het acknowledge-bit 1, dan weet de zendende node dat het bericht herhaald moet worden. Samen met nog wat methodes voor het afhandelen van error's maakt dit van CAN-bus een van de meest betrouwbare en meest elegante bussystemen op de markt.

Een volledig CAN-bericht bevat nog wat overige bits en bytes. In een volgend blogbericht ga ik in op het gebruik van de CAN-berichten voor de Burton. Dan komen de control bits en de data bytes aan bod.

Een volledig standaard CAN-bericht.



*) De specificatie CAN 2.0 Part A maakt gebruik van het standaard frame met een 11-bits identificatiecode. Part B van de specificatie maakt gebruik van het extended frame met een 29-bits identificatiecode.

zondag 5 januari 2020

Lichtschakelaar

Het dashboard van de Burton is waarschijnlijk voor veel bouwers het onderwerp waar de meeste creativiteit bij komt kijken. Klokjes, schakelaars, lampjes, elektronica, enz... Klassieke of moderne look? En heb je al gekozen voor de onderdelen, dan moet er nog een keuze gemaakt worden voor de indeling. Misschien moet het dashboard wel houten of aluminium elementen gaan bevatten. Allemaal keuzes die door mij ook nog niet (definitief) gemaakt zijn. Ik zit er wel aan te denken om enkele elementen uit de Eend te gaan hergebruiken.

Zo wil ik ook graag op een-of-andere manier de lichtschakelaar gaan inzetten. Een multifunctioneel apparaat waar alle (standaard) verlichting én de claxon mee bediend wordt. Mooi, want ik wil eigenlijk niet zo heel veel knoppen op het dashboard. De schakelaar ziet er een beetje vermoeid uit, dus die heeft een opfrisbeurt nodig.


De lichtschakelaar.


De schakelaar is vrij gemakkelijk uit elkaar te halen. Wel mooi hoe de schakelaar drie bewegingen combineert:
  1. Draaibeweging: 0 (uit), V (Ville, binnen bebouwde kom) en R (Route, buiten bebouwde kom).
  2. Omhoog en omlaag (of naar voren en naar achteren): wisselen tussen stadslicht en dimlicht (in stand V) of wisselen tussen groot licht en dimlicht (in stand R).
  3. Op de knop drukken: claxon.

Enkele boutjes missen nog op de foto...

Het tonnetje linksonder op bovenstaande foto bevat een patroon van geleidende strookjes/vlakjes waarmee de boordspanning van 12 volt geschakeld wordt. Ik ben van mening dat de schakelaar niet juist in elkaar zit. Het ringetje links van het tonnetje zit op de verkeerde plek. Lees vooral verder...

De contacten.


De twee contacten links op de foto schakelen de claxon. Het middelste contact zet 12 volt op het tonnetje. De drie contacten rechts schakelen het stadslicht, het dimlicht en het groot licht.


Opgefrist.


Het stangetje heb ik in de accuboormachine geklemd en met een schuurpapiertje en daarna met wat polijstmiddel bewerkt. Ziet er weer glimmend uit, maar da's geen chroom meer. Dus ik moet nog iets bedenken om het staal te beschermen. Ook het tonnetje heb ik in de boormachine geklemd en met een scotch brite bewerkt.


Daar hoort het ringetje te zitten.

Op bovenstaande foto zit het ringetje (naar mijn bescheiden mening) wél op de juiste plek. Tussen het palletje en de twee bladveertjes. Het palletje blijft zo niet meer 'haken' achter de bladveertjes. Nu snap ik pas waarom de schakelaar in sommige standen altijd een beetje hakerig draaide. En wat draait hij nu lekker soepel zeg! Die wil ik hoe dan ook in de Burton terug zien. Tenzij ik weer op andere gedachten kom, natuurlijk...


Ziet er weer bruikbaar uit.


De schakelaar wordt aangesloten via de kant die naar het dashboard gericht is. Normaliter wordt het volledige vermogen van de verlichting (en de claxon) geschakeld. Beetje off-topic, maar onderschat niet hoe veel dit is. Een snel rekensommetje als het groot licht aan staat:
  • Groot licht: 2 x 60 watt
  • Stadslicht: 2 x 5 watt
  • Achterlicht: 2 x 5 watt
  • Dashboard, kentekenplaat enz: ~10 watt
Da's in totaal al snel 150 watt wat overeen komt met ruim 12 ampère. En dan ben ik vast nog wat vergeten. Aanhanger of zo... Al die amps gaan door de contacten heen. Geen wonder dat die schakelaar wat warm kan worden. Zeker als de contacten niet meer helemaal schoon zijn en een overgangsweerstand naar het tonnetje hebben. Bij mijn installatie zal het allemaal niet zo'n vaart lopen. De schakelaars worden aangesloten op een microcontroller, dus daar loopt geen noemenswaardige stroom meer door.

Op onderstaande foto is te zien hoe de lichtschakelaar aangesloten wordt. Een beetje typisch, maar daar staat Citroën om bekend.


Aansluitingen.

  • A: Boordspanning, 12 volt.
  • B: Claxon.
  • C: Stadslicht.
  • D: Groot licht.
  • E: Dimlicht.

Er zijn meldingen van auto's waarbij D en E omgewisseld zijn. Klinkt eigenlijk wel logisch, want dan schakel je na één keer draaien tussen stadslicht en groot licht en na twee keer draaien tussen dimlicht en groot licht. Voelt intuïtiever aan, maar is niet volgens de oorspronkelijke gedachte van Citroën. De vraag is of dat belangrijk is voor een Burton-bouwer?