ኢኤስፒ32 ትምህርት 49/55 - የዲሲ ሞተርን በኢንተርኔት በኩል አዳፍሩት IoT በመጠቀም ይቆጣጠሩ | SunFounder የኢኤስፒ32 ኪት
በዚህ መማሪያ ውስጥ፣ ESP32 እና Adafruit IO MQTT አገልግሎትን በመጠቀም የዲሲ ሞተርን በበይነመረብ እንዴት መቆጣጠር እንደምንችል እንመረምራለን። የዲሲ ሞተር ፍጥነት እና አቅጣጫ በርቀት ሊተነተኑ ይችላሉ፣ ይህም ከየትኛውም ቦታ በበይነመረብ ግንኙነት ቀልጣፋ ቁጥጥር እንዲኖር ያስችላል። ይህ ፕሮጀክት አብሮ የተሰራ Wi-Fi ያለው፣ ለኢንተርኔት ኦፍ ዘንግስ (IoT) አፕሊኬሽኖች ተስማሚ የሚያደርገውን የESP32 ማይክሮኮንትሮለር አቅም ያሳያል።
ሞተሩ ሊጀመር፣ ሊቆም እና ፍጥነቱ ከAdafruit IO ጋር በተገናኘ የድር በይነገጽ አማካኝነት የሚስተካከልበትን ስርዓት እንተገብራለን። ተጠቃሚዎች ለሞተር ቁጥጥር የተወሰኑ ርዕሶችን መመዝገብ እና መለኪያዎችን በዚሁ መሰረት ማስተካከል ይችላሉ። ሂደቱን በተሻለ ለመረዳት፣ ከዚህ መማሪያ ጋር የተያያዘውን ቪዲዮ መመልከትዎን ያረጋግጡ (በቪዲዮው 00:00 ላይ)።
ሃርድዌር ተብራርቷል
ለዚህ ፕሮጀክት፣ የስርዓታችን እምብርት የሆነውን ESP32 ማይክሮኮንትሮለር እንጠቀማለን። ESP32 የWi-Fi ግንኙነቶችን ማስተናገድ ይችላል፣ ይህም ለIoT አፕሊኬሽናችን ፍጹም ያደርገዋል። ከAdafruit IO መድረክ ጋር ይገናኛል፣ ይህም በMQTT ፕሮቶኮል መልዕክቶችን እንድንልክ እና እንድንቀበል ያስችለናል።
በተጨማሪም፣ የዲሲ ሞተርን ለመቆጣጠር አስፈላጊ የሆነውን L293D ሞተር ሾፌር እንጠቀማለን። L293D ሁለት የዲሲ ሞተሮችን መንዳት ይችላል እና ሁለቱንም አቅጣጫ እና ፍጥነት በPulse Width Modulation (PWM) ለመቆጣጠር ያስችላል። በመሠረቱ በESP32 እና በሞተሩ መካከል እንደ በይነገጽ ሆኖ ይሰራል፣ ሞተሩ የሚፈልገውን ከፍተኛ ጅረት ያስተዳድራል እንዲሁም ESP32ን ከማንኛውም ጎጂ የback-emf ምልክቶች ይከላከላል።
የዳታሼት ዝርዝሮች
| አምራች | Texas Instruments |
|---|---|
| የክፍል ቁጥር | L293D |
| የሎጂክ/IO ቮልቴጅ | 4.5 - 36 ቪ |
| የአቅርቦት ቮልቴጅ | 4.5 - 36 ቪ |
| የውጤት ጅረት (በአንድ ቻናል) | 600 ሚኤ |
| ከፍተኛ ጅረት (በአንድ ቻናል) | 1.2 ኤ |
| የPWM ድግግሞሽ መመሪያ | 10 kHz (በተለምዶ) |
| የግቤት ሎጂክ ገደቦች | 0.8 ቪ (ከፍተኛ)፣ 2.0 ቪ (ዝቅተኛ) |
| የቮልቴጅ ጠብታ / RDS(on) / ሙሌት | 1.5 ቪ ከፍተኛ |
| የሙቀት ገደቦች | 150 °C |
| ፓኬጅ | DIP-16 |
| ማስታወሻዎች / ልዩነቶች | አራት እጥፍ ከፍተኛ ጅረት ግማሽ-H ሾፌር |
- ለቀጣይ አሰራር ትክክለኛ የሙቀት መበታተንን ያረጋግጡ።
- የሞተርን ፍጥነት ውጤታማ በሆነ መንገድ ለመቆጣጠር PWM ይጠቀሙ።
- ጉዳትን ለመከላከል የግቤት ቮልቴጅ ገደቦችን ይከታተሉ።
- በሁሉም ክፍሎች መካከል ትክክለኛ የመሬት ግንኙነቶችን ያረጋግጡ።
- ስለ back-emf ይጠንቀቁ; አስፈላጊ ከሆነ ዳዮዶችን ይጠቀሙ።
- የፖላሪቲ ለውጥ የሞተርን አቅጣጫ ሊነካ ስለሚችል ሽቦውን ሁለት ጊዜ ያረጋግጡ።
- ሙሉ አሰራር ከመጀመርዎ በፊት በዝቅተኛ ቮልቴጅ ይሞክሩ።
- ለረጅም ጊዜ ጥቅም ላይ በሚውልበት ጊዜ ከመጠን በላይ ሙቀትን ይጠንቀቁ።
- የሜካኒካል ማብሪያ / ማጥፊያዎች ጥቅም ላይ ከዋሉ ዲባውንሲንግ ማድረግዎን ያረጋግጡ።
- ESP32 በሞተሩ ጅረት ከመጠን በላይ እንዳይጫን ያረጋግጡ።
የሽቦ መግጠሚያ መመሪያዎች
የኃይል አቅርቦቱን በማገናኘት ይጀምሩ። የውጭ የኃይል ምንጭዎን አወንታዊ ተርሚናል ከL293D VCC ፒን (ፒን 8) እና መሬቱን ከGND ፒን (ፒን 4) ጋር ያገናኙ። አስፈላጊ ከሆነ ESP32 በተናጠል መሰራቱን ያረጋግጡ፣ በተለምዶ በማይክሮ ዩኤስቢ ግንኙነት።
በመቀጠል፣ ሞተሩን ከL293D ጋር ያገናኙ። የሞተሩ አንድ ተርሚናል ከውጤት ፒን 3 (የL293D ፒን 2) እና ሌላኛው ተርሚናል ከውጤት ፒን 6 (የL293D ፒን 7) ጋር መገናኘት አለበት። ለቁጥጥር ምልክቶች፣ የESP32 ፒን 13ን ከግቤት ፒን 2 (የL293D ፒን 1) እና ፒን 14ን ከግቤት ፒን 7 (የL293D ፒን 2) ጋር ያገናኙ። የኢኔብል ፒን (ፒን 1) ሾፌሩን ለማግበር ከ5ቪ አቅርቦት ጋር መገናኘት አለበት። በመጨረሻም፣ የESP32 መሬት ከL293D መሬት ጋር ለጋራ ማጣቀሻ መገናኘቱን ያረጋግጡ።
የኮድ ምሳሌዎች እና ማብራሪያ
የቀረበው ኮድ አስፈላጊ ቤተ-መጻሕፍትን ያስጀምራል እና የWi-Fi እና MQTT ደንበኛን ያዘጋጃል። ቁልፍ መለያዎች motorSpeed፣ motorDirection እና motorStart ያካትታሉ፣ እነዚህም ከAdafruit IO በተቀበሉት ትዕዛዞች መሰረት የሞተሩን አሰራር ያስተዳድራሉ።
bool debug = false;
#define motor1A 13
#define motor2A 14
int motorSpeed = 0;
int motorDirection = 1;
int motorStart = 1;
በዚህ ክፍል ውስጥ፣ የሞተር ፒኖች ከፍጥነት፣ አቅጣጫ እና የመጀመር/ማቆም ሁኔታን ለመቆጣጠር ከመጀመሪያ ተለዋዋጮች ጋር ይገለጻሉ። motorSpeed ተለዋዋጭ ከAdafruit IO ግቤት መሰረት ይስተካከላል።
void setup() {
Serial.begin(115200);
WiFi.begin(WLAN_SSID, WLAN_PASS);
delay(2000);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
በሴትአፕ ተግባሩ ውስጥ፣ ተከታታይ ግንኙነት ይጀመራል እና ESP32 ከተገለጸው የWi-Fi አውታረ መረብ ጋር ይገናኛል። ይህ ግንኙነት የMQTT ግንኙነትን ለማንቃት ወሳኝ ነው።
void loop() {
MQTT_connect();
mqtt.processPackets(500);
runMotor();
}
ይህ ሉፕ ተግባር የMQTT ግንኙነትን ያቋቁማል እና የተቀበሉትን ፓኬቶች በማስኬድ ሞተሩን በቅርብ ጊዜ በተቀበሉት ትዕዛዞች መሰረት ይቆጣጠራል። runMotor() ተግባር የአሁኑን ቅንብሮች በሞተሩ ላይ ለመተግበር ይጠራል።
ማሳያ / ምን እንደሚጠበቅ
ሲስተሙ ሲጠናቀቅ እና ኮዱ ሲሰቀል፣ ሞተሩን በAdafruit IO ዳሽቦርድ በኩል መቆጣጠር መቻል አለብዎት። የሞተሩን ፍጥነት በስላይደር ማስተካከል እና አቅጣጫውን በቶግል ማብሪያ / ማጥፊያ መቀየር ይችላሉ። ሁሉም ነገር በትክክል ከተገናኘ፣ ሞተሩ ለእነዚህ ትዕዛዞች በቅጽበት ምላሽ ይሰጣል፣ ይህም የስርዓቱን ዝቅተኛ መዘግየት ያሳያል (በቪዲዮው ላይ በ00:00)።
የተለመዱ ችግሮች በተሳሳተ ሽቦ አያያዝ ምክንያት የተገላቢጦሽ የሞተር አቅጣጫን ያካትታሉ፣ ስለዚህ ሞተሩ እንደተጠበቀው ባይሰራ ግንኙነቶቹን በድጋሚ ያረጋግጡ። በተጨማሪም፣ የMQTT ርዕሶችዎ ከኮዱ ጋር እንዲዛመዱ በAdafruit IO ውስጥ በትክክል መዋቀራቸውን ያረጋግጡ።
የቪዲዮ የጊዜ ምልክቶች
- 00:00 መጀመሪያ
- 2:21 የፕሮጀክቱ መግቢያ
- 4:20 የዲሲ ሞተር እንዴት እንደሚቆጣጠር
- 6:39 L293D የሞተር ሾፌር
- 11:42 MQTT ምንድን ነው?
- 15:03 Adafruit IO ማዋቀር
- 19:17 የሽቦ አያያዝ ተብራርቷል
- 22:42 ኮድ ተብራርቷል
- 35:28 የፕሮጀክት ማሳያ
/***********************************************************************
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
ምንጮች እና ምንጮች
አሁን ምንም ምንጮች የለም።
ፋይሎች📁
አንድ ፋይል የለም።