ESP32 Tutorial 30/55 - Servo via het web aansturen met MQTT met behulp van de Adafruit IO-service | SunFounder's ESP32 IoT-leerkit
In deze tutorial leren we hoe we de positie van een servomotor kunnen aansturen met behulp van de ESP32-microcontroller en het MQTT-protocol via het web. Door gebruik te maken van de Adafruit IO-service kun je de servo op verschillende hoeken positioneren, zoals 0°, 90° of 180°, op afstand. Dit project demonstreert de mogelijkheden van de ESP32, die ingebouwde Wi-Fi en Bluetooth heeft, waardoor het een krachtig hulpmiddel is voor IoT-toepassingen.

In dit project zullen we een MQTT-broker opzetten met behulp van Adafruit IO, een dashboard maken om de servo te bedienen en de ESP32 hierop aansluiten. De servopositie kan worden aangepast via een schuifregelaar op het dashboard, waardoor real-time bediening mogelijk is vanaf elk apparaat met internettoegang (in video op 5:30).
Hardware uitgelegd
De belangrijkste componenten van dit project zijn de ESP32-microcontroller en de servomotor. De ESP32 is een veelzijdige microcontroller met geïntegreerde Wi-Fi- en Bluetooth-mogelijkheden, waardoor het ideaal is voor IoT-toepassingen. Het communiceert met de Adafruit IO-service via het MQTT-protocol, dat lichtgewicht en efficiënt is voor het verzenden van berichten via internet.
De servomotor is een roterende actuator die nauwkeurige controle van de hoekpositie mogelijk maakt. Het werkt door een pulsbreedtemodulatie (PWM)-signaal te ontvangen dat de positie bepaalt. In dit project verbinden we de servo met een van de digitale pinnen op de ESP32, zodat we de hoek op afstand kunnen regelen.
Datasheet-details
| Fabrikant | Parallax |
|---|---|
| Onderdeelnummer | SG90 |
| Logica/IO-spanning | 3,3 V - 5 V |
| Voedingsspanning | 4,8 V - 6,0 V |
| Uitgangsstroom (per kanaal) | 1 A max |
| PWM-frequentierichtlijn | 50 Hz |
| Ingangslogische drempels | 0,3 V - 0,7 V |
| Spanningsval / RDS(on) / verzadiging | 0,2 V max |
| Thermische limieten | Bedrijfstemperatuur: -10°C tot 60°C |
| Behuizing | Kunststof behuizing |
| Opmerkingen / varianten | Mini-servo, 180° rotatie |
- Zorg voor een juiste voedingsspanning voor de servo (4,8 V - 6,0 V).
- Gebruik een gemeenschappelijke aarde tussen de ESP32 en de servo.
- Bewaak het PWM-signaal om te voorkomen dat de limieten van de servo worden overschreden.
- Sluit de servo stevig aan om loskoppelingen tijdens gebruik te voorkomen.
- Werk de Adafruit MQTT-bibliotheek bij om compatibiliteit te garanderen.
MQTT-diagrammen
Bedradingsinstructies

Om de servomotor op de ESP32 aan te sluiten, begin je met het verbinden van de aarddraad van de servo met de aardpin op de ESP32. Verbind vervolgens de voedingsdraad (meestal rood) van de servo met de 5V-pin op de ESP32. Sluit tot slot de signaaldraad (vaak geel of wit) aan op digitale pin 25 van de ESP32. Zorg ervoor dat de verbindingen stevig zijn om loskoppelingen tijdens gebruik te voorkomen.
Als je een batterij gebruikt om de ESP32 van stroom te voorzien, zorg er dan voor dat de batterijspanning binnen het acceptabele bereik ligt voor zowel de ESP32 als de servo. Controleer bovendien of de bedrading overeenkomt met de pindefinities in je code om problemen te voorkomen (in video op 12:45).
Codevoorbeelden & uitleg
In de meegeleverde code nemen we eerst de benodigde bibliotheken voor de ESP32 en MQTT op. We definiëren het servo-object en specificeren de pin waarmee het is verbonden met const int servoPin = 25;. De standaardhoek wordt ook ingesteld met const int defaultServoAngle = 90;, wat de beginpositie is wanneer de ESP32 opstart.
Servo myServo;
const int servoPin = 25;
const int defaultServoAngle = 90;
int servoAngle = defaultServoAngle;
Dit fragment initialiseert de servo op pin 25 en stelt de standaardhoek in op 90°. De variabele servoAngle wordt bijgewerkt op basis van de berichten die van de MQTT-broker worden ontvangen.
In de setup()-functie verbinden we met Wi-Fi en stellen we de MQTT-client in. De inloggegevens voor Adafruit IO worden hier gedefinieerd, inclusief de gebruikersnaam en sleutel:
#define AIO_USERNAME "robojax"
#define AIO_KEY "aio_xmIW58uNNsjJCSOqzZ9QoHyq29wu"
Dit gedeelte brengt de verbinding met de Adafruit IO-service tot stand. Zorg ervoor dat je deze waarden vervangt door je eigen Adafruit IO-inloggegevens bij het implementeren van de code.
Tot slot zorgt de hoofdloop ervoor dat de verbinding met de MQTT-server actief blijft en verwerkt het inkomende berichten. De servopositie wordt bijgewerkt op basis van de ontvangen hoek:
mqtt.processPackets(500);
int pulseWidth = map(servoAngle, 0, 180, minPulseWidth, maxPulseWidth);
myServo.writeMicroseconds(pulseWidth);
Deze code mapt de servo-hoek naar de overeenkomstige pulsbreedte en stuurt deze naar de servomotor. De functie processPackets() stelt de ESP32 in staat om inkomende MQTT-berichten te verwerken, zodat de servo reageert op opdrachten die via het Adafruit IO-dashboard worden verzonden.
Demonstratie / Wat je kunt verwachten
Zodra alles is ingesteld, zou je de servo vanaf het Adafruit IO-dashboard moeten kunnen bedienen met behulp van de schuifregelaar die je hebt gemaakt. Terwijl je de schuifregelaar beweegt, zal de servo zijn hoek in realtime aanpassen. Zorg ervoor dat je ESP32 is verbonden met Wi-Fi en dat de MQTT-verbinding stabiel is. Als de servo niet reageert, controleer dan de bedrading en de voeding van de servo (in de video op 20:15).
Wees je bewust van de bereiklimieten voor de servo; het verzenden van een waarde buiten 0° tot 180° kan ervoor zorgen dat deze zich onverwacht gedraagt. De code bevat controles om dergelijke gevallen te voorkomen door de hoek binnen dit bereik te begrenzen.
Video-tijdstempels
- 00:00 Start
- 1:54 Projectintroductie
- 2:52 Introductie tot MQTT
- 6:50 Adafruit IO-installatie
- 9:54 Bedrading van de servo
- 11:07 Code uitgelegd
- 18:59 ESP32-board en COM-poort selecteren
- 22:10 Projectdemonstratie
/***********************************************************************
This is Arduino sketch for ESP32 to control Servo motor using MQTT service of Adafruit
www.Robojax.com
Written By Ahamd Shamshiri
on Feb 2nd, 2024
Watch video instruction for this code on YouTube https://youtu.be/T4DhWNg2Rb8
Adafruit MQTT Library ESP32 Adafruit IO SSL/TLS example
this code can be downloaded from https://robojax.com/RJT671
/// ref: https://www.electronicwings.com/esp32/esp32-mqtt-client
*/
#include <ESP32Servo.h>
// Define the servo and the pin it is connected to
Servo myServo;
const int servoPin = 25;
const int defaultServoAngle = 90;
int servoAngle =defaultServoAngle;
// Define the minimum and maximum pulse widths for the servo
const int minPulseWidth = 500; // 0.5 ms
const int maxPulseWidth = 2500; // 2.5 ms
#include <WiFi.h>
#include "WiFiClientSecure.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/************************* WiFi Access Point *********************************/
#define WLAN_SSID "Barqasaa"
#define WLAN_PASS "wan9&Jang~5"
/************************* Adafruit.io Setup *********************************/
#define AIO_SERVER "io.adafruit.com"
// Using port 8883 for MQTTS
#define AIO_SERVERPORT 8883
// Adafruit IO Account Configuration
// (to obtain these values, visit https://io.adafruit.com and click on Active Key)
// #define AIO_USERNAME "YOUR_ADAFRUIT_IO_USERNAME"
// #define AIO_KEY "YOUR_ADAFRUIT_IO_KEY"
#define AIO_USERNAME "robojax"
#define AIO_KEY "aio_xmIW58uNNsjJCSOqzZ9QoHyq29wu"
/************ Global State (you don't need to change this!) ******************/
// WiFiFlientSecure for SSL/TLS support
WiFiClientSecure client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
// io.adafruit.com root CA
const char* adafruitio_root_ca = \
"-----BEGIN CERTIFICATE-----\n"
"MIIEjTCCA3WgAwIBAgIQDQd4KhM/xvmlcpbhMf/ReTANBgkqhkiG9w0BAQsFADBh\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n"
"MjAeFw0xNzExMDIxMjIzMzdaFw0yNzExMDIxMjIzMzdaMGAxCzAJBgNVBAYTAlVT\n"
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
"b20xHzAdBgNVBAMTFkdlb1RydXN0IFRMUyBSU0EgQ0EgRzEwggEiMA0GCSqGSIb3\n"
"DQEBAQUAA4IBDwAwggEKAoIBAQC+F+jsvikKy/65LWEx/TMkCDIuWegh1Ngwvm4Q\n"
"yISgP7oU5d79eoySG3vOhC3w/3jEMuipoH1fBtp7m0tTpsYbAhch4XA7rfuD6whU\n"
"gajeErLVxoiWMPkC/DnUvbgi74BJmdBiuGHQSd7LwsuXpTEGG9fYXcbTVN5SATYq\n"
"DfbexbYxTMwVJWoVb6lrBEgM3gBBqiiAiy800xu1Nq07JdCIQkBsNpFtZbIZhsDS\n"
"fzlGWP4wEmBQ3O67c+ZXkFr2DcrXBEtHam80Gp2SNhou2U5U7UesDL/xgLK6/0d7\n"
"6TnEVMSUVJkZ8VeZr+IUIlvoLrtjLbqugb0T3OYXW+CQU0kBAgMBAAGjggFAMIIB\n"
"PDAdBgNVHQ4EFgQUlE/UXYvkpOKmgP792PkA76O+AlcwHwYDVR0jBBgwFoAUTiJU\n"
"IBiV5uNu5g/6+rkS7QYXjzkwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsG\n"
"AQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMDQGCCsGAQUFBwEB\n"
"BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEIGA1Ud\n"
"HwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds\n"
"b2JhbFJvb3RHMi5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEW\n"
"HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQELBQADggEB\n"
"AIIcBDqC6cWpyGUSXAjjAcYwsK4iiGF7KweG97i1RJz1kwZhRoo6orU1JtBYnjzB\n"
"c4+/sXmnHJk3mlPyL1xuIAt9sMeC7+vreRIF5wFBC0MCN5sbHwhNN1JzKbifNeP5\n"
"ozpZdQFmkCo+neBiKR6HqIA+LMTMCMMuv2khGGuPHmtDze4GmEGZtYLyF8EQpa5Y\n"
"jPuV6k2Cr/N3XxFpT3hRpt/3usU/Zb9wfKPtWpoznZ4/44c1p9rzFcZYrWkj3A+7\n"
"TNBJE0GmP2fhXhP1D/XVfIW/h0yCJGEiV9Glm/uGOa3DXHlmbAcxSyCRraG+ZBkA\n"
"7h4SeM6Y8l/7MBRpPCz6l8Y=\n"
"-----END CERTIFICATE-----\n";
/****************************** Feeds ***************************************/
// Setup a feed called 'test' for publishing and 'test2' for subscription.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Subscribe SERVO = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/servo-angle-1");
/*************************** Sketch Code ************************************/
void setup() {
// Attach the servo to the specified pin and set its pulse width range
myServo.attach(servoPin, minPulseWidth, maxPulseWidth);
// Set the PWM frequency for the servo
myServo.setPeriodHertz(50); // Standard 50Hz servo
Serial.begin(115200);
delay(10);
Serial.println(F("Adafruit IO MQTTS (SSL/TLS) Example"));
// Connect to WiFi access point.
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
delay(1000);
WiFi.begin(WLAN_SSID, WLAN_PASS);
delay(2000);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Set Adafruit IO's root CA
client.setCACert(adafruitio_root_ca);
// register callback for feed
SERVO.setCallback(servoCallback);
// Setup MQTT subscription for time feed.
mqtt.subscribe(&SERVO);
}
// uint32_t x=0;
void loop() {
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();
Serial.print("Angle: ");
Serial.println(servoAngle);
// wait 0.5 seconds for subscription messages
mqtt.processPackets(500);
//from lesson 17
int pulseWidth = map(servoAngle, 0, 180, minPulseWidth, maxPulseWidth);
myServo.writeMicroseconds(pulseWidth);
delay(15);
// wait a couple seconds to avoid rate limit
//delay(2000);
}
void servoCallback(char* message, uint16_t len) {
char messageBuffer[40];
snprintf(messageBuffer, sizeof(messageBuffer), "Servo status is :: %s, len :: %u", message, len);
Serial.println(messageBuffer);
Serial.println(message);
String inString = message;//sotre the message to String
servoAngle = inString.toInt();//convert the message to Integer
if(servoAngle >180 || servoAngle < 0)
{
servoAngle =0;
}
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1)
;
}
}
Serial.println("MQTT Connected!");
}
Common Course Links
Common Course Files
Dingen die je misschien nodig hebt
-
AliExpressPurchase SG90 Servo motor 180 or 360 from AliExpresss.click.aliexpress.com
Hulpmiddelen en referenties
-
DocumentatieESP32 Tutorial 17/55- SunFunder Servo motor documentationdocs.sunfounder.com
-
ExternSG90 servo on Amazon USAamzn.to
Bestanden📁
Andere bestanden
-
SG90 Seroo motor datasheet
robojax-servo-SG90_datasheet.pdf0.12 MB