Search Code

ESP32 Tutorijal 49/55 - Upravljanje DC motorom preko interneta koristeći Adafruit IoT | SunFounder-ov ESP32 komplet

ESP32 Tutorijal 49/55 - Upravljanje DC motorom preko interneta koristeći Adafruit IoT | SunFounder-ov ESP32 komplet

U ovom tutorijalu ćemo istražiti kako kontrolisati DC motor preko interneta koristeći ESP32 i Adafruit IO MQTT servis. Brzina i smjer DC motora mogu se daljinski upravljati, omogućavajući efikasnu kontrolu s bilo kojeg mjesta s internetskom vezom. Ovaj projekat demonstrira mogućnosti ESP32 mikrokontrolera, koji ima ugrađen Wi-Fi, što ga čini idealnim za Internet of Things (IoT) aplikacije.

esp32-49-DC-motor-mqtt-main

Implementirat ćemo sistem gdje se motor može pokrenuti, zaustaviti, a njegova brzina prilagoditi putem web interfejsa povezanog s Adafruit IO. Korisnici se mogu pretplatiti na određene teme za kontrolu motora i prilagoditi parametre u skladu s tim. Da biste bolje razumjeli proces, svakako pogledajte video koji prati ovaj tutorijal (u videu na 00:00).

Objašnjenje hardvera

Za ovaj projekat koristit ćemo ESP32 mikrokontroler, koji je srce našeg sistema. ESP32 je sposoban za upravljanje Wi-Fi komunikacijom, što ga čini savršenim za našu IoT aplikaciju. Povezuje se na Adafruit IO platformu, omogućavajući nam slanje i primanje poruka putem MQTT protokola.

Osim toga, koristit ćemo L293D motor drajver, koji je neophodan za kontrolu DC motora. L293D može pokretati dva DC motora i omogućava kontrolu i smjera i brzine putem Pulse Width Modulation (PWM). U suštini djeluje kao interfejs između ESP32 i motora, upravljajući većom strujom koju motor zahtijeva, dok izoluje ESP32 od potencijalno štetnih povratnih elektromotornih sila (back-emf).

Detalji iz tehničke dokumentacije

Proizvođač Texas Instruments
Broj dijela L293D
Logički/IO napon 4.5 - 36 V
Napon napajanja 4.5 - 36 V
Izlazna struja (po kanalu) 600 mA
Maksimalna struja (po kanalu) 1.2 A
Smjernice za PWM frekvenciju 10 kHz (tip.)
Ulazni logički pragovi 0.8 V (visok), 2.0 V (nizak)
Pad napona / RDS(on) / zasićenje 1.5 V max
Termička ograničenja 150 °C
Pakovanje DIP-16
Napomene / varijante Četverostruki visokostrujni polu-H drajver

 

  • Osigurajte odgovarajuće hlađenje za kontinuirani rad.
  • Koristite PWM za efikasnu kontrolu brzine motora.
  • Poštujte ograničenja ulaznog napona kako biste spriječili oštećenja.
  • Provjerite ispravne veze uzemljenja između svih komponenti.
  • Budite oprezni s povratnom elektromotornom silom; koristite diode ako je potrebno.
  • Dvaput provjerite ožičenje jer polaritet može utjecati na smjer motora.
  • Testirajte s nižim naponom prije punog rada.
  • Pazite na pregrijavanje tokom duže upotrebe.
  • Obavezno uklonite odbijanje kontakata (debounce) mehaničkih prekidača ako se koriste.
  • Osigurajte da ESP32 nije preopterećen strujom motora.

Upute za ožičenje

ESP32-15_L293D_motor_schematic

Započnite povezivanjem napajanja. Spojite pozitivni terminal vašeg vanjskog izvora napajanja na VCC pin L293D (pin 8) i uzemljenje na GND pin (pin 4). Osigurajte da je ESP32 napajan zasebno ako je potrebno, obično putem mikro USB veze.

Zatim spojite motor na L293D. Jedan terminal motora treba spojiti na izlazni pin 3 (pin 2 L293D), a drugi terminal na izlazni pin 6 (pin 7 L293D). Za kontrolne signale, spojite pin 13 ESP32 na ulazni pin 2 (pin 1 L293D) i pin 14 na ulazni pin 7 (pin 2 L293D). Enable pin (pin 1) također treba spojiti na 5V napajanje kako biste aktivirali drajver. Na kraju, osigurajte da je uzemljenje ESP32 povezano s uzemljenjem L293D za zajedničku referencu.

Primjeri koda i objašnjenje

Priloženi kod inicijalizira potrebne biblioteke i postavlja Wi-Fi i MQTT klijent. Ključni identifikatori uključuju motorSpeed, motorDirection i motorStart, koji upravljaju radom motora na osnovu komandi primljenih s Adafruit IO.

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

U ovom izvatku definirani su pinovi motora zajedno s početnim varijablama za kontrolu brzine, smjera i stanja pokretanja/zaustavljanja motora. Varijabla motorSpeed će se prilagođavati na osnovu unosa s Adafruit IO.

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

U setup funkciji pokreće se serijska komunikacija, a ESP32 se povezuje na navedenu Wi-Fi mrežu. Ova veza je ključna za omogućavanje MQTT komunikacije.

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

Ova loop funkcija uspostavlja MQTT vezu i obrađuje dolazne pakete kako bi kontrolisala motor na osnovu najnovijih primljenih komandi. Funkcija runMotor() se poziva kako bi se trenutne postavke primijenile na motor.

Demonstracija / Šta očekivati

Kada je podešavanje završeno i kod je uploadovan, trebali biste moći kontrolisati motor putem Adafruit IO kontrolne ploče. Brzinu motora možete podešavati pomoću klizača, a smjer promijeniti pomoću prekidača. Ako je sve pravilno spojeno, motor će reagirati na ove komande u realnom vremenu, pokazujući nisku latenciju sistema (u videu na 00:00).

Uobičajeni problemi uključuju obrnuti smjer motora zbog pogrešnog povezivanja, pa provjerite spojeve ako se motor ne ponaša kako se očekuje. Također, osigurajte da su vaše MQTT teme pravilno postavljene u Adafruit IO kako bi odgovarale kodu.

Vremenske oznake videa

  • 00:00 Početak
  • 2:21 Uvod u projekat
  • 4:20 Kako se kontroliše DC motor
  • 6:39 L293D drajver motora
  • 11:42 Šta je MQTT?
  • 15:03 Adafruit IO podešavanje
  • 19:17 Objašnjeno povezivanje
  • 22:42 Objašnjen kod
  • 35:28 Demonstracija projekta

Images

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

Resources & references

No resources yet.

Files📁

No files available.