8 Oktober 2026 –
Twee motoren, een bewegingssensor, een ESP32-S3 en een flinke hoeveelheid software. Wat is ervoor nodig om een robot zelfstandig op twee wielen te laten balanceren?
Een robot die op twee wielen rijdt en daarbij zelf zijn evenwicht bewaart. Het principe is bekend, maar hoe werkt zoiets in de praktijk? En wat komt er allemaal bij kijken om een dergelijke robot zelf te bouwen en aan de praat te krijgen?
Met die vragen ben ik aan de slag gegaan met de Self-Balancing Robot Kit van Elektor. Een bouwpakket waarin mechanica, elektronica, sensortechniek en software samenkomen. Het leek me een interessant project om niet alleen de robot te bouwen, maar vooral ook te ontdekken hoe de balansregeling werkt en welke invloed de verschillende instellingen hebben op het rijgedrag. Zoals wel vaker bij dit soort projecten, bleek het mechanisch in elkaar zetten uiteindelijk niet het lastigste onderdeel.

Wat zit er in het bouwpakket?
De robot is opgebouwd rondom een ESP32-S3 microcontroller. Deze verzorgt de aansturing van de motoren, verwerkt de sensorgegevens en communiceert via Bluetooth met een smartphone. Verder bestaat de kit uit twee DC-reductiemotoren met encoders, een MPU6050 bewegingssensor, een TFT-kleurendisplay, een ultrasone afstandssensor, een accupakket en verschillende onderdelen voor het chassis.
De encoders meten de beweging van de motorassen. De MPU6050 bevat een accelerometer en een gyroscoop, waarmee de robot zijn beweging en hellingshoek kan bepalen. Het interessante is dat deze onderdelen afzonderlijk weinig bijzonders doen. Pas wanneer ze via software samenwerken, ontstaat een systeem dat actief zijn evenwicht kan bewaren.

Eerst de mechanica
De montage begint met het bevestigen van de twee motoren aan het chassis. Vervolgens worden de wielen gemonteerd en krijgen de elektronica, accu en sensoren hun plaats. De constructie bestaat uit meerdere montageplaten die met afstandsbussen aan elkaar worden bevestigd. De transparante bovenplaat geeft zicht op de elektronica en beschermt tegelijkertijd de componenten.
Bij de montage is het belangrijk dat beide motoren goed zijn uitgelijnd, de wielen vrij kunnen draaien en de bedrading nergens tegenaan loopt. De motoren hebben aan de achterzijde een encoderprint. Daarmee kan de ESP32 informatie verzamelen over de draairichting en rotatie van de motoren. Dat is later onder andere handig bij het vergelijken van de twee motoren.

Na het aansluiten van de bekabeling, de accu en het display staat er een compacte tweewielige robot op tafel. Mechanisch is het project dan grotendeels afgerond. Maar rijden doet hij nog niet.

Een ESP32-S3 programmeren met Arduino
Voor de software gebruik ik de Arduino IDE. De robot wordt geleverd met voorbeeldsoftware en verschillende hulpprogramma’s voor het kalibreren van de bewegingssensor en de motoren. De eerste stap is het installeren van de juiste ESP32-boardondersteuning en de benodigde libraries. Ik heb uiteindelijk gewerkt met ESP32 by Espressif Systems versie 2.0.17 en GFX Library for Arduino versie 1.4.6. Die versienummers zijn belangrijk. Zeker bij projecten waarbij verschillende libraries samenwerken, kan een nieuwere versie onverwachte problemen veroorzaken. En dat gebeurde ook hier.
De eerste hindernis: software installeren
Tijdens het installeren van de ESP32-boardondersteuning liep de Arduino IDE tegen een download-time-out aan. Na wat uitzoekwerk bleek dat de standaard netwerk-time-out te kort was. Door in het bestand arduino-cli.yaml (bij Arduino IDE 2 te vinden in de map .arduinoIDE in je gebruikersmap) de verbindingstime-out te verhogen naar 300 seconden, kon de installatie alsnog worden uitgevoerd.
yaml
network:
connection_timeout: 300s
Daarmee was de eerste hindernis genomen. Vervolgens moesten de overige libraries worden geïnstalleerd. Onder andere voor de MPU6050, de motorregeling, het display en de Bluetooth-communicatie. Ook daarbij bleek dat niet iedere combinatie zomaar werkte.
Een aangepaste Dabble-library
Voor de bediening via een smartphone maakt de robot gebruik van DabbleESP32. De robotsoftware gebruikt echter de functie Dabble.processInput_tick(), terwijl de standaard DabbleESP32-library deze functie niet bevat. Dat is geen onbelangrijk detail. Een zelfbalancerende robot moet zijn regelberekeningen voortdurend blijven uitvoeren. Wanneer een functie voor de Bluetooth-communicatie te lang wacht, kan dit de balansregeling verstoren, met alle gevolgen van dien.
De robotsoftware verwacht daarom een aangepaste manier om de Bluetooth-gegevens te verwerken. Ik heb de aangepaste DabbleESP32-library uit de downloads van Elektor gebruikt in plaats van de versie uit de Library Manager. Dit was een mooi voorbeeld van een probleem waarbij je niet zomaar een ontbrekende functie moet vervangen door een andere functie die ongeveer hetzelfde lijkt te doen. Eerst begrijpen waarom die aanpassing is gemaakt, daarna pas wijzigen.
Later kwam ook nog de foutmelding Invalid FQBN: invalid option 'ZigbeeMode' voorbij. Die had betrekking op de boardconfiguratie van de Arduino IDE en niet op de robot zelf. De optie ZigbeeMode bestaat pas in de 3.x-versies van de ESP32-boardondersteuning. Met versie 2.0.17 geïnstalleerd stuurde de IDE die instelling nog steeds mee. Het opnieuw selecteren van het ESP32-S3-board en het nalopen van de boardinstellingen loste dat op.
Hoe blijft een robot rechtop staan?
Het principe van een zelfbalancerende robot is vergelijkbaar met het balanceren van een stok op je hand. Wanneer de robot naar voren helt, moeten de wielen naar voren bewegen om het zwaartepunt weer onder controle te krijgen. Helt hij naar achteren, dan moeten de motoren de andere kant op corrigeren.
De MPU6050 levert hiervoor de meetgegevens. De software gebruikt deze informatie om de hellingshoek te bepalen. Vervolgens berekent een PID-regelaar welke motorcorrectie nodig is. PID staat voor Proportional, Integral en Derivative. De P reageert op de huidige afwijking van de gewenste stand, de I op de afwijking die zich in de loop van de tijd opbouwt en de D op hoe snel de afwijking verandert. Samen bepalen ze hoe krachtig en hoe snel de robot corrigeert. Een verkeerde instelling kan ervoor zorgen dat de robot te traag reageert, gaat oscilleren of juist veel te agressief corrigeert. Maar voordat je met de PID-instellingen kunt experimenteren, moeten de sensoren en motoren eerst goed zijn gekalibreerd.

De MPU6050 kalibreren
Een accelerometer en gyroscoop geven niet automatisch perfecte meetwaarden. Ook wanneer de robot volledig stil ligt, kunnen er kleine afwijkingen in de metingen aanwezig zijn. Voor het bepalen van deze afwijkingen bevat de software een afzonderlijk programma: SBRobot_IMU_Zero. Tijdens deze procedure wordt de robot horizontaal en stabiel neergelegd. Vervolgens verzamelt de software grote aantallen metingen van de accelerometer en gyroscoop. Uit deze metingen worden zes offsetwaarden berekend: drie voor de accelerometer en drie voor de gyroscoop. Voor mijn robot leverde de kalibratie uiteindelijk de volgende waarden op:
cpp
#define X_OFFSET_ACCEL (-2971)
#define Y_OFFSET_ACCEL (1651)
#define Z_OFFSET_ACCEL (1624)
#define X_OFFSET_GYRO (55)
#define Y_OFFSET_GYRO (18)
#define Z_OFFSET_GYRO (12)
Deze waarden worden vervolgens overgenomen in de hoofdsoftware. De kalibratie duurt enige tijd, omdat het programma duizenden metingen verzamelt en verschillende correctiestappen uitvoert. Het is belangrijk om de robot tijdens dit proces niet te bewegen en te wachten totdat de volledige procedure is afgerond. Een verkeerde sensoroffset betekent immers dat de regelaar met een onjuiste uitgangspositie werkt. En een robot die denkt dat hij rechtop staat terwijl hij eigenlijk iets overhelt, zal daar voortdurend voor proberen te corrigeren.

Twee motoren, twee verschillende eigenschappen
Na de bewegingssensor zijn de motoren aan de beurt. Hoewel beide motoren hetzelfde type zijn, betekent dit niet dat ze bij dezelfde aansturing exact even snel draaien. Verschillen in wrijving, de tandwieloverbrenging en de elektromotor kunnen ervoor zorgen dat de ene motor iets eerder begint te draaien dan de andere.
Met het programma SBRobot_Motor_Compare kunnen deze verschillen worden onderzocht. Bij deze tests moet de robot zodanig worden ondersteund dat de wielen vrij kunnen draaien. Daarbij wordt onder andere gekeken naar de minimale PWM-waarde waarbij de motoren betrouwbaar beginnen te draaien en de verhouding tussen de motorsnelheden. Bij gelijke aansturing mat ik een PWM van 158 voor de linkermotor en 166 voor de rechtermotor. De rechtermotor draaide daarmee ongeveer 5% sneller.
Daarom heb ik de softwarematige correctie voor de rechtermotor aangepast naar 0,95 (158 / 166 ≈ 0,95). De minimale aansturing waarbij de motoren betrouwbaar draaien, staat in MOTOR_MIN_ABS_SPEED.
cpp
#define MOTOR_MIN_ABS_SPEED 43
double motor_speed_multiplier_left = 1.0;
double motor_speed_multiplier_right = 0.95;
Wat ik interessant vind, is dat je hier een mechanisch verschil tussen twee motoren met software kunt compenseren. Dat is precies waar mechatronica om draait: mechanica, elektronica en software die elkaar aanvullen.

De eerste rijtests
Na de montage, het installeren van de software en de kalibratiestappen wordt het tijd om de robot daadwerkelijk te testen. Via Bluetooth kan de ESP32-S3 verbinding maken met de Dabble-app op een smartphone. Daarmee zijn commando’s beschikbaar om vooruit, achteruit en naar links of rechts te bewegen.
Op het TFT-display verschijnt een afbeelding en de ultrasone sensor aan de voorkant geeft de robot bijna een gezicht. De eerste tests heb ik op tafel uitgevoerd. Daarna was het tijd voor wat meer bewegingsruimte op de werkplaatsvloer.
Voor de rijtests op de vloer ben ik letterlijk op mijn knieën gegaan om de robot goed te kunnen volgen en van dichtbij te kunnen besturen. Met de smartphone in de hand zie je direct hoe de robot op de stuurcommando’s reageert. Tegelijkertijd is de ESP32 voortdurend bezig met het verwerken van de sensorgegevens en het aansturen van de motoren. De combinatie van Bluetooth-besturing, motorregeling en sensormetingen maakt het een interessant systeem om verder te onderzoeken.

Wat heb ik geleerd?
Dit project laat opnieuw zien dat een bouwpakket niet automatisch betekent dat alles direct werkt. Het mechanisch opbouwen is meestal nog redelijk overzichtelijk. De uitdaging zit vooral in het combineren van alle onderdelen tot een betrouwbaar werkend systeem.
Een paar dingen neem ik mee uit dit project:
– Leg de gebruikte software- en libraryversies vast
– Controleer eerst de ontwikkelomgeving voordat je problemen in de hardware zoekt
– Kalibreer sensoren en motoren afzonderlijk
– Wacht bij kalibratieprogramma’s altijd op de definitieve resultaten
– Verander bij het oplossen van problemen bij voorkeur één parameter tegelijk
– Een programma dat zonder fouten compileert, hoeft in de praktijk nog niet goed te functioneren
Vooral dat laatste is iets wat je bij embedded projecten regelmatig tegenkomt. Software kan technisch correct zijn, terwijl de timing, sensorwaarden of motorreacties toch niet overeenkomen met wat je verwacht. Dan begint het interessante deel: meten, analyseren, aanpassen en opnieuw testen.
Wat kan ik er verder mee?
Nu de robot is opgebouwd en de eerste rijtests zijn uitgevoerd, zijn er verschillende mogelijkheden om het project verder uit te breiden. Zo lijkt het me interessant om de PID-regeling verder te onderzoeken en de meetgegevens van de MPU6050 zichtbaar te maken.
Ook de motorencoders bieden mogelijkheden om de afgelegde afstand en de snelheid nauwkeuriger te bepalen. De ultrasone afstandssensor kan worden gebruikt voor obstakeldetectie, waardoor een volgende stap richting gedeeltelijk autonoom rijden mogelijk wordt. Een andere interessante uitbreiding is het draadloos verzamelen en visualiseren van de sensordata. Daarmee kun je bijvoorbeeld de gemeten hellingshoek, gewenste motorcorrectie en daadwerkelijke motorbeweging met elkaar vergelijken.
Voor onderwijs en workshops is dit een mooi demonstratieplatform. Een PID-regeling uitleggen met een grafiek is één ding. De gevolgen van een verkeerde instelling direct zien aan een robot die begint te schommelen, maakt het een stuk tastbaarder.

Waarom ik dit soort projecten blijf doen
Wat mij vooral aanspreekt, is dat je bij dit soort projecten verschillende technische disciplines bij elkaar brengt. Je begint met een verzameling onderdelen en probeert daar een werkend systeem van te maken. Onderweg kom je dingen tegen die niet werken zoals verwacht. Een library die niet compatibel blijkt, een sensor die gekalibreerd moet worden of twee motoren die toch niet helemaal identiek reageren.
Dat zijn geen redenen om te stoppen, maar juist momenten waarop je iets nieuws kunt leren. Voor mij zit het plezier niet alleen in het uiteindelijke resultaat, maar vooral in het proces ernaartoe. Zelf bouwen, proberen, fouten maken, uitzoeken waarom iets niet werkt en vervolgens ontdekken hoe het wél kan. Dat is wat techniek voor mij interessant maakt. En ondertussen staat er weer een leuke robot op twee wielen in de werkplaats.
Wat heb ik gebruikt
– Elektor Self-Balancing Robot Kit
– ESP32-S3 microcontroller
– MPU6050 bewegingssensor (accelerometer + gyroscoop)
– 2x DC-reductiemotor met encoder
– TFT-kleurendisplay
– Ultrasone afstandssensor
– Accupakket
– Arduino IDE 2
– ESP32 by Espressif Systems v2.0.17
– GFX Library for Arduino v1.4.6
– DabbleESP32 (aangepaste versie) + Dabble-app op smartphone
– Kalibratieprogramma’s SBRobot_IMU_Zero en SBRobot_Motor_Compare


