CARduino - Theoretische achtergrond

Theoretische achtergrond

De code waarin je gaat schrijven als je Arduino gaat programmeren is een variatie van de bestaande codetalen C en C++. Om onze uiteindelijke code te kunnen begrijpen is hier een uitleg van de belangrijkste begrippen. Aan de hand van deze begrippen en de aantekeningen aan de zijkant van de code zou een leek in programmeren onze redenatie in de code moeten volgen. Eerst volgt een snelle uitleg over de opbouw van een code.

Code:

 

/*

Blink

Lichtje brandt voor een seconde, lichtje isuit voor een seconde en dit herhaalt zich.

Dit is de eerste code die je leert begrijpen.

*/

 

// Geef de led een naam: je koppelt de led aan een pin op je Arduino board. Je kunt nu het woord led gebruiken in je code. Zou je dit niet doen dan moet je overal in je code het getal 13 gebruiken.

int led = 13;

 

//void setup wordt niet herhaald. Als de code wordt geüpload voert de Arduino slechts eenmaal deze commando’s uit. Dit gebeurt ook als je Arduino wordt gereset.

void setup()

{

pinMode(led,OUTPUT);

//geeft aan dat de led een output is, dat wil zeggen dat je er signalen naar toe stuurt en dat er niet gereageerd mag worden op signalen die er vanaf komen.

 

 

} // De haakjes geven aan dat binnen de haakjes de code staat die uitgevoerd moet worden.

 

 

// the loop routine wordt in tegenstelling tot de setup wel keer op keer herhaald.

void loop()

In bovenstaande code staat met ‘//’ (twee schuine streepjes) een aantekening weergegeven. Deze staat hier in een andere kleur om duidelijk te maken wat code is en wat niet. Als men een echte code zou krijgen geven de aantekeningen veel handige informatie over wat welke regel doet en op deze manier kan men de denkstappen van de programmeur volgen. In deze code hebben we een paar begrippen al uitgelegd, maar dit voorbeeld was vooral om de algemene opbouw van een code te laten zien. 

Het begin

Om te beginnen met code schrijven, leer je eerst hoe een code eruit moet zien. Bij de Arduino gebruik je altijd de volgende volgorde (ook te zien in de voorbeeldcode op pagina 4): eventueel extra informatie bovenaan, setup en daarna loop. Je kunt ook nog extra functies toevoegen, dit wordt onder het kopje “Overig” op pagina 7 verder uitgelegd.

Je begint met het hernoemen van je pins (ingangen op je Arduino board) van een nummer naar een naam of functie, in dit geval dus led. Dit doe je met int. Int of voluit integer gebruik je om variabelen te declareren van het type int. In ons stuk boven de setup hebben wij twee soorten variabelen. De ene is wat de naam doet vermoeden, een variabele die verandert, omdat hij in ons geval gemeten wordt. Bij ons zijn dat dan ook de variabelen cm, Leftcm, Rightcm. De andere soort variabele is een zogenaamde constante. Dat zijn variabelen die constant hetzelfde blijven en dus nooit van waarde veranderen. Bij ons zijn dat Forward, Backward, Right en Left. Alle variabelen moeten gedeclareerd worden voordat ze opgeroepen kunnen worden in het programma. De variabelen die wij declareren in onze code zijn vaste variabelen, ook wel globale variabelen. Deze globale variabelen moeten voor de setup worden ingevoerd. Anders werken ze als lokale variabelen en werken ze alleen binnen hun functie. Deze lokale variabelen worden ook wel tijdelijke variabelen genoemd.

 

In het stuk van de code boven de setup voeg je ook libraries toe. Deze “bibliotheken” voegen een voorgeprogrammeerde code toe die met bepaalde commando’s kan worden gebruikt. 

Een voorbeeld hiervan is een servo, een kleine motor die 180 graden kan draaien. Met een servo library kun je veel makkelijker de servo naar een bepaald aantal graden laten draaien. Zonder servo library zal jij zelf moeten timen hoe lang je een elektrisch signaal moet sturen om een draaibeweging van een bepaald aantal graden te verwezenlijken. Om een library toe te voegen aan je code gebruik je het commando #include (=toevoegen). De vertaling geeft een duidelijk idee wat dit commando doet. Dit commando wordt alleen gebruikt om libraries toe te voegen. 

Setup

In je setup zet je de dingen die slechts een keer aangegeven hoeven te worden, deze worden ook maar 1 keer uitgevoerd. Zoals een bepaalde pin als input of output aangeven. Dit doe je met pinMode. Hierdoor kan men of signalen ergens naar toe zenden (output) of signalen van deze pin ontvangen (input). Bij output kun je denken aan een pin die stroom geeft om een led te laten branden. En bij een input kun je denken aan een pin die een signaal dat hij van buiten (bijvoorbeeld een knopje) krijgt en aan de Arduino doorgeeft. 

 

Ook serial commando’s komen voor in de setup. Het serial commando gebruik je voor communicatie tussen de Arduino en de computer. Als je in het programma zit waar je de code schrijft, kun je een scherm op je computer openen, waarmee je waarden af kan lezen. Hierdoor kun je bijvoorbeeld kijken hoeveel cm je sensor afleest of je kunt je Arduino als rekenmachine gebruiken en de antwoorden op je computerscherm laten verschijnen. 

In onze code hebben we het vooral gebruikt om te kijken of alles goed werkte. Door de seriële verbinding met de computer te maken, konden we kijken of de sensor goed draaide met de servo als je te dicht bij kwam. Ook konden we de verbinding gebruiken om de auto te testen. 

In een oudere code hadden we namelijk de auto uitgezet, maar een serial.print met de tekst ‘auto naar rechts’ als hij de Rightturn had uitgevoerd en ‘auto naar links’ als hij de Leftturn had uitgevoerd, hierdoor konden we zien of de code vloeiend werkte. 

In de setup gebruik je eigenlijk alleen ‘Serial.begin(getal)’. Dit vertelt de Arduino een verbinding te beginnen met je computer. Het getal tussen haakjes (zie bijlage voor voorbeelden) is de snelheid van deze “praat”verbinding met je computer. Dit getal is in de eenheid baud (bits per seconde).

 

In het setup gedeelte koppel je ook de servo aan een bepaalde pin. Dit gebeurt met het commando servo.attach(nummer van de pin).

Loop

Hier staat meestal de grootste hoeveelheid tekst en zie je ook de meeste commando’s. De loop wordt meestal oneindig vaak doorlopen. Daarom heeft het hier veel meer nut dan in de setup om het commando delay te gebruiken. De loop wordt pas uitgevoerd nadat de setup is doorlopen.

 

De commando’s digitalWrite en digitalRead worden gebruikt afhankelijk van het soort pin waar zij bij horen (input of output). ‘DigitalWrite’ zend een signaal en hoort dus bij de output en digitalRead leest een signaal af en hoort dus bij input. 

 

In het loop gedeelte kan men met het serial commando de Arduino opdragen stukken tekst naar je computer te sturen, dit kan ook in een willekeurige andere functie. Het serial commando is dan ‘Serial.print’ of ‘Serial.println’. De ln staat voor line oftewel regel, hiermee sluit je één regel af en zorg je dat de volgende Serial.print op een andere regel is. De ‘Serial.print’ is alleen handig als de Arduino aan je computer gekoppeld zit anders heeft dit commando geen nut. Maar als de Arduino wel aan je computer verbonden is kan je met de ‘Serial.print’ testen of je sensor goed werkt of je kunt een soort rekenmachine maken(zie bijlage).

 

In de loop wordt ook veel gebruik gemaakt van het if statement. Het commando hiervoor is ‘if’ . Met een if statement kan men voorwaardes (als, dan) stellen waaraan voldaan moet worden voordat een bepaalde handeling uitgevoerd wordt. Hierin kan men ook het ‘while’ statement gebruiken. Tijdens die handeling moet aan de achter de while gestelde voorwaarde voldaan worden. Wordt er niet aan die waarden voldaan, dan stopt de handeling. Het verschil tussen de twee is dat bij het if statement van tevoren aan de waarden voldaan moet worden en daarna niet meer, maar bij het while statement moet er constant aan de voorwaarden voldaan worden. Aan het einde van je if statement kan je ook een ‘else’ invoeren, voor het geval dat er niet aan de if voorwaarden voldaan wordt. Wat er dus achter else staat wordt uitgevoerd als er niet aan de if voorwaarden is voldaan. Bij onze code is het noodzakelijk dat er een else staat, maar er kan ook voor gekozen worden deze niet toe te voegen en dan doet de Arduino gewoon niks.

 

Het ‘do’ commando komt ook voor in de loop en is ook vrij makkelijk te begrijpen. Het ‘do’ commando zit geïntegreerd in je ‘while’ statement.

Het vertelt de Arduino simpelweg te doen wat je achter het ‘do’ commando hebt getypt, bijvoorbeeld do standardscan(). 

Overig

Als men een grote code moet schrijven en de loop overzichtelijk wil houden, kan er voor gekozen worden om voor elk stuk code dat veel herhaald wordt of erg lang is, een aparte functie te schrijven. Dit zou je kunnen doen omdat de loop het meest ingewikkelde stukje programma is. Hier moet alles goed op elkaar aansluiten om de code goed te laten werken. En omdat het bij programmeren heel nauw komt kijken wat betreft details: een simpele puntkomma of dubbele haakjes vergeten maakt je code onwerkzaam. 

 

Hierom hebben wij er ook voor gekozen deze extra functies te gebruiken. Eigenlijk geeft je een stukje code een naam, bijvoorbeeld standardscan. In plaats van de hele serie commando’s van standardscan op te schrijven op elke plaats in de code waar een standardscan uitgevoerd moet worden, geef je de commando’s die samen standardscan vormen een naam en dat noem je dan een functie. In dit geval standardscan maar dit zou ook taart of stoel kunnen zijn. Vervolgens zet je void plus deze naam (standardscan) gevolgd door () (dubbele haakjes) in je loop, dus: void standardscan(). En dan heet het pas officieel een functie. Hierdoor hoef je de standardscan commando’s slechts 1 keer op te schrijven.

Je kunt nu deze functie overal in je code aanroepen. 

 

We hebben het telkens over loop en setup terwijl in de code toch echt void loop en void setup staat. Je gebruikt void alleen voor een functie. Daarom staat het ook bij bijvoorbeeld void standardscan. Wat void precies doet is er voor zorgen dat de functie geen waarde teruggeeft. Dat betekent dat die specifieke functie geen invloed heeft op andere functies. 

Let op: dit betekent niet dat variabelen niet meer gebruikt kunnen worden! De variabelen staan voor de void setup gedeclareerd en kunnen daarom in alle functies gebruikt worden en kunnen op deze manier toch verschillende functies op elkaar in laten spelen. Bijvoorbeeld met de Leftcm en Rightcm die gemeten worden in respectievelijk Leftscan en Rightscan en daarna via de variabelen informatie doorgeven aan de loop, terwijl voor alle functies void staat. 

 

Bij het berekenen van de afstand door de sensor staat: 

cm= uS / US_ROUNDTRIP_CM. Dit kan zo geschreven worden door de informatie die is toegevoegd aan de code met de sensorlibrary. We hebben besloten voor deze manier te kiezen, omdat dit de kortste manier is om de Arduino de afstand te laten berekenen, die gemeten wordt door de sensor, ondanks dat je hieruit weinig kan aflezen. Wat er ook had kunnen staan is: 

cm = (uS/10^6/2 )* (vgeluid * 100). Wat gewoon een uitgewerkte vorm is van 

x = v * t . cm = x, t = microseconden/10^6/2 en v = vgeluid * 100. Het aantal microseconden (uS) wordt gedeeld door een miljoen omdat je dan de tijd in seconden krijgt en hij wordt dan nog door 2 gedeeld omdat de sensor een geluidspuls uitzendt en de echo hiervan weer ontvangt. Dat betekent dat er 2 keer de afstand is afgelegd en daarom deel je dus door 2. Je vermenigvuldigt de geluidssnelheid met 100 om de geluidssnelheid van m/s naar cm/s om te zetten.