Codewerkplaats Les 5 (Luidspreker)
Dit is al de vijfde les. Deze les gaan we de luidspreker aansluiten en programmeren. Ook leren we hoe we de seriële monitor gebruiken.
Luidspreker [↑]
Deze luidspreker sluiten we aan op pin 8 van de Arduino.
Het pennetje waarbij het min-teken staat komt aan de GND (zwarte draad)
Zo sluit je de luidspreker aan op pin 8 van de Arduino
Luidspreker op het chassis schroeven [↑]
Voor het bevestigen gebruiken we wat dunnere schroeven (M2,5 x 16) met kleinere moertjes en twee afstandsbusjes van 5 mm.
Het programma [↑]
Met het programma hieronder kunnen we de knoppen van de afstandsbediening hiervoor gebruiken:
Knop | Doet dit |
2 | Ga vooruit |
8 | Ga achteruit |
4 | Draai links |
6 | Draai rechts |
5 | STOP |
EQ | Koplampen AAN/UIT |
CH- | Mode Ultrasoon, het karretje rijdt vanzelf en ontwijkt objecten die in de weg staan. |
CH+ | Speel geluid |
Bibliotheken [↑]
Zorg dat je deze libraries in de IDE hebt geladen:
- L298N
NewPing(is niet meer nodig)- IRremote
De code [↑]
Kopieer de code hieronder en plak deze in de IDE op je laptop:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
// Versie 2024-03-26_1630 // Dit is de code die we gaan gebruiken bij de Codewerkplaats op 5-4-2024 // Geschreven door Chris Dorna, met dank aan Paul van Deelen die me hielp // bij het oplossen van het probleem dat de rechter motor niet meer bestuurd // kon worden als de bibliotheek IRremote werd gebruikt. #include <L298N.h> // We gebruiken de library L298N voor de motordriver // Dit programma is getest met versie 2.0.3 van deze bibliotheek #include <IRremote.hpp> // We gebruiken de library IRremote voor de afstandsbediening // Dit programma is getest met versie 4.3.0 van deze bibliotheek unsigned long ontvangenCode; // Variabele om code uit afstandsbediening in op te slaan #define pinLampRechts 6 // Nummer van de pin waarop de koplamp rechts is aangesloten. #define pinLampLinks 7 // Nummer van de pin waarop de koplamp links is aangesloten. #define pinZoemer 8 // Nummer van de pin waarop de zoemer is aangesloten // Maak L298N-object voor de rechter motor L298N motorRechts(5, 4, 3); // ENA, IN1, IN2 // Draad van pin 3 naar IN2 is bruin // Draad van pin 4 naar IN1 is rood // Draad van pin 5 naar ENA is bruin // Maak L298N-object voor de linker motor L298N motorLinks(9, 10, 11); // ENB, IN3, IN4 // Draad van pin 9 naar ENB is bruin // Draad van pin 10 naar IN4 is rood // Draad van pin 11 naar IN3 is oranje int gemetenAfstand = 0; // Wordt gebruikt om de afstand in op te slaan boolean modeUltrasoon = false; // Variabele om aan te geven of robotkarretje // in de mode 'Ultrasoon' moet werken int basissnelheidLinks; // omdat de motoren niet allemaal even snel draaien int basissnelheidRechts; // slaan we de basissnelheid op in deze variabelen int snelheidLinks; // Variabelen om actuele snelheid van de motoren in op te slaan int snelheidRechts; void setup() { pinMode(13, OUTPUT); // LED op de Arduino digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW); pinMode(pinLampRechts, OUTPUT); pinMode(pinLampLinks, OUTPUT); // Hiermee kunnen we informatie van de Arduino naar de laptop sturen. // Dit is handig om fouten in het programma op te sporen Serial.begin(9600); Serial.println("Communicatie tussen Arduino en Serial Monitor van IDE gestart"); IrReceiver.begin(2); // Start IR-ontvanger (aangesloten op pin 2) digitalWrite(pinLampRechts, HIGH); // Koplamp Rechts AAN digitalWrite(pinLampLinks, HIGH); // Koplamp Links AAN basissnelheidLinks = 110; basissnelheidRechts = 125; snelheidLinks = basissnelheidLinks; snelheidRechts = basissnelheidRechts; motorLinks.setSpeed(snelheidLinks); // Instellen snelheid (kan van 0 tot 255) motorRechts.setSpeed(snelheidRechts); } void loop() { if (IrReceiver.decode()) { // Kijken of we een IR-signaal hebben ontvangen ontvangenCode = IrReceiver.decodedIRData.decodedRawData; Serial.println("--------------------"); // Stuur informatie naar de laptop, Serial.print("DEC: "); // dit werkt alleen als de USB-kabel is aangesloten Serial.println(ontvangenCode); // if (ontvangenCode != 0) { // != betekent NIET gelijk switch (ontvangenCode) { case 3125149440: // Knop CH- [ULTRASOON] // Gebruiken we om robot in de stand 'Ultrasoon' te zetten modeUltrasoon = true; Serial.println("*** Knop CH- ***"); break; case 3108437760: // Knop CH Serial.println("*** Knop CH ***"); break; case 3091726080: // Knop CH+ [Geluid afspelen] Serial.println("*** Knop CH+ ***"); for (int i = 0; i < 5; i = i + 1) { // deze lus wordt 5 keer afgespeeld functieSpeelToon(pinZoemer, 500, 500); // 500 Hz 500 ms functieSpeelToon(pinZoemer, 750, 500); // 750 Hz 500 ms } break; case 4077715200: // Knop 1 Serial.println("*** Knop 1 ***"); break; case 3877175040: // Knop 2 [RECHTDOOR] modeUltrasoon = false; Serial.println("*** Knop 2 [RECHTDOOR)] ***"); motorLinks.forward(); // vooruit motorRechts.forward(); // vooruit break; case 2707357440: // Knop 3 Serial.println("*** Knop 3 ***"); break; case 4144561920: // Knop 4 [LINKS] modeUltrasoon = false; Serial.println("*** Knop 4 [LINKS] ***"); motorLinks.stop(); motorRechts.forward(); // vooruit break; case 3810328320: // Knop 5 [STOP en RESET] modeUltrasoon = false; Serial.println("*** Knop 5 [STOP en RESET] ***"); motorLinks.stop(); // stop motorRechts.stop(); // stop snelheidLinks = basissnelheidLinks; // terug naar de basissnelheid snelheidRechts = basissnelheidRechts; break; case 2774204160: // Knop 6 [RECHTS] modeUltrasoon = false; Serial.println("*** Knop 6 [RECHTS] ***"); motorLinks.forward(); // vooruit motorRechts.stop(); break; case 3175284480: //Knop 7 Serial.println("*** Knop 7 ***"); break; case 2907897600: //Knop 8 [ACHTERUIT] modeUltrasoon = false; Serial.println("*** Knop 8 [ACHTERUIT] ***"); motorLinks.backward(); // achteruit motorRechts.backward(); // achteruit break; case 3041591040: //Knop 9 Serial.println("*** Knop 9 ***"); break; case 3910598400: //knop 0 Serial.println("*** Knop 0 ***"); break; case 4127850240: // Knop EQ [LAMPEN AAN/UIT] Serial.println("*** Knop EQ ***"); // Als de koplampen AAN zijn, gaan ze UIT en andersom // Eerder hebben we tegen de Arduino gezegd dat de pinnen 6 // (pinLampLinks) en 7 (pinLampRechts) worden gebruikt als OUTPUT. // met de digitalRead() hieronder kijken we of de lamp AAN of // UIT is. Met het uitroepteken geef je aan dat de waarde moet // worden omgekeerd. // Deze 'omkeertruc'is getest op een Arduino Nano digitalWrite(pinLampRechts, !digitalRead(pinLampRechts)); // Koplamp Rechts digitalWrite(pinLampLinks, !digitalRead(pinLampLinks)); // Koplamp Links break; case 4161273600: // knop MIN [GA LANGZAMER] Serial.println("*** Knop MIN ***"); Serial.print("Snelheid Links: "); Serial.println(snelheidLinks); Serial.print("Snelheid Rechts: "); Serial.println(snelheidRechts); if (snelheidLinks > 25) { snelheidLinks = snelheidLinks - 25; motorLinks.setSpeed(snelheidLinks); // Instellen snelheid motorRechts.setSpeed(snelheidRechts); motorLinks.forward(); // De nieuwe snelheid wordt pas gebruikt motorRechts.forward(); // als je opnieuw een opdracht geeft } break; case 3927310080: // knop PLUS [GA SNELLER] Serial.println("*** Knop PLUS ***"); Serial.print("Snelheid Links: "); Serial.println(snelheidLinks); Serial.print("Snelheid Rechts: "); Serial.println(snelheidRechts); if (snelheidLinks < 225) { snelheidLinks = snelheidLinks + 25; snelheidRechts = snelheidRechts + 25; motorLinks.setSpeed(snelheidLinks); // Instellen snelheid motorRechts.setSpeed(snelheidRechts); motorLinks.forward(); // De nieuwe snelheid wordt pas gebruikt motorRechts.forward(); // als je opnieuw een opdracht geeft } break; } } IrReceiver.resume(); // IrReceiver weer starten } if (modeUltrasoon == true) { functieUltrasoon(); } } void functieUltrasoon() { // We beginnen met het meten we de afstand en zetten deze in // de variabele gemetenAfstand. gemetenAfstand = meetAfstand(16, 17, 40); // pin Trigger = 16 // pin Echo = 17 // Maximale afstand = 40 if (gemetenAfstand > 0 && gemetenAfstand < 10) { // De gemeten afstand is kleiner dan 10 cm // - De twee is gelijk tekens '==' geven aan dat er twee dingen met // elkaar worden vergeleken. // - De twee rechte streepjes '&&', geven EN aan. functieSpeelToon(pinZoemer, 1000, 500); // Laat een toon horen (1000 Hz, 500 ms) digitalWrite(13, HIGH); // LED op Arduino AAN motorLinks.stop(); // motor eerst stoppen vóór je richting omkeert motorRechts.stop(); // motor eerst stoppen vóór je richting omkeert motorLinks.backward(); // achteruit motorRechts.backward(); // achteruit delay(500); motorLinks.stop(); delay(500); motorRechts.stop(); } else { // De gemeten afstand is groter dan 10 cm digitalWrite(13, LOW); // LED op Arduino UIT motorLinks.forward(); // vooruit motorRechts.forward(); // vooruit } } int meetAfstand(int pinTrigger, int pinEcho, int maxAfstand) { // Deze functie bepaalt de afstand tussen de ultrasoonsensor en een // obstakel. // In de Codewerkplaats gaan we niet uitleggen hoe dit werkt en het advies // is om niet te gaan sleutelen aan deze code. // Bereken de maximale wachttijd op basis van de maximale afstand unsigned long maxDuur = (maxAfstand * 2 * 1000000L) / 34300; // in microseconden // Zorg dat de triggerPin laag is en wacht voor stabiliteit pinMode(pinTrigger, OUTPUT); digitalWrite(pinTrigger, LOW); delayMicroseconds(2); // Genereer een korte ultrasone puls digitalWrite(pinTrigger, HIGH); delayMicroseconds(10); // Ultrasone puls duurt 10 microseconden digitalWrite(pinTrigger, LOW); // Zet echoPin als INPUT nadat de puls is verzonden pinMode(pinEcho, INPUT); // Meet de duur van de teruggekeerde echo pulse met een time-out op basis van de maximale afstand long duur = pulseIn(pinEcho, HIGH, maxDuur); if (duur == 0) { // Als er geen echo is gedetecteerd binnen de time-out, geef -1 terug return -1; } // Bereken de afstand gebaseerd op de duur van de echo int afstand = duur * 0.0343 / 2; return afstand; // Geef de gemeten afstand terug } void functieSpeelToon(uint8_t pin, unsigned long frequentie, unsigned int duur) { // Deze functie is gebaseerd op de bibliotheek TimerFreeTone van Tim Eckel // (https://bitbucket.org/teckel12/arduino-timer-free-tone/wiki/Home) // Samen met ChatGPT is de code aangepast voor de Codewerkplaats // In de Codewerkplaats gaan we niet uitleggen hoe dit werkt en het advies // is om niet te gaan sleutelen aan deze code frequentie = 500000 / frequentie; // Bereken de helft van de periode van de vierkante golf (in microseconden). // Zet pin in uitgangsmodus. uint8_t pinBit = digitalPinToBitMask(pin); volatile uint8_t *pinOutput = (uint8_t *)portOutputRegister(digitalPinToPort(pin)); *(uint8_t *)portModeRegister(digitalPinToPort(pin)) |= pinBit; uint32_t startTime = millis(); // Begintijd van de noot. while (millis() - startTime < duur) { // Lus voor de duur. *pinOutput |= pinBit; // Zet pin hoog. delayMicroseconds(frequentie); // Duur van vierkante golf (hoe lang de pin hoog blijven). *pinOutput &= ~pinBit; // Zet pin laag. delayMicroseconds(frequentie); // Duur van vierkante golf (hoe lang de pin laag blijven). } } |
Over de functieSpeelToon
Voor het afspelen vaneen toon zit er in het programma een speciale functie functieSpeelToon().
In de buurt van regel 85 zie je deze code
85 86 87 88 |
for (int i = 0; i < 5; i = i + 1) { // deze lus wordt 5 keer afgespeeld functieSpeelToon(pinZoemer, 500, 500); // 500 Hz 500 ms functieSpeelToon(pinZoemer, 750, 500); // 750 Hz 500 ms } |
Je ziet hier een lus die 5 keer wordt afgespeeld.
Bij het aanroepen van functieSpeelToon geven we drie getallen mee:
- Het eerste getal geeft aan op welke pin de luidspreker is aangesloten. Eerder hebben we een variabele pinZoemer gemaakt en deze de waarde 8 gegeven.
- Het tweede getal is de hoogte van de toon in Hertz.
- Het derde getal geeft aan hoeveel milliseconden de toon moet duren.
Tonen
Pas het programma zo aan dat deze tonen worden gespeeld:
- 262 Hz
- 294 Hz
- 262 Hz
- 349 Hz
- 330 Hz
- 294 Hz
- 262 Hz
- 392 Hz
- 349 Hz
- 330 Hz
- 262 Hz
- 440 Hz
- 349 Hz
- 392 Hz
- 349 Hz
Seriële monitor
In het programma kom je een paar keer de opdracht Serial.Println() tegen.
Hiermee wordt via de USB-kabel informatie van de Arduino naar de IDE gestuurd.
Hieronder zie je een eenvoudig programma dat telt van 0 tot oneindig.
1 2 3 4 5 6 7 8 9 10 11 |
int teller = 0; // Dit is onze teller, en we beginnen bij 0. void setup() { Serial.begin(9600); // Dit start de "chat" met de computer. } void loop() { Serial.println(teller); // De Arduino stuurt het huidige getal naar de computer. teller = teller + 1; // We voegen 1 toe aan de teller. delay(1000); // We wachten 1 seconde voordat we weer optellen. } |
Om de waarde van teller in de Arduino IDE te laten zien moet de Arduino via een USB-kabel met de laptop zijn verbonden.
Klik op de knop Serial Monitor boven in het scherm.
Je kan nu meelezen met de Arduino
9600?
De Seriële monitor kan werken op verschillende snelheden. Het is belangrijk dat de snelheid die je in het programma (groen) en de seriële monitor dezelfde snelheid instelt. 9600 is een veelgebruikte snelheid.
Link naar de website [↑]
Colofon [↑]
Huis73 | maakte het mogelijk om deze lessen te schrijven en organiseert de lessen. | |
Digitaal Atelier | had de spullen voor het lasersnijden en 3d-printen van de onderdelen en is ook nog eens een hartstikke leuke ruimte waar iedereen hartstikke leuke dingen kan doen. | |
Stichting Leaphy | was de eerste die in Nederland op grote schaal Arduino-robotkarretjes beschikbaar stelde en ook nog eens de programmeeromgeving Leaphy Easybloqs ontwikkelde en voor iedereen beschikbaar stelt. | |
CodeKids | bedacht de lessen, ontwikkelde een eigen (goedkoper) karretje en verzorgt de lessen. | |
Iedereen mag materiaal uit deze lessen (her)gebruiken als daarbij de bron (www.codekids.nl) wordt vermeld. |