Search Code

Tutorial ESP32 30/55 - Mengontrol Servo Melalui Web menggunakan MQTT dengan Layanan Adafruit IO | Kit Pembelajaran IoT ESP32 SunFounder

Tutorial ESP32 30/55 - Mengontrol Servo Melalui Web menggunakan MQTT dengan Layanan Adafruit IO | Kit Pembelajaran IoT ESP32 SunFounder

Dalam tutorial ini, kita akan mempelajari cara mengontrol posisi motor servo menggunakan mikrokontroler ESP32 dan protokol MQTT melalui web. Dengan memanfaatkan layanan Adafruit IO, Anda akan dapat memposisikan servo pada berbagai sudut seperti 0°, 90°, atau 180° dari jarak jauh. Proyek ini menunjukkan kemampuan ESP32, yang mencakup Wi-Fi dan Bluetooth bawaan, menjadikannya alat yang kuat untuk aplikasi IoT.

ESP32-30_MQTT_diagram-0

Dalam proyek ini, kita akan menyiapkan broker MQTT menggunakan Adafruit IO, membuat dasbor untuk mengontrol servo, dan menghubungkan ESP32 ke sana. Posisi servo akan dapat disesuaikan melalui penggeser di dasbor, memungkinkan kontrol waktu nyata dari perangkat apa pun yang terhubung ke internet (dalam video pada 5:30).

Penjelasan Perangkat Keras

Komponen utama proyek ini mencakup mikrokontroler ESP32 dan motor servo. ESP32 adalah mikrokontroler serbaguna dengan kemampuan Wi-Fi dan Bluetooth terintegrasi, menjadikannya ideal untuk aplikasi IoT. Ia berkomunikasi dengan layanan Adafruit IO menggunakan protokol MQTT, yang ringan dan efisien untuk mengirimkan pesan melalui internet.

Motor servo adalah aktuator putar yang memungkinkan kontrol presisi posisi sudut. Ia beroperasi dengan menerima sinyal modulasi lebar pulsa (PWM) yang menentukan posisinya. Dalam proyek ini, kita akan menghubungkan servo ke salah satu pin digital pada ESP32, memungkinkan kita mengontrol sudutnya dari jarak jauh.

Detail Datasheet

Produsen Parallax
Nomor bagian SG90
Tegangan logika/IO 3,3 V - 5 V
Tegangan suplai 4,8 V - 6,0 V
Arus keluaran (per saluran) Maks 1 A
Panduan frekuensi PWM 50 Hz
Ambang logika masukan 0,3 V - 0,7 V
Penurunan tegangan / RDS(on) / saturasi Maks 0,2 V
Batas termal Suhu operasi: -10°C hingga 60°C
Kemasan Kasing plastik
Catatan / varian Servo mini, rotasi 180°

 

  • Pastikan suplai tegangan yang tepat ke servo (4,8 V - 6,0 V).
  • Gunakan ground bersama antara ESP32 dan servo.
  • Pantau sinyal PWM untuk menghindari melebihi batas servo.
  • Hubungkan servo dengan aman untuk menghindari koneksi terputus selama operasi.
  • Perbarui pustaka Adafruit MQTT untuk memastikan kompatibilitas.

Diagram MQTT

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

Instruksi Pengkabelan

ESP32-17-Sevo_motor-wiring

Untuk menghubungkan motor servo ke ESP32, mulailah dengan menghubungkan kabel ground servo ke pin ground pada ESP32. Selanjutnya, hubungkan kabel daya (biasanya merah) servo ke pin 5V pada ESP32. Terakhir, hubungkan kabel sinyal (sering berwarna kuning atau putih) ke pin digital 25 pada ESP32. Pastikan koneksi aman untuk mencegah koneksi terputus selama operasi.

Jika Anda menggunakan baterai untuk memberi daya pada ESP32, pastikan tegangan baterai berada dalam rentang yang dapat diterima untuk ESP32 dan servo. Selain itu, periksa ulang bahwa pengkabelan sesuai dengan definisi pin yang digunakan dalam kode Anda untuk menghindari masalah (dalam video pada 12:45).

Contoh Kode & Penjelasan

Dalam kode yang disediakan, pertama-tama kita menyertakan pustaka yang diperlukan untuk ESP32 dan MQTT. Kita mendefinisikan objek servo dan menentukan pin yang terhubung dengannya dengan const int servoPin = 25;. Sudut default juga diatur dengan const int defaultServoAngle = 90;, yang akan menjadi posisi awal saat ESP32 boot.


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

Cuplikan ini menginisialisasi servo pada pin 25 dan mengatur sudut defaultnya menjadi 90°. Variabel servoAngle akan diperbarui berdasarkan pesan yang diterima dari broker MQTT.

Dalam fungsi setup(), kita terhubung ke Wi-Fi dan mengatur klien MQTT. Kredensial untuk Adafruit IO didefinisikan di sini, termasuk nama pengguna dan kunci:


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

Bagian ini membangun koneksi ke layanan Adafruit IO. Pastikan untuk mengganti nilai-nilai ini dengan kredensial Adafruit IO Anda sendiri saat mengimplementasikan kode.

Terakhir, loop utama memastikan bahwa koneksi ke server MQTT tetap aktif dan memproses pesan masuk. Posisi servo diperbarui berdasarkan sudut yang diterima:


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

Kode ini memetakan sudut servo ke lebar pulsa yang sesuai dan mengirimkannya ke motor servo. Fungsi processPackets() memungkinkan ESP32 untuk menangani pesan MQTT yang masuk, memastikan servo bereaksi terhadap perintah yang dikirim melalui dasbor Adafruit IO.

Demonstrasi / Apa yang Diharapkan

Setelah semuanya diatur, Anda seharusnya dapat mengontrol servo dari dasbor Adafruit IO menggunakan penggeser yang Anda buat. Saat Anda menggerakkan penggeser, servo akan menyesuaikan sudutnya secara real-time. Pastikan ESP32 Anda terhubung ke Wi-Fi, dan koneksi MQTT stabil. Jika servo tidak merespons, periksa kabel dan catu daya ke servo (di video pada 20:15).

Perhatikan batas rentang untuk servo; mengirim nilai di luar 0° hingga 180° dapat menyebabkan perilaku yang tidak terduga. Kode ini mencakup pemeriksaan untuk mencegah hal tersebut dengan membatasi sudut dalam rentang ini.

Stempel Waktu Video

  • 00:00 Mulai
  • 1:54 Pengenalan proyek
  • 2:52 Pengenalan MQTT
  • 6:50 Pengaturan Adafruit IO
  • 9:54 Pengkabelan servo
  • 11:07 Penjelasan kode
  • 18:59 Memilih papan ESP32 dan port COM
  • 22:10 Demonstrasi proyek

Gambar

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

Hal-hal yang mungkin Anda butuhkan

Sumber daya & referensi

Berkas📁

File lainnya