ESP32 Tutorial 49/55 - Control DC Motor Over The internet using Adafruit IoT | SunFounder's ESP32 kit
SunFounder Documentation page ESP32 Learning Kit
Purchase SunFounder ESP32 Learning Kit
In this video we learn how to control the speed, direction and start/stop of DC motor using ESP32 over clould using MQTT protocol provided by Adafruit.
Topics in this lesson
Use Chapters from timeline or click on the time
- 00:00 Introduction
- 2:21 Intoduction to the project
- 4:20 How DC Motor is controlled
- 6:39 L293D Motor Driver
- 11:42 What is MQTT?
- 15:03 Adafruit IO setup
- 19:17 Wiring Explained
- 22:42 Code explained
- 35:28 Project Demonstration
/* Watch video instruction for this code on YouTube https://youtu.be/OUgyPXNYg3g Resource page for this lesson and code: http://robojax.com/course3 Tutoril by https://youTube.com/@robojax /*********************************************************************** This is Arduino sketch for ESP32 to DC Motor using MQTT service of Adafruit www.Robojax.com 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#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: /feeds/ 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!"); }