Voorbeeldprogramma: verschil tussen versies
(69 tussenliggende versies door 3 gebruikers niet weergegeven) | |||
Regel 1: | Regel 1: | ||
{{Hoofdmenu}} | {{Hoofdmenu}} | ||
De Microcontroller wordt in de taal C++ geprogrammeerd. Deze taal heeft een aantal [[regels]] die je in de gaten moet houden om een goed programma te maken. | |||
Die [[regels]] zijn net zoiets als de spelling en gramatica van de Nederlandse of Engelse taal. Ze regelen hoe de taal moet gebruiken. | |||
Als je een programma maakt wat niet volgens de [[regels]] is, zal de computer het niet begrijpen en een foutmelding geven. Je moet dan je programma veranderen. Lees de [[regels]] dus eerst goed, en houd je er aan! Hieronder staan een paar programma's om te beginnen. | |||
<br> | |||
Een aantal voorbeeldprogramma's staan hier: | |||
=De basis= | =De basis= | ||
Dit is een leeg programma. Het doet niets, maar is wel een ''correct'' programma (zonder spelfouten). | Dit is een leeg programma. Het doet niets, maar is wel een ''correct'' programma (zonder spelfouten). | ||
<syntaxhighlight | <syntaxhighlight> | ||
//leeg.ino: Een leeg programma, dit doet niets | //leeg.ino: Een leeg programma, dit doet niets | ||
void setup() | void setup() | ||
Regel 19: | Regel 27: | ||
=Led aan en uit= | =Led aan en uit= | ||
Een programma wat een lampje laat knipperen is de basis voor iedere programmeur. Het laat zien dat alles werkt: | |||
Een | <syntaxhighlight lang="arduino" > | ||
// knipper.ino: knipper de groene led, aan en uit, met 1 seconde ertussen. | // knipper.ino: knipper de groene led, aan en uit, met 1 seconde ertussen. | ||
// Voer deze instructie 1x uit bij het aanzetten | // Voer deze instructie 1x uit bij het aanzetten | ||
void setup() | void setup() | ||
{ | { | ||
pinMode(14, OUTPUT); // Schakel aansluiting (pin) nummer 14 als uitgang. Deze aansluiting is verbonden met de LED | pinMode(14, OUTPUT); // Schakel aansluiting (pin) nummer 14 als uitgang. Deze aansluiting is verbonden met de LED | ||
} | } | ||
Regel 37: | Regel 45: | ||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | delay(1000); // Wacht 1 seconden (1000 milliseconden) | ||
} | } | ||
</syntaxhighlight> | |||
Dan nog een: Dit is een variatie op het eerste programma, maar maakt een wat langer patroon | Dan nog een: Dit is een variatie op het eerste programma, maar maakt een wat langer patroon | ||
<syntaxhighlight> | |||
// knipper2. | // knipper2.ino: Maak een knipper patroon | ||
// Voer deze instructie 1x uit bij het aanzetten | // Voer deze instructie 1x uit bij het aanzetten | ||
void setup() | void setup() | ||
Regel 69: | Regel 77: | ||
delay(1000); | delay(1000); | ||
} | } | ||
</syntaxhighlight> | |||
=Schakelaar inlezen= | =Schakelaar inlezen= | ||
Als je de linker schakelaar S2 indrukt, dan gaat het rode lampje uit. | |||
<syntaxhighlight> | |||
// schakelaar.ino - lees een schakelaar in, en schake led aan en uit | // schakelaar.ino - lees een schakelaar in, en schake led aan en uit | ||
Regel 81: | Regel 92: | ||
void loop() | void loop() | ||
{ | { | ||
if ( digitalRead(5) == HIGH ) | if ( digitalRead(5) == HIGH ) // als de schakelaar HOOG is (niet ingedrukt) | ||
digitalWrite(2, HIGH); | { | ||
else | digitalWrite(2, HIGH); // zet dan de uitgang HOOG (lamp aan) | ||
digitalWrite(2, LOW); | } | ||
else // anders | |||
{ | |||
digitalWrite(2, LOW); // zet de uitgang LAAG (lamp uit) | |||
} | |||
} | } | ||
</syntaxhighlight> | |||
=Wachten op de schakelaar (met while loop)= | |||
<syntaxhighlight> | |||
// wacht.ino - lees een schakelaar in en wacht tot je er op drukt | |||
void setup() | |||
{ | |||
pinMode(5, INPUT_PULLUP); // drukknop, als input | |||
pinMode(2, OUTPUT); // Rode LED als output | |||
pinMode(14, OUTPUT); // Groene LED als output | |||
digitalWrite(2, HIGH); // zet de uitgang HOOG (lamp aan) | |||
while ( digitalRead(5) == HIGH ) // zolang de schakelaar HOOG is (niet ingedrukt) | |||
{ | |||
; // doe niets (en doe de while loop nog een keer) | |||
} | |||
digitalWrite(2, LOW); // zet de rode led uitgang LAAG (lamp uit) | |||
} | |||
// Knipper de groene led in de loop | |||
void loop() | |||
{ | |||
digitalWrite(14, HIGH); | |||
delay(1000); | |||
digitalWrite(14, LOW); | |||
delay(1000); | |||
} | |||
</syntaxhighlight> | |||
=Een servo besturen= | =Een servo besturen= | ||
Sluit de servo aan op de uitgang 13 van de Launchpad. Als je het programma start gaat de servo bewegen tussen twee posities (90 graden uit elkaar) | |||
met een wachttijd van 1 seconde tussen de bewegingen. Meer informatie over de <code>Servo</code> functies vind je op de [[Servo]] pagina. | |||
<syntaxhighlight> | |||
// beweeg.ino: Beweeg een servo tussen twee posities | // beweeg.ino: Beweeg een servo tussen twee posities | ||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden | |||
Servo motorA; // definieer een servo met de naam motorA | |||
void setup() | |||
{ | |||
motorA.attach(13); // vebind servo met aansluitpen 13 | |||
} | |||
Servo | void loop() | ||
{ | |||
motorA.write(30); // beweeg naar 30 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(120); // beweeg naar 120 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
} | |||
</syntaxhighlight> | |||
== Twee servos besturen== | |||
<syntaxhighlight> | |||
// beweeg.ino: Beweeg een servo tussen twee posities | |||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden | |||
Servo motorA; // definieer een servo met de naam motorA | |||
Servo motorB; // definieer een servo met de naam motorB | |||
void setup() | void setup() | ||
{ | { | ||
motorA.attach(13); // vebind servo met aansluitpen 13 | |||
motorB.attach(10); // vebind servo met aansluitpen 10 | |||
} | } | ||
void loop() | void loop() | ||
{ | { | ||
motorA.write(30); // beweeg naar 30 graden stand | |||
delay(1000); | motorB.write (30); // beweeg naar 30 graden stand | ||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
delay(1000); | motorA.write(120); // beweeg naar 120 graden stand | ||
motorB.write(120); // beweeg naar 120 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
} | |||
</syntaxhighlight> | |||
==Servo posities testen== | |||
Om te kijken waar de servo posities precies zijn kun je het volgende programma gebruiken (de maximale posities zijn 0 en 180)<br> | |||
Er zitten al twee motoren in dus je kunt het programma voor de tweede motor aanpassen (of de stekkers even omdraaien)<br> | |||
<syntaxhighlight> | |||
// test.ino: Beweeg de servo naar alle posities | |||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden | |||
Servo motorA; // definieer een servo met de naam motorA | |||
Servo motorB; // definieer een servo met de naam motorB | |||
void setup() | |||
{ | |||
motorA.attach(13); // vebind servo met aansluitpen 13 | |||
motorB.attach(10); // vebind servo met aansluitpen 10 | |||
} | } | ||
void loop() | |||
{ | |||
motorA.write(0); // beweeg naar 0 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(30); // beweeg naar 30 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(60); // beweeg naar 60 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(90); // beweeg naar 90 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(120); // beweeg naar 120 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(150); // beweeg naar 150 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(180); // beweeg naar 180 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
} | |||
</syntaxhighlight> <br><br> | |||
=De servo besturen met de schakelaar= | |||
==Start servo beweging met schakelaar== | |||
Sluit de servo aan op aansluitpen 13 en op 10 van de Launchpad. Druk op de linker schakelaar, de servos gaan nu bewegen. | |||
<syntaxhighlight> | |||
// beweeg.ino: Beweeg servo na drukken op de knop | |||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden | |||
Servo motorA; // definieer een servo met de naam motorA | |||
Servo motorB; // definieer een servo met de naam motorB | |||
void setup() | |||
{ | |||
pinMode(5, INPUT_PULLUP); // drukknop, als input | |||
motorA.attach(13); // vebind servo met aansluitpen 13 | |||
motorB.attach(10); // vebind servo met aansluitpen 10 | |||
while ( digitalRead(5) == HIGH ) // zolang de schakelaar HOOG is (niet ingedrukt) | |||
{ | |||
; // doe niets (en doe de while loop nog een keer) | |||
} | |||
} | |||
// Beweeg motor A en B op en neer | |||
void loop() | |||
{ | |||
motorA.write(30); // beweeg A naar 30 graden stand | |||
delay(100); // Wacht 0,1 seconden (100 milliseconden) | |||
motorB.write (30); // beweeg B naar 30 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
motorA.write(120); // beweeg A naar 120 graden stand | |||
delay(100); // Wacht 0,1 seconden (100 milliseconden) | |||
motorB.write(120); // beweeg B naar 120 graden stand | |||
delay(1000); // Wacht 1 seconden (1000 milliseconden) | |||
} | |||
</syntaxhighlight> | |||
=De servo | ==Stuur servo naar een positie met de schakelaar== | ||
Sluit de servo aan op aansluitpen 13 van de Launchpad, en druk op de linker schakelaar. De servo moet nu tussen twee posities bewegen. | |||
<syntaxhighlight> | |||
// beweeg-schakelaar.ino: Beweeg een servo tussen twee posities | |||
// als je op de schakelaar drukt | |||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken | |||
Servo motor1; // definieer een servo met de naam motor1 | |||
void setup() | |||
{ | |||
motor1.attach(13); // vebind servo met aansluitpen 13 | |||
pinMode(5, INPUT_PULLUP); | |||
} | |||
void loop() | |||
{ | |||
if ( digitalRead(5) == HIGH ) // als de schakelaar HOOG is (niet ingedrukt): | |||
{ | |||
motor1.write(30); // beweeg naar 30 graden stand | |||
} | |||
else // anders: | |||
{ | |||
motor1.write(120); // beweeg naar 120 graden stand | |||
} | |||
} | |||
</syntaxhighlight><br><br> | |||
=Een functie= | =Een functie= | ||
Een functie is een manier om 1x iets te schrijven, en meerdere keren te gebruiken. Hier een voorbeeld van een [[wikipedia:nl:Morse|morse code]] | |||
Eerst worden functies gemaakt voor de ''punt'' en de ''streep'' van de morse code, en vervolgens worden deze functies gebruikt in de <code>morse_s()</code> en <code>morse_o()</code> functie, die in het hoofdprogramma <code>loop()</code> aangeroepen worden om het woord ''SOS'' te maken. | |||
<syntaxhighlight> | |||
// functie.ino - voorbeeld van het gebruik van functies, stuur een morse code (http://nl.wikipedia.org/wiki/Morse) | |||
// Bij het aanzetten: schakel aansluitpen 2 (rode lampje) als uitgang | |||
void setup() | |||
{ | |||
pinMode(2, OUTPUT); | |||
} | |||
// geef een korte flits op de rode lamp | |||
void punt() | |||
{ | |||
digitalWrite(2, HIGH); | |||
delay(200); | |||
digitalWrite(2, LOW); | |||
delay(200); | |||
} | |||
// geef een lange flits op de rode lamp | |||
void streep() | |||
{ | |||
digitalWrite(2, HIGH); | |||
delay(600); | |||
digitalWrite(2, LOW); | |||
delay(200); | |||
} | |||
// stuur de letter "S" | |||
void morse_s() | |||
{ | |||
punt(); | |||
punt(); | |||
punt(); | |||
delay(600); | |||
} | |||
// stuur de letter "O" | |||
void morse_o() | |||
{ | |||
streep(); | |||
streep(); | |||
streep(); | |||
delay(600); | |||
} | |||
// stuur de de hele tijd de morse-code "SOS" (HELP!) via het lampje | |||
void loop() | |||
{ | |||
morse_s(); | |||
morse_o(); | |||
morse_s(); | |||
delay(1400); | |||
} | |||
</syntaxhighlight> | |||
=Een herhaling= | |||
Een herhaling is een manier om een functie een aantal keer uit te voeren. Dat doe je met het <code>for()</code> commando. | |||
Het <code>for()</code> commando gebruik je zo: <code>for( begin; test; ophogen; ) commando;</code>. | |||
In het <code>begin</code> stuk maak je geheugen aan voor een teller. In het <code>test</code> stuk controleer je of je nog door moet gaan. Als dit <code>waar</code> is, dan wordt het commando nog | |||
een keer uitgevoerd. Als het <code>niet waar</code> is stop de herhaling. Bij het <code>ophogen</code> stuk kan je ieder keer de waarde van de variabele veranderen. | |||
<syntaxhighlight> | |||
// forlooop.ino | |||
// | |||
void setup() | |||
{ | |||
pinMode(2,OUTPUT); // groene led is een uitgang | |||
} | |||
// deze loop | |||
void loop() | |||
{ | |||
// 10 keer snel knipperen | |||
for(int teller=0; teller<10; teller = teller + 1 ) | |||
{ | |||
digitalWrite(2, HIGH); // groen aan | |||
delay(100); | |||
digitalWrite(2, LOW); // groen uit | |||
delay(100); | |||
} | |||
// 5 keer langzaam kipperen | |||
for(int teller=0; teller<5; teller = teller + 1 ) | |||
{ | |||
digitalWrite(2, HIGH); // groen aan | |||
delay(200); | |||
digitalWrite(2, LOW); // groen uit | |||
delay(200); | |||
} | |||
} | |||
</syntaxhighlight> | |||
=Een afloop= | =Een afloop= | ||
Een afloop is een manier om verschillende dingen achter elkaar te doen. Het wordt vaak gebruikt in robots. | |||
<syntaxhighlight> | |||
// afloop.ino | |||
int stap; // de stap variabele | |||
void setup() | |||
{ | |||
stap = 1; // we beginnen met stap = 0 | |||
pinMode(2,OUTPUT); // groene led is een uitgang | |||
pinMode(5, INPUT_PULLUP); // de schakelaar is een ingang | |||
pinMode(14,OUTPUT); // rode led is een uitgang | |||
Serial.begin(9600); | |||
} | |||
void loop() | |||
{ | |||
switch( stap ) // doe iets, afhankelijk van de waarde van stap | |||
{ | |||
case 1: // als stap 1 is dan: | |||
digitalWrite(2, HIGH); // groen aan | |||
digitalWrite(14, HIGH); // rood aan | |||
stap = 2; // de volgende keer is stap 2 | |||
break; // stop en ga verder na het einde van de switch } | |||
case 2: // als stap 2 is dan: | |||
digitalWrite(2, LOW); // groen uit | |||
stap = 3; // de volgende keer is stap 3 | |||
break; // stop en ga verder na het einde van de switch } | |||
case 3: // als stap 3 is dan: | |||
if ( digitalRead(5) == LOW ) // als we op de linker knop drukken dan: | |||
stap = 4; // ga naar stap 4 | |||
else | |||
stap = 1; // de volgende keer is stap 1 | |||
break; | |||
case 4: // als stap 4 is dan: | |||
digitalWrite(14, LOW); // rood uit | |||
delay(4000); // wacht | |||
stap = 1; // de volgende keer is stap 1 | |||
break; | |||
default: // als stap een andere waarde heeft dan 1 van de eerder case waarden, dan: | |||
stap = 1; | |||
} | |||
delay(500); // wacht 1/2 seconde | |||
Serial.print("Stap is: "); | |||
Serial.println(stap); | |||
} | |||
</syntaxhighlight> | |||
=Variabelen= | |||
Met variabelen kan je getallen bewaren in de microcontroller. Je kan dit getal meerdere keren gebruiken in je programma en er ook mee | |||
rekenen. Als je de waarde van een variabele verandert, dan verander je de waarde op alle plekken waar deze variabele gebruikt wordt. | |||
Met <code>int</code> definieer je een variabele van het type [http://nl.wikipedia.org/wiki/Integer_%28informatica%29| ''integer'']. Dat is een geheel getal dat een waarde kan hebben van | |||
<code>-32768</code> tot <code>32767</code>. | |||
<syntaxhighlight> | |||
// variabelen.ino | |||
// Zet een variabele en gebruik 'm meerdere keren in je programma | |||
#include <Servo.h> // Gebruik de Servos | |||
int pos1 = 30; // maak een variabele met de naam pos1 en zet hem op de waarde 30 | |||
int pos2 = 60; // maak een variabele met de naam pos2 en zet hem op de waarde 60 | |||
int t1 = 1000; // t1 wordt waarde 1000; | |||
int t2 = 2000; // t2 wordt waarde 2000; | |||
Servo s1; // maak een servo met de naam s1 | |||
void setup() | |||
{ | |||
s1.attach(10); // verbind s1 met pin 10 | |||
} | |||
void loop() | |||
{ | |||
s1.write(pos1); // ga naar pos1 | |||
delay(t1); // wacht t1 | |||
s1.write(pos2); // ga naar pos2 | |||
delay(t1); // wacht t1 | |||
s1.write(pos1); // ga naar pos1 | |||
delay(t2); // wacht t2 | |||
s1.write(pos2); // ga naar pos2 | |||
delay(t2); // wacht t2 | |||
} | |||
</syntaxhighlight> | |||
=Berichten sturen naar de computer= | |||
Met [[Serial]] kan je berichten sturen naar de computer | |||
=Berichten sturen via infrarood licht= | |||
Met [[IR]] kan je berichten sturen met onzichtbaar infrarood licht. Dit kan je gebruiken om verschillende robots met elkaar te laten praten. Je kan het bijvoorbeeld gebruiken om verschillende microcontrollers gelijk te starten, of even snel te laten lopen. Zie ook [[Dirigent]] voor meer voorbeelden. | |||
==Verzenden== | |||
Dir programma verstuurt een IR signaal als je op de linker knop drukt. Het rode ledje gaat uit als je drukt. | |||
<syntaxhighlight> | |||
/* | |||
* irstuur.ino | |||
* Stuur een puls naar de IR led als je op de knop drukt | |||
*/ | |||
void setup() | |||
{ | |||
pinMode(6,OUTPUT); // IR led | |||
pinMode(2,OUTPUT); // rode LED | |||
pinMode(5, INPUT_PULLUP); // schakelaar | |||
} | |||
void loop() | |||
{ | |||
if ( digitalRead(5) == LOW ) // Als je op de linker knop drukt | |||
{ | |||
digitalWrite(2,LOW); // zet rode LED UIT | |||
tone(6,36000,1); // Stuur puls op de IR van 36khz en 1miliseconde lang | |||
delay(1); // Wacht 1 miliseconde | |||
} | |||
else // Anders (als knop niet ingedrukt is): | |||
{ | |||
digitalWrite(2,HIGH); // zet rode LED AAN | |||
} | |||
} | |||
</syntaxhighlight> | |||
==Ontvangen - Simpel== | |||
Als er IR signaal ontvangen wordt, gaat de rode led aan. Kijk met een afstandsbediening (of andere launchpad die staat te zenden) of je signaal ontvangt. | |||
<syntaxhighlight> | |||
/* | |||
* ir.ino | |||
* Simpele IR ontvanger: de rode led gaat aan als IR signaal ontvangen wordt | |||
* het nummer van de knop wordt niet ingelezen (alleen IR AAN/UIT) | |||
*/ | |||
void setup() | |||
{ | |||
pinMode(7,INPUT_PULLUP); // IR sensor | |||
pinMode(2,OUTPUT); // rode LED | |||
} | |||
void loop() | |||
{ | |||
if ( digitalRead(7) == HIGH ) | |||
digitalWrite(2, LOW); | |||
else | |||
digitalWrite(2, HIGH); | |||
}</syntaxhighlight> | |||
==Ontvangen - Wachten op IR== | |||
Dit programma wacht tot er een IR signaal ontvangen wordt, bijvoorbeeld van een afstandsbediening of andere launchpad die staat te zenden. | |||
<syntaxhighlight> | |||
/* | |||
* irwacht.ino | |||
* IR ontvanger: wacht op IR signaal. De rode led gaat uit als IR signaal ontvangen is, | |||
* en dan begint de loop() functie pas | |||
*/ | |||
void setup() | |||
{ | |||
pinMode(7,INPUT_PULLUP); // IR sensor: deze ingang wordt LAAG als er een signaal ontvangen wordt. | |||
pinMode(2,OUTPUT); // Rode LED | |||
pinMode(14,OUTPUT); // Groene LED | |||
digitalWrite(2, HIGH); // Zet rode led aan | |||
digitalWrite(14, LOW); // Zet groene led uit | |||
while ( digitalRead(7) == HIGH ); // Herhaal loop zolang IR signaal HOOG is (en doe niets). | |||
digitalWrite(2, LOW); // Zet rode led uit | |||
} | |||
void loop() | |||
{ | |||
delay(500); // wacht 0.5 sec | |||
digitalWrite(14, HIGH); // Zet groene led aan | |||
delay(500); // wacht o.5 sec | |||
digitalWrite(14, LOW); // Zet groene led uit | |||
}</syntaxhighlight> | |||
==Ontvangen - Met uitlezen van afstandsbedienings knop== | |||
Dit programma leest de IR sensor uit, en kijkt welke knop er van een (TV, DVD of versterker) afstandsbediening ingedrukt wordt. Hij stuurt de waarde van de knop naar de PC via de [[Serial]] poort. Het rode ledje gaat knipperen als er een code ontvangen is. Hij maakt daarvoor gebruik van de | |||
<code>IRremote</code> [[Bibliotheek]]. Je kan hiermee met de afstandsbediending meerdere knoppen herkennen. Let op: Werkt niet met alle aftsandsbedieningen van alle merken. Als hij het niet doet: zoek dan een andere afstandsbediening. | |||
<syntaxhighlight> | |||
/* | |||
* irdump.ino | |||
* ontvang IR signalen, en laat de code zien op het scherm. | |||
* Open het serial window (ctrl+shift+m). Zorg dat de seriele poort goed staat en de jumpers 'horizontaal' staan. | |||
* Richt een afstandsbediending van een TV op de ontvanger en druk op een knop. | |||
* De rode led knippert als er iets ontvangen wordt | |||
*/ | |||
#include <IRremote.h> | |||
IRrecv irrecv(7); // maak een IR ontvanger, verbonden met pin 7 | |||
decode_results results; // geheugen voor het ontvangen van codes | |||
void setup() | |||
{ | |||
Serial.begin(9600); // zet communicatiesnelheid met pc | |||
irrecv.enableIRIn(); // Start de ontvanger | |||
pinMode(2,OUTPUT); | |||
digitalWrite(2,HIGH); | |||
} | |||
void loop() { | |||
if (irrecv.decode(&results)) { // als er een code ontvangen is, | |||
digitalWrite(2,LOW); // Geef een flits op de led | |||
delay(100); // | |||
digitalWrite(2,HIGH); // | |||
Serial.print("IR code: "); // schrijf naar scherm | |||
Serial.println(results.value, HEX); // laat de code dan zien | |||
irrecv.resume(); // ontvang volgende code | |||
} | |||
}</syntaxhighlight> | |||
==Ontvangen - led knippert afhankelijk van de afstandsbediening toets== | |||
Dir programma leest de IR sensor uit, en kijkt welke knop er ingedrukt wordt. | |||
Als je een 1 indrukt gaat de led 1x kinpperen, als je een 2 indrukt gaat de led 2x knipperen enzovoort. | |||
Je kunt in de functies doKey1 .. doKey9 je eigen programma code toevoegen! | |||
<syntaxhighlight> | |||
/* | |||
* infraroodToets.ino | |||
* ontvang IR signalen, en laat de code zien op het scherm. | |||
* Open het serial window (ctrl+shift+m). | |||
* en zorg dat de seriele poort goed staat en de jumpers 'horizontaal' staan. | |||
* Richt een afstandsbediending van een TV op de ontvanger en druk op een knop. | |||
* De rode led knippert het aantal keren van de toets die ingedrukt wordt | |||
*/ | |||
#include <IRremote.h> | |||
IRrecv irrecv(7); // maak een IR ontvanger, verbonden met pin 7 | |||
decode_results results; // geheugen voor het ontvangen van codes | |||
void setup() | |||
{ | |||
Serial.begin(9600); // zet communicatiesnelheid met pc | |||
irrecv.enableIRIn(); // Start de ontvanger | |||
pinMode(2,OUTPUT); | |||
digitalWrite(2,HIGH); | |||
} | |||
void loop() { | |||
if (irrecv.decode(&results)) { // als er een code ontvangen is, | |||
Serial.print("IR code: "); // schrijf naar scherm | |||
Serial.println(results.value, HEX); // laat de code dan zien | |||
int key = results.value % 16; // haal het laatste cijfer op van de code | |||
Serial.print("key: "); // schrijf toets naar scherm | |||
Serial.println(key); | |||
switch (key){ | |||
case 1: | |||
doKey1(); | |||
break; | |||
case 2: | |||
doKey2(); | |||
break; | |||
case 3: | |||
doKey3(); | |||
break; | |||
case 4: | |||
doKey4(); | |||
break; | |||
case 5: | |||
doKey5(); | |||
break; | |||
case 6: | |||
doKey6(); | |||
break; | |||
case 7: | |||
doKey7(); | |||
break; | |||
case 8: | |||
doKey8(); | |||
break; | |||
case 9: | |||
doKey9(); | |||
break; | |||
default: | |||
break; | |||
} | |||
irrecv.resume(); // ontvang volgende code | |||
} | |||
} | |||
void doKey1(){ | |||
flashLed(1); | |||
} | |||
void doKey2(){ | |||
flashLed(2); | |||
} | |||
void doKey3(){ | |||
flashLed(3); | |||
} | |||
void doKey4(){ | |||
flashLed(4); | |||
} | |||
void doKey5(){ | |||
flashLed(5); | |||
} | |||
void doKey6(){ | |||
flashLed(6); | |||
} | |||
void doKey7(){ | |||
flashLed(7); | |||
} | |||
void doKey8(){ | |||
flashLed(8); | |||
} | |||
void doKey9(){ | |||
flashLed(9); | |||
} | |||
void flashLed(int nr) | |||
{ | |||
Serial.print("Flashled: "); // schrijf naar scherm | |||
Serial.println(nr); // laat de code dan zien | |||
for (int i = 0; i < nr; i++) | |||
{ | |||
digitalWrite(2,HIGH); // Geef een flits op de led | |||
delay(100); | |||
digitalWrite(2,LOW); | |||
delay(100); | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
=Dirigent= | |||
Een [[http://nl.wikipedia.org/wiki/Dirigent dirigent]] zorgt ervoor dat alle muzikanten in een orkest gelijk beginnen en in hetzelfde tempo spelen. Als we met ons robot orkest gaan spelen, moeten we ook zorgen dat iedereen op het zelfde moment start en in hetzelfe tempo speelt. | |||
==Probleem== | |||
Hebben wij ook een dirigent nodig bij onze robot orkesten? Robots zijn toch heel precies en doen altijd exact hoe ze geprogrammeerd zijn. Dus waarom zouden ze naar een dirigent moeten luisteren? | |||
Doe het volgende experiment om dat uit te zoeken: | |||
* Zet het programmatje [[Voorbeeldprogramma#Led_aan_en_uit|Led aan en uit]] in '''twee''' launchpad microcontrollers | |||
* Zet de twee launchpads naast elkaar en druk bij beide op de RESET (S1) knop. | |||
* Laat ''op hetzelfe moment'' beide reset knoppen los | |||
* Beide ledjes knipperen als het goed is nu even snel en gelijktijdig | |||
* Wacht ongeveer 2 minuten | |||
* Kijk nu of de ledjes nog steeds gelijktijdig knipperen. Ja? Of hebben we een probleem? | |||
==Wat gebeurt hier?== | |||
Iedere microcontroller heeft zijn eigen klok en die loopt op een vast tempo (hij telt 16miljoen keer per seconde), maar niet iedere klok loopt exact gelijk (je kent het probleem wel van je eigen horloge of wekker) sommige lopen een beetje sneller, andere lopen een beetje langzamer. Dus als je een tijdje wacht, dan zal de klok van de ene microcontroller iets voor gaan lopen, en de andere iets achter. Dan lopen ze dus uit de maat. | |||
==Oplossing== | |||
De oplossing is het maken van een dirigent die de andere robots in de maat kan houden. Hiervoor moeten de microcontrollers met elkaar kunnen ''praten'' dit kan bijvoorbeeld met de infrarood zender en ontvanger. Kijk hiervoor ook naar de voorbeeld programmas [[Voorbeeldprogramma#Verzenden|Verzenden]] en [[Voorbeeldprogramma#Ontvangen_-_Simpel|Ontvangen]]. Dat kan je gebruiken om alle microcontrollers gelijk te laten starten (net zoals bij de knop), maar dat lost het probleem nog niet op, want daarna kunnen ze alsnog uit de maat gaan lopen, omdat hun klokken niet even snel lopen. | |||
Een aanpassing van dit programma kan gebruikt worden om (net als een dirigent) steeds de maat aan te geven. | |||
===Dirigent (zender)=== | |||
<syntaxhighlight> | |||
/* | |||
* dirigent.ino | |||
* Wacht op indrukken van knop S2 en stuur dan continue IR pulsjes, met een snelheid van 1000 per seconde | |||
* Deze pulsjes kunnen ontvangen worden door andere robots (zorg dat de zender en ontvanger elkaar goed zien!) | |||
*/ | |||
void setup() | |||
{ | |||
pinMode(6,OUTPUT); // pen 6: IR led (uitgang) | |||
pinMode(2,OUTPUT); // pen 2: rode LED (uitgang) | |||
pinMode(14,OUTPUT); // pen 14: groene LED (uitgang) | |||
pinMode(5, INPUT_PULLUP); // schakelaar (ingang) | |||
digitalWrite(14,HIGH); // Zet groene led aan | |||
while ( digitalRead(5) == HIGH ); // Loop zolang de knop S2 NIET is ingedruk (groene led is aan) en doe niets | |||
digitalWrite(14,LOW); // Zet groene led uit | |||
} | |||
void loop() | |||
{ | |||
digitalWrite(2,HIGH); // zet rode LED UIT | |||
tone(6,36000,1); // Stuur puls op de IR van 36khz en 1miliseconde lang | |||
delay(1); // wacht 1 milliseconde | |||
digitalWrite(2,LOW); // zet rode LED AAN | |||
} | |||
</syntaxhighlight> | |||
=== De ontvanger === | |||
<syntaxhighlight> | |||
/* | |||
* ontvanger.ino | |||
* IR ontvanger. Telt pulsjes die deze binnenkomen via de IR ontvanger | |||
* Met de wacht() functie kan je wachten tot er een aantal pulsen ontvangen zijn | |||
* Verschillende microcontrollers kunnen nu exact even lang wachten als ze allemaal naar dezelfde zender kijken. | |||
* | |||
*/ | |||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden | |||
Servo motorA; // definieer een servo met de naam motorA | |||
// wacht tot er een aantal pulsen ontvangen is (iedere overgang van LAAG naar HOOG wordt geteld) | |||
void wacht(int pulsen) | |||
{ | |||
while ( pulsen > 0 ) // Zolang we nog niet op nul zijn | |||
{ | |||
while( digitalRead(7) == LOW ); // wacht zolang IR ingang LAAG is | |||
while( digitalRead(7) == HIGH ); // wacht zolang IR ingang HOOG is | |||
pulsen = pulsen - 1; // trek 1 af van de pulsen teller | |||
} | |||
} | |||
// setup: initialiseer de IO's en verbind de signaal functie met de ingang | |||
void setup() | |||
{ | |||
pinMode(7,INPUT_PULLUP); // IR sensor op pen 7 als ingang schakelen | |||
pinMode(2,OUTPUT); // rode LED op pen 2 als uitgang schakelen | |||
motorA.attach(13); // vebind servo met aansluitpen 13 | |||
} | |||
// loop: wacht steeds op een aantal pulsjes, en zet de servo in een andere stand | |||
void loop() | |||
{ | |||
wacht(250); // wacht totdat er 250 pulsjes ontvangen zijn | |||
digitalWrite(2,HIGH); // Rode led aan | |||
motorA.write(40); // Zet de servo op stand 40 | |||
wacht(100); // Wacht totdat er nog 100 pulsjes ontvangen zijn | |||
motorA.write(80); // zet de servo op stand 80 | |||
digitalWrite(2,LOW); // Rode led uit | |||
} | |||
</syntaxhighlight> | |||
=Drumloop= | |||
Dit is een programma wat veel mogelijkheden van de microcontroller gebruikt: | |||
* de posities zijn opgeslagen in variabelen | |||
* Het drumprogramma is opgeslagen in een tabel | |||
Het is bedoeld voor een tweearmige robot. Je kan het ritme aanpassen met de tabel, en de posities van de armen | |||
met a_op, a_neer, b_op en b_neer. | |||
<syntaxhighlight> | |||
// drum2.ino // een geavanceerd drum programma met 2 servos. Heeft variabelen voor positie en een tabel met het drumritme | |||
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden | |||
Servo motorA; // definieer een servo met de naam motorA | |||
Servo motorB; // definieer een servo met de naam motorB | |||
void setup() | |||
{ | |||
pinMode(5, INPUT_PULLUP); // drukknop, als input | |||
motorA.attach(13); // vebind servo met aansluitpen 13 | |||
motorB.attach(10); // vebind servo met aansluitpen 10 | |||
while ( digitalRead(5) == HIGH ) // zolang de schakelaar HOOG is (niet ingedrukt) | |||
{ | |||
; // doe niets (en doe de while loop nog een keer) | |||
} | |||
} | |||
// arm posities | |||
int a_neer = 115; // hoger getal is stokje lager | |||
int b_neer = 25; // lager getal is stokje lager | |||
int a_op = 100; | |||
int b_op = 40; | |||
// tabel met drumritme | |||
int a[] = { 1,0,1,0,1,0,0,0, 1,0,1,0,1,0,0,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0}; //rechts (kort) | |||
int b[] = { 1,0,0,0,1,0,0,0, 1,0,0,0,1,0,0,0, 1,0,1,0,1,0,0,0, 1,0,1,0,1,0,0,0}; //links (lang) | |||
int i = 0; // teller om door de tabel te lopen | |||
// Beweeg motor A en B op en neer | |||
void loop() | |||
{ | |||
i++; // hoog teller 1 op | |||
if ( i > sizeof(a) / sizeof(a[0]) ) // als teller voorbij de laatste waarde van de tabel is: | |||
i = 0; // zet de teller weer op nul (begin van de tabel) | |||
if ( a[i] == 1 ) // Als waarde in tabel a "1" is: | |||
motorA.write(a_neer); // beweeg A naar beneden | |||
else | |||
motorA.write (a_op); // beweeg A omhoog | |||
if ( b[i] == 1) // Als waarde in tabel b "1" is: | |||
motorB.write(b_neer); // beweeg B naar beneden | |||
else | |||
motorB.write (b_op); // beweeg B omhoog | |||
delay(100); // Wacht 0.1 seconden (100 milliseconden) | |||
} | |||
</syntaxhighlight> |
Huidige versie van 17 feb 2014 om 08:21
Beginnen | Hardware | Software | Voorbeeldprogramma | Inkscape & lasersnijden | Errors & Tips | Kekbot | [TrompBot Website] | Trompbots | Percussie & ritme | Fioretti programma
De Microcontroller wordt in de taal C++ geprogrammeerd. Deze taal heeft een aantal regels die je in de gaten moet houden om een goed programma te maken. Die regels zijn net zoiets als de spelling en gramatica van de Nederlandse of Engelse taal. Ze regelen hoe de taal moet gebruiken. Als je een programma maakt wat niet volgens de regels is, zal de computer het niet begrijpen en een foutmelding geven. Je moet dan je programma veranderen. Lees de regels dus eerst goed, en houd je er aan! Hieronder staan een paar programma's om te beginnen.
Een aantal voorbeeldprogramma's staan hier:
De basis
Dit is een leeg programma. Het doet niets, maar is wel een correct programma (zonder spelfouten).
//leeg.ino: Een leeg programma, dit doet niets
void setup()
{
// Hier komen de opdrachten die 1 keer gedaan moeten worden bij het aanzetten
}
void loop()
{
// Hier komen de opdrachten die elke keer gedaan moeten worden
}
tip: Als er op een regel twee forward slashes staan (dat ziet er zo uit: //) dan wordt alles daarna tot het einde van de regel niet gelezen door de computer. Dat is makkelijk want zo kan je commentaar in je programma zetten zodat je zelf nog weet wat je had bedoeld.
Led aan en uit
Een programma wat een lampje laat knipperen is de basis voor iedere programmeur. Het laat zien dat alles werkt:
// knipper.ino: knipper de groene led, aan en uit, met 1 seconde ertussen.
// Voer deze instructie 1x uit bij het aanzetten
void setup()
{
pinMode(14, OUTPUT); // Schakel aansluiting (pin) nummer 14 als uitgang. Deze aansluiting is verbonden met de LED
}
// Blijf deze functie herhalen, zoalang de microcontroller aan staat
void loop()
{
digitalWrite(14, HIGH); // zet pin 14 uitgang HOOG (aan)
delay(1000); // Wacht 1 seconden (1000 milliseconden)
digitalWrite(14, LOW); // zet pin 14 uitgang LAAG (aan)
delay(1000); // Wacht 1 seconden (1000 milliseconden)
}
Dan nog een: Dit is een variatie op het eerste programma, maar maakt een wat langer patroon
// knipper2.ino: Maak een knipper patroon
// Voer deze instructie 1x uit bij het aanzetten
void setup()
{
pinMode(14, OUTPUT); // Schakel aansluiting (pin) nummer 14 als uitgang. Deze aansluiting is verbonden met de LED
}
// Blijf deze functie herhalen, zoalang er spanning op de microcontroller staat
void loop()
{
digitalWrite(14, HIGH);
delay(100);
digitalWrite(14, LOW);
delay(100);
digitalWrite(14, HIGH);
delay(200);
digitalWrite(14, LOW);
delay(200);
digitalWrite(14, HIGH);
delay(200);
digitalWrite(14, LOW);
delay(1000);
}
Schakelaar inlezen
Als je de linker schakelaar S2 indrukt, dan gaat het rode lampje uit.
// schakelaar.ino - lees een schakelaar in, en schake led aan en uit
void setup()
{
pinMode(5, INPUT_PULLUP); // drukknop, als input
pinMode(2, OUTPUT); // LED als output
}
void loop()
{
if ( digitalRead(5) == HIGH ) // als de schakelaar HOOG is (niet ingedrukt)
{
digitalWrite(2, HIGH); // zet dan de uitgang HOOG (lamp aan)
}
else // anders
{
digitalWrite(2, LOW); // zet de uitgang LAAG (lamp uit)
}
}
Wachten op de schakelaar (met while loop)
// wacht.ino - lees een schakelaar in en wacht tot je er op drukt
void setup()
{
pinMode(5, INPUT_PULLUP); // drukknop, als input
pinMode(2, OUTPUT); // Rode LED als output
pinMode(14, OUTPUT); // Groene LED als output
digitalWrite(2, HIGH); // zet de uitgang HOOG (lamp aan)
while ( digitalRead(5) == HIGH ) // zolang de schakelaar HOOG is (niet ingedrukt)
{
; // doe niets (en doe de while loop nog een keer)
}
digitalWrite(2, LOW); // zet de rode led uitgang LAAG (lamp uit)
}
// Knipper de groene led in de loop
void loop()
{
digitalWrite(14, HIGH);
delay(1000);
digitalWrite(14, LOW);
delay(1000);
}
Een servo besturen
Sluit de servo aan op de uitgang 13 van de Launchpad. Als je het programma start gaat de servo bewegen tussen twee posities (90 graden uit elkaar)
met een wachttijd van 1 seconde tussen de bewegingen. Meer informatie over de Servo
functies vind je op de Servo pagina.
// beweeg.ino: Beweeg een servo tussen twee posities
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden
Servo motorA; // definieer een servo met de naam motorA
void setup()
{
motorA.attach(13); // vebind servo met aansluitpen 13
}
void loop()
{
motorA.write(30); // beweeg naar 30 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(120); // beweeg naar 120 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
}
Twee servos besturen
// beweeg.ino: Beweeg een servo tussen twee posities
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden
Servo motorA; // definieer een servo met de naam motorA
Servo motorB; // definieer een servo met de naam motorB
void setup()
{
motorA.attach(13); // vebind servo met aansluitpen 13
motorB.attach(10); // vebind servo met aansluitpen 10
}
void loop()
{
motorA.write(30); // beweeg naar 30 graden stand
motorB.write (30); // beweeg naar 30 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(120); // beweeg naar 120 graden stand
motorB.write(120); // beweeg naar 120 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
}
Servo posities testen
Om te kijken waar de servo posities precies zijn kun je het volgende programma gebruiken (de maximale posities zijn 0 en 180)
Er zitten al twee motoren in dus je kunt het programma voor de tweede motor aanpassen (of de stekkers even omdraaien)
// test.ino: Beweeg de servo naar alle posities
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden
Servo motorA; // definieer een servo met de naam motorA
Servo motorB; // definieer een servo met de naam motorB
void setup()
{
motorA.attach(13); // vebind servo met aansluitpen 13
motorB.attach(10); // vebind servo met aansluitpen 10
}
void loop()
{
motorA.write(0); // beweeg naar 0 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(30); // beweeg naar 30 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(60); // beweeg naar 60 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(90); // beweeg naar 90 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(120); // beweeg naar 120 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(150); // beweeg naar 150 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(180); // beweeg naar 180 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
}
De servo besturen met de schakelaar
Start servo beweging met schakelaar
Sluit de servo aan op aansluitpen 13 en op 10 van de Launchpad. Druk op de linker schakelaar, de servos gaan nu bewegen.
// beweeg.ino: Beweeg servo na drukken op de knop
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden
Servo motorA; // definieer een servo met de naam motorA
Servo motorB; // definieer een servo met de naam motorB
void setup()
{
pinMode(5, INPUT_PULLUP); // drukknop, als input
motorA.attach(13); // vebind servo met aansluitpen 13
motorB.attach(10); // vebind servo met aansluitpen 10
while ( digitalRead(5) == HIGH ) // zolang de schakelaar HOOG is (niet ingedrukt)
{
; // doe niets (en doe de while loop nog een keer)
}
}
// Beweeg motor A en B op en neer
void loop()
{
motorA.write(30); // beweeg A naar 30 graden stand
delay(100); // Wacht 0,1 seconden (100 milliseconden)
motorB.write (30); // beweeg B naar 30 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
motorA.write(120); // beweeg A naar 120 graden stand
delay(100); // Wacht 0,1 seconden (100 milliseconden)
motorB.write(120); // beweeg B naar 120 graden stand
delay(1000); // Wacht 1 seconden (1000 milliseconden)
}
Stuur servo naar een positie met de schakelaar
Sluit de servo aan op aansluitpen 13 van de Launchpad, en druk op de linker schakelaar. De servo moet nu tussen twee posities bewegen.
// beweeg-schakelaar.ino: Beweeg een servo tussen twee posities
// als je op de schakelaar drukt
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken
Servo motor1; // definieer een servo met de naam motor1
void setup()
{
motor1.attach(13); // vebind servo met aansluitpen 13
pinMode(5, INPUT_PULLUP);
}
void loop()
{
if ( digitalRead(5) == HIGH ) // als de schakelaar HOOG is (niet ingedrukt):
{
motor1.write(30); // beweeg naar 30 graden stand
}
else // anders:
{
motor1.write(120); // beweeg naar 120 graden stand
}
}
Een functie
Een functie is een manier om 1x iets te schrijven, en meerdere keren te gebruiken. Hier een voorbeeld van een morse code
Eerst worden functies gemaakt voor de punt en de streep van de morse code, en vervolgens worden deze functies gebruikt in de morse_s()
en morse_o()
functie, die in het hoofdprogramma loop()
aangeroepen worden om het woord SOS te maken.
// functie.ino - voorbeeld van het gebruik van functies, stuur een morse code (http://nl.wikipedia.org/wiki/Morse)
// Bij het aanzetten: schakel aansluitpen 2 (rode lampje) als uitgang
void setup()
{
pinMode(2, OUTPUT);
}
// geef een korte flits op de rode lamp
void punt()
{
digitalWrite(2, HIGH);
delay(200);
digitalWrite(2, LOW);
delay(200);
}
// geef een lange flits op de rode lamp
void streep()
{
digitalWrite(2, HIGH);
delay(600);
digitalWrite(2, LOW);
delay(200);
}
// stuur de letter "S"
void morse_s()
{
punt();
punt();
punt();
delay(600);
}
// stuur de letter "O"
void morse_o()
{
streep();
streep();
streep();
delay(600);
}
// stuur de de hele tijd de morse-code "SOS" (HELP!) via het lampje
void loop()
{
morse_s();
morse_o();
morse_s();
delay(1400);
}
Een herhaling
Een herhaling is een manier om een functie een aantal keer uit te voeren. Dat doe je met het for()
commando.
Het for()
commando gebruik je zo: for( begin; test; ophogen; ) commando;
.
In het begin
stuk maak je geheugen aan voor een teller. In het test
stuk controleer je of je nog door moet gaan. Als dit waar
is, dan wordt het commando nog
een keer uitgevoerd. Als het niet waar
is stop de herhaling. Bij het ophogen
stuk kan je ieder keer de waarde van de variabele veranderen.
// forlooop.ino
//
void setup()
{
pinMode(2,OUTPUT); // groene led is een uitgang
}
// deze loop
void loop()
{
// 10 keer snel knipperen
for(int teller=0; teller<10; teller = teller + 1 )
{
digitalWrite(2, HIGH); // groen aan
delay(100);
digitalWrite(2, LOW); // groen uit
delay(100);
}
// 5 keer langzaam kipperen
for(int teller=0; teller<5; teller = teller + 1 )
{
digitalWrite(2, HIGH); // groen aan
delay(200);
digitalWrite(2, LOW); // groen uit
delay(200);
}
}
Een afloop
Een afloop is een manier om verschillende dingen achter elkaar te doen. Het wordt vaak gebruikt in robots.
// afloop.ino
int stap; // de stap variabele
void setup()
{
stap = 1; // we beginnen met stap = 0
pinMode(2,OUTPUT); // groene led is een uitgang
pinMode(5, INPUT_PULLUP); // de schakelaar is een ingang
pinMode(14,OUTPUT); // rode led is een uitgang
Serial.begin(9600);
}
void loop()
{
switch( stap ) // doe iets, afhankelijk van de waarde van stap
{
case 1: // als stap 1 is dan:
digitalWrite(2, HIGH); // groen aan
digitalWrite(14, HIGH); // rood aan
stap = 2; // de volgende keer is stap 2
break; // stop en ga verder na het einde van de switch }
case 2: // als stap 2 is dan:
digitalWrite(2, LOW); // groen uit
stap = 3; // de volgende keer is stap 3
break; // stop en ga verder na het einde van de switch }
case 3: // als stap 3 is dan:
if ( digitalRead(5) == LOW ) // als we op de linker knop drukken dan:
stap = 4; // ga naar stap 4
else
stap = 1; // de volgende keer is stap 1
break;
case 4: // als stap 4 is dan:
digitalWrite(14, LOW); // rood uit
delay(4000); // wacht
stap = 1; // de volgende keer is stap 1
break;
default: // als stap een andere waarde heeft dan 1 van de eerder case waarden, dan:
stap = 1;
}
delay(500); // wacht 1/2 seconde
Serial.print("Stap is: ");
Serial.println(stap);
}
Variabelen
Met variabelen kan je getallen bewaren in de microcontroller. Je kan dit getal meerdere keren gebruiken in je programma en er ook mee
rekenen. Als je de waarde van een variabele verandert, dan verander je de waarde op alle plekken waar deze variabele gebruikt wordt.
Met int
definieer je een variabele van het type integer. Dat is een geheel getal dat een waarde kan hebben van
-32768
tot 32767
.
// variabelen.ino
// Zet een variabele en gebruik 'm meerdere keren in je programma
#include <Servo.h> // Gebruik de Servos
int pos1 = 30; // maak een variabele met de naam pos1 en zet hem op de waarde 30
int pos2 = 60; // maak een variabele met de naam pos2 en zet hem op de waarde 60
int t1 = 1000; // t1 wordt waarde 1000;
int t2 = 2000; // t2 wordt waarde 2000;
Servo s1; // maak een servo met de naam s1
void setup()
{
s1.attach(10); // verbind s1 met pin 10
}
void loop()
{
s1.write(pos1); // ga naar pos1
delay(t1); // wacht t1
s1.write(pos2); // ga naar pos2
delay(t1); // wacht t1
s1.write(pos1); // ga naar pos1
delay(t2); // wacht t2
s1.write(pos2); // ga naar pos2
delay(t2); // wacht t2
}
Berichten sturen naar de computer
Met Serial kan je berichten sturen naar de computer
Berichten sturen via infrarood licht
Met IR kan je berichten sturen met onzichtbaar infrarood licht. Dit kan je gebruiken om verschillende robots met elkaar te laten praten. Je kan het bijvoorbeeld gebruiken om verschillende microcontrollers gelijk te starten, of even snel te laten lopen. Zie ook Dirigent voor meer voorbeelden.
Verzenden
Dir programma verstuurt een IR signaal als je op de linker knop drukt. Het rode ledje gaat uit als je drukt.
/*
* irstuur.ino
* Stuur een puls naar de IR led als je op de knop drukt
*/
void setup()
{
pinMode(6,OUTPUT); // IR led
pinMode(2,OUTPUT); // rode LED
pinMode(5, INPUT_PULLUP); // schakelaar
}
void loop()
{
if ( digitalRead(5) == LOW ) // Als je op de linker knop drukt
{
digitalWrite(2,LOW); // zet rode LED UIT
tone(6,36000,1); // Stuur puls op de IR van 36khz en 1miliseconde lang
delay(1); // Wacht 1 miliseconde
}
else // Anders (als knop niet ingedrukt is):
{
digitalWrite(2,HIGH); // zet rode LED AAN
}
}
Ontvangen - Simpel
Als er IR signaal ontvangen wordt, gaat de rode led aan. Kijk met een afstandsbediening (of andere launchpad die staat te zenden) of je signaal ontvangt.
/*
* ir.ino
* Simpele IR ontvanger: de rode led gaat aan als IR signaal ontvangen wordt
* het nummer van de knop wordt niet ingelezen (alleen IR AAN/UIT)
*/
void setup()
{
pinMode(7,INPUT_PULLUP); // IR sensor
pinMode(2,OUTPUT); // rode LED
}
void loop()
{
if ( digitalRead(7) == HIGH )
digitalWrite(2, LOW);
else
digitalWrite(2, HIGH);
}
Ontvangen - Wachten op IR
Dit programma wacht tot er een IR signaal ontvangen wordt, bijvoorbeeld van een afstandsbediening of andere launchpad die staat te zenden.
/*
* irwacht.ino
* IR ontvanger: wacht op IR signaal. De rode led gaat uit als IR signaal ontvangen is,
* en dan begint de loop() functie pas
*/
void setup()
{
pinMode(7,INPUT_PULLUP); // IR sensor: deze ingang wordt LAAG als er een signaal ontvangen wordt.
pinMode(2,OUTPUT); // Rode LED
pinMode(14,OUTPUT); // Groene LED
digitalWrite(2, HIGH); // Zet rode led aan
digitalWrite(14, LOW); // Zet groene led uit
while ( digitalRead(7) == HIGH ); // Herhaal loop zolang IR signaal HOOG is (en doe niets).
digitalWrite(2, LOW); // Zet rode led uit
}
void loop()
{
delay(500); // wacht 0.5 sec
digitalWrite(14, HIGH); // Zet groene led aan
delay(500); // wacht o.5 sec
digitalWrite(14, LOW); // Zet groene led uit
}
Ontvangen - Met uitlezen van afstandsbedienings knop
Dit programma leest de IR sensor uit, en kijkt welke knop er van een (TV, DVD of versterker) afstandsbediening ingedrukt wordt. Hij stuurt de waarde van de knop naar de PC via de Serial poort. Het rode ledje gaat knipperen als er een code ontvangen is. Hij maakt daarvoor gebruik van de
IRremote
Bibliotheek. Je kan hiermee met de afstandsbediending meerdere knoppen herkennen. Let op: Werkt niet met alle aftsandsbedieningen van alle merken. Als hij het niet doet: zoek dan een andere afstandsbediening.
/*
* irdump.ino
* ontvang IR signalen, en laat de code zien op het scherm.
* Open het serial window (ctrl+shift+m). Zorg dat de seriele poort goed staat en de jumpers 'horizontaal' staan.
* Richt een afstandsbediending van een TV op de ontvanger en druk op een knop.
* De rode led knippert als er iets ontvangen wordt
*/
#include <IRremote.h>
IRrecv irrecv(7); // maak een IR ontvanger, verbonden met pin 7
decode_results results; // geheugen voor het ontvangen van codes
void setup()
{
Serial.begin(9600); // zet communicatiesnelheid met pc
irrecv.enableIRIn(); // Start de ontvanger
pinMode(2,OUTPUT);
digitalWrite(2,HIGH);
}
void loop() {
if (irrecv.decode(&results)) { // als er een code ontvangen is,
digitalWrite(2,LOW); // Geef een flits op de led
delay(100); //
digitalWrite(2,HIGH); //
Serial.print("IR code: "); // schrijf naar scherm
Serial.println(results.value, HEX); // laat de code dan zien
irrecv.resume(); // ontvang volgende code
}
}
Ontvangen - led knippert afhankelijk van de afstandsbediening toets
Dir programma leest de IR sensor uit, en kijkt welke knop er ingedrukt wordt. Als je een 1 indrukt gaat de led 1x kinpperen, als je een 2 indrukt gaat de led 2x knipperen enzovoort. Je kunt in de functies doKey1 .. doKey9 je eigen programma code toevoegen!
/*
* infraroodToets.ino
* ontvang IR signalen, en laat de code zien op het scherm.
* Open het serial window (ctrl+shift+m).
* en zorg dat de seriele poort goed staat en de jumpers 'horizontaal' staan.
* Richt een afstandsbediending van een TV op de ontvanger en druk op een knop.
* De rode led knippert het aantal keren van de toets die ingedrukt wordt
*/
#include <IRremote.h>
IRrecv irrecv(7); // maak een IR ontvanger, verbonden met pin 7
decode_results results; // geheugen voor het ontvangen van codes
void setup()
{
Serial.begin(9600); // zet communicatiesnelheid met pc
irrecv.enableIRIn(); // Start de ontvanger
pinMode(2,OUTPUT);
digitalWrite(2,HIGH);
}
void loop() {
if (irrecv.decode(&results)) { // als er een code ontvangen is,
Serial.print("IR code: "); // schrijf naar scherm
Serial.println(results.value, HEX); // laat de code dan zien
int key = results.value % 16; // haal het laatste cijfer op van de code
Serial.print("key: "); // schrijf toets naar scherm
Serial.println(key);
switch (key){
case 1:
doKey1();
break;
case 2:
doKey2();
break;
case 3:
doKey3();
break;
case 4:
doKey4();
break;
case 5:
doKey5();
break;
case 6:
doKey6();
break;
case 7:
doKey7();
break;
case 8:
doKey8();
break;
case 9:
doKey9();
break;
default:
break;
}
irrecv.resume(); // ontvang volgende code
}
}
void doKey1(){
flashLed(1);
}
void doKey2(){
flashLed(2);
}
void doKey3(){
flashLed(3);
}
void doKey4(){
flashLed(4);
}
void doKey5(){
flashLed(5);
}
void doKey6(){
flashLed(6);
}
void doKey7(){
flashLed(7);
}
void doKey8(){
flashLed(8);
}
void doKey9(){
flashLed(9);
}
void flashLed(int nr)
{
Serial.print("Flashled: "); // schrijf naar scherm
Serial.println(nr); // laat de code dan zien
for (int i = 0; i < nr; i++)
{
digitalWrite(2,HIGH); // Geef een flits op de led
delay(100);
digitalWrite(2,LOW);
delay(100);
}
}
Dirigent
Een [dirigent] zorgt ervoor dat alle muzikanten in een orkest gelijk beginnen en in hetzelfde tempo spelen. Als we met ons robot orkest gaan spelen, moeten we ook zorgen dat iedereen op het zelfde moment start en in hetzelfe tempo speelt.
Probleem
Hebben wij ook een dirigent nodig bij onze robot orkesten? Robots zijn toch heel precies en doen altijd exact hoe ze geprogrammeerd zijn. Dus waarom zouden ze naar een dirigent moeten luisteren?
Doe het volgende experiment om dat uit te zoeken:
- Zet het programmatje Led aan en uit in twee launchpad microcontrollers
- Zet de twee launchpads naast elkaar en druk bij beide op de RESET (S1) knop.
- Laat op hetzelfe moment beide reset knoppen los
- Beide ledjes knipperen als het goed is nu even snel en gelijktijdig
- Wacht ongeveer 2 minuten
- Kijk nu of de ledjes nog steeds gelijktijdig knipperen. Ja? Of hebben we een probleem?
Wat gebeurt hier?
Iedere microcontroller heeft zijn eigen klok en die loopt op een vast tempo (hij telt 16miljoen keer per seconde), maar niet iedere klok loopt exact gelijk (je kent het probleem wel van je eigen horloge of wekker) sommige lopen een beetje sneller, andere lopen een beetje langzamer. Dus als je een tijdje wacht, dan zal de klok van de ene microcontroller iets voor gaan lopen, en de andere iets achter. Dan lopen ze dus uit de maat.
Oplossing
De oplossing is het maken van een dirigent die de andere robots in de maat kan houden. Hiervoor moeten de microcontrollers met elkaar kunnen praten dit kan bijvoorbeeld met de infrarood zender en ontvanger. Kijk hiervoor ook naar de voorbeeld programmas Verzenden en Ontvangen. Dat kan je gebruiken om alle microcontrollers gelijk te laten starten (net zoals bij de knop), maar dat lost het probleem nog niet op, want daarna kunnen ze alsnog uit de maat gaan lopen, omdat hun klokken niet even snel lopen.
Een aanpassing van dit programma kan gebruikt worden om (net als een dirigent) steeds de maat aan te geven.
Dirigent (zender)
/*
* dirigent.ino
* Wacht op indrukken van knop S2 en stuur dan continue IR pulsjes, met een snelheid van 1000 per seconde
* Deze pulsjes kunnen ontvangen worden door andere robots (zorg dat de zender en ontvanger elkaar goed zien!)
*/
void setup()
{
pinMode(6,OUTPUT); // pen 6: IR led (uitgang)
pinMode(2,OUTPUT); // pen 2: rode LED (uitgang)
pinMode(14,OUTPUT); // pen 14: groene LED (uitgang)
pinMode(5, INPUT_PULLUP); // schakelaar (ingang)
digitalWrite(14,HIGH); // Zet groene led aan
while ( digitalRead(5) == HIGH ); // Loop zolang de knop S2 NIET is ingedruk (groene led is aan) en doe niets
digitalWrite(14,LOW); // Zet groene led uit
}
void loop()
{
digitalWrite(2,HIGH); // zet rode LED UIT
tone(6,36000,1); // Stuur puls op de IR van 36khz en 1miliseconde lang
delay(1); // wacht 1 milliseconde
digitalWrite(2,LOW); // zet rode LED AAN
}
De ontvanger
/*
* ontvanger.ino
* IR ontvanger. Telt pulsjes die deze binnenkomen via de IR ontvanger
* Met de wacht() functie kan je wachten tot er een aantal pulsen ontvangen zijn
* Verschillende microcontrollers kunnen nu exact even lang wachten als ze allemaal naar dezelfde zender kijken.
*
*/
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden
Servo motorA; // definieer een servo met de naam motorA
// wacht tot er een aantal pulsen ontvangen is (iedere overgang van LAAG naar HOOG wordt geteld)
void wacht(int pulsen)
{
while ( pulsen > 0 ) // Zolang we nog niet op nul zijn
{
while( digitalRead(7) == LOW ); // wacht zolang IR ingang LAAG is
while( digitalRead(7) == HIGH ); // wacht zolang IR ingang HOOG is
pulsen = pulsen - 1; // trek 1 af van de pulsen teller
}
}
// setup: initialiseer de IO's en verbind de signaal functie met de ingang
void setup()
{
pinMode(7,INPUT_PULLUP); // IR sensor op pen 7 als ingang schakelen
pinMode(2,OUTPUT); // rode LED op pen 2 als uitgang schakelen
motorA.attach(13); // vebind servo met aansluitpen 13
}
// loop: wacht steeds op een aantal pulsjes, en zet de servo in een andere stand
void loop()
{
wacht(250); // wacht totdat er 250 pulsjes ontvangen zijn
digitalWrite(2,HIGH); // Rode led aan
motorA.write(40); // Zet de servo op stand 40
wacht(100); // Wacht totdat er nog 100 pulsjes ontvangen zijn
motorA.write(80); // zet de servo op stand 80
digitalWrite(2,LOW); // Rode led uit
}
Drumloop
Dit is een programma wat veel mogelijkheden van de microcontroller gebruikt:
- de posities zijn opgeslagen in variabelen
- Het drumprogramma is opgeslagen in een tabel
Het is bedoeld voor een tweearmige robot. Je kan het ritme aanpassen met de tabel, en de posities van de armen met a_op, a_neer, b_op en b_neer.
// drum2.ino // een geavanceerd drum programma met 2 servos. Heeft variabelen voor positie en een tabel met het drumritme
#include <Servo.h> // zeg de computer dat we de servo functies willen gebruiken, anders kan hij die niet vinden
Servo motorA; // definieer een servo met de naam motorA
Servo motorB; // definieer een servo met de naam motorB
void setup()
{
pinMode(5, INPUT_PULLUP); // drukknop, als input
motorA.attach(13); // vebind servo met aansluitpen 13
motorB.attach(10); // vebind servo met aansluitpen 10
while ( digitalRead(5) == HIGH ) // zolang de schakelaar HOOG is (niet ingedrukt)
{
; // doe niets (en doe de while loop nog een keer)
}
}
// arm posities
int a_neer = 115; // hoger getal is stokje lager
int b_neer = 25; // lager getal is stokje lager
int a_op = 100;
int b_op = 40;
// tabel met drumritme
int a[] = { 1,0,1,0,1,0,0,0, 1,0,1,0,1,0,0,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0}; //rechts (kort)
int b[] = { 1,0,0,0,1,0,0,0, 1,0,0,0,1,0,0,0, 1,0,1,0,1,0,0,0, 1,0,1,0,1,0,0,0}; //links (lang)
int i = 0; // teller om door de tabel te lopen
// Beweeg motor A en B op en neer
void loop()
{
i++; // hoog teller 1 op
if ( i > sizeof(a) / sizeof(a[0]) ) // als teller voorbij de laatste waarde van de tabel is:
i = 0; // zet de teller weer op nul (begin van de tabel)
if ( a[i] == 1 ) // Als waarde in tabel a "1" is:
motorA.write(a_neer); // beweeg A naar beneden
else
motorA.write (a_op); // beweeg A omhoog
if ( b[i] == 1) // Als waarde in tabel b "1" is:
motorB.write(b_neer); // beweeg B naar beneden
else
motorB.write (b_op); // beweeg B omhoog
delay(100); // Wacht 0.1 seconden (100 milliseconden)
}