Pagina1 van 1

Arduino Programmeren voor Beginners – Deel 3: Werken met Informatie

Arduino Programmeren voor Beginners – Deel 3: Werken met Informatie
   40

In dit derde deel van Arduino Programmeren voor Beginners, gaan we praten over informatie oftewel “data” en hoe we daar meer kunnen werken.  We gaan kijken naar soorten informatie, hoe we informatie kunnen opslaan in “variabelen” en “constanten”. Het afhandelen van informatie is natuurlijk bij uitstek waar computers voor gemaakt zijn.

Deze reeks richt zich hoofdzakelijk op het Arduino Programmeren voor beginners, en dan specifiek voor m’n neefjes Bram en Max – gebrek aan kennis voor wat betreft de Engelse taal en wiskundige achtergrond hoeft waarschijnlijk geen probleem te zijn. Het gebruik van extra componenten blijft beperkt tot een minimum.




Overzicht van dit Hoofdstuk

  Een volledig overzicht van de cursus vindt je hier: Cursus Overzicht.

Met dank aan Lineke voor de taal correcties!

DataTypes: Data voor Arduino Programmeren

Elk programma werkt op de een of andere manier met data – kenmerkend voor computers. Informatie, of te wel “data”, wordt weergegeven, ingelezen, uitgevoerd, veranderd, gesorteerd, etc. etc. – Wat je ook doet met een computer, er wordt data verwerkt.

Waarom Data Types?

Informatie, data dus, kennen we in verschillende vormen en formaten, en iedere “variant” zou de computer op een andere manier moeten behandelen. Ik zal proberen dat uit te leggen.

Laten we beginnen met twee basis types van “data”, als voorbeeld: Tekst en Nummers.
Als voorbeeld waarom deze twee verschillende data typen anders behandelt moeten worden, zou je kunnen denken aan het volgende:
Je kunt twee teksten niet met elkaar vermenigvuldigen, maar twee nummer wel.
Je kunt twee stukken tekst achter elkaar plakken, maar bij nummer eindig je dan mogelijkerwijs met onzin.

Als voorbeeld dus “abc” ×def” gaat nergens over, maar “abc+def” zou “abcdef” kunnen worden.
Hetzelfde met nummers; 3 × 4 levert 12 en 3 + 4 levert 7 (en dus niet “34“)!

Omdat tekst ook nummers kan bevatten, wordt het e.e.a. nog ingewikkelder voor een computer.

Het wordt nog lastiger als we weten hoe tekst en hoe nummers in de computer worden opgeslagen. We moeten daarvoor even terug gaan naar de uitleg van “bit” en “byte” in het voorgaande deel. We weten dat een byte uit 8 bits bestaat en voldoende ruimte biedt om letters op te slaan. Dus als we tekst opslaan dan gebruiken we een byte per letter.

Als we met nummers werken, dan veranderd dit. Een byte kan namelijk een nummer van 0 … 255 opslaan.
Met het nummer 34 in gedachten:
Als we “34” als tekst opslaan, dan hebben we dus 2 “letters” en gebruiken we dus minimaal 2 bytes.
Als we het nummer 34 opslaan, dan zien we dat dit al in 1 byte past!

Dit zijn natuurlijk eenvoudige voorbeelden, en in werkelijkheid kunnen deze voorbeelden nog veel complexer zijn. Ik denk dat je nu snapt waarom de computer verteld moet worden met welk type data het te maken heeft. Het moet weten welke soort handeling mogelijk is, hoe die handeling gedaan moet worden en hoe het data op kan slaan.

That’s why there are in most programming languages so called “data types” – which defines the type and how to handle a given kind of data.

Data Types definiëren hoe data behandelt en opgeslagen wordt.

Data Types voor de Arduino

Je hebt misschien al gezien dat ik, rond tekst, dubbele aanhalingstekens plaats ( ). Dat is de manier waarom in de programmeertaal C (de taal die voor Arduino Programmeren gebruikt wordt) de gebruikelijke manier om tekst aan te geven. Een dergelijke reeks karakters (tekst) noemt men een “string“, en een “string” is een van die zogenaamde “data types”.

De taal C kent een aantal verschillende “Data Types”, en ik laat ze hieronder zien zoals de Arduino ze kent – maak je niet ongerust als je niet meteen begrijpt wat het allemaal betekend. Naar mate je ze meer en meer gaat gebruiken wordt het e.e.a. duidelijker en zul je ze ook gemakkelijker onthouden.

Data Types
 Data Type  Toepassing / Type waarden  Geheugen verbruik
 array Een array kan gezien worden als een reeks waarden die aangesproken kunnen worden met behulp van een zogenaamd index nummer.  Wisselend
 boolean Een boolean kan slecht 1 van deze twee waarden aannemen: true (waar) of false (niet waar)  1 byte
 byte
 of
 unsigned char
Een geheel nummer tussen 0255  1 byte
 char Een enkel teken (of karakter – zie onze karakter lijst)  1 byte
 double Een nummer met cijfers achter de komma, met dubbele precisie (op de meeste Arduino’s hetzelfde als een float)  4 bytes
 float Een nummer met cijfers achter de komma, bereik van -3.4028235E+38 … -3.4028235E+38 (niet super nauwkeurig!)  4 bytes
 int
 or
 short
Geheel nummer tussen -32,768 … 32,767   2 bytes
 long Geheel nummer tussen -2,147,483,648 … 2,147,483,647  4 bytes
 string
(char array)
Een array van Char(acters)  Wisselend
 String
(object)
Een string object, kost iets meer geheugen maar biedt wat extra handigheidjes  Wisselend
 unsigned int
 of
 word
Een geheel nummer tussen 065,535  2 bytes
 unsigned long Een geheel nummer tussen 04,294,967,295  4 bytes
 void “niks” (alleen gebruikt voor functie definities)  N.V.T.

N.B. : De data types waar je “wisselend” ziet staan in de geheugenverbruik-kolom, groeien naar behoeft (en nemen dus meer of minder geheugen in beslag).

N.B. : Berekeningen met cijfers met nummers achter de komma zijn beduidend langzamer dan berekening met gehele nummers.

Zoals je ziet; niet ieder data type, neemt even veel geheugen in beslag. Men probeert data (informatie) zo efficiënt mogelijk op te slaan. Soms kan dat resulteren in onverwachte resultaten als je bijvoorbeeld een data type kiest die niet alle data kan bevatten. Bijvoorbeeld een “byte” (0-255) voor het opslaan van het nummer 300.

Arduino’s hebben maar een beperkte geheugencapaciteit, ga er dus zuinig mee om!

Nu dat we een hele lijst hebben gezien, gaan we kijken naar de meest gangbare typen data: boolean, int, char, string, float en array.
Array zullen we later bekijken, laten we eerst eens gaan kijken naar de eenvoudigere typen.

Als voorbeeld beginnen we met de boolean waarden. Een boolean kan slechts één van de volgende twee waarden aannemen: “true” (waar) of “false” (onwaar of niet waar). Je kunt dat ook lezen als Ja/Nee, Aan/Uit, etc. en wordt heel vaak gebruikt bij het vergelijken van informatie. Bijvoorbeeld “is het licht aan?” – we vergelijken de informatie (licht aan) met een mogelijk antwoord (Ja of Nee). Dit gaat straks dus handig worden bij het aan- of uitzetten van lampjes, of het lezen van schakelaar of sensoren.

Bedenk dat “true” en “false” vast zijn gedefinieerd in de Arduino (IDE) en altijd worden getypt met kleine letters.

De boolean waarden “true” en “false” worden opgeslagen als nummers.
Initieel zul je hier niet veel mee doen, maar het is belangrijk om te weten dat true = 1 en false = 0 .

Int (integer) is een geheel nummer, dus een nummer zonder cijfers achter de komma. Dit data type is een van de makkelijkste typen o mee te werken en worden dus vaak voor berekeningen gebruikt zoals optellen, aftellen, etc. of bijvoorbeeld voor pin nummers enzo.

Een char wordt gebruikt voor letters, maar ook voor cijfers en bijzondere tekens (char staat voor character, het Engelse woord voor karakter, ook in het Nederlands gebruiken we het woord karakter om letters, cijfers en tekens te benoemen) – eigenlijk elke “letter” die we in een string kunnen plaatsen – wat ons bij een complexer data type brengt: de string.

Er zijn 2 string soorten: string (array van chars) en String (object).
Haal ze niet door elkaar want ze zijn echt andere beestjes!

Arduino kent 2 soorten van strings.

De ene is een string en is wat eenvoudig, namelijk een array van characters (een reeks van char), en wordt met een kleine “s” geschreven.

De andere String is een stukje meer complex omdat het een zogenaamd “object” is – dit string type wordt met een hoofdletter “S” geschreven. We praten later meer over objecten, maar voor het moment is het goed te weten dat objecten vaak met handige functies komen.

We hebben dus 3 soorten basis data types: nummers (int, long, float, double, etc.), tekst (char en strings) en Booleans (true/false).
De Array types zijn een groepering, reeks of lijst van deze “eenvoudigere” data types.

Wat zijn Variabelen?

We hebben even snel gekeken wat voor soorten data er zijn – en daar zouden we nog wel een paar dagen over door kunnen praten. Maar wat doen we nu met deze zogenaamde “data types”? Nou, we gaan ze gebruiken in wat ze “variabelen” noemen.

Variabelen zijn “namen” die wijzen naar een specifiek stukje geheugen – het “adres” waar de data staat in het geheugen.

Om nu te weten wat we kunnen verwachten, moeten we de computer (Arduino) dus niet alleen vertellen waar het staat, maar ook wat er staat. Zoals je al eerder zag; tekst en nummers werken niet hetzelfde, en verschillende data types kunnen een verschillende hoeveelheid geheugen gebruiken.

Deze “namen” gebruiken we in ons programma om te refereren naar informatie of data.

Variabelen zijn een soort “”aanduiding” of “plaatshouder” voor de data die we in ons programma gebruiken (meer correct: de geheugen locatie waar onze data gevonden kan worden).

Klink lekker onduidelijk? Geen probleem, laten we eens naar wat voorbeelden kijken.

Hier onder wat voorbeelden hoe we variabelen kunnen gebruiken (dit is niet helemaal correct notatie voor de taal C!) – we definiëren wat variabelen en doen er wat berekeningen mee:


1
2
3
4
5
6
A = 4
B = 12
C = 4 + 12   // = 16
D = A + B    // = 4 + 12 = 16
C = 4 + A    // = 4 + 4 = 8
A = A + A    // = 4 + 4 = 8

In de eerste regel maken we een variabele met de naam “A” welke we de waarde 4 geven als “data”.
De tweede regel is vergelijkbaar maar nu definiëren we de variabele “B”, met de waarde 12.

Wanneer we de variabele “A” aanroepen, dan wijzen we eigenlijk naar diens waarde … 4.
Hetzelfde geldt voor de variabele “B”, met een waarde van 12.

We kunnen in regel 3 zien dat we er ook mee kunnen rekenen: We maken de variabele “C” en geven het de waarde van 4 en 12 opgeteld (16).

Omdat de variabele een waarde heeft kunnen we daar ook mee gaan rekenen zoals we in regel 4 zien waar we [de waarde van] “A” en “B” optellen.
We tellen de waarden van de variabele “A” (4) en de variabele “B” (12) op, wat resulteert in 16, en die waarde wijzen we toe aan de variabele D.

De 5de regel laat zien dat we variabelen en nummers door elkaar kunnen gebruiken door de variabele “C” een nieuwe waarde tegen, wat het resultaat is van het optellen van 4 en de waarde van de variabele “A”. De “oude” waarde van de variabele “C” wordt hierdoor dus overschreven!

Regel 6 maakt het nog gekker. We tellen de waarde van de variabele “A” en de waarde van dezelfde variabele “A” op (wat dus 4+4 is) en slaan dit weer op in weer dezelfde variabele “A” (8). Eerst telt de computer dus de waarden op, en vervolgens slaat die het resultaat op in de variabele, welke nu de waarde “8” heeft.

Dus … variabelen zijn variabel – ze kunnen veranderen.

Tot dusver gebruikte ik simpele letters voor de variabelen, maar je kunt er beter zinvolle namen voor gaan gebruiken waardoor het programma voor ons mensen beter te lezen is.

Variabelen dienen namen te hebben die zinvol zijn en bijdragen aan de leesbaarheid van jouw programma…

Een voorbeeld:


1
2
3
ZakGeld = 4
SpaarGeld = 12
AlMijnGeld = ZakGeld + Spaargeld

Je ziet meteen wat we hier aan het doen zijn – stukken beter leesbaar dan alleen maar een “A” of een “B”.

Let echter wel op dat de namen van variabelen hoofdletter gevoelig zijn. “ZakGeld” is dus niet hetzelfde als “zakGeld”, “Zakgeld”, “zakgeld” of “ZAKGELD”!

Variabelen, en andere namen in code, zijn over het algemeen hoofdletter gevoelig !

We moeten echter nog een paar extra regels in de gaten houden. We mogen namelijk alleen maar letters, nummers en een zogenaamde underscore (liggend streepje: _ ) gebruiken, maar niet speciale tekens of spaties!

Namen van variabelen:

  • Beginnen ALTIJD met een letter(a, b, …, z, A, B, … , Z) of een underscore ( _ )
  • mag letters bevatten
  • mag underscore(s) bevatten
  • mag nummers  bevatten
  • MAG NOOIT speciale tekens, symbolen of spaties bevatten

Laten we eens een voorbeeld programma maken.
We gaan in dit “programma” alleen maar hele getallen gebruiken – kun je al raden welk data type we nodig zouden kunnen hebben?

Daarvoor moeten we eerst wat meer weten. Stel we gaan ons eigen geld tellen en we hebben het niet al te breed, dan zou het kunnen zijn dat een int genoeg is (€32.768).

Omdat we alles maar 1 keer willen doen, zullen we onze “code” maar even in de “setup()” zetten.
Ter herinnering: “setup()” wordt maar 1x doorlopen, “loop()” wordt eindeloos herhaald.

Maar omdat we resultaten willen zien moeten we dus eerst de praat snelheid even instellen tussen de computer en de Arduino – zodat de “Seriële Monitor” functioneert, zoals we dat eerder gedaan hebben.

Daarna gaan we 3 variabelen definiëren: ZakGeld, SpaarGeld en AlMijnGeld en we maken deze gehele nummers, en voor het voorbeeld kiezen we dus “int”.
Zie je hoe we iedere regel (statement) in onderstaande code met een puntkomma afsluiten? Niet vergeten hè!?

In de volgende stap gaan we de variabelen een waarde geven.

Uiteindelijk sturen we de resultaten naar de “Seriële monitor”.
Hiervoor gebruiken we weer “Serial.print” zodat we kunnen zien wat de naam van de variabelen kunnen zien.
En vervolgens gebruiken we “Serial.println” om de waarde van de variabele weer te geven. Hier zien we een klein verschil tussen “Serial.print” en “Serial.println” – die laatste begint namelijk een nieuwe regel na het printen van de informatie. De extra “ln” (Engels: LINE betekent regel) zorgt hiervoor.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void setup() {
  // snelheid voor de seriële monitor:
  Serial.begin(9600);
 
  // variabelen definiëren als "int"
  int ZakGeld;
  int SpaarGeld;
  int AlMijnGeld;

  // variabelen waarden geven
  ZakGeld = 4;
  SpaarGeld = 12;
  AlMijnGeld = ZakGeld + SpaarGeld;

  // variabelen weergeven
  Serial.print("ZakGeld = ");
  Serial.println(ZakGeld);

  Serial.print("SpaarGeld = ");
  Serial.println(SpaarGeld);

  Serial.print("AlMijnGeld = ");
  Serial.println(AlMijnGeld);
}

void loop() {
  // leave empty for now
}

Kopieer deze code en plak het in de Arduino IDE waarbij het de eventuele bestaande code (tekst) geheel vervangt.
Klik vervolgens op de “Compileer en Upload” knop (het kan zijn dat de Arduino IDE vraagt of je deze code wilt opslaan – gewoon doen en op “Save” klikken).
Na wat geknipper start de Arduino het programma en zien we het volgende in het Seriële Monitor venster:


ZakGeld = 4
SpaarGeld = 12
AlMijnGeld = 16

Wat zijn Constanten?

Constanten zijn “namen” (vergelijkbaar met zoals we namen in variabelen gebruikt hebben) die ook een waarde hebben, maar die nooit veranderen in een programma.
Ze worden vaak gebruikt als een bepaalde vaste waarde wordt gebruikt of als een waarde vaak gebruikt wordt in een programma, maar als je in de toekomst deze waarden zou willen veranderen heb je hiermee voorkomen dat je moet gaan zoeken naar iedere keer dat die waarde in je programma voorbij komt.

Een Constante lijkt op een variabele, maar dan met een Vaste Waarde.

Namen van Constanten volgende dezelfde regels als voor variabelen.

Je zou kunnen zeggen dat we 3 soorten constanten hebben.

We hebben de constanten die in de Arduino IDE of Arduino Bibliotheken zijn gedefinieerd, en diegene die we in ons programma definiëren (b.v. “true” en “false”).

Ehm, je zei toch dat we er “3” hadden – ik zie er maar 2 … !?
Dat klopt helemaal en dat komt omdat we 2 manieren hebben waarop we onze eigen constanten kunnen definiëren.

We kunnen constanten definiëren met het trefwoord “const“,
of we kunnen een zogenaamde “compiler aanwijzing” (compiler directive) gebruiken: “#define“.

Het grootste verschil is het gebied (scope) waarin de constante werkt of beschikbaar is – ik laat je zo het verschil zien.

Gebruik “const” als je deze alleen in een bepaald deel van het programma wilt zien, of als je denkt dat je deze later gaat omzetten naar een variabele.

Gebruik “#define” voor de meeste andere gevallen.

const

Het definiëren van een constant wordt als volgt gedaan voor “const”:

const int AantalLichten = 5;

Dit lijkt veel op de manier waarop we een variabele definiëren, misschien kun jij je dit nog herinneren:

int AlMijnGeld;

Een “const” constante gedraagt net als een variabele …
Je kunt alleen z’n waarde niet veranderen.

 

We hebben er gewoon het woord “const” voor geplakt, zodat we weten dat deze waarde nooit verandert, en we wijzen het meteen een waarde toe met “ = 5 “.

Dus niet vergeten: Je kunt de waarde dus NIET veranderen als het programma draait.
Als we dit in de “setup()” doen, dan zal deze constante alleen maar bekend zijn in “setup()” – je ziet ‘m dus niet in “loop()”.

#define

Een alternatieve manier van constanten gebruiken is met de define compiler instructie – wat aan het begin van onze code gedaan wordt:

#define AantalLichten 5

We zien hier een aantal belangrijk verschillen.

Als eerste, starten we deze regel met een hash (hekje of pound, of te wel dit symbool: #). We hebben dat nog niet eerder gezien en het geeft de compiler (vertaler) specifieke opdrachten die uitgevoerd worden voor de vertaling start. In principe zegt het “voor je gaat vertalen, vervang alle AantalLichten in de code met het nummer 5“. Dus in tegenstelling van de “const” methode, wijst deze dus niet naar een geheugen locatie!
Er zijn nog meer compiler instructies maar we laten het even bij deze.

In tegenstelling tot gewone instructies zien we ook dat de puntkomma ontbreekt (;) – wat alleen correct is voor compiler instructies en commentaar.

En als laatste typen we gewoon “5” in plaats van ” = 5 ” – het is-gelijk symbool is hier niet van toepassing.

Als je een constante op deze manier definieert, dan is deze over het gehele programma bekend en bereikbaar.

Wat is Scope (bereik of werkgebied)?

We hebben het net even vermeld: Scope – wat zoiets wil zeggen als bereik of (werk)gebied.
Dit is van toepassing voor zowel variabelen, constanten en zelfs functies. Maar dus niet van toepassing voor “#define”!

Wanneer we dus over de “scope” van een variabele of constante praten, dan bedoelen we dus eigenlijk “dat deel van onze code waar deze constante of variabele bestaat en zichtbaar is”.

N.B.: Vanaf dit punt zal ik spreken over variabelen, maar de “const” constanten gedragen zich identiek aan variabelen – met het verschil natuurlijk dat je de constanten niet kunt wijzigen.

De Scope van een variabele geeft aan “waar” deze gezien en gebruikt kan worden in de code van ons programma.

Hierdoor kennen we twee hoofdgroepen van variabelen: lokale variabelen en globale variabelen.

Globale variabelen zijn OVERAL in jouw programma te zien. Om dat voor elkaar te krijgen moeten ze wel op een speciale plaats gedefinieerd worden. Vaak zijn dit waarden die op veel plaatsen in het programma gebruikt worden.

Lokale variabelen echter hebben maar een beperkt gebied waarin ze beschikbaar zijn en bestaan. Dit wordt vaak gedaan als een waarde alleen in bijvoorbeeld 1 functie gebruikt wordt.

Dus wat zijn nou die gebieden waar we het steeds over hebben?

Laten we eens naar een “leeg” Arduino programma kijken:


1
2
3
4
5
6
7
8
void setup() {
  // put your setup code here, to run once:

}
void loop() {
  // put your main code here, to run repeatedly:

}

We zien 2 gebieden: het blok “setup()” en “loop()” – beiden omsloten door accolades. Maar er is nog een 3de gebied: het gehele programma.

Laten we eens een globale variabele definiëren, om dit te illustreren:


1
2
3
4
5
6
7
8
9
10
11
int GlobaleVariable; // GlobaleVariable kan hier gebruikt worden

void setup() {
  // put your setup code here, to run once:
  // GlobaleVariable kan hier gebruikt worden
}

void loop() {
  // put your main code here, to run repeatedly:
  // GlobaleVariable kan hier gebruikt worden
}

En nu een voorbeeld van een lokale variabele:


1
2
3
4
5
6
7
8
9
10
11
12
// LokaleVariabele kan hier NIET gebruikt worden

void setup() {
  // put your setup code here, to run once:
  int LokaleVariabele;
  // LokaleVariabele kan hier WEL gebruikt worden
}

void loop() {
  // put your main code here, to run repeatedly:
  // LokaleVariabele kan hier NIET gebruikt worden
}

Dit was misschien niet de meest uitgebreide uitleg, maar ik vermoed dat je het wel snapt.

We kunnen echter meerdere lokale variabelen opzetten die hetzelfde heten, in verschillende blokken natuurlijk.

Als ik “LokaleVariabele” definieer in de functie “setup()” EN in de functie “loop()”, dan zijn beiden een lokale variabele, ook al zijn de namen hetzelfde. Echter, als we de waarde van “LokaleVariabele” veranderen in “setup()” dan heeft dit geen invloed op “LokaleVariabele” in de functie “loop()”!
Ze heten hetzelfde, maar ze hebben ieder hun eigen geheugen locatie. Je snapt al dat dit to verwarring kan leiden!


1
2
3
4
5
6
7
8
9
10
11
12
13
// LokaleVariabele kan hier NIET gebruikt worden

void setup() {
  // put your setup code here, to run once:
  int LokaleVariabele;
  // LokaleVariabele kan hier WEL gebruikt worden, maar dit is niet dezelfde als in loop()
}

void loop() {
  // put your main code here, to run repeatedly:
 int LokaleVariabele;
 // LokaleVariabele kan hier WEL gebruikt worden, maar dit is niet dezelfde als in setup()
}

Laten we eens gaan kijken naar een werkend programma waarbij we er een rommeltje van gaan maken.

We zien hier ook meteen een nieuwe constructie die we bij “const” ook hebben gezien: het definiëren van een variabele en het meteen een waarde geven, allemaal in 1 instructie: int A = 0;. Deze regel (regel 1) maakt de GLOBALE variabele “A”.

In zowel “setup()” als “loop()” maken we weer een variabele “A” en geven we het een waarde. Deze variabelen bestaan dus alleen maar in hun eigen blok en zijn LOKALE variabelen.

We kunnen de functie “delay(x)” gebruiken om een programma te pauzeren voor “x” milli seconden (1000 = 1 seconde)

Draai dit programma maar eens op de Arduino.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int A = 0;

void setup() {
  int A;
  A = 1;
  Serial.begin(9600);
 
  // print the values to the serial monitor
  Serial.print("Setup: A = ");
  Serial.println(A);
}

void loop() {
  int A;
  A = 2;
 
  // print the values to the serial monitor
  Serial.print("Loop: A = ");
  Serial.println(A);

  delay(100000);
}

De output (uitvoer) zal zijn:

Setup: A = 1
Loop: A = 2

Om het effect van LOKAAL en GLOBAAL te zien, gaan we nu even in “setup()” twee regels uitschakelen met behulp van commentaar-tekens (//).
Start het programma weer op de Arduino:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int A = 0;

void setup() {
 // int A;
 // A = 1;
 Serial.begin(9600);
 
 // print the values to the serial monitor
 Serial.print("Setup: A = ");
 Serial.println(A);
}

void loop() {
 int A;
 A = 2;
 
 // print the values to the serial monitor
 Serial.print("Loop: A = ");
 Serial.println(A);

 delay(100000);
}

De output wordt nu:

Setup: A = 0
Loop: A = 2

De globale variabele is nu in gebruik in de “setup()” functie. Maar, in de “loop()” functie wordt deze globale variabele niet gebruikt omdat er een lokale variabele is met dezelfde naam – en deze lokale variabele wordt dus in “loop()” gebruikt.

Laten we eens alleen met een globale variabele werken en diens waarde in de verschillende delen veranderen:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int A = 0;

void setup() {
  Serial.begin(9600);
 
  Serial.print("Setup: Eerste A = ");
  Serial.println(A);

  A = 10;
  // print the values to the serial monitor
  Serial.print("Setup: Tweede A = ");
  Serial.println(A);
}

void loop() {
  Serial.print("Loop: Eerst A = ");
  Serial.println(A);

  A = 20;
 
  // print the values to the serial monitor
  Serial.print("Loop: Tweede A = ");
  Serial.println(A);

  delay(100000);
}

De variabele “A” is nu een GLOBALE variabele – Dus het kan overal gezien en gebruikt worden.

De output zou er zo uit moeten zien:

Setup: Eerste A = 0
Setup: Tweede A = 10
Loop: Eerste A = 10
Loop: Tweede A = 20

Dus we definiëren de globale variabele “A” en geven deze de waarde nul (0) – het staat immers buiten alle blokken.
In “setup()”, geeft de “Serial.print” weer wat de waarde van “A” is en dat het gelezen en gebruikt kan worden.
Hier veranderen we de waarde van “A” naar 10, en geven deze ook weer.
In “loop()”, laten we ook weer zien dat we “A” kunnen lezen en dat het nu de nieuwe waarde heeft die we in “setup()” hebben opgegeven.
En vervolgens veranderen we deze weer.

Nummer Types en Weergave

Er zijn verschillende nummersysteem om nummer te representeren of weer te geven. Kijk maar eens naar deze Wiki Lijst van Nummer Systemen. Voor ons programmeurs zijn de volgende drie eigenlijk de meest gebruikte nummersystemen: Decimaal, Hexadecimaal en Binaire nummers (in die volgorde). Vaak zullen we echter gewoon decimale nummer gebruiken. Maar wat zijn dan die nummersystemen?

Decimale Nummers

Het decimale systeem is het systeem dat we dagelijks gebruiken. Het nummersysteem waarbij we 10 verschillende symbolen gebruiken: 0, 1, 2, 3, 4, 5, 6, 7, 8, en 9. Omdat dit 10 symbolen heeft, noemen we dit het “Decimale” systeem (Deci betekent 10).

Ik ben er wel zeker van dat je weet hoe het tellen in het decimale systeem werkt, we doen het immers elke dag. Maar om de andere twee systemen beter te begrijpen, gaan we toch even door op hoe het “tellen” werkt voor een decimaal systeem …

Als we beginnen met tellen dan hebben we 0, 1, 2, 3, 4, 5, 6, 7, 8, en 9. voor het volgende nummer (dus 9+1) starten we weer met nul en verhogen voorgaand nummer met 1. Welk nummer voor “9” hoor ik je al vragen?

Stel we zetten een aantal nullen voor een nummer, de waarde van het nummer verandert hierdoor niks en de extra nullen hebben geen toegevoegde waarde.Laten we eens beginnen met 3 nullen voor het nummer.

We gaan weer tellen: 0001, 0002, … , 0008, 0009, 0010, 0011, 0012, … , 0018, 0019, 0020, 0021, … 0099, 0100, 0101, … etc.

Elke keer als een nummer voorbij de “9” wil gaan, dan starten we dat nummer met 0 (nul) en verhogen het voorgaande nummer met 1.

Snappie?

Dus als we het nummer 0999 hebben, en deze met 1 willen verhogen, dan zal deze 9 terug naar nul gezet worden (0990), vervolgens verhogen we het nummer ervoor met 1 (0990), maar daardoor wordt dit nummer ook weer groter dan 9 en wordt dus ook weer teruggezet op nul (0900), hierdoor moet het nummer daarvoor ook weer met 1 verhoogd worden (0900), maar daardoor moet dat nummer ook weer op nul worden gezet (0000) en het nummer ervoor weer met 1 worden verhoogd waardoor we eindigen met 1000.

Ben je er nog? Even onthouden, want we hebben dit later weer nodig.

We weten natuurlijk al dat we een decimaal nummer met Serial.print(nummer);  kunnen weergeven.
We kunnen het ook schrijven alsSerial.print(nummer, DEC);, waarbij DEC aangeeft dat we het nummer als een decimaal nummer willen zien. Deze methode (DEC) werkt overigens het beste met hele getallen, floating point nummers (nummers met cijfers achter de komma) kunnen onverwachte resultaten geven.

Binaire Nummers

Het binaire nummer systeem kent eigenlijk maar twee nummers: 0 en 1. Daarom heet het een “binair” system, “bi” wil zeggen “twee”.

In tegenstelling tot wat je zou verwachten, vindt het binaire systeem zijn oorsprong niet in de computerwereld – het bestaat al eeuwen voor we wisten wat een computer zou kunnen zijn. Het is helaas in het Engels, maar deze Wiki pagina over de geschiedenis ervan is zeer zeker leuk om eens te lezen!

Dat even terzijde, het binaire systeem is natuurlijk wel bij uitstek geschikt voor computers omdat het maar twee waarden kent: true of false, ja of nee, of: aan of uit.

Het tellen in het binaire systeem werkt overigens hetzelfde als bij het decimale systeem, alleen hebben we dan wel veel minder nummers om mee te werken.

Dus, inclusief de denkbeeldige nullen voor het nummer, laten we eens gaan tellen: 0000, 0001 en de nummers zijn op. Dus zetten we het nummer weer terug naar nul, en verhogen het voorgaande nummer weer met 1. Net zoals we dat zagen bij het decimale systeem, dus als we doorgaan met tellen: 0010, 0011, en weer zijn de nummer op, dus herhalen we weer nummer naar nul zetten en voorgaand nummer met 1 verhogen, enz. 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111.

Nu we weten hoe we tellen, zouden we een conversietabel kunnen maken zodat we binaire nummers om kunnen zetten naar decimale nummers:

Binaire Nummers
 Binair nummer  Decimaal nummer
0000  0
0001  1
0010  2
0011  3
0100  4
0101  5
0110  6
0111  7
 1000  8
 1001  9
 1010  10
 1011  11
 1100  12
 1101  13
 1110  14
 1111  15

Er is echter een eenvoudigere methode dan steeds een hele tabel uit de kast halen (en dan heb ik het niet over calculator op jouw computer, want dat gaat natuurlijk nog sneller).

Als je een beetje bekend bent met rekenen “tot de macht”, dan kan het volgende handig zijn voor het berekenen van de decimale waarde van een binair getal. Als je namelijk een tabel moet maken voor b.v. 16 bits binaire nummers, b.v. 1101 1000 0000 0101, dan kon dat weleens een lange tabel gaan worden.Er is een manier om dat “sneller” te doen (OK, de calculator op jouw PC doet het VEEL sneller).

Elke positie in een binair nummer heeft een waarde, en als we positie van rechts naar links tellen dan is dat:
“2 tot de macht positie” vermenigvuldigd met 0 of 1, net wat de bit waarde in die positie is.

We gebruiken “2” omdat het binaire nummer systeem maar 2 waarden kent: 0 en 1.

Dus als we naar een 4 bit nummer (dit noemt men een nibble!) gaan kijken, bijvoorbeeld: 1010.

Binaire conversie
 Positie 3 Positie 2  Positie 1  Positie 0
 1  0  1  0
 23 = 2×2×2 = 8  22 = 2×2 = 4  21 = 2  20 = 1
 1×8  0x4  1×2  0x1
 = 8  = 0  = 2  = 0

Het resultaat is de som van deze nummers, of te wel: 1010 binair = 8+0+2+0 = 10 decimaal.

De meeste programmeurs vergeten de details van deze truc gemakkelijk, zoals gezegd: de rekenmachine van onze computer kan dit sneller, en de meeste programmeertalen hebben functies ingebouwd die dit ook snel kunnen doen voor ons.

Iets om te onthouden: een byte is 8 bits en als alle bits de waarde 1 hebben, dan krijgen we 1111 1111, wat meteen de maximale waarde van een byte is: 255.

Je kunt binaire nummers overigens gewoon in jouw programma code gebruiken, door er “0b” (nul-b) voor te typen. Bijvoorbeeld: 0b1010

Het weergeven van binaire nummers werkt ook gewoon, als voorbeeld voor het nummer 1010: Serial.println(0b1010);
Dit print echter de decimale waarde van het binaire nummer, wat dus hetzelfde werkt als Serial.println(0b1010, DEC);

Om een nummer nu als binair te printen, gebruiken we: Serial.println(0b1010, BIN);
Dit werkt voor alle nummersystemen, dus als we een decimaal nummer meegeven dan levert Serial.println(10, BIN); de output “1010”.

Hexadecimale Nummers

OK, we hebben dus Binair en Decimaal gezien, maar wat zijn dan Hexadecimale Nummers?

Overigens: de meeste mensen gebruiken de term “hex” om aan te geven dat ze het over hexadecimale nummers hebben.

In het Hexadecimale systeem hebben we 16 nummers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, en F. (Hex = 6  en  Deci = 10)

Het tellen werkt hetzelfde als we hebben gezien bij decimale nummers en binaire nummers, al hebben we nu dus meer “nummers” beschikbaar om mee te werken.

Als voorbeeld, weer met de extra nullen ervoor: 0001, 0002, … , 0009, 000A, … 000F, 0010, 0011,… 001F, 0020, 0021,… etc.

Conversie naar een decimaal nummer lijkt wat lastiger, maar werkt vergelijkbaar als bij conversie van binaire nummers.

Stel we hebben het hexadecimale nummer 2FA. Weer van rechts naar links tellen voor de posities, dan moeten we de waarde van het nummer vermenigvuldigen met 16 tot de macht positie nummer. We gebruiken hier “16” omdat het hexadecimale systeem 16 nummers kent. De som van de uitkomst is weer de decimale waarde.

In een voorbeeld:

Hexadecimale conversie
 Positie 1  Positie 2  Positie 3
 2 × 162  F × 161  A x 160
 = 2 × 256  = 15 (F) × 16  = 10 × 1
 = 512  = 240  = 10

De, 2FA Hexadecimaal is hetzelfde als 512+240+10 = 762 decimaal.

Ook hexadecimale nummers kunnen we in onze code gebruiken door er “0x” (nul-x) voor te typen, dus bijvoorbeeld: 0x2FA

We kunnen ze dus ook printen, zoals we eerder hebben gezien, met bijvoorbeeld Serial.println(0x2FA); maar dit print dus een nummer in decimaal formaat. Wil je nu liever de hexadecimale waarde als output zien, dan gebruiken we Serial.println(0x2FA, HEX);. En dit werkt dus ook weer met decimale nummer en binaire nummers.

Nummers Weergeven

Hieronder een stukje demo code hoe we met decimale, binaire en hexadecimale nummers kunnen werken.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void setup() {
  Serial.begin(9600);

  int decNummer = 10;
  int hexNummer = 0x2FA;
  int binNummer = 0b10001010;

  Serial.println("Alle Nummers als decimaal:");
  Serial.println(decNummer);
  Serial.println(decNummer, DEC);
  Serial.println(hexNummer);
  Serial.println(hexNummer, DEC);
  Serial.println(binNummer);
  Serial.println(binNummer, DEC);

  Serial.println("Alle Nummers als Hexadecimaal:");
  Serial.println(decNummer, HEX);
  Serial.println(hexNummer, HEX);
  Serial.println(binNummer, HEX);

  Serial.println("Alle Nummers als Binair:");
  Serial.println(decNummer, BIN);
  Serial.println(hexNummer, BIN);
  Serial.println(binNummer, BIN);  
}

void loop() {
  // leave empty for now
}

De output van dit voorbeeld (merk op dat “, DEC” toevoegen dus niet nodig is):

Alle Nummers als decimaal:
10
10
762
762
138
138
Alle Nummers als Hexadecimaal:
A
2FA
8A
Alle Nummers als Binair:
1010
1011111010
10001010

Operators (bewerkers)

Nu dat we wat gezien hebben van Data Types, Variabelen, Scope (bereik) en hoe we ze kunnen weergeven (print), wordt het tijd om eens te gaan kijken, naar wat men noemt “Operators“. “Operator” is het Engelse woord voor “Bewerker” – beetje beroerde vertaling, maar het geeft toch wel weer wat ze doen.

Een Operator (bewerker) is een symbool dat iets doet met data.

Dus een Operator “doet iets” met data en is meestal een symbool. Denk daarbij bijvoorbeeld aan het “+” symbool, welke we gebruiken om “optellen” aan te geven in berekeningen. De “+” operator bewerkt dus de data door het op te tellen.

Voor Arduino Programmeren, zouden we 6 basis “groepen” van operators kunnen maken (zie ook de Arduino Reference pagina’s, die helaas in het Engels zijn).
In dit eerste stukje kijken we naar operators voor berekeningen, maar daarna gaan we ook kijken naar andere operators, bijvoorbeeld gebruikt voor het vergelijken van data (informatie).

Rekenkundige Operators

Zoals we al eerder zagen; Operators (bewerkers) kunnen gebruikt worden voor berekeningen, en de meeste van deze symbolen ken je eigenlijk al wel. Sommige van deze symbolen zijn echter net even anders op de computer.

Als voorbeeld, op school heb je geleerd dat een deling er zo uit ziet:  12 : 4 = 3   (in sommige landen gebruikt men het “÷” teken)
Op de computer, en dus ook in de programmeertaal C, schrijft men dit echter als volgt:  12 / 4 = 3

We zien dit ook bij vermenigvuldigen. Op school schrijf je:  3 × 4 = 12  (in wiskunde kan dit ook een “.” zijn)
Op de computer is dit echter: 3 * 4 = 12

Rekenkundige Operators
 Symbool  Doel
=  Toewijzen
+  Optellen
 Aftrekken
*  Vermenigvuldigen
/  Delen
%  Modulo

De onbekende jongen in het rijtje kan de “modulo” operator zijn.
Modulo is wat we op school “deelrest” noemen bij een staartdeling. Als voorbeeld: Stel we delen 5 door 2 met een staartdeling, dan is het antwoord 2 (immers: 2×2=4) en de deelrest is dan 1 omdat 5 – 4 = 1, en 1 kunnen we niet door 2 delen.
Dus,… de “modulo” van 5 gedeeld door 2 is:  5 % 2 = 1.

Nog even een paar voorbeelden:
We delen 10 door 5, dan is het antwoord 2 en de deelrest 0, dus 10 % 5 = 0.
Zo zien we ook dat 33 % 7 = 5, dus 33 delen door 7, resulteert in 5, omdat de deling 4 levert (4×7=28) en de deelrest 5 (33-28=5) is.

Die andere rare jongen is het “is gelijk” teken (=), of te wel een “toewijzing” waarbij bijvoorbeeld een waarde wordt gekopieerd naar b.v. een variabele.

Dit zijn de basis rekenkundige operators. Maar vergeet niet dat een programma in principe een verzameling instructies is waarin we met informatie (data) werken. Dus niet alleen maar rekenen maar ook vergelijken. Niet belangrijk om te onthouden; maar in principe is vergelijk gebaseerd op rekenen.

Vergelijking Operators

Als we bezig zijn met Arduino Programmeren, dan zul je snel merken dat het belangrijk is dat we beslissingen kunnen maken in een programma. Bijvoorbeeld: het licht aanzetten als het donker is. Hiervoor moeten we zaken gaan vergelijken en dat is waar deze groep operators van toepassing gaan zijn.

Je hoeft de volgende operators niet meteen te onthouden, naarmate je meer werkt met beslissingen in een programma, ga je ze vanzelf onthouden.

Bedenk ook dat een vergelijking altijd een antwoord geeft die waar (true) of onwaar (false) is!

Vergelijking levert altijd een waar (true”) of onwaar (false) antwoord – dit is dus een boolean antwoord!

Dus als voorbeeld:  5 > 2  levert waar (true) en  5 < 2 levert onwaar (“false”).
Ehm maar wat betekenen die tekentjes nou? Even in de volgende tabel kijken:

Comparison Operatos
 Symbool  Doel
==  is gelijk aan
!=  is niet gelijk aan
<  is kleiner dan
>  is groter dan
<=  is kleiner dan of gelijk aan
>=  is groter dan of gelijk aan

Het onthouden van de betekenis van deze symbolen is niet altijd even gemakkelijk en daarom hebben we hiervoor een ezelsbruggetje.

Als we voor het “<” teken een plaatje zetten, net als hieronder afgebeeld, dan wordt het een “K“. De “K” van “Kleiner dan”.
Makkelijk hè? Het andere teken wordt daarmee automatisch het tegenovergestelde natuurlijk; groter dan.

Ezelsbruggetje - Kleiner dan

Ezelsbruggetje – Kleiner dan

 

Hieronder dan een klein programma om dit in werking te zien. Vergeet niet: een vergelijking resulteert in een boolean antwoord, en een boolean wordt als nummer opgeslagen dus “true” (1) en “false” (0). Als we een boolean printen (weergeven) dan zien we dus het nummer en niet “true” of “false”.


1
2
3
4
5
6
7
8
9
10
11
12
boolean A;

void setup() {
  Serial.begin(9600);

  A = 5 < 2;
  Serial.print("A = ");
  Serial.println(A);
}

void loop() {
}

Dit voorbeeld doet het volgende:

We definiëren de variabele “A” als een “boolean” (dus een variabele die de waarde “true” of “false” heeft).
We gebruiken de vergelijking operator “<” – in andere woorden, we kijken vergelijken 5 met 2 en kijken dus of 5 kleiner is dan 2. Het voor de hand liggende antwoord is dus natuurlijk ONWAAR (false). Omdat booleans echter als nummer worden opgeslagen, resulteert dit dus in de weergave van het getal “0” (nul).

Meer details over vergelijken in het volgende hoofdstuk …

Boolean Operators

Ook al kan het gebruik van vergelijking operators wat verwarrend zijn, boolean operators zijn misschien nog verwarrender – maar; in het volgende hoofdstuk zal duidelijk worden wat we hier allemaal mee kunnen doen.

Boolean operators zijn operators die we in de gewone taal uitspreken als “en”, “of” en “niet”.

Boolean Operator
 Symbool  Doel
 &&  AND (en)
 ||  OR (of)
 !  NOT (niet)

Ik zal proberen deze voorbeelden uit te leggen, maar het geeft niets als je het allemaal nog niet 100% kunt bevatten.

AND (&&) of te wel: “EN”

De AND operator (Engels voor “en”) kijkt of twee waarden waar zijn.

Stel we hebben 2 boolean waarden, “ZietErUitAlsEenEend” en “KlinktAlsEenEend“.

We gaan deze twee waarden gebruiken om te bepalen of we te maken hebben met een “Eend“, en daarvoor moeten beiden WAAR (true) zijn.
Dus we hebben te maken met een Eend als ZietErUitAlsEenEend AND (EN) KlinktAlsEenEend beiden waar (true) zijn.

Eend = ZietErUitAlsEenEend && KlinktAlsEenEend.

Als een van deze waarden niet waar (false) is, of als zelfs beiden niet waar zijn, dan hebben we dus niet (false) met een Eend te maken.

Hieronder een simpele tabel met voorbeelden. AND levert een WAAR als beide waarden WAAR zijn.

And (en) Resultaten
 Waarde1  Waarde2  Resultaat van Waarde1 AND (en) Waarder2  
 true  true  = true
 true  false  = false
 false  true  = false
 false  false  = false

OR (||) of te wel: “OF”

De OR operator (Engels voor “of”) kijkt of minstens 1 van de 2 waarden waar is.

Laten we als voorbeeld de volgende boolean variabelen bekijken: “DonkerBuiten” en “Na21Uur” (na 9 uur ’s avonds).
Om te kijken of de buiten verlichting aan moet (variabele: “LichtenAan“) moet minstens een van deze twee variabelen waar (true) zijn.

Dus LichtenAan als het DonkerBuiten OR (OF) Na21Uur.

LichtenAan = DonkerBuiten || Na21Uur.

Weer een tabelletje met de mogelijke combinaties. OR levert dus een WAAR (true) als minimaal 1 van de 2 waarden WAAR is.

Or (of) Resultaten
 Waarde1  Waarde2  Resultaat van Waarde2 OR (of) Waarde2 
 true  true  = true
 true  false  = true
 false  true  = true
 false  false  = false

NOT (!) of te wel: “NIET”

De NOT (Engels voor “niet”) draait een boolean om,
Dus een “true”→”false” or “false”→”true” …

De boolean “not” operator draait een boolean om naar diens tegengestelde waarde. Zie het als een licht schakelaar waarbij je het licht aan en uit kunt zetten. Het schakelen van aan naar uit is wat “not” doet. Het geeft het tegenovergestelde antwoord.

Als voorbeeld, als “LichtenAan” waar is (true), dan is NOT (niet) “LichtenAan” dus onwaar (false).
Maar als “LichtenAan” niet waar (false) is, dan is NOT “LichtenAan” dus waar (true).

Dus: NOT true = false, en NOT false = true.

!true = false
!false = true

We hebben hier eigenlijk geen tabel voor nodig, maar om het toch even compleet te maken:

NOT (niet) resultaten
 Waarde1  Resultaat van NOT Waarde1
 true  false
 false  true

Wat kleine experimenten

We hebben nu een aantal operators (bewerkers) doorlopen, laten we eens wat gaan spelen met wat we geleerd hebben.


1
2
3
4
5
6
7
8
9
void setup() {
  Serial.begin(9600);
 
  Serial.print("Het antwoord is: ");
  Serial.println(true && false);
}

void loop() {
}

In dit voorbeeld, gebruiken we de “AND” (&&) boolean operator.

Even niet vergeten dat booleans dus als nummer opgeslagen worden he? Dus true=1 en false=0 wanneer deze weergegeven worden.

In regel 5 kunnen we ook een aantal andere operator voorbeelden zetten:


Serial.println(true && true);   // AND; true and true  = true  = 1
Serial.println(true || true);   // OR ; true or true   = true  = 1
Serial.println(false || false); // OR ; false or false = false = 0
Serial.println(false || true);  // OR ; false or true  = true  = 1
Serial.println(!true);          // NOT; not true       = false = 0

Samengestelde (Compound) Operators

Compound Operators, ook wel “Samengestelde” operators, worden vaak gebruikt om minder te hoeven typen als we een programma schrijven. Dit wordt vaak gebruikt, maar persoonlijk ben ik er niet zo’n fan van omdat het de duidelijkheid of leesbaarheid van jouw programma nadelig beïnvloed. Omdat ze toch zo vaak gebruikt worden, zul je ze wel moeten leren kennen – helaas.

Meestal combineert een Compound Operator twee of meer operators of stappen in 1 stap. Dit maakt leesbaarheid dus wat minder. Merk ook opdat ik hieronder niet alle compound operators vermeldt.

Een Compound Operator (samengestelde operator) combineert een aantal operators of stappen naar een enkele stap …

Compound (Samengestelde) Operators
 Symbol  Purpose  Example
 ++  waarde verhogen  A++; // verhoog A met 1 en geef de oude waarde van A terug
++A; // verhoog A met 1 en geef de nieuwe waarde van A terug
 —  waarde verlagen  A–; // verlaag A met 1 en geef de oude waarde van A terug
–A; // verlaag A met 1 en geef de nieuwe waarde van A terug
 +=  samengetrokken optelling  A += B; // hetzelfde als A = A + B;
 -=  samengetrokken aftrekken  A -= B; // hetzelfde als A = A – B;
 *=  samengetrokken vermenigvuldiging  A *= B; // hetzelfde als A = A * B;
 /=  samengetrokken deling  A /= B; // hetzelfde als A = A / B;
 %=  samengetrokken modulo  A %= B; // hetzelfde als A = A % B;

 

Zoals je hier uit de tabel al kunt opmaken: soms is zo’n compound operator moeilijk te volgen of eenvoudig te verwarren. Omdat we er ook niets mee winnen, wat ons eindprogramma betreft, raad ik beginners zeker aan om deze niet of zo min mogelijk te gebruiken.

Een eenvoudig voorbeeld:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int A = 0;

void setup() {
  Serial.begin(9600);
 
  Serial.print("Setup: A = ");
  Serial.println(A);
}

void loop() {
  Serial.begin(9600);
 
  A += 1; // the same as: A = A + 1;
 
  // print the values to the serial monitor
  Serial.print("Tellen in de loop():  A = ");
  Serial.println(A);

  delay(1000);
}

De output ziet er dan zo uit:

Setup: A = 0
Tellen in de loop(): A = 1
Tellen in de loop(): A = 2
Tellen in de loop(): A = 3
Tellen in de loop(): A = 4
Tellen in de loop(): A = 5
Tellen in de loop(): A = 6
Tellen in de loop(): A = 7
...

Als we nu regel 13 zouden veranderen naar het beter leesbare A = A + 1; , en dit op de Arduino starten, dan zullen we 2 dingen zien.
Als eerste zul je zien dat de compiler precies hetzelfde resultaat levert wat omvang betreft voor beiden voorbeelden (dusA+=1; enA=A+1;) …
Je zult nu ook zien dat A = A + 1; beter leesbaar is.

Dus nogmaals, zeker voor beginners: beperk het gebruik van deze samengestelde (compound) operators.

Pointer Access Operators en Bitwise Operators

Deze twee groepen slaan we hier gewoon over omdat deze toch aanzienlijk meer ervaring eisen. Als je wat meer programmeer ervaring opgedaan hebt, dan zul je vanzelf merken wanneer je ze nodig hebt en het kan zelfs zijn dat je ze nooit nodig zult hebben. 

OK, we hebben weer een hoop informatie voor onze kiezen gekregen en ik adviseer iedereen dan ook om er eens lekker mee te gaan experimenteren, dat zou behulpzaam kunnen zijn in het volgende hoofdstuk van Arduino Programmeren voor Beginners.

Als je vragen hebt: stel ze dan hieronder, en bedenk dat er geen domme vragen zijn, behalve dan natuurlijk de vraag die niet gesteld is. We zijn allemaal een keer bij nul begonnen!

Volgende hoofdstuk: Arduino Programmeren voor Beginners – Deel 4: Beslissingen

Ondersteun ons ...


Jouw ondersteuning wordt zeer gewaardeerd, en hoeft zelfs niets te kosten. Bijvoorbeeld door links naar ons te delen op social media, of andere websites.

Andere vormen kunnen ook gratis zijn (b.v. shoppen op Amazon).
Alle opbrengsten worden gebruikt voor web-hosting kosten, project hardware en software, koffie, etc.

Hartelijk dank voor wie al heeft bijgedragen!
Het is altijd geweldig om te zien hoe men mijn artikeltjes en applicaties weet te waarderen.

Merk op dat het klikken op affiliate links een kleine commissie voor ons kunnen genereren - dit wordt zeer gewaardeerd.

Reacties


Er zijn 40 reacties welke je hieronder kunt lezen.
Je kunt jouw eigen opmerkingen plaatsen m.b.v. dit formulier, of een reactie op een bestaande opmerking plaatsen door op de "Beantwoorden" knop te klikken.

  • 14 aug 2016 - 0:51 - Alfred Reactie Link

    Heel mooi gedaan en zeker een goede uitleg.

    Klein schoonheid foutje wat ik tegen kwam:)

    Bij: Samengestelde (Compound) Operators

    Symbol — waarde verlagen en bij Example staat A++; en ++A;
    Dat moet natuurlijk A–; en –A; zijn.

    Beantwoorden

    Alfred

    • 14 aug 2016 - 10:53 - hans - Auteur: Reactie Link

      Hallo Alfred,

      als eerste dank je wel voor het vinden van die fout – ik heb het meteen verbetert …
      En natuurlijk ook hartelijk dank voor het compliment, dat wordt zeer gewaardeerd en werkt motiverend 

      Beantwoorden

      hans

  • 17 jan 2017 - 23:23 - Pierre Pasmans Reactie Link

    In de tabel met binaire nummers moet het onderste decimale getal niet 16 maar 15 zijn.

    verder hartelijk dank voor de heldere uitleg. Als beginner heb ik daar veel behoefte aan.

    Beantwoorden

    Pierre Pasmans

  • 26 jan 2017 - 10:47 - remko Reactie Link

    Hallo Hans,

    Volgens mij mag er nog een klein stukje bijgevoegd worden in dit hoofdstuk, maar ik kan het natuurlijk ook mis hebben hoor.

    Het volgende onderwerpje: XOR- instructie schrijft je als teken ^.  met waarheidstabel XOR, met bitmanipulatie kan je  de uitgang omkeren. Hierbij wordt de uitgang ingelezen en via XOR-manipultie met het getal 1 geïnverteerd.  Het tabel moet er nog bijgevoegd worden.

    Beantwoorden

    remko

    • 26 jan 2017 - 15:36 - hans - Auteur: Reactie Link

      Hoi Remko,

      dank je wel voor de input! 
      Je hebt helemaal gelijk dat XOR nog toegevoegd zou mogen worden.
      Ik vermoed dat ik deze functie vergeten ben omdat ik deze zo erg zelden gebruik. Ik zal proberen vandaag tijd te vinden om het toe te voegen.

      Dank je wel voor de feedback! 

      Beantwoorden

      hans

    • 26 jan 2017 - 16:01 - hans - Auteur: Reactie Link

      Ah, ik moest nog even wakker worden (pas net m’n eerste kopje koffie op hahah).
      Ik heb bitwise operators bewust uit de “cursus” gelaten omdat werken op bit niveau voor de meeste beginners te verwarrend is en net even te complexe materie. Er zijn natuurlijk een paar uitzonderingen die makkelijk zijn, maar als ik aan het onderwerp begin, dan moet ik natuurlijk meteen alles vermelden.

      Ik denk dat het beter is om dit voor een andere cursus te bewaren.

      Toch nog heel erg bedankt voor de input Remko! 

      Beantwoorden

      hans

      • 27 jan 2017 - 21:19 - remko Reactie Link

        Prima toch!

        Leuk er komt dus nog een cursus voor gevorderden. 

        Heb je misschien een idee wanneer die ongeveer komt? Ik wil je natuurlijk niet onder druk zetten hoor, maar ik ben gewoon enthousiast.

        Beantwoorden

        remko

        • 30 jan 2017 - 0:56 - hans - Auteur: Reactie Link

          Enthousiasme zie ik altijd wel als een positief teken! 

          Ik zal kijken wanneer ik er aan toe kom – helaas moet er een dak boven het hoofd zijn en een boterham op de plak, dus de meeste tijd gaat verloren aan werken overdag … maar ik denk dat m’n neefjes er misschien in de toekomst ook lol aan gaan beleven, dus wie weet. 

          Beantwoorden

          hans

  • 27 apr 2017 - 22:17 - Guido van Laere Reactie Link

    Dank je wel voor deze prachtige en zeer duidelijke cursus!

    Was voor mij absoluut zeer waardevol!

    Beantwoorden

    Guido van Laere

    • 29 apr 2017 - 23:13 - hans - Auteur: Reactie Link

      Hallo Guido!

      Dank je wel voor het compliment! En vooral bedankt dat je de moeite hebt genomen om een bedankje te plaatsen.
      Motiverend voor mij en mooi om te horen dat je wat aan de kleine cursus had! 

      Beantwoorden

      hans

  • 20 mei 2017 - 18:13 - Mjb Reactie Link

    Wat een top uitleg!

    Erg duidelijk allemaal, ik heb normaal een hekel aan lezen. Maar dit leest lekker weg!

    Ga zo door!

    Beantwoorden

    Mjb

    • 20 mei 2017 - 18:28 - hans - Auteur: Reactie Link

      Hallo Mjb!

      Dank je wel voor het geweldige compliment! (Ik heb zelf ook een hekel aan lezen )
      Blij om te horen dat het lekker leest! 

      Beantwoorden

      hans

  • 20 aug 2017 - 10:33 - Leo Reactie Link

    deze lessen waren voor mij heel goed om een begin te krijgen. Heel duidelijke uitleg , bedankt

    Echter loop ik vast op een ding.

    In de les wordt aangegeven dat A=A+1 dit de waarde verhoogd van A met elke keer 1.

    In de loop heb ik staan : float  kwh=kwh+1

    kwh blijft echt 1

    Kunt u aangeven wat er fout is ?

    Beantwoorden

    Leo

    • 20 aug 2017 - 23:40 - Leo Reactie Link

      sorry het was nog gezegd, variabele zijn hoofdletter gevoelig.

      Beantwoorden

      Leo

    • 26 aug 2017 - 16:38 - hans - Auteur: Reactie Link

      Hallo Leo,

      sorry voor de late reactie, en hartelijk dank voor het mooie compliment 
      Nog mooier is dat je zelf de oplossing hebt gevonden … toppie! 

      Beantwoorden

      hans

  • 9 apr 2018 - 13:16 - Hans Reactie Link

    Dank Hans voor je prachtige cursus.

    Heb heel lang geleden, toen C++ werd uitgevonden, wat programmaatjes gemaakt. Deze werden met ponsbandjes gelezen, en na een week kreeg je antwoord of je programma werkte….

    Nu kan ik stap voor stap dingen testen en kijken hoe het werkt en ook veranderingen aanbrengen en er mee “spelen”.

    Er gaat weer n wereld voor mij open!

    Beantwoorden

    Hans

    • 11 apr 2018 - 10:31 - hans - Auteur: Reactie Link

      Hallo naamgenoot!

      Hartelijk dank voor zo’n leuke en positieve reactie – dat werkt motiverend en wordt zeer gewaardeerd.

      Ponsbanden haha, leuk om daar weer eens iets over te horen (mijn eerste printer, way back in the day, was een telex die ook met ponsbanden werkte) 

      Veel plezier met de mini cursus!

      Groetjes,

      Beantwoorden

      hans

  • 25 jun 2018 - 11:26 - Jurgen Reactie Link

    Ik ben al een tijdje aan het spelen met Arduino maar het leren gaat bij mij wat langzaam (zeker als de informatie in het Engels is). Je cursus is dan ook bijzonder inspirerend en zet alles netjes op een rijtje. Ik merk dan ook dat ik één en ander nu echt begin te begrijpen! Hartelijk dank hiervoor!

    Beantwoorden

    Jurgen

    • 26 jun 2018 - 11:55 - hans - Auteur: Reactie Link

      Hoi Jurgen!

      Geweldig om te horen!  Dank je wel dat je de moeite hebt genomen een dank-je-wel bericht te plaatsen, dat wordt zeer gewaardeerd – zeker omdat de Engelstalige versie aanzienlijk vaker bezocht wordt, en ik me soms afvraag of een Nederlands-talige versie nog wel zin heeft. Het antwoord op mijn vraag is dus: Ja! 

      Beantwoorden

      hans

  • 27 jul 2018 - 16:10 - Dirk Reactie Link

    Dag Hans,

    Supercursus en aangenaam om door te gaan !

    Dirk.

    Beantwoorden

    Dirk

    • 30 jul 2018 - 11:23 - hans - Auteur: Reactie Link

      Hoi Drik,

      hartelijk dank voor het compliment – ik ben geen schrijver maar vindt het wel mooi om te horen dat het prettig leesbaar is en dat je er wat aan had! 

      Beantwoorden

      hans

  • 4 dec 2018 - 14:01 - jac Reactie Link

    hoi,Wat fijn om een nederlandstalige cursus te vinden!!!!
    het hoort mogelijk niet helemaal hier thuis maar toch,..
    bij het uitlezen van een HX711 is de volgende mogelijkheid beschikbaar:
    Serial.println(scale.get_units(10), 2);
    lcd.println(scale.get_units(10), 2);
    met (scale.get_units(10), 2) wordt het gemiddelde van 10 waarnemingen weergegeven met 2 cijfers achter de komma.
    dat wordt 2 keer berekend, zowel voor de seriële als voor de lcd opdracht.
    Om tijd te sparen dacht ik een variabele aan te maken, “waarde” (ook in de declaratie) , deze de waarde van (scale.get_units(10), 2) te geven en dan  waarde te laten printen/zenden.
     als volgt:

    float waarde = 0;

    void setup() {
      }
    void loop() {
    ..
    waarde = (scale.get_units(10), 1);
    Serial.println(waarde);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(waarde);

    dit werkt niet, waarde wordt 1 en veranderd niet meer,  dus ik doe het niet goed.
     de gebruikte lib is   github.com/bogde/HX711
    projekt is te vinden op https://www.homemadecircuitsprojects.com/2018/02/weighing-scale-project-using-load-cell.html

    Beantwoorden

    jac

    • 4 dec 2018 - 15:27 - hans - Auteur: Reactie Link

      Hoi Jac,

      dank je wel voor het compliment .
      Iedere keer als ik bijna het Nederlandse deel van de website wil opgeven (want het is en blijft veel werk), krijg ik een motiverende reactie haha. Mooi! We gaan dus door met het Nederlandse deel.

      Ik moest even kijken, scale.get_units() geeft inderdaad een float terug dus “float waarde;” is correct.
      En mee dat ik daarnaar keek zag ik wat er fout ging. Kleinigheidje dat iedereen kan overkomen.
      Kijk ook naar de Arduino Serial.print referentie.

      De volgende regel geeft het float nummer met 1 cijfer achter de komma weer;

      Serial.println(scale.get_units(10), 1);

      En dat is prima want het is een functie van serial.println.
      Echter, een waarde toewijzen aan de variable “waarde” kun je zo niet gebruiken.
      Ten eerste is toewijzen van de waarde geen functie, en al zou het een functie zijn, dan is het formaat aanpassen van het nummer geen optie.

      Pas het volgende aan;

      waarde = scale.get_units(10);  // <--- hier
      Serial.println(waarde,1); // <-- hier
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(waarde,1); // <-- en hier

      Dus de waarde als de “echte” waarde opslaan in de variable “waarde” en pas het formaat aanpassen als het wordt weergegeven.

      Hopelijk help dit. 

      Beantwoorden

      hans

      • 4 dec 2018 - 21:56 - Jac Reactie Link

        dag Hans,

        geweldig !!

        Het werkt nu precies zoals ik bedoeld heb en de uitleg is ook duidelijk.

        Ik ben niet zo’n held in programmeren en als je dan op zoiets blijft hangen wordt je moedeloos.

        Nu weer helemaal gemotiveerd om verder te gaan.

        Jac

        Beantwoorden

        Jac

      • 5 dec 2018 - 22:57 - hans - Auteur: Reactie Link

        Hoi Jac,

        graag gedaan!
        Blij te horen dat het probleem is opgelost en je weer motivatie hebt gevonden .

        Beantwoorden

        hans

  • 5 jan 2019 - 23:58 - Jan Reactie Link

    Hoi Hans

    Mijn zoon heeft van sinterklaas een arduino starters set gekregen 

    Na een dag ledjes te hebben laten knipperen en lcd schermpjes te hebben voorzien van tekst heeft hij allemaal wilde ideeën gekregen 

    “Pap ik wil een dit maken pap ik wil een dat maken, programmeer jij dat even”

    Oeps  wat nu GOOGLE!!

    Toen was ik toch zeer gelukkig dat deze uitleg op mij pad kwam 

    Zeer duidelijke lekker te lezen Nederlandse uitleg 

    Ga hier zeker mee door Hans !!

    Beantwoorden

    Jan

    • 6 jan 2019 - 16:07 - hans - Auteur: Reactie Link

      Hoi Jan,

      geweldig om te horen! 

      Elke keer als ik bijna opgeef voor wat betreft de Nederlandse versie van Tweaking4All, dan weet toch weer iemand me een motiverend bericht te sturen. Helemaal top!

      Ook geweldig om te horen dat jouw zoontje aan de slag gaat met de Arduino. 

      Dank je wel!

      Beantwoorden

      hans

  • 20 sep 2019 - 22:09 - Raymond Reactie Link

    Wat fijn dat je een Nederlandstalige cursus hebt geschreven. Dank je wel!

    Beantwoorden

    Raymond

    • 23 sep 2019 - 11:21 - hans - Auteur: Reactie Link

      Dank je wel Raymond!
      Altijd erg motiverend als men een bedankje voorbij ziet komen, dus dat wordt zeer gewaardeerd. 

      Beantwoorden

      hans

  • 2 jan 2020 - 17:46 - dirk Reactie Link

    Hallo

    Hoe kan ik een waarde aan een variabele toekennen vanaf het toetsenbord terwijl het programma loopt?

    char getal_een;

    char getal_twee;

    char som;

    void setup() 

    {

    Serial.begin(9600);

    }

    void loop() 

    Serial.print(“Geef het eerste getal in”);

    Serial.println(“”);

    //welke instructie moet ik ingeven opdat een getal dat je ingeeft op het toetsenbord in variabele getal_een zou komen?

    Serial.println(“”);

    Serial.print(“Geef het tweede getal in”);

    Serial.println(“”);

    //welke instructie moet ik ingeven opdat een getal dat je ingeeft op het toetsenbord in variabele getal_twee zou komen?

    Serial.print(“De som van de twee getallen is”);

    som=getal_een + getal_twee;

    Serial.print(som);

    while(true) {}

    }

    Beantwoorden

    dirk

    • 4 jan 2020 - 11:57 - hans - Auteur: Reactie Link

      Hi Drik,

      Deel 9 geeft hier meer info over.

      Ik gebruik hiervoor soms een kleine functie:

      String WachtOpInvoer(String Vraag) {
        Serial.println(Vraag);
       
        while(!Serial.available()) {
          // wacht op input
        }
       
        return Serial.readStringUntil(10);
      }

      Die je dan aanroept als volgt:

      ...
      String antwoord;
      ...
      antwoord = WachtOpInvoer("Voer een geheel nummer in");
      ...
      Serial.print(“Het ingevoerde nummer was:”);
      Serial.println(antwoord);

      Merk op dat de waarde dus een tekst is (String).
      De “String” is een object welke een aantal handige functies heeft, zoals de functie “toInt“, voor conversie naar een geheel nummer. (zo-ook toFloat, of toDouble, voor nummers met een komma)

      Hopelijk helpt je dit op weg.

      Beantwoorden

      hans

  • 7 nov 2020 - 0:14 - Lineke Reactie Link

    Ik ben lekker aan het lezen en het helpt enorm. Programmeren was me niet geheel onbekend maar ik merkte dat ik door de bomen het bos even niet meer zag en wou even terug naar de basis. Daar is jouw site zeer geschikt voor!

    Wat me wel opvalt is dat er hier en daar wat typ- en taalfouten inzitten. Ik snap ook wel dat je geen zin hebt om je daar ook nog mee bezig te houden. 

    Idee: zal ik voor jou de tekst eens kritisch onder de loep nemen? Niet inhoudelijk want dat is gewoon goed, maar qua tekst? 

    Meldt maar of je dat prettig zou vinden. 

    Dank voor alle tips tot dusver!

    Beantwoorden

    Lineke

    • 7 nov 2020 - 11:09 - Hans - Auteur: Reactie Link

      Hoi Lineke,

      leuk om te horen dat de kleine cursus een handig hulpmiddel is 

      Type en taalfouten mag je zeker melden. Ik spreek niet meer dagelijks Nederlands (al bijna 20 jaar niet meer), en het vertalen van een artikel kost best wat extra tijd en is dus soms wat gehaast. Je mag me dus zeker fouten melden. Je mag dit hier doen of per email (webmaster at tweaking4all punt com). 

      Beantwoorden

      Hans

      • 7 nov 2020 - 16:23 - Lineke Reactie Link

        Hallo Hans

        Dank je voor je antwoord. Ik zet het dan wel op de mail. Dan pak ik de hele tekst, hoeven allebei alleen maar te kopiëren en te plakken.

        Beantwoorden

        Lineke

      • 7 nov 2020 - 16:42 - Hans - Auteur: Reactie Link

        Fantastisch en het wordt zeer gewaardeerd 

        Beantwoorden

        Hans

  • 17 jan 2021 - 11:44 - Ron Reactie Link

    Net Arduinoset ontvangen en nu leren programmeren. Zeer handige handleiding, ik ben er blij mee!Nu nog kijken of ik mijn kinderen ook enthousiast krijg.

    Beantwoorden

    Ron

    • 17 jan 2021 - 12:19 - Hans - Auteur: Reactie Link

      Hallo Ron!

      Dank je wel voor het plaatsen van een reactie!
      Mooi om te horen dat je blij bent met deze mini cursus 

      Groetjes,

      Beantwoorden

      Hans

  • 12 jul 2021 - 10:33 - Wim Fabrice Reactie Link

    Mooie aanzet om mensen te leren programmeren !!
    Graag een kleine opmerking :

    In Deel 3 > Wat is scope > het stukje broncode vóór je begint met “Nummer Types en Weergave”
    “Laten we eens met een globale variabele werken en diens waarde in de verschillende delen veranderen.”

    Hier mag je in de broncode  in de “loop”  Serial.begin(9600); weglaten.
    Anders krijg je de waarde van de variabele A in de “setup” niet te zien op de seriële monitor.

    Vriendelijke groeten,

    Wim.

    Beantwoorden

    Wim Fabrice

    • 12 jul 2021 - 10:42 - Hans - Auteur: Reactie Link

      Dank je wel Wim voor het compliment en de tip – het wordt zeer gewaardeerd! 
      Ik heb de code aangepast – Serial.being() in de loop() is inderdaad geen goed idee …

      Beantwoorden

      Hans



Jouw Opmerking ...

Plaats hier geen grote bestanden (zoals source codes, log files of config files). Gebruik hiervoor het Forum.

Delen:
*
*
Laat me per email weten als er nieuwe reacties zijn.
       Je kunt jouw RSS reader gebruiken om reacties te volgen.


Tweaking4All gebruikt de gratis Gravatar dienst voor Avatar weergave.