Search Code

Tutorial ESP32 30/55 - Controlați Servo prin web folosind MQTT cu serviciul Adafruit IO | Kitul de învățare IoT ESP32 de la SunFounder

Tutorial ESP32 30/55 - Controlați Servo prin web folosind MQTT cu serviciul Adafruit IO | Kitul de învățare IoT ESP32 de la SunFounder

În acest tutorial, vom învăța cum să controlăm poziția unui servomotor folosind microcontrolerul ESP32 și protocolul MQTT prin internet. Folosind serviciul Adafruit IO, veți putea poziționa servomotorul la diferite unghiuri, cum ar fi 0°, 90° sau 180°, de la distanță. Acest proiect demonstrează capacitățile ESP32, care include Wi-Fi și Bluetooth integrate, fiind un instrument puternic pentru aplicații IoT.

ESP32-30_MQTT_diagram-0

În acest proiect, vom configura un broker MQTT folosind Adafruit IO, vom crea un dashboard pentru a controla servomotorul și vom conecta ESP32 la acesta. Poziția servomotorului va fi reglabilă printr-un glisor pe dashboard, permițând controlul în timp real de pe orice dispozitiv conectat la internet (în video la 5:30).

Hardware Explicat

Componentele principale ale acestui proiect includ microcontrolerul ESP32 și servomotorul. ESP32 este un microcontroler versatil cu capacități integrate de Wi-Fi și Bluetooth, fiind ideal pentru aplicații IoT. Acesta comunică cu serviciul Adafruit IO folosind protocolul MQTT, care este ușor și eficient pentru transmiterea mesajelor prin internet.

Servomotorul este un actuator rotativ care permite controlul precis al poziției unghiulare. Acesta funcționează prin primirea unui semnal de modulație a lățimii impulsului (PWM) care dictează poziția sa. În acest proiect, vom conecta servomotorul la unul dintre pinii digitali ai ESP32, permițându-ne să controlăm unghiul său de la distanță.

Detalii din Fișa Tehnică

Producător Parallax
Număr de piesă SG90
Tensiune logică/IO 3.3 V - 5 V
Tensiune de alimentare 4.8 V - 6.0 V
Curent de ieșire (pe canal) 1 A max
Ghid de frecvență PWM 50 Hz
Praguri logice de intrare 0.3 V - 0.7 V
Cădere de tensiune / RDS(on) / saturație 0.2 V max
Limite termice Temperatură de operare: -10°C până la 60°C
Pachet Carcasă din plastic
Note / variante Mini servomotor, rotație de 180°

 

  • Asigurați o tensiune de alimentare adecvată pentru servomotor (4.8 V - 6.0 V).
  • Folosiți o masă comună între ESP32 și servomotor.
  • Monitorizați semnalul PWM pentru a evita depășirea limitelor servomotorului.
  • Conectați ferm servomotorul pentru a evita deconectările în timpul funcționării.
  • Actualizați biblioteca Adafruit MQTT pentru a asigura compatibilitatea.

Diagrame MQTT

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

Instrucțiuni de Cablare

ESP32-17-Sevo_motor-wiring

Pentru a conecta servomotorul la ESP32, începeți prin conectarea firului de masă al servomotorului la pinul de masă de pe ESP32. Apoi, conectați firul de alimentare (de obicei roșu) al servomotorului la pinul de 5V de pe ESP32. În final, conectați firul de semnal (adesea galben sau alb) la pinul digital 25 de pe ESP32. Asigurați-vă că conexiunile sunt sigure pentru a preveni orice deconectare în timpul funcționării.

Dacă folosiți o baterie pentru a alimenta ESP32, asigurați-vă că tensiunea bateriei este în intervalul acceptabil atât pentru ESP32, cât și pentru servomotor. În plus, verificați de două ori că cablarea corespunde definițiilor pinilor folosite în codul dvs. pentru a evita orice probleme (în video la 12:45).

Exemple de Cod & Explicații

În codul furnizat, includem mai întâi bibliotecile necesare pentru ESP32 și MQTT. Definim obiectul servomotorului și specificăm pinul la care este conectat cu const int servoPin = 25;. Unghiul implicit este, de asemenea, setat cu const int defaultServoAngle = 90;, care va fi poziția inițială când ESP32 pornește.


Servo myServo;
const int servoPin = 25;
const int defaultServoAngle = 90;
int servoAngle = defaultServoAngle;

Acest fragment inițializează servomotorul pe pinul 25 și setează unghiul său implicit la 90°. Variabila servoAngle va fi actualizată pe baza mesajelor primite de la brokerul MQTT.

În funcția setup(), ne conectăm la Wi-Fi și configurăm clientul MQTT. Credențialele pentru Adafruit IO sunt definite aici, inclusiv numele de utilizator și cheia:


#define AIO_USERNAME "robojax"
#define AIO_KEY "aio_xmIW58uNNsjJCSOqzZ9QoHyq29wu"

Această secțiune stabilește conexiunea la serviciul Adafruit IO. Asigurați-vă că înlocuiți aceste valori cu propriile credențiale Adafruit IO atunci când implementați codul.

În final, bucla principală asigură că conexiunea la serverul MQTT rămâne activă și procesează mesajele primite. Poziția servomotorului este actualizată pe baza unghiului primit:


mqtt.processPackets(500);
int pulseWidth = map(servoAngle, 0, 180, minPulseWidth, maxPulseWidth);
myServo.writeMicroseconds(pulseWidth);

Acest cod mapează unghiul servomotorului la lățimea corespunzătoare a impulsului și o trimite către motorul servo. Funcția processPackets() permite ESP32 să gestioneze mesajele MQTT primite, asigurând că servomotorul reacționează la comenzile trimise prin tabloul de bord Adafruit IO.

Demonstrație / Ce să te aștepți

Odată ce totul este configurat, ar trebui să poți controla servomotorul din tabloul de bord Adafruit IO folosind glisorul creat. Pe măsură ce muți glisorul, servomotorul își va ajusta unghiul în timp real. Asigură-te că ESP32 este conectat la Wi-Fi și că conexiunea MQTT este stabilă. Dacă servomotorul nu răspunde, verifică cablajul și sursa de alimentare a servomotorului (în videoclip la 20:15).

Fii atent la limitele de interval ale servomotorului; trimiterea unei valori în afara intervalului 0° la 180° poate cauza un comportament neașteptat. Codul include verificări pentru a preveni astfel de situații prin limitarea unghiului în acest interval.

Marcaje temporale din videoclip

  • 00:00 Început
  • 1:54 Introducerea proiectului
  • 2:52 Introducere în MQTT
  • 6:50 Configurare Adafruit IO
  • 9:54 Cablarea servomotorului
  • 11:07 Explicarea codului
  • 18:59 Selectarea plăcii ESP32 și a portului COM
  • 22:10 Demonstrația proiectului

Imagini

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
Limba: 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!");
}

Lucruri de care ai putea avea nevoie

Resurse și referințe

Fișiere📁

Alte fișiere