Search Code

Návod ESP32 30/55 - Ovládanie serva cez web pomocou MQTT pomocou služby Adafruit IO | IoT výučbová súprava ESP32 od SunFounder

Návod ESP32 30/55 - Ovládanie serva cez web pomocou MQTT pomocou služby Adafruit IO | IoT výučbová súprava ESP32 od SunFounder

V tomto návode sa naučíme, ako ovládať polohu servomotora pomocou mikrokontroléra ESP32 a protokolu MQTT cez web. Využitím služby Adafruit IO budete môcť diaľkovo nastavovať servo do rôznych uhlov, ako napríklad 0°, 90° alebo 180°. Tento projekt demonštruje možnosti ESP32, ktorý obsahuje vstavané Wi-Fi a Bluetooth, čo z neho robí výkonný nástroj pre IoT aplikácie.

ESP32-30_MQTT_diagram-0

V tomto projekte nastavíme MQTT broker pomocou Adafruit IO, vytvoríme dashboard na ovládanie serva a pripojíme k nemu ESP32. Poloha serva bude nastaviteľná pomocou posuvníka na dashboarde, čo umožní ovládanie v reálnom čase z akéhokoľvek zariadenia pripojeného na internet (vo videu o 5:30).

Vysvetlenie hardvéru

Hlavné komponenty tohto projektu zahŕňajú mikrokontrolér ESP32 a servomotor. ESP32 je všestranný mikrokontrolér s integrovanými funkciami Wi-Fi a Bluetooth, čo ho robí ideálnym pre IoT aplikácie. Komunikuje so službou Adafruit IO pomocou protokolu MQTT, ktorý je ľahký a efektívny na prenos správ cez internet.

Servomotor je rotačný aktuátor, ktorý umožňuje presné ovládanie uhlovej polohy. Funguje na základe prijímania signálu s pulznou šírkovou moduláciou (PWM), ktorý určuje jeho polohu. V tomto projekte pripojíme servo k jednému z digitálnych pinov na ESP32, čo nám umožní diaľkovo ovládať jeho uhol.

Podrobnosti z datasheetu

Výrobca Parallax
Označenie dielu SG90
Logické/IO napätie 3,3 V - 5 V
Napájacie napätie 4,8 V - 6,0 V
Výstupný prúd (na kanál) max. 1 A
Odporúčaná frekvencia PWM 50 Hz
Vstupné logické prahy 0,3 V - 0,7 V
Pokles napätia / RDS(on) / saturácia max. 0,2 V
Tepelné limity Prevádzková teplota: -10°C až 60°C
Puzdro Plastové puzdro
Poznámky / varianty Mini servo, rotácia 180°

 

  • Zabezpečte správne napájanie serva (4,8 V - 6,0 V).
  • Použite spoločnú zem medzi ESP32 a servom.
  • Sledujte PWM signál, aby ste neprekročili limity serva.
  • Bezpečne pripojte servo, aby nedošlo k odpojeniu počas prevádzky.
  • Aktualizujte knižnicu Adafruit MQTT, aby ste zabezpečili kompatibilitu.

MQTT diagramy

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

Pokyny na zapojenie

ESP32-17-Sevo_motor-wiring

Na zapojenie servomotora k ESP32 začnite pripojením uzemňovacieho vodiča serva k uzemňovaciemu pinu na ESP32. Potom pripojte napájací vodič (zvyčajne červený) serva k 5V pinu na ESP32. Nakoniec pripojte signálny vodič (často žltý alebo biely) k digitálnemu pinu 25 na ESP32. Uistite sa, že sú pripojenia bezpečné, aby nedošlo k odpojeniu počas prevádzky.

Ak na napájanie ESP32 používate batériu, uistite sa, že napätie batérie je v prijateľnom rozsahu pre ESP32 aj servo. Okrem toho skontrolujte, či zapojenie zodpovedá definíciám pinov použitým vo vašom kóde, aby ste predišli problémom (vo videu o 12:45).

Príklady kódu a vysvetlenie

V poskytnutom kóde najprv zahrnieme potrebné knižnice pre ESP32 a MQTT. Definujeme objekt serva a určíme pin, na ktorý je pripojené, pomocou const int servoPin = 25;. Predvolený uhol je tiež nastavený pomocou const int defaultServoAngle = 90;, čo bude počiatočná poloha pri spustení ESP32.


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

Tento úryvok inicializuje servo na pinu 25 a nastaví jeho predvolený uhol na 90°. Premenná servoAngle sa bude aktualizovať na základe správ prijatých z MQTT brokera.

Vo funkcii setup() sa pripojíme k Wi-Fi a nastavíme MQTT klienta. Prihlasovacie údaje pre Adafruit IO sú definované tu, vrátane používateľského mena a kľúča:


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

Táto časť vytvára pripojenie k službe Adafruit IO. Pri implementácii kódu nezabudnite nahradiť tieto hodnoty vlastnými prihlasovacími údajmi Adafruit IO.

Nakoniec hlavná slučka zabezpečuje, aby pripojenie k MQTT serveru zostalo aktívne, a spracováva prichádzajúce správy. Poloha serva sa aktualizuje na základe prijatého uhla:


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

Tento kód mapuje uhol serva na zodpovedajúcu šírku impulzu a posiela ju servomotoru. Funkcia processPackets() umožňuje ESP32 spracovávať prichádzajúce MQTT správy, čím zabezpečuje, že servo reaguje na príkazy odoslané cez Adafruit IO dashboard.

Demonštrácia / Čo očakávať

Keď bude všetko nastavené, mali by ste byť schopní ovládať servo z Adafruit IO dashboardu pomocou posuvníka, ktorý ste vytvorili. Pri pohybe posuvníka bude servo upravovať svoj uhol v reálnom čase. Uistite sa, že je vaše ESP32 pripojené k Wi-Fi a MQTT pripojenie je stabilné. Ak servo nereaguje, skontrolujte zapojenie a napájanie serva (vo videu v čase 20:15).

Majte na pamäti limity rozsahu serva; odoslanie hodnoty mimo 0° až 180° môže spôsobiť neočakávané správanie. Kód obsahuje kontroly, ktoré takýmto prípadom predchádzajú obmedzením uhla na tento rozsah.

Časové značky videa

  • 00:00 Začiatok
  • 1:54 Predstavenie projektu
  • 2:52 Úvod do MQTT
  • 6:50 Nastavenie Adafruit IO
  • 9:54 Zapojenie serva
  • 11:07 Vysvetlenie kódu
  • 18:59 Výber dosky ESP32 a COM portu
  • 22:10 Demonštrácia projektu

Images

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

Things you might need

Resources & references

Files📁

Other files