Search Code

ESP32 Tutorial 30/55 - Servo via het web aansturen met MQTT met behulp van de Adafruit IO-service | SunFounder's ESP32 IoT-leerkit

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.

ESP32-30_MQTT_diagram-0

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

ESP32-30_MQTT_diagram-2
ESP32-30_MQTT_diagram
ESP32-28_dht_temperature-sensor-main

Bedradingsinstructies

ESP32-17-Sevo_motor-wiring

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

Afbeeldingen

ESP32-17-Sevo_motor-schematic
ESP32-17-Sevo_motor-schematic
ESP32-17-Sevo_motor-wiring
ESP32-17-Sevo_motor-wiring
ESP32-28_dht_temperature-sensor-main
ESP32-28_dht_temperature-sensor-main
ESP32-30_MQTT_diagram
ESP32-30_MQTT_diagram
ESP32-30_MQTT_diagram-0
ESP32-30_MQTT_diagram-0
ESP32-30_MQTT_diagram-2
ESP32-30_MQTT_diagram-2
831-ESP32 Tutorial 30/55- ESP32 to control Servo motor using MQTT service of Adafruit
Taal: C++
/***********************************************************************
 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!");
}

Dingen die je misschien nodig hebt

Hulpmiddelen en referenties

Bestanden📁

Andere bestanden