Samouczek ESP32 49/55 - Sterowanie silnikiem prądu stałego przez internet za pomocą Adafruit IoT | Zestaw SunFounder ESP32
W tym samouczku dowiemy się, jak sterować silnikiem prądu stałego przez internet za pomocą ESP32 oraz usługi Adafruit IO MQTT. Prędkość i kierunek obrotów silnika prądu stałego mogą być sterowane zdalnie, co umożliwia wydajną kontrolę z dowolnego miejsca z dostępem do internetu. Ten projekt demonstruje możliwości mikrokontrolera ESP32, który posiada wbudowane Wi-Fi, co czyni go idealnym do zastosowań w Internecie Rzeczy (IoT).
Zaimplementujemy system, w którym silnik może być uruchamiany, zatrzymywany, a jego prędkość regulowana za pomocą interfejsu internetowego połączonego z Adafruit IO. Użytkownicy mogą subskrybować określone tematy do sterowania silnikiem i odpowiednio dostosowywać parametry. Aby lepiej zrozumieć proces, koniecznie obejrzyj wideo towarzyszące temu samouczkowi (na wideo w 00:00).
Wyjaśnienie Sprzętu
Do tego projektu wykorzystamy mikrokontroler ESP32, który jest sercem naszego systemu. ESP32 jest w stanie obsługiwać komunikację Wi-Fi, co czyni go idealnym do naszej aplikacji IoT. Łączy się z platformą Adafruit IO, umożliwiając nam wysyłanie i odbieranie wiadomości za pomocą protokołu MQTT.
Dodatkowo użyjemy sterownika silnika L293D, który jest niezbędny do sterowania silnikiem prądu stałego. L293D może napędzać dwa silniki prądu stałego i umożliwia kontrolę zarówno kierunku, jak i prędkości za pomocą modulacji szerokości impulsu (PWM). Działa on zasadniczo jako interfejs między ESP32 a silnikiem, zarządzając wyższym prądem wymaganym przez silnik, jednocześnie izolując ESP32 od potencjalnie szkodliwych sygnałów przeciw-EMF.
Szczegóły z Karty Katalogowej
| Producent | Texas Instruments |
|---|---|
| Numer części | L293D |
| Napięcie logiczne/IO | 4,5 - 36 V |
| Napięcie zasilania | 4,5 - 36 V |
| Prąd wyjściowy (na kanał) | 600 mA |
| Prąd szczytowy (na kanał) | 1,2 A |
| Zalecana częstotliwość PWM | 10 kHz (typ.) |
| Progi logiczne wejściowe | 0,8 V (wysoki), 2,0 V (niski) |
| Spadek napięcia / RDS(on) / nasycenie | 1,5 V maks. |
| Limity termiczne | 150 °C |
| Obudowa | DIP-16 |
| Uwagi / warianty | Poczwórny sterownik połowiczny H o wysokim prądzie |
- Zapewnij odpowiednie odprowadzanie ciepła do ciągłej pracy.
- Użyj PWM do skutecznego sterowania prędkością silnika.
- Przestrzegaj limitów napięcia wejściowego, aby zapobiec uszkodzeniom.
- Sprawdź prawidłowe połączenia masy między wszystkimi komponentami.
- Uważaj na przeciw-EMF; w razie potrzeby użyj diod.
- Sprawdź dwukrotnie okablowanie, ponieważ polaryzacja może wpływać na kierunek obrotów silnika.
- Przetestuj przy niższym napięciu przed pełną pracą.
- Uważaj na przegrzewanie podczas dłuższego użytkowania.
- Upewnij się, że przełączniki mechaniczne są odtłumione, jeśli są używane.
- Upewnij się, że ESP32 nie jest przeciążony prądem silnika.
Instrukcje Okablowania
Zacznij od podłączenia zasilania. Podłącz dodatni zacisk zewnętrznego źródła zasilania do pinu VCC układu L293D (pin 8), a masę do pinu GND (pin 4). Upewnij się, że ESP32 jest zasilany osobno, jeśli to konieczne, zwykle przez połączenie micro USB.
Następnie podłącz silnik do L293D. Jeden zacisk silnika należy podłączyć do pinu wyjściowego 3 (pin 2 układu L293D), a drugi zacisk do pinu wyjściowego 6 (pin 7 układu L293D). Dla sygnałów sterujących podłącz pin 13 ESP32 do pinu wejściowego 2 (pin 1 układu L293D) i pin 14 do pinu wejściowego 7 (pin 2 układu L293D). Pin włączający (pin 1) powinien być również podłączony do zasilania 5 V, aby aktywować sterownik. Na koniec upewnij się, że masa ESP32 jest połączona z masą L293D, aby uzyskać wspólny punkt odniesienia.
Przykłady Kodów i Omówienie
Dostarczony kod inicjalizuje niezbędne biblioteki oraz konfiguruje klienta Wi-Fi i MQTT. Kluczowe identyfikatory to motorSpeed, motorDirection i motorStart, które zarządzają pracą silnika na podstawie poleceń otrzymanych z Adafruit IO.
bool debug = false;
#define motor1A 13
#define motor2A 14
int motorSpeed = 0;
int motorDirection = 1;
int motorStart = 1;
W tym fragmencie zdefiniowano piny silnika wraz z początkowymi zmiennymi do sterowania prędkością, kierunkiem oraz stanem start/stop silnika. Zmienna motorSpeed będzie dostosowywana na podstawie danych wejściowych z Adafruit IO.
void setup() {
Serial.begin(115200);
WiFi.begin(WLAN_SSID, WLAN_PASS);
delay(2000);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
W funkcji setup inicjalizowana jest komunikacja szeregowa, a ESP32 łączy się z określoną siecią Wi-Fi. To połączenie jest kluczowe dla umożliwienia komunikacji MQTT.
void loop() {
MQTT_connect();
mqtt.processPackets(500);
runMotor();
}
Ta funkcja pętli ustanawia połączenie MQTT i przetwarza przychodzące pakiety, aby sterować silnikiem na podstawie najnowszych otrzymanych poleceń. Funkcja runMotor() jest wywoływana w celu zastosowania bieżących ustawień do silnika.
Demonstracja / Czego Się Spodziewać
Po zakończeniu konfiguracji i wgraniu kodu powinieneś być w stanie sterować silnikiem za pomocą pulpitu Adafruit IO. Możesz regulować prędkość silnika za pomocą suwaka oraz zmieniać jego kierunek za pomocą przełącznika. Jeśli wszystko jest poprawnie podłączone, silnik będzie reagował na te polecenia w czasie rzeczywistym, co pokazuje niskie opóźnienie systemu (na wideo w 00:00).
Do typowych problemów należy odwrócony kierunek obrotów silnika spowodowany nieprawidłowym podłączeniem, dlatego sprawdź połączenia, jeśli silnik nie zachowuje się zgodnie z oczekiwaniami. Dodatkowo upewnij się, że tematy MQTT są poprawnie skonfigurowane w Adafruit IO, aby odpowiadały kodowi.
Znaczniki czasowe wideo
- 00:00 Start
- 2:21 Wprowadzenie do projektu
- 4:20 Jak sterowany jest silnik prądu stałego
- 6:39 Sterownik silnika L293D
- 11:42 Co to jest MQTT?
- 15:03 Konfiguracja Adafruit IO
- 19:17 Wyjaśnienie podłączeń
- 22:42 Wyjaśnienie kodu
- 35:28 Demonstracja projektu
/***********************************************************************
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!");
}
Common Course Links
Common Course Files
Zasoby i odniesienia
Brak zasobów.
Pliki📁
Brak dostępnych plików.