In het vorige deel hebben we de ESP32 zijn eigen WLAN laten opzetten. Met een PC, smartphone of tablet konden we dan inloggen op het netwerk „ESP32_MyJourneyIoT“ en via een webbrowser (op adres 192.168.4.1 van de ESP32-webserver) een configuratieformulier opvragen. Daar vulden we dan in tekstvelden de SSID en het wachtwoord van het eigenlijke huisnetwerk in. Na ontvangst van het formulier probeert de ESP32 meteen verbinding met het router-netwerk te maken, maar ook zijn eigen netwerk blijft beschikbaar. Als het inloggen goed gaat, licht de RGB-LED, die we op het breadboard met het ESP32-Board hadden verbonden, groen op. De ESP32 is nu klaar om via het router-netwerk een andere webpagina te laten zien, waarmee we een andere LED kunnen bedienen.


De ESP32 genereert PWM

Natuurlijk is zo’n groene LED ten teken dat de server klaar is al heel nuttig. Maar een continu oplichtende LED betekent alleen, dat de betreffende poortpen van de controller „hoog“ is. De controller kan intussen best gecrasht zijn en daarom niet meer in staat zijn om aanvragen van clients te verwerken. Een knipperende LED zou al een beter signaal zijn. Zoiets is gemakkelijk te realiseren, als we de Arduino-sketch uit de vorige aflevering een klein beetje aanpassen. In de hoofdlus wordt immers periodiek getest of er een HTTP-aanvraag van een client is binnengekomen en daarna volgt een korte delay van 50 ms (enzovoort). Met een eenvoudige teller kunnen we er gemakkelijk voor zorgen dat de LED bijvoorbeeld (ongeveer) één keer per seconde aan- en uitgaat. Maar ik wilde het nog wat mooier maken, door de LED continu te laten uitfaden. Dat kunnen we doen met de PWM-functies van de ESP32, die de ontwikkelaar van Espressif in een hardware-bibliotheek voor ons beschikbaar heeft gemaakt (zie dit tutorial). Met
ledcSetup(0, 5000, 8);
ledcAttachPin(PinNumber, 0);
 
kunnen we in de setup-functie een PWM-kanaal 0 instellen op een oplossend vermogen van 8 bits en verbinden met een outputpen. In de Loop-functie kunnen we dan met
 
ledcWrite(0, DutyCycle)
 
een duty-cycle 0..255 instellen op dat kanaal. De gebruikelijke PWM-functies van de Arduino, analogWrite(…), werken bij de door mij gebruikte versie van de ESP32-library (nog) niet.


Objectgeoriënteerd programmeren

We staan dus voor de taak om een life sign-signaal te genereren voor de groene LED. En dit keer gaan we die code nu eens zelf in eigen library-files onderbrengen. Ik heb daar een goed tutorial over gevonden op Internet (in het Duits). Ik heb me daardoor laten inspireren, de files RGBLED.h en RGBLED.cpp gemaakt en ze in de library-map van de Arduino-ontwikkelomgeving gezet. De compiler zoekt hier standaard naar de code, als we in het hoofdprogramma verwijzen naar de bibliotheek met:
 
#include <RGBLED.h>

De library (die u onderaan deze pagina kunt downloaden) is geschreven in de vorm van een klassenbibliotheek. Die specificeert variabelen en functies en vormt daarmee een blauwdruk voor wat een RGB-LED binnen een programma zou moeten „kunnen“. Zo kunnen we bijvoorbeeld met de functie
 
setRGB(byte colorRed, byte colorGreen, byte colorBlue)
 
8-bits waarden instellen voor de kleuren rood, groen en blauw om veel verschillende kleuren weer te geven. De klassevariabelen
byte redPin;
byte greenPin;
byte bluePin;
 
bevatten echter de nummers van de pennen waar de rode, groene en blauwe LED op zijn aangesloten.
Om een bepaalde RGB-LED aan te spreken in onze toepassingscode, moeten we uit de blauwdruk (de code van de klasse) eerst een object construeren, dat verantwoordelijk wordt voor onze RGB-LED. In het hoofdprogramma doen we dat met
RGBLED BreadboardRGBLED(PIN_LED_RED, PIN_LED_GREEN, PIN_LED_BLUE);

RBGLED is de naam van onze klasse, BreadboardRGBLED is de naam van het object, waarmee we de betreffende RGB-LED vanaf nu in de code van het hoofdprogramma kunnen aanspreken. We geven aan de construerende functie (de constructor) als parameters de nummers van de drie ESP32-pennen, waar de RGB-LED op is aangesloten. Vanwege de hard gecodeerde nummers 0, 1 en 2 van de PWM-kanalen in de library (zie screenshot) is het helaas niet mogelijk, om met deze klasse nog meer objecten aan te maken om andere RGB-LED’s in een project aan te spreken. Voor dat soort functionaliteit zouden tabellen voor het administreren van de hardware-resources nodig zijn.



Vanaf nu kunnen we in het hoofdprogramma de kleuren van onze RGB-LED op het breadboard met
BreadboardRGBLED.setRGB(colorRed, colorGreen, colorBlue);
 
instellen. Dat dat met PWM werkt en dat daarbij de functies ledc… worden gebruikt, speelt zich vanaf nu allemaal achter de schermen af. De ontwikkelaar van het hoofdprogramma hoeft alleen maar de bovengenoemde include-regel, de constructor en de zojuist genoemde „public“ functie te kennen om de kleuren in te kunnen stellen.

Ik heb in de library ook nog een functie dimRGB() geïmplementeerd om de met setRGB() ingestelde kleurwaarde in ongeveer 16 stappen omlaag te kunnen dimmen (bij elke aanroep één stap, en daarna gaat de helderheid weer terug naar de ingestelde kleurwaarde). De functie SwitchRGBLED(…) die we al eerder gebruikt hebben, heb ik ook in de library gezet. Met
 
BreadboardRGBLED.SwitchRGBLED(LED_GREEN);
 
kunnen we de LED groen laten oplichten, met
 
BreadboardRGBLED.SwitchRGBLED(LED_ON);
 
wordt weer de zojuist met setRGB ingestelde kleur gekozen.

ESP32-webserver met life sign

Met de library was het nu gemakkelijk om de ESP32 continu een life sign te laten weergeven, terwijl hij op aanvragen wacht. Als SSID en wachtwoord van de router goed zijn ingesteld, dan licht de RGB-LED niet meer simpelweg continu groen op, maar fadet hij van groen naar donkergroen en flitst dan weer op met volle helderheid.
Ik heb het hoofdprogramma uit de vorige aflevering maar een klein beetje hoeven aan te passen. Voor „delay 50 ms“ heb ik in de hoofdlus de regel
BreadboardRGBLED.dimRGB();
 
tussengevoegd. Maar het dimmen moet alleen gebeuren, als er werkelijk is ingelogd op het netwerk. Daarvoor gebruik ik de nieuwe status-variabele RouterNetworkDeviceState, die bij succesvol inloggen op NETWORKSTATE_LOGGED wordt gezet.

Maar ik kon het toch niet laten om de toepassing van vorige keer nog wat verder uit te breiden. Dat begint met het schema: Op pen 25 van de ESP32 heb ik, via een weerstand van 1 k nog de blauwe LED van de RGB-LED aangesloten. En in het configuratieformulier dat we via „192.168.4.1“ bereiken, kunnen we nu ook de kleur van het OK-signaal aanpassen (zie screenshot). Misschien wilt u immers een blauwe OK-LED in plaats van een groene, of misschien moet de OK-LED wat minder fel oplichten. In plaats van tekstvelden zijn in het formulier drie schuifregelaars (sliders) gebruikt om de kleuren in te stellen.



In het hoofdprogramma worden alle instellingen, net als eerder, beheerd met behulp van arrays. Het nieuwe array
 
int    ConfigType[8];

bepaalt, of de configuratiewaarde van het type String (invoer in een tekstveld) of byte (instelling met een slider) is. De functie
 
String EncodeFormHTMLFromValues(String TitleOfForm, int CountOfConfigValues)

stelt de code van de HTML-pagina samen.
 
Als de pagina op 192.168.4.1 wordt opgeroepen, bevat hij zes configuratiewaarden (de eerste is de waarde voor het instellen van de actuator-LED). Als we de „normale“ pagina oproepen via het router-netwerk, dan bestaat het uitgeleverde formulier alleen uit een tekstveld voor het instellen van deze LED. Omdat we voor beide pagina’s dezelfde functies gebruiken voor het samenstellen van de HTML-code en het evalueren van de antwoorden, is het programma niet erg groot.

Probeer het geheel eens uit. U kunt de Arduino-sketch downloaden onderaan deze pagina. Het is een goed idee om het ook te vergelijken met de sketch van vorige keer. Ook de library zit natuurlijk in de download. De map RGBLED, die de .h- en de .cpp-file bevat, moet (zoals al eerder opgemerkt) in de library-map van de Arduino-IDE worden ondergebracht.
 
In de volgende aflevering gaan we de in de afgelopen afleveringen verworven kennis gebruiken om een apparaat te bouwen dat meetwaarden naar de cloud stuurt.