ESP32 Tutoriaal 30/55 - Beheer Servo oor die web met MQTT met behulp van Adafruit IO Diens | SunFounder se ESP32 IoT-leerkit
In hierdie tutoriaal sal ons leer hoe om die posisie van 'n servomotor te beheer met behulp van die ESP32-mikrobeheerder en MQTT-protokol oor die web. Deur gebruik te maak van die Adafruit IO-diens, sal jy die servo op verskeie hoeke soos 0°, 90°, of 180° op afstand kan posisioneer. Hierdie projek demonstreer die vermoëns van die ESP32, wat ingeboude Wi-Fi en Bluetooth insluit, wat dit 'n kragtige hulpmiddel vir IoT-toepassings maak.

In hierdie projek sal ons 'n MQTT-tussenganger met Adafruit IO opstel, 'n kontrolebord skep om die servo te beheer, en die ESP32 daaraan koppel. Die servo-posisie sal deur 'n skuifbalk op die kontrolebord verstelbaar wees, wat intydse beheer vanaf enige internet-geaktiveerde toestel moontlik maak (in video by 5:30).
Hardeware Verduidelik
Die primêre komponente van hierdie projek sluit die ESP32-mikrobeheerder en die servomotor in. Die ESP32 is 'n veelsydige mikrobeheerder met geïntegreerde Wi-Fi- en Bluetooth-vermoëns, wat dit ideaal maak vir IoT-toepassings. Dit kommunikeer met die Adafruit IO-diens deur die MQTT-protokol, wat liggewig en doeltreffend is vir die oordrag van boodskappe oor die internet.
Die servomotor is 'n roterende aktuator wat presiese beheer van hoekposisie moontlik maak. Dit werk deur 'n polsbreedtemodulasie (PWM)-sein te ontvang wat sy posisie bepaal. In hierdie projek sal ons die servo aan een van die digitale penne op die ESP32 koppel, wat ons in staat stel om sy hoek op afstand te beheer.
Datablad Besonderhede
| Vervaardiger | Parallax |
|---|---|
| Deelnommer | SG90 |
| Logika/IO-spanning | 3.3 V - 5 V |
| Toevoerspanning | 4.8 V - 6.0 V |
| Uitsetstroom (per kanaal) | 1 A maks |
| PWM-frekwensie riglyn | 50 Hz |
| Inset logika drempels | 0.3 V - 0.7 V |
| Spanningval / RDS(on) / versadiging | 0.2 V maks |
| Termiese limiete | Werkingstemperatuur: -10°C tot 60°C |
| Verpakking | Plastiekomhulsel |
| Notas / variante | Mini-servo, 180°-rotasie |
- Verseker behoorlike spanningtoevoer na die servo (4.8 V - 6.0 V).
- Gebruik 'n gemeenskaplike grond tussen die ESP32 en servo.
- Monitor die PWM-sein om te verhoed dat die servo se limiete oorskry word.
- Koppel die servo veilig om ontkoppelings tydens werking te vermy.
- Werk die Adafruit MQTT-biblioteek op om versoenbaarheid te verseker.
MQTT-diagramme
Bedradingsinstruksies

Om die servomotor aan die ESP32 te bedraad, begin deur die gronddraad van die servo aan die grondpen op die ESP32 te koppel. Koppel volgende die kragdraad (gewoonlik rooi) van die servo aan die 5V-pen op die ESP32. Koppel laastens die seindraad (dikwels geel of wit) aan digitale pen 25 op die ESP32. Verseker dat die verbindings veilig is om enige ontkoppelings tydens werking te voorkom.
As jy 'n battery gebruik om die ESP32 van krag te voorsien, maak seker dat die batteryspanning binne die aanvaarbare reeks vir beide die ESP32 en die servo is. Kontroleer ook dubbel dat die bedrading ooreenstem met die pen-definisies wat in jou kode gebruik word om enige probleme te vermy (in video by 12:45).
Kode Voorbeelde & Deurloop
In die verskafde kode sluit ons eers die nodige biblioteke vir die ESP32 en MQTT in. Ons definieer die servo-objek en spesifiseer die pen waaraan dit gekoppel is met const int servoPin = 25;. Die standaardhoek word ook gestel met const int defaultServoAngle = 90;, wat die aanvanklike posisie sal wees wanneer die ESP32 opstart.
Servo myServo;
const int servoPin = 25;
const int defaultServoAngle = 90;
int servoAngle = defaultServoAngle;
Hierdie uittreksel initialiseer die servo op pen 25 en stel sy standaardhoek op 90°. Die veranderlike servoAngle sal opgedateer word op grond van die boodskappe wat van die MQTT-tussenganger ontvang word.
In die setup()-funksie koppel ons aan Wi-Fi en stel die MQTT-kliënt op. Die geloofsbriewe vir Adafruit IO word hier gedefinieer, insluitend die gebruikersnaam en sleutel:
#define AIO_USERNAME "robojax"
#define AIO_KEY "aio_xmIW58uNNsjJCSOqzZ9QoHyq29wu"
Hierdie afdeling vestig die verbinding met die Adafruit IO-diens. Maak seker dat jy hierdie waardes met jou eie Adafruit IO-geloofsbriewe vervang wanneer jy die kode implementeer.
Laastens verseker die hoof-lus dat die verbinding met die MQTT-bediener aktief bly en verwerk inkomende boodskappe. Die servo-posisie word opgedateer op grond van die ontvangde hoek:
mqtt.processPackets(500);
int pulseBreedte = map(servoHoek, 0, 180, minPulseBreedte, maxPulseBreedte);
myServo.skryfMikrosekondes(pulseBreedte);
Hierdie kode karteer die servo-hoek na die ooreenstemmende polsbreedte en stuur dit na die servo-motor. Die processPackets()-funksie stel die ESP32 in staat om inkomende MQTT-boodskappe te hanteer, wat verseker dat die servo reageer op opdragte wat via die Adafruit IO-kontroleskerm gestuur word.
Demonstrasie / Wat om te Verwacht
Sodra alles opgestel is, behoort jy die servo vanaf die Adafruit IO-kontroleskerm te kan beheer met behulp van die skuifbalk wat jy geskep het. Soos jy die skuifbalk beweeg, sal die servo sy hoek intyds aanpas. Maak seker dat jou ESP32 aan Wi-Fi gekoppel is en dat die MQTT-verbinding stabiel is. As die servo nie reageer nie, kontroleer die bedrading en die kragtoevoer na die servo (in video by 20:15).
Wees bewus van die reeksbeperkings vir die servo; die stuur van 'n waarde buite 0° tot 180° kan veroorsaak dat dit onverwags optree. Die kode bevat kontroles om sulke gevalle te voorkom deur die hoek binne hierdie reeks te klem.
Video Tydstempels
- 00:00 Begin
- 1:54 Projekbekendstelling
- 2:52 Inleiding tot MQTT
- 6:50 Adafruit IO-opstelling
- 9:54 Bedrading van servo
- 11:07 Kode verduidelik
- 18:59 Kies ESP32-bord en COM-poort
- 22:10 Projekdemonstrasie
/***********************************************************************
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
Goedere wat jy dalk nodig het
-
AliExpressPurchase SG90 Servo motor 180 or 360 from AliExpresss.click.aliexpress.com
Hulpbronne en verwysings
-
DokumentasieESP32 Tutorial 17/55- SunFunder Servo motor documentationdocs.sunfounder.com
-
BuitenburgSG90 servo on Amazon USAamzn.to
Lêers📁
Ander lêers
-
SG90 Servo motor datasheet
robojax-servo-SG90_datasheet.pdf0.12 MB