Draaien, klikken, bouwen – in 1 uur een User Interface met de M5Stack Dial – ESP32-S3

3 Januari 2026 –

Eerste kennismaking
Afgelopen maand viel mijn oog op de M5Stack Dial: een slimme draaiknop die vol zit met interessante features. Denk aan een helder 1,28″ rond TFT-touchdisplay, een rotary encoder met drukknop, een ESP32-S3 met WiFi en Bluetooth, een RFID-module voor tagherkenning, een ingebouwde RTC en een brede voedingsrange van 6–36 V of gewoon via USB-C. Deze module werd in 2023 geïntroduceerd door M5Stack Technology Co. Ltd, een Shenzhen-gebaseerd bedrijf dat modulaire IoT-ontwikkelboards en maker-producten ontwerpt en produceert.

Vorm en toepassing
De M5Stack Dial is een compacte, professioneel uitgevoerde ESP32-S3 controller met draaiknop, touchscreen en haptische feedback – een voelbare terugkoppeling: kleine trillingen of klikjes die je met je vingers voelt wanneer je een knop draait of indrukt. – als directe bevestiging dat een actie is geregistreerd, zonder dat je hoeft te kijken. Hij nodigt direct uit tot draaien en drukken, waarbij alle ingebouwde features logisch samenkomen. Ideaal voor IoT-bediening, realtime dashboards en snelle prototypes. Alles zit erin: encoder, display, speaker en sensoren. Maar minstens zo belangrijk: hij ziet er strak uit. Daardoor is hij perfect als fysieke bouwsteen bij prototyping, waarbij de focus meteen kan liggen op user interface design en code.

Programmeerplatformen
Omdat de M5Stack Dial gebaseerd is op een ESP32, is hij toegankelijk voor zowel beginners als gevorderden. Programmeren kan op meerdere platforms, afhankelijk van je ambitie en complexiteit. Als meest voor de hand liggende opties zie ik:
– Arduino IDE – snel starten, veel voorbeelden, ideaal voor prototyping en workshops
– PlatformIO – strakker projectbeheer voor grotere of professionele projecten
– ESP-IDF – maximale controle voor low-level en performance-kritische toepassingen
– UIFlow – low-/no-code met MicroPython, geschikt voor demos en onderwijs

Technische kern
Het hart van de module wordt gevormd door de M5StampS3: een 240 MHz dual-core ESP32-S3 met 8 MB flash. Het display is een 240×240 px rond TFT-scherm met een GC9A01-driver. De rotary encoder levert 64 pulsen per omwenteling. De RFID-chip is een WS1850S en ondersteunt 13,56 MHz ISO14443 NFC-tags. De on-board buzzer is klein, maar luid genoeg voor duidelijke audiofeedback. In deep sleep verbruikt de module slechts 1,9 µA, te wekken via een knop of RTC-interrupt. De twee poorten aan de achterzijde ondersteunen I2C, UART en GPIO. Afmetingen: 51×51×32,3 mm, met een inbouwring van 45 mm.

De uitdaging
Vandaag stel ik mezelf de uitdaging om binnen één uur een interface te bouwen waarmee een maximumtemperatuur ingesteld kan worden. Instellen gebeurt via de rotary encoder in stappen van 0,5 °C. Onderaan het scherm wil ik een progressbar die naast een numerieke ook een visuele weergave geeft. Op de achtergrond draait een actieve animatie van wuivende palmbomen. Daarnaast toon ik een tekstvariabele, standaard ingesteld op ‘BotBerg Prototyping’. Naar rechts draaien verhoogt de temperatuur met een hogere click-toon, naar links verlaagt deze met een lagere toon. Een druk op de encoder zet de temperatuur direct terug naar 20,5 °C.

Benodigdheden M5Stack Dial opstelling
– M5Stack Dial (ESP32-S3) – de centrale hardware met encoder, touchscreen en audiofeedback
– USB-C kabel – voor voeding en programmeren vanaf PC of laptop
– PC of laptop – met Windows, macOS of Linux
– Arduino IDE – programmeeromgeving voor code en upload
– LovyanGFX library – voor het aansturen van het ronde TFT-display

Opzet en libraries
Voor het programmeren gebruik ik de Arduino IDE. Eerst voeg ik de M5Stack Dial boarddefinitie toe en daarna de LovyanGFX-library voor het TFT-display. In de pinmapping definieer ik alle SPI-instellingen voor het scherm (MOSI, MISO, SCLK, CS, RST en BL), plus de GPIO’s voor de rotary encoder, de drukknop en de buzzer.

Interface en logica
Vervolgens definieer ik het TFT-display met de GC9A01-driver binnen LovyanGFX. Voor de achtergrondverlichting stel ik PWM in op de backlight-pin. De encoder A en B krijgen interrupts en daarna kan ik me volledig richten op de user interface. Ik bouw een sunset-gradient, maak sprites voor de wuivende palmbomen en bereken exact de pixelposities voor alle tekst. De progressbar loopt van 0–100 % en schaalt mee met de encoderwaarde. Voor audiofeedback programmeer ik een buzzer die in toonhoogte mee-ademt. Om ongewenste triggers te voorkomen, implementeer ik debounce door alleen een ‘falling edge’ te registreren. In de setup activeer ik alle GPIO’s, interrupts en standaard TFT-instellingen zoals rotatie, helderheid en kleurdiepte. In de loop blijft eigenlijk alleen het updaten van het scherm over.

Resultaat
Na het compileren blijkt dat het programma minder dan 30 % van het totale flashgeheugen gebruikt en dat slechts 6 % van het dynamisch geheugen bezet is. Het uploaden duurt nog geen 3 seconden en direct verschijnt het resultaat op het scherm. De interface reageert snel, elke rotatie geeft hoorbare feedback en op de achtergrond wuiven de palmbomen rustig door. Ik kijk op de klok: 55 minuten sinds de eerste regel code. Uitdaging geslaagd — en weer een stuk kennis en ervaring rijker.