Verplichte vragenlijst
Open de bijbehorende ANS pagina via Toledo (Cursusinhoud -> Labo -> LABO 1: Invulformulier)
Gedurende dit Applicatie College kom je Titels tegen (zoals deze) die je aangeven welke vraag je moet invullen in ANS.
Wanneer de tijd van dit applicatiecollege erop zit, klik op Submit of Verzenden, zelfs indien je nog niet helemaal klaar bent!
De basics
OPGELET: Trek je microcontroller uit wanneer je hardware aanpassingen maakt → Spanningsloos opbouwen!
Het voorbeeld uit de vorige stap demonstreerde wat eigenschappen van het display. Hieronder zie je een meer compacte sketch.
We vertrekken vanaf deze voorbeeld-sketch om jullie kennis te laten maken met de basics.
- Upload onderstaande code naar je microcontroller:
// 1) Importeer libraries
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // Constructor for the TFT library
// 2) Definieer constanten
#define TFT_GREY 0x5AEB // New colour
// 3) Initialiseer variabelen
int numberOfClicks = 0;
// 4) De setup functie (wordt 1x uitgevoerd wanneer de microcontroller spanning krijgt)
void setup(void) {
tft.init();
tft.setRotation(1); //setRotation: 1: Scherm in landscape
}
// 5) De loop functie (wordt uitgevoerd zolang de microcontroller voorzien is van spanning)
void loop() {
// Print titel
tft.fillScreen(TFT_BLACK); //Fill screen with random colour
tft.setCursor(0, 0, 4); //(cursor at 0,0; font 4, println autosets the cursor on the next line)
tft.setTextColor(TFT_BLACK, TFT_YELLOW); // Textcolor, BackgroundColor; independent of the fillscreen
tft.println("- Clicks teller -"); //Print on cursorpos 0,0
// Print aantal
tft.setCursor(0, 50, 4); //(cursor at 0,0; font 4, println autosets the cursor on the next line)
tft.setTextColor(TFT_GREEN,TFT_BLACK); // Green Text with black background
// Test some print formatting functions
tft.print("Aantal = "); tft.println(numberOfClicks); // Print floating point number
delay(100);
numberOfClicks++;
}
5.1 De structuur van een sketch
Iedere Arduino sketch heeft dezelfde structuur. Controleer of je deze structuren kan terugvinden in de code hierboven.
- Importeren van libraries (bibiliotheken met bestaande code)
- Definiëren van constanten
- Initialiseren van variabelen
- De setup functie: Deze wordt 1x uitgevoerd bij het opstarten van de microcontroller (dus ook na elke reset!)
- De loop functie: Na het uitvoeren van de setup zal de loop zichzelf continu blijven herhalen.
Na het uploaden van de vorige sketch zag je het display flikkeren. Dit komt omdat we in de loop telkens het scherm volledig zwart maken met de functie: tft.fillScreen(TFT_BLACK);
In principe moeten we maar 1x het scherm zwart maken en de titel printen. Daarna moet enkel de groene text met “numberOfClicks” worden geüpdatet.
Om het flikkeren te vermijden kan je in de bovenstaande code het printen van de titel 1x uitvoeren in de setup, in plaats van continu in de loop.
Voer deze aanpassing uit en controleer of de flikkering weg is.
Om je setup overzichtelijk te houden kan hiervoor eventueel een nieuwe functie definiëren onder de loop() zoals: Vervolgens kan je deze functie oproepen in setup() met “printTitel();”
void printTitel(){ ... }
5.2 De Serial monitor
De display op de TTGO kan handig zijn tijdens het debuggen van code. Er is echter ook nog een andere manier om leesbare feedback te krijgen van je microcontroller, namelijk met behulp van de Serial Monitor.
- Open de Serial Monitor via Tools > Serial Monitor of via het vergrootglas icoon rechtsboven in de Arduino IDE. (A in de figuur hieronder)
- Je ziet nu een venster waarin niets gebeurt. Laten we daar snel verandering in brengen.
- Om gebruik te maken van de Serial Monitor moet je de functie Serial.begin(115200) uitvoeren in de setup.
- Daarna kan je Serial.println() in de loop gebruiken om info te printen naar de Serial Monitor
#include <TFT_eSPI.h> // Hardware-specific library
TFT_eSPI tft = TFT_eSPI();
int numberOfClicks = 0; //Globale variabele
void setup(void) {
Serial.begin(115200);
tft.init();
tft.setRotation(1); //setRotation: 1: Screen in landscape
// Print titel
tft.fillScreen(TFT_BLACK); //Fill screen with random colour
tft.setCursor(0, 0, 4); //(cursor at 0,0; font 4, println autosets the cursor on the next line)
tft.setTextColor(TFT_BLACK, TFT_YELLOW); // Textcolor, BackgroundColor; independent of the fillscreen
tft.println("- Clicks teller -"); //Print on cursorpos 0,0
}
void loop() {
Serial.println(numberOfClicks); //Print naar de terminal
// Print aantal naar het ingebouwde display
tft.setCursor(0, 50, 4); //(cursor at 0,0; font 4, println autosets the cursor on the next line)
tft.setTextColor(TFT_GREEN,TFT_BLACK); // Green Text with black background
tft.print("Aantal = ");
tft.println(numberOfClicks); // Print naar het ingebouwde Display
delay(100);
numberOfClicks++; //Update het aantal kliks.
}
- Open de Serial monitor via Tools > Serial Monitor of via het vergrootglas icoon rechtsboven in de Arduino IDE
- Stel de baudrate in (115200 baud, B in de figuur hierboven)
- Je ziet nu “numberOfClicks” verschijnen in de Serial Monitor (Veld C in de figuur hierboven)
Als de tekst in je Serial Monitor niet leesbaar is, controleer dan of je baud rate juist is. De baud rate in van je Serial Monitor moet gelijk zijn aan de baud rate die je meegeeft aan de Serial.begin(unsigned long baudRate) functie.
In de Serial Monitor window zie je bovenaan ook een TextField. Dit kan gebruikt worden om berichten naar de microcontroller te sturen. Zo kan je dus bidirectionele seriële communicatie opzetten tussen je computer en microcontroller, maar hier gaan we nu niet verder op in.
Naast de Serial Monitor voorziet de Arduino IDE ook een Serial Plotter. Deze zal later zeker nog gebruikt worden. Je kan de Serial Plotter al eens bekijken door op het symbooltje naast Serial Monitor knopje te klikken.
De Serial Monitor moet niet gesloten worden, maar voordat je opnieuw code gaat uploaden kan je best de plotter eerst sluiten.
5.3 Reset
Onze microcontroller is uitgerust met een reset knop. Wanneer deze knop wordt ingedrukt, dan wordt de processor gereset, en zal de setup functie opnieuw worden uitgevoerd. In onze vorige Sketch zal dus “numberOfClicks” terug 0 worden.
- Test de functionaliteit van de reset knop terwijl je Serial Monitor geopend is.
5.3 GPIO
De TTGO beschikt over een groot aantal GPIO (General Purpose Inputs and Outputs), ze kan deze zien op de afbeelding hieronder.
Merk op dat hier enkele “speciallekes” tussen zitten:
- In principe kan elke GPIO pin als digitale input of als digitale output gebruikt worden, maar sommige GPIO’s kunnen nog iets meer.
- Je kan GPIO pinnen “aanspreken” door gebruik te maken van hun naam die in het grijs staat aangeduid (vb: 2, 17 of 22).
- Digitale input: Om bijvoorbeeld een knop in te lezen (maximaal 3.3V)
- Aan of uit
- Hoog of laag
- 1 of 0
- Digitale output: Om bijvoorbeeld een LED aan te sturen (aan of uit / hoog of laag)
- Hoog = 3.3 V
- Laag = 0 V
- Digitale input: Om bijvoorbeeld een knop in te lezen (maximaal 3.3V)
- Pinnen met het label ADC zijn gekoppeld aan een ADC (Analoog naar Digitaal Convertor). Deze kunnen gebruikt worden om spanningen tussen de 0 V en 3.3 V te meten. Een hogere spanning aanleggen op deze pin ZAL schade veroorzaken aan de microcontroller.
- Pinnen met ADC kunnen bijvoorbeeld gebruikt worden om een draaiknop (potentiometer) mee uit te lezen.
- Pinnen met het label DAC zijn gekoppeld aan een DAC (Digitaal naar Analoog Convertor). Deze pinnen kunnen dus gebruikt worden om een variabele spanning aan te leggen tussen de 0 V en 3.3 V.
- Pinnen met DAC kunnen bijvoorbeeld gebruikt worden als stuursignaal om een DC motor aan te sturen.
- Pinnen met het label touch kunnen gebruikt worden voor capsense toepassingen: dit zijn bijvoorbeeld aanraakgevoelige knoppen, touchwheels of sliders.
- De Wire_SDA en Wire_SCL pin kunnen worden gebruikt voor de communicatie (I²C) tussen microcontroller en randapparatuur/sensoren.
Sla deze afbeelding op op je PC, dat kan handig van pas komen tijdens komende labo’s.
5.3 LED aansturen - de schakeling
We gaan voor de eerste keer gebruik maken van onze GPIO om een LED aan te sturen. We beginnen hieraan door eerst de nodige aansluitingen op ons breadboard te maken.
De naam breadboard kende zijn oorsprong in een tijd waarin men spijkers in een broodplank klopte om daar vervolgens draadjes rond te wikkelen om zo elektrische connecties te maken.
Je moderne breadboard is reeds voorzien van enkele doorverbindingen (zie hieronder).
Deze reeds aanwezige doorverbinden zorgen ervoor dat je componenten met elkaar kan verbinden met een minimum aan draadjes.
Nu is het tijd om zelf te gaan bouwen. Belangrijk hierbij is dat je ALTIJD gebruik maakt van de volgende kleurconventie:
BELANGRIJK:
- Voedingsspanning = alles op 3.3V: RODE draadjes
- GND = REFERENTIE-SPANNING = 0V: ZWARTE draadjes
Bij gebrek aan de bovenstaande kleuren: lichte kleuren voor voedingsspanning (Oranje, Geel, …). Donkere kleuren voor GND (Donker blauw, Bruin, …)
We bouwen NOOIT met een spanning hoger dan 3.3V (dus ook niet de 5V op je bordje!!!). Dit zal je microcontroller onherstelbaar beschadigen!
Bouwen:
- Sluit een kleine rode en zwarte jumper wire aan op de 3.3V pin en de GND zoals hieronder. Dit is heel handig, want hierdoor heb je aan de bovenkant van je breadboard een lijn met 3.3V en aan de onderkant een lijn met GND
We plaatsen de + en de - bewust ver uit elkaar op het breadboard zodat jullie niet zo snel kortsluiting maken. We spreken van kortsluiting wanneer er een directe verbinding is tussen + en -.
- Test nu of je LED werkt door hem aan te sluiten zoals hieronder is weergegeven. Gebruik een 220 Ohm weerstand om de stroom te limiteren. Als je dit niet doet kan je LED stuk gaan.
Let op de polariteit van je led door naar de lengte van het pinnetje of de vlakke zijde te kijken.
Je led moet nu branden!
- Verplaats de weerstand, zodat deze niet meer verbonden is met de +3.3V maar met pin 25. Het is handig om hiervoor een jumperdraad te gebruiken!
Je LED zal nu niet meer branden. We zullen pin 25 gebruiken om de led mee aan te sturen, dit lijkt een “speciale” pin in de pinout, maar je kan deze gewoon gebruiken als een GPIO.
5.4 LED aansturen - de software
In eerste instantie is het handig om een variabele toe te kennen aan de pin waarop we onze led zullen aansluiten
- int firstLedPin = 25; // Kies een naam voor onze ledpin
Vervolgens moeten we in de setup definiëren wat we met onze firstLedPin willen gaan doen. We kunnen hem namelijk gebruiken als input of als output. Dit stellen we in met behulp van de volgende functie:
pinMode(firstLedPin, OUTPUT);
of
pinMode(firstLedPin, INPUT);
- De microcontroller zal de LED aansturen (niet uitlezen). Een LED is dus een OUTPUT.
- –> Configureer de pin in de setup zodat hij gebruikt kan worden om een LED aan te sturen
Nadat de pinMode is toegekend kunnen we firstLedPin gaan gebruiken in de loop. Je kan de pin hoog of laag maken met de volgende functie:
digitalWrite(firstLedPin, HIGH);
of
digitalWrite(firstLedPin, LOW);
- Schrijf code in de loop die ervoor zorgt dat je led 1 keer knippert per seconde
Gebruik de delay() functie
Je LED moet nu knipperen en op het display kan je nu ook aflezen hoe vaak je led al geknipperd heeft.
5.5 Knop inlezen
Je hebt nu succesvol een GPIO als output gebruikt om een LED aan de sturen.
We gaan gelijkaardig te werk om een m.b.v. GPIO een knop in te lezen (INPUT).
Een knop inlezen lijkt misschien triviaal, maar er komt meer bij kijken dan je op het eerste zicht zou denken. Door te leren hoe je een knop uitleest met een microcontroller zal je in praktijk ondervinden hoe digitale elektronica is opgebouwd uit “eentjes” en “nullen”, en wat deze “eentjes” en “nulletjes” betekenen in praktijk, namelijk een “hoge spanning” en een “lage spanning”.
Een lichtknop
Om er een beetje in te komen bekijken we eerst even hoe een lichtknop werkt (zie schema hieronder)
- Indien de schakelaar open is, dan is de stroomkring onderbroken. Er vloeit geen stroom en de lamp brandt niet.
- Indien de schakelaar gesloten is, dan verkrijgen we een gesloten elektrisch circuit. Er vloeit een stroom en de lamp zal branden.
De werking van je huisverlichting kunnen we dus verklaren door middel van stroomkringen die open of dicht zijn.
Een knop inlezen met een microcontroller
Wanneer we een knop willen inlezen met een microcontroller, dan zijn we niet zozeer geïnteresseerd in het uitlezen van een “stroom”.
Om een knop in te lezen, zal onze microcontroller daarentegen het spanningsniveau aan een bepaalde pin inlezen. Wij programmeren de microcontroller, dus wij kunnen de microcontroller meegeven dat:
- Een “hoge ingelezen spanning” overeenkomt met een “ingedrukte schakelaar” en dat
- Een “lage ingelezen spanning” overeenkomt met een “open schakelaar”
Maar evenzeer kunnen we ook het omgekeerde “wijsmaken” aan onze microcontroller.
Maar waarom zouden we onze microcontroller iets “wijsmaken” ? Wel, dat hangt af van het circuitje dat we rond onze schakelaar bouwen.
We beschouwen hieronder vier mogelijke opties om een schakelaar uit te lezen, waarvan er drie werken zoals bedoeld.
Probeer eerst de werking van alle schema’s hieronder te begrijpen. Scroll dan verder naar beneden om te lezen hoe je alle vier de opties zelf kan testen met je eigen microcontroller.
Let op: Jullie microswitch maakt bij een druk op de knop contact tussen pinnen A en B (2 pootjes aan dezelfde kant van de knop).
Voorbeeld Pull-Down schakeling
Gebruik:
- int buttonPin = 2;
- Gebruik een weerstand van 1k Ω
Stel de pinMode in
pinMode(buttonPin, INPUT);
of
pinMode(buttonPin, INPUT_PULLUP) ;
Lees de knop uit in de loop en print de waarde “buttonVal” i.p.v. “numberOfClicks” naar de Serial Monitor
- bool buttonVal = digitalRead(buttonPin);
- Serial.println(buttonVal);
Opdracht: Test elk van de vier opties uit het bovenstaand schema.
Met behulp van je Serial Monitor kan je makkelijk zien of je knop werkt.
Tip:
- Test ook nog eens je Serial Plotter
- De ESP32 ondersteunt naast INPUT_PULLUP ook INPUT_PULLDOWN als pinMode
5.6 OPDRACHT
Werk de volgende code uit:
-
Maak een aparte functie verhoogTeller() die ervoor zorgt dat
- de waarde van “numberOfClicks” verhoogt
- de led blinkt
- de display wordt ge-updated
-
Voer de functie verhoogTeller() uit telkens er op de knop gelikt wordt.
Gebruik IF statement. Google de syntax (Of gebruik een LLM).
Je merkt waarschijnlijk op dat er soms een click teveel geregistreerd wordt. Dit verschijnsel heeft een naam “Switch bounce” of in het Nederlands “Denderen van een knop”. Dit probleem kan hardwarematig opgelost worden m.b.v. een codensator, of softwarematig. We spreken over het “debouncen van een knop”, wanneer we het denderprobleem oplossen of afvangen.
- Debounce de knop softwarematig m.b.v. volgende info - arduino.cc/en/Tutorial/Debounce
VRAAG 1 tot en met 7
LET OP: Roep de docent om je schakeling te tonen, VUL in afwachting VRAAG 1-7 in.
5.7 Analoge potmeter inlezen: schakeling
Quick recap:
- Je kan nu een led aansturen (Digital output: aan of uit)
- Je kan een knop inlezen (Digital input: open of gesloten)
- Je kan een status laten zien via de Serial Output
Nu gaan we een hoeksensor of analoge draaiknop (meestal potentiometer of potmeter genoemd) inlezen.
Jouw potmeter is een variable weerstand, tussen de centrale pin en een van de buitenste pinnen.
- Knop volledig dicht = 0 Ohm (ongeveer)
- Knop volledig open = 50k Ohm (ongeveer)
- De weerstand tussen beide buitenste pinnen blijft constant op ongeveer 50 kOhm
- Sluit de buitenste pinnen van je potmeter aan op de + en - (respectievelijk 3.3V en GND). Zoek zelf uit of de polariteit een rol speelt
- Verbind de middelste pin van de potmeter met een pin die ADC ondersteunt met behulp van een 1k Ohm weerstand in serie.
- De ADC (Analog naar digitaal convertor) is nodig om de analoge waardes om te vormen naar een digitale waarde
5.7 Analoge potmeter inlezen: software
Opgelet: Indien je niet kan uploaden na het aansluiten van de bovenstaande schakeling, controleer even of je geen kortsluiting gemaakt hebt, of te veel stroom uit je ESP trekt. GPIO2 is hier extra gevoelig aan! Dit kan je zien wanneer de backlight van het display zal aan/uit knipperen tijdens het uploaden. Koppel tijdens het uploaden GPIO2 los, of stel een andere pin in in software.
- Definieer je pin nummer met bv:
int potMeterPin = ...
- Stel de pinMode van potMeterPin in
- Lees in de loop de analoge waarde van de potMeterPin in
int potMeterVal = analogRead(potMeterPin)
- Print nu enkel de waarde potMeterVal naar de Serial Monitor om te checken of je draaiknop werkt.
Gebruik: Serial.println();
Test ook opnieuw je Serial Plotter. Voeg wat extra delay() toe als de plot niet duidelijk is
Vraag: Wat is de minimale waarde die je inleest, wat is de maximale waarde? Kan je hieruit afleiden “hoeveel bits de ADC heeft?”
VRAAG 8 tot en met 10
5.8 PWM - Intro
Zoals je in de pinout afbeelding hierboven kan zien beschikt onze TTGO maar over 2 pinnen met een DAC (Digitaal naar analoog convertor). Dit wil zeggen we slechts met 2 pinnen een spanning tussen de 0 V en 3.3 V kunnen uitsturen. Met alle andere pinnen kunnen we enkel 0V of 3.3V uitsturen.
In eerste instantie zou je misschien denken dat we enkel met deze twee DAC pinnen de helderheid van een LED kunnen aanpassen, maar dit is niet het geval. Dankzij PWM (Pulse Width Modulation = Puls breedte modulatie) kunnen we ook spelen met de helderheid van een led, of de snelheid van een DC motor bijvoorbeeld
In geval van PWM hebben het over een digitale uitgang (we kunnen alleen 0 V of 3.3 V uitsturen), maar we gaan hierbij voortdurend schakelen tussen deze twee waardes. Indien we op die wijze bv. een LED zouden aansturen, dan zien we die LED knipperen indien de gehanteerde frequentie laag is (enkele Hz tot maximaal enkele tientallen Hz). Bij hogere frequenties (pakweg boven 70 Hz) reageren onze ogen echter te traag om het aan- en uitschakelen nog waar te nemen. Wat we wel merken, is dat de LED feller lijkt te branden bij een hoge duty cycle dan bij een lage. De duty cycle geeft aan hoeveel procent van de periodetijd de uitgang actief is. Uiteindelijk komt de lichtintensiteit (ongeveer) overeen met de gemiddelde waarde van het PWM-signaal.
Wanneer we gebruik maken van PWM om de helderheid van een LED te beïnvloeden, dan wordt er geen gebruik gemaakt van de DAC (digitaal naar analoog-convertor)!
Door gebruik te maken van een eenvoudige filter kan je het PWM signaal omvormen naar een analoge spanning. Dit wordt voorgesteld in de rechtse figuur hierboven: de groene puls-trein is het PWM signaal, het rode sinusvormige signaal is na filtering. Let op, de meeste microcontrollers kunnen enkel een positieve spanning aanleggen, dus de bovenstaande GIF is niet representatief voor onze ESP32!
5.9 PWM - Op een ESP32
PWM implementeren op een ESP32 is wat complexer dan bij b.v. een doorsnee Arduino microcontroller, vanwege de uitgebreidere hardware.
De ESP32 heeft een PWM controller met 16 onafhankelijke kanalen die geconfigureerd kunnen worden om PWM signalen aan te leggen met verschillende eigenschappen, en deze kunnen aan eender welke GPIO pin gekoppeld worden.
Volg de volgende instructies om een PWM signaal te genereren. We bouwen nog steeds verder aan ons huidig programma en zullen met PWM onze firstLedPin aansturen.
- Initialiseer volgende variabelen om ons PWM signaal te configureren:
// setting PWM properties
const int freq = 5000; // Hz
const int ledChannel = 0;
const int resolution = 8; // Resolutie van de duty cycle, dus in 256 stappen regelbaar
- Voeg de configuratie aan de setup toe:
ledcAttachChannel(firstLedPin, freq, resolution, ledChannel);
- leg het PWM signaal aan in de loop:
for (int brightness = 0 ; brightness <= 255; brightness++) {
ledcWriteChannel(ledChannel, brightness); // leg PWM signaal aan
delay(10);
}
Je zal nu de helderheid van je LED zien veranderen
Opdracht: Speel eens met de waarde van de frequentie, maak deze bv eens 10 Hz. Wat zie je? Zorg dat je dit kan verklaren, vraag anders uitleg aan docenten.
VRAAG 11
5.10 Extra opdrachtjes om de basics onder de knie te krijgen
Jullie kennen nu de basics die nodig zijn om met je microcontroller hardware aan te sturen of uit te lezen
- Digitale input
- Digitale output
- Analog input
- PWM output
- Debouncen van knoppen
- Serial Monitor en Serial Plotter voor debuggen
Voer nu onderstaande opdrachtjes uit om meer vertrouwd te raken met deze technieken.
5.11 LED dimmer met potmeter
Zorg ervoor dat je de intensiteit van de LED kan instellen met de potmeter, door de potentiometer in te lezen in de ESP!
Gebruik de map() functie van Arduino
5.12 Countdown timer
Maak een aftelklokje wat begint bij 60 seconden en dan continu aftelt.
Zorg ervoor dat je met je knop de aftelklok kan pauzeren door een klik, en terug verder kan laten lopen met een tweede klik.
5.13 Twee PWM signalen
Bouw een setup met 2 LEDs die aangesloten zijn op 2 verschillende pinnen. Vergeet de stroombegrenzende weerstand niet!
Leg 2 verschillende PWM signalen aan (2 verschillende channels) aan deze LEDs.
Terwijl de ene led van licht naar donker varieert, moet de andere het omgekeerde doen.
5.14 Vrije opdracht
Nu al klaar?
Bedenk zelf nog een demo die toont wat je vandaag hebt geleerd en toon hem aan de docenten.
5.15 OPRUIMEN
Laat de TTGO op het breadboard zitten, indien je het development board wil loshalen, doe dit dan erg voorzichtig, zodat de pootjes niet ombuigen!