Search Code

Hướng dẫn ESP32 49/55 - Điều khiển động cơ DC qua Internet bằng Adafruit IoT | Bộ kit ESP32 của SunFounder

Hướng dẫn ESP32 49/55 - Điều khiển động cơ DC qua Internet bằng Adafruit IoT | Bộ kit ESP32 của SunFounder

Trong hướng dẫn này, chúng ta sẽ khám phá cách điều khiển động cơ DC qua internet bằng ESP32 và dịch vụ Adafruit IO MQTT. Tốc độ và hướng của động cơ DC có thể được điều khiển từ xa, cho phép kiểm soát hiệu quả từ bất kỳ đâu có kết nối internet. Dự án này chứng minh khả năng của vi điều khiển ESP32, có Wi-Fi tích hợp, lý tưởng cho các ứng dụng Internet vạn vật (IoT).

esp32-49-DC-motor-mqtt-main

Chúng ta sẽ triển khai một hệ thống trong đó động cơ có thể được khởi động, dừng và điều chỉnh tốc độ qua giao diện web kết nối với Adafruit IO. Người dùng có thể đăng ký các chủ đề cụ thể để điều khiển động cơ và điều chỉnh các tham số tương ứng. Để hiểu rõ hơn về quy trình, hãy xem video đi kèm với hướng dẫn này (trong video tại 00:00).

Phần cứng được giải thích

Đối với dự án này, chúng ta sẽ sử dụng vi điều khiển ESP32, là trái tim của hệ thống. ESP32 có khả năng xử lý truyền thông Wi-Fi, làm cho nó hoàn hảo cho ứng dụng IoT của chúng ta. Nó kết nối với nền tảng Adafruit IO, cho phép chúng ta gửi và nhận tin nhắn qua giao thức MQTT.

Ngoài ra, chúng ta sẽ sử dụng trình điều khiển động cơ L293D, rất cần thiết để điều khiển động cơ DC. L293D có thể điều khiển hai động cơ DC và cho phép điều khiển cả hướng và tốc độ thông qua Điều chế độ rộng xung (PWM). Về cơ bản, nó hoạt động như một giao diện giữa ESP32 và động cơ, quản lý dòng điện cao hơn mà động cơ yêu cầu trong khi cách ly ESP32 khỏi các tín hiệu sức điện động ngược có thể gây hại.

Chi tiết bảng dữ liệu

Nhà sản xuất Texas Instruments
Số bộ phận L293D
Điện áp logic/IO 4.5 - 36 V
Điện áp cung cấp 4.5 - 36 V
Dòng điện đầu ra (mỗi kênh) 600 mA
Dòng điện đỉnh (mỗi kênh) 1.2 A
Hướng dẫn tần số PWM 10 kHz (điển hình)
Ngưỡng logic đầu vào 0.8 V (cao), 2.0 V (thấp)
Sụt áp / RDS(on) / bão hòa 1.5 V tối đa
Giới hạn nhiệt 150 °C
Đóng gói DIP-16
Ghi chú / biến thể Trình điều khiển nửa H dòng cao bốn kênh

 

  • Đảm bảo tản nhiệt thích hợp cho hoạt động liên tục.
  • Sử dụng PWM để điều khiển tốc độ động cơ hiệu quả.
  • Quan sát giới hạn điện áp đầu vào để tránh hư hỏng.
  • Kiểm tra kết nối đất thích hợp giữa tất cả các thành phần.
  • Cẩn thận với sức điện động ngược; sử dụng diode nếu cần thiết.
  • Kiểm tra lại dây nối vì cực tính có thể ảnh hưởng đến hướng động cơ.
  • Thử nghiệm với điện áp thấp hơn trước khi vận hành đầy đủ.
  • Theo dõi quá nhiệt trong quá trình sử dụng kéo dài.
  • Đảm bảo khử nhiễu các công tắc cơ học nếu được sử dụng.
  • Đảm bảo ESP32 không bị quá tải bởi dòng điện của động cơ.

Hướng dẫn nối dây

ESP32-15_L293D_motor_schematic

Bắt đầu bằng cách kết nối nguồn điện. Kết nối cực dương của nguồn điện bên ngoài với chân VCC của L293D (chân 8) và cực âm với chân GND (chân 4). Đảm bảo ESP32 được cấp nguồn riêng nếu cần, thường qua kết nối micro USB.

Tiếp theo, kết nối động cơ với L293D. Một đầu của động cơ nên được kết nối với chân đầu ra 3 (chân 2 của L293D) và đầu kia với chân đầu ra 6 (chân 7 của L293D). Đối với tín hiệu điều khiển, kết nối chân 13 của ESP32 với chân đầu vào 2 (chân 1 của L293D) và chân 14 với chân đầu vào 7 (chân 2 của L293D). Chân kích hoạt (chân 1) cũng nên được kết nối với nguồn 5V để kích hoạt trình điều khiển. Cuối cùng, đảm bảo đất của ESP32 được kết nối với đất của L293D để có tham chiếu chung.

Ví dụ mã & hướng dẫn chi tiết

Mã được cung cấp khởi tạo các thư viện cần thiết và thiết lập máy khách Wi-Fi và MQTT. Các định danh chính bao gồm motorSpeed, motorDirectionmotorStart, quản lý hoạt động của động cơ dựa trên các lệnh nhận được từ Adafruit IO.

bool debug = false;
#define motor1A 13
#define motor2A 14
int motorSpeed = 0;
int motorDirection = 1;
int motorStart = 1;

Trong đoạn trích này, các chân động cơ được định nghĩa cùng với các biến ban đầu để điều khiển tốc độ, hướng và trạng thái khởi động/dừng của động cơ. Biến motorSpeed sẽ được điều chỉnh dựa trên đầu vào từ Adafruit IO.

void setup() {
  Serial.begin(115200);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  delay(2000);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

Trong hàm setup, truyền thông nối tiếp được khởi tạo và ESP32 kết nối với mạng Wi-Fi được chỉ định. Kết nối này rất quan trọng để cho phép truyền thông MQTT.

void loop() {
  MQTT_connect();
  mqtt.processPackets(500);
  runMotor();
}

Hàm loop này thiết lập kết nối MQTT và xử lý các gói tin đến để điều khiển động cơ dựa trên các lệnh mới nhất nhận được. Hàm runMotor() được gọi để áp dụng các cài đặt hiện tại cho động cơ.

Trình diễn / Điều gì sẽ xảy ra

Khi quá trình thiết lập hoàn tất và mã được tải lên, bạn sẽ có thể điều khiển động cơ thông qua bảng điều khiển Adafruit IO. Bạn có thể điều chỉnh tốc độ động cơ bằng thanh trượt và thay đổi hướng của nó bằng công tắc bật/tắt. Nếu mọi thứ được nối dây chính xác, động cơ sẽ phản hồi các lệnh này trong thời gian thực, thể hiện độ trễ thấp của hệ thống (trong video tại 00:00).

Các vấn đề thường gặp bao gồm đảo chiều động cơ do nối dây sai, vì vậy hãy kiểm tra lại các kết nối nếu động cơ không hoạt động như mong đợi. Ngoài ra, hãy đảm bảo rằng các chủ đề MQTT của bạn được thiết lập chính xác trong Adafruit IO để khớp với mã.

Mốc thời gian video

  • 00:00 Bắt đầu
  • 2:21 Giới thiệu về dự án
  • 4:20 Cách động cơ DC được điều khiển
  • 6:39 Bộ điều khiển động cơ L293D
  • 11:42 MQTT là gì?
  • 15:03 Thiết lập Adafruit IO
  • 19:17 Giải thích về nối dây
  • 22:42 Giải thích mã
  • 35:28 Trình diễn dự án

Hình ảnh

ESP32-15_L293D_motor_schematic
ESP32-15_L293D_motor_schematic
esp32-49-DC-motor-mqtt-main
esp32-49-DC-motor-mqtt-main
851-ESP32 Tutorial 49/55- Arduino code using ESP32 to DC Motor using MQTT service of Adafruit
Ngôn ngữ: C++
/***********************************************************************
 This is Arduino sketch for ESP32 to DC Motor using MQTT service of Adafruit
 Watch video instruction https://youtu.be/OUgyPXNYg3g
 📚⬇️ Download and resource page https://robojax.com/RJT673
 Written By Ahamd Shamshiri
 on Feb 18, 2024

  Adafruit MQTT Library ESP32 Adafruit IO SSL/TLS example

  

/// ref: https://www.electronicwings.com/esp32/esp32-mqtt-client
*/
bool debug = false;
#define motor1A 13
#define motor2A 14

// PWM settings
const int freq = 500; // PWM frequency: 500 Hz
const int resolution = 8; // PWM resolution: 8 bits
const int channelA = 0; // PWM channel for motor1A: 0
const int channelB = 1; // PWM channel for motor2A: 1

char* dir[]={"CCW", "CW"};

int motorSpeed =0;
int motorDirection =1;
int motorStart = 1;
int dutyCycle =0;

#include <WiFi.h>
#include "WiFiClientSecure.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/************************* WiFi Access Point *********************************/


#define WLAN_SSID "Book"
#define WLAN_PASS "88888888"

/************************* 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_jHpm60SEsWUdU5x472FViZjWzsY9"

/************ 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 MOTOR_SPEED = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/motor.speed");
Adafruit_MQTT_Subscribe MOTOR_DIRECTION = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/motor.direction");
Adafruit_MQTT_Subscribe MOTOR_START = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/motor.start");


/*************************** Sketch Code ************************************/


void setup() {
  // Set up PWM
  ledcSetup(channelA, freq, resolution);
  ledcSetup(channelB, freq, resolution);

  // Attach PWM channels to GPIO pins
  ledcAttachPin(motor1A, channelA);
  ledcAttachPin(motor2A, channelB);

  Serial.begin(115200);
  delay(10);

  Serial.println(F("DC Motor over MQTT 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
  MOTOR_SPEED.setCallback(MOTOR_SPEED_Callback);
  // Setup MQTT subscription for time feed.
  mqtt.subscribe(&MOTOR_SPEED);

  // register callback for feed
  MOTOR_DIRECTION.setCallback(MOTOR_DIRECTION_Callback);
  // Setup MQTT subscription for time feed.
  mqtt.subscribe(&MOTOR_DIRECTION);

  // register callback for feed
  MOTOR_START.setCallback(MOTOR_START_Callback);
  // Setup MQTT subscription for time feed.
  mqtt.subscribe(&MOTOR_START);

}

// 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("Speed: ");
  // Serial.print (motorSpeed);
  // Serial.print(" Dir: ");
  // Serial.print (dir[motorDirection]);
  // Serial.print(" Sart: ");
  // Serial.println(motorStart);

  // Serial.print("DutyCycle: ");
  // Serial.println(dutyCycle);

  // wait 0.5 seconds for subscription messages
  mqtt.processPackets(500);

   runMotor();//very important
  // wait a couple seconds to avoid rate limit
  //delay(2000);
}

void MOTOR_SPEED_Callback(char* message, uint16_t len) {
  char messageBuffer[40];
  //snprintf(messageBuffer, sizeof(messageBuffer), "Color status is :: %s, len :: %u", message, len);
  //Serial.println(messageBuffer);
  Serial.println(message);
  String inString = message;//sotre the message to String
 
  motorSpeed  =  inString.toInt();//convert the message to Integer
  if(motorSpeed >100 || motorSpeed < 0)
  {
    motorSpeed = 0;
  }
  dutyCycle = map (motorSpeed, 0, 100, 0, 255);
 
}


void MOTOR_DIRECTION_Callback(char* message, uint16_t len) {
  char messageBuffer[40];
  //snprintf(messageBuffer, sizeof(messageBuffer), "Color status is :: %s, len :: %u", message, len);
  //Serial.println(messageBuffer);
  Serial.println(message);
  String inString = message;//sotre the message to String
 
  motorDirection  =  inString.toInt();//convert the message to Integer

 
}


void MOTOR_START_Callback(char* message, uint16_t len) {
  char messageBuffer[40];
  //snprintf(messageBuffer, sizeof(messageBuffer), "Color status is :: %s, len :: %u", message, len);
  //Serial.println(messageBuffer);
  Serial.println(message);

  String inString = message;//sotre the message to String
 
  motorStart  =  inString.toInt();//convert the message to Integer

 
}


void runMotor()
{

  if(motorStart ==1)
  {
      if(debug)
      {
        Serial.print("Motor running:");
        Serial.print(dir[motorDirection]);
        Serial.print(" at ");
        Serial.print(motorSpeed);
        Serial.println("%");
      }
    if(motorDirection)
    {
      ledcWrite(channelA, dutyCycle);
      ledcWrite(channelB, 0);
      delay(50); 
    }else{

      ledcWrite(channelA, 0);
      ledcWrite(channelB, dutyCycle);
      delay(50); 
    }
  }else{
    if(debug)
    {
      Serial.println("***Motor Stopped***");
    }
      ledcWrite(channelA, 0);
      ledcWrite(channelB, 0);   
  }

}//runMotor() end

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

Tài nguyên & tài liệu tham khảo

Chưa có tài nguyên nào.

Tập tin📁

Không có tệp nào khả dụng.