Search Code

ESP32 Упатство 30/55 - Контролирај серво преку веб користејќи MQTT со Adafruit IO сервис | SunFounder's ESP32 IoT комплет за учење

ESP32 Упатство 30/55 - Контролирај серво преку веб користејќи MQTT со Adafruit IO сервис | SunFounder's ESP32 IoT комплет за учење

Во ова упатство, ќе научиме како да ја контролираме позицијата на серво мотор користејќи го ESP32 микроконтролерот и MQTT протоколот преку интернет. Со користење на Adafruit IO услугата, ќе можете да го позиционирате сервото под различни агли како 0°, 90° или 180° од далечина. Овој проект ги демонстрира можностите на ESP32, кој вклучува вграден Wi-Fi и Bluetooth, што го прави моќна алатка за IoT апликации.

ESP32-30_MQTT_diagram-0

Во овој проект, ќе поставиме MQTT брокер користејќи Adafruit IO, ќе креираме контролна табла за контрола на сервото, и ќе го поврземе ESP32 со него. Позицијата на сервото ќе може да се прилагодува преку лизгач на контролната табла, овозможувајќи контрола во реално време од кој било уред поврзан на интернет (во видео на 5:30).

Објаснување на хардверот

Примарните компоненти на овој проект вклучуваат ESP32 микроконтролер и серво мотор. ESP32 е разноврсен микроконтролер со интегрирани Wi-Fi и Bluetooth можности, што го прави идеален за IoT апликации. Тој комуницира со Adafruit IO услугата користејќи го MQTT протоколот, кој е лесен и ефикасен за пренос на пораки преку интернет.

Серво моторот е ротационен актуатор кој овозможува прецизна контрола на аголната позиција. Тој работи со примање на пулсно-ширински модулиран (PWM) сигнал кој ја одредува неговата позиција. Во овој проект, ќе го поврземе сервото на еден од дигиталните пинови на ESP32, овозможувајќи ни да го контролираме неговиот агол од далечина.

Детали од техничката спецификација

Производител Parallax
Број на дел SG90
Логички/I/O напон 3.3 V - 5 V
Напон на напојување 4.8 V - 6.0 V
Излезна струја (по канал) 1 A макс
Насоки за PWM фреквенција 50 Hz
Прагови на влезна логика 0.3 V - 0.7 V
Пад на напон / RDS(on) / сатурација 0.2 V макс
Термички граници Работна температура: -10°C до 60°C
Пакет Пластична кутија
Белешки / варијанти Мини серво, 180° ротација

 

  • Обезбедете соодветно напојување на сервото (4.8 V - 6.0 V).
  • Користете заедничка земја помеѓу ESP32 и сервото.
  • Следете го PWM сигналот за да избегнете надминување на границите на сервото.
  • Безбедно поврзете го сервото за да избегнете исклучувања за време на работа.
  • Ажурирајте ја Adafruit MQTT библиотеката за да обезбедите компатибилност.

MQTT Дијаграми

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

Инструкции за поврзување

ESP32-17-Sevo_motor-wiring

За да го поврзете серво моторот со ESP32, започнете со поврзување на жицата за земја на сервото со пинот за земја на ESP32. Потоа, поврзете ја жицата за напојување (обично црвена) на сервото со 5V пинот на ESP32. На крај, поврзете ја сигналната жица (често жолта или бела) со дигиталниот пин 25 на ESP32. Осигурете се дека врските се безбедни за да спречите какви било исклучувања за време на работа.

Ако користите батерија за напојување на ESP32, проверете дали напонот на батеријата е во прифатливиот опсег и за ESP32 и за сервото. Дополнително, проверете дали жиците одговараат на дефинициите на пиновите користени во вашиот код за да избегнете какви било проблеми (во видео на 12:45).

Примери на код & Објаснување

Во дадениот код, прво ги вклучуваме потребните библиотеки за ESP32 и MQTT. Го дефинираме серво објектот и го одредуваме пинот на кој е поврзан со const int servoPin = 25;. Стандардниот агол исто така е поставен со const int defaultServoAngle = 90;, кој ќе биде почетната позиција кога ESP32 ќе се вклучи.


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

Овој фрагмент го иницијализира сервото на пин 25 и го поставува неговиот стандарден агол на 90°. Променливата servoAngle ќе се ажурира врз основа на пораките примени од MQTT брокерот.

Во setup() функцијата, се поврзуваме на Wi-Fi и го поставуваме MQTT клиентот. Акредитивите за Adafruit IO се дефинирани тука, вклучувајќи го корисничкото име и клучот:


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

Овој дел ја воспоставува врската со Adafruit IO услугата. Осигурете се да ги замените овие вредности со вашите сопствени Adafruit IO акредитиви кога го имплементирате кодот.

Конечно, главната јамка осигурува дека врската со MQTT серверот останува активна и обработува дојдовни пораки. Позицијата на сервото се ажурира врз основа на примениот агол:


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

Овој код го мапира аголот на сервото на соодветната ширина на пулсот и го испраќа до серво моторот. Функцијата processPackets() му овозможува на ESP32 да обработува дојдовни MQTT пораки, обезбедувајќи сервото да реагира на команди испратени преку Adafruit IO контролната табла.

Демонстрација / Што да очекувате

Откако сè ќе биде поставено, ќе можете да го контролирате сервото од Adafruit IO контролната табла користејќи го лизгачот што сте го создале. Додека го движите лизгачот, сервото ќе го прилагодува својот агол во реално време. Осигурете се дека вашиот ESP32 е поврзан на Wi-Fi и дека MQTT врската е стабилна. Ако сервото не реагира, проверете ги жиците и напојувањето на сервото (во видеото на 20:15).

Внимавајте на границите на опсегот за сервото; испраќањето вредност надвор од 0° до 180° може да предизвика неочекувано однесување. Кодот вклучува проверки за да спречи такви случаи со ограничување на аголот во овој опсег.

Временски ознаки на видеото

  • 00:00 Почеток
  • 1:54 Вовед во проектот
  • 2:52 Вовед во MQTT
  • 6:50 Поставување на Adafruit IO
  • 9:54 Поврзување на сервото
  • 11:07 Објаснување на кодот
  • 18:59 Избор на ESP32 плоча и COM порта
  • 22:10 Демонстрација на проектот

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