In this tutorial we will learn how to control a DC motor remotely with the ESP32. We will be using the Arduino core and the HTTP async web server library. The tests shown on this tutorial were performed using an ESP32 board from DFRobot.
Introduction
In this tutorial we will learn how to control a DC motor remotely with the ESP32. We will be using the Arduino core and the HTTP async web server library. You can read more about how to set a server with the mentioned library at this previous post.
For an introductory tutorial on how to connect the ESP32 to a DC motor, please check the previous tutorial, which contains a detailed explanation about the code and the connection diagram. Note that we will need an additional integrated circuit called ULN2803A. You can read more about it here.
The tests shown on this tutorial were performed using an ESP32 board from DFRobot.
The code
As usual, we will start by the library includes we need for our code to work. We are going to need the WiFi.h library, so we can connect the ESP32 to a WiFi network, and the ESPAsyncWebServer.h library, so we can have access to the functions that will allow us to setup the server
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
Then we will declare a global variable to hold the number of the ESP32 digital pin that will be connected to the motor. In my case I’ll be using pin 13, but you can use any available GPIO of your board.
int motorPin = 13;
Then we will need to declare the credentials of the WiFi network, so we can access it. We will need the network name and the password.
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPass";
To finalize the global variables declaration, we will need an object of class AsyncWebServer. This object will be used below to setup the routes of the server and to initialize it.
Note that the constructor of this class receives as parameter the number of the port where the server will be listening for requests. We will be using the default HTTP port, which is 80.
AsyncWebServer server(80);
Moving on to the Arduino setup function, we will start by opening a serial connection, so we can output some results of our program.
Serial.begin(115200);
After that, we will initialize the digital pin as output, since we will be using it to control the DC motor. We do this by calling the pinMode function, passing as first input the number of the pin and as second the constant OUTPUT.
pinMode(motorPin, OUTPUT);
Next we will take care of connecting the ESP32 to the WiFi network, using the previously declared credentials. After the procedure, we will print the local IP assigned to the device, so the HTTP client knows where to reach it.
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
Then we will take care of setting the server routes, which will allow us to remotely control the DC motor. We will have two routes, one to turn it on and the other to turn it off.
We will call “/on” to the route that turns on the motor. This route will listen to HTTP PUT requests, since we are basically updating the status of the resource (our motor).
Note that it is arguable if we should use PATCH instead, since we are actually doing a partial update of the resource, but here we are keeping things simple.
As implementation of the route handling function, we will turn the motor on. To do it, we should set the digital pin to a high state. This is done with a call to the digitalWrite function, passing as first input the number of the pin and as second input the constant HIGH.
After that, we should return an answer to the client indicating the command was correctly executed. For this, simply returning an OK status code (200) is enough. To do that, we call the send method on the AsyncWebServerRequest object, passing as input the value of the status code to be returned to the client.
server.on("/on", HTTP_PUT, [](AsyncWebServerRequest * request) {
digitalWrite(motorPin, HIGH);
request->send(200);
});
The second route, which will turn off the motor, will be called “/off“. It will also only listen to HTTP PUT requests.
The implementation will be similar, except that for this route we will set the digital pin to a low voltage level. We do this by calling the digitalWrite function, passing as first input the number of the pin and as second the constant LOW.
To finalize the handling function implementation, we will also return a 200 code to the client.
server.on("/off", HTTP_PUT, [](AsyncWebServerRequest * request) {
digitalWrite(motorPin, LOW);
request->send(200);
});
To complete the setup function, we only need to call the begin method on the server object, which will ensure the server will start listening to incoming HTTP requests.
server.begin();
The final code can be seen below.
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
int motorPin = 13;
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPass";
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
pinMode(motorPin, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP());
server.on("/on", HTTP_PUT, [](AsyncWebServerRequest * request) {
digitalWrite(motorPin, HIGH);
request->send(200);
});
server.on("/off", HTTP_PUT, [](AsyncWebServerRequest * request) {
digitalWrite(motorPin, LOW);
request->send(200);
});
server.begin();
}
void loop() {}
Testing the code
To test the code, simply compile it and upload it to your ESP32 board, assuming that all the electric connections between the device, the ULN2803A and the motor are already done.
Once the procedure finishes, open the Arduino IDE serial monitor. When the device connects to the WiFi network, its local IP address should get printed. Copy it.
To send the on and off commands to the device, the easiest way is using a tool such as Postman. So, in Postman, simply select the HTTP PUT method from the methods dropdown, and send the request to the following endpoint, changing #yourDeviceIp# by the IP you have just copied, and #command# by the values “on” or “off”:
http://#yourDeviceIp#/#command#
Like illustrated in the video below, you should be able to control the status of the DC motor by sending the mentioned commands:
Related Posts
- Using an ULN2803A to control a DC motor
- ESP8266 Arduino: Controlling a DC motor
- ESP32 Arduino: Controlling a relay
- ESP32 Arduino: Controlling a relay remotely using HTTP
- ESP32 Socket Server: Controlling a relay remotely
Is there any chance you can add more code to get a web page with on and off buttons?
Thanks