How to Control ELEGOO 28BYJ-48 Stepper Motors With ESP32 Wirelessly
by SuitableBat9 in Circuits > Wireless
725 Views, 4 Favorites, 0 Comments
How to Control ELEGOO 28BYJ-48 Stepper Motors With ESP32 Wirelessly
This Is My First Time Creating An Instructables So Sorry If Its Bad Im Just try To Help People. I Use This For Many This Including Opening And Closing My Blinds And My Vent. If You Have Questions Or Need Help Or Even Have Any Suggestions Comment Them Below
Supplies
- ELEGOO 28BYJ-48 Stepper Motor With ULN2003 Driver Board (Amazon Link)
- Some Jumper Wires
- ESP32
Connect ULN2003 Driver Board to ESP32
Connect IN1 To Pin 13 On ESP32 (Could Also Be D13 Or G13)
Connect IN2 To Pin 12 On ESP32 (Could Also Be D12 Or G12)
Connect IN3 To Pin 14 On ESP32 (Could Also Be D14 Or G14)
Connect IN4 To Pin 27 On ESP32 (Could Also Be D27 Or G27)
You Can Either Connect The Positive And Negative To The 5V (As VIN On ESP32) And The GND On The ESP32 Or You Can Use A Separate Adapter For 12V To Make It More Powerful
Arduino Setting
Upload Code to ESP32
Open Arduino IDE And Paste The Code Below
const int CW =1;
const int CCW =2;
const int STOP =3;
int Pin1 = 13;//IN1 is connected to 13
int Pin2 = 12;//IN2 is connected to 12
int Pin3 = 14;//IN3 is connected to 14
int Pin4 = 27;//IN4 is connected to 27
long angles[] = {360, 270, 90, 20, 287, 2000, 2000};//angles of each push button
int directions[] ={CW, CCW, CW, CCW, CW, CW, CCW};//direction of eacch push button
int speedFactors[] = {10, 1, 4, 10, 2, 1, 1};//speed for each push button
const String statusTitle[]={
"Motor sent to ",
"Motor sent to ",
"Motor sent to ",
"Motor sent to ",
"Motor sent to "};
const String directionTitle[]={"CW", "CCW"};
const String stopPushButtonTitle="STOP";
const String topTitle1 ="° in ";
const String topTitle2 ="Speed factor: ";
const String topTitle3 ="Angle: ";
const String topTitle4 ="Direction: ";
const String topTitle5 =", Speed: ";
const String topTitle6 ="Send";
const String customMainTitle ="( C )Motor sent to ";
const int customValueButtonID=99;
const String motorStopped ="Motor Stopped";
int correction_CW = 150;//watch video for details
int correction_CCW = 150;//watch video for details
int poleStep = 0;
long stepVale =0;
const int SPR=64*64;
long goToAngle=0;
int activeButton=0;
int speedValue =1;
int pole1[] ={0,0,0,0, 0,1,1,1, 0};//pole1, 8 step values
int pole2[] ={0,0,0,1, 1,1,0,0, 0};//pole2, 8 step values
int pole3[] ={0,1,1,1, 0,0,0,0, 0};//pole3, 8 step values
int pole4[] ={1,1,0,0, 0,0,0,1, 0};//pole4, 8 step values
int count=0;
int dirStatus = STOP;// stores direction status 3= stop (do not change)
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char *ssid = "SSIDHERE";
const char *password = "PASSWORDHERE";
WebServer server(80);
void handleRoot() {
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
String HTML ="<!DOCTYPE html>\
<html>\
<head>\
\t\n<title>Robojax ESP32 Stepper Motor</title>\
\t\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\
\n<style>\
\nhtml,body{\t\nwidth:100%\;\nheight:100%\;\nmargin:0}\n*{box-sizing:border-box}\n.colorAll{\n\tbackground-color:#90ee90}\n.colorBtn{\n\tbackground-color:#add8e6}\n.angleButtdon,a{\n\tfont-size:30px\;\nborder:1px solid #ccc\;\ndisplay:table-caption\;\npadding:7px 10px\;\ntext-decoration:none\;\ncursor:pointer\;\npadding:5px 6px 7px 10px}a{\n\tdisplay:block}\n.btn{\n\tmargin:5px\;\nborder:none\;\ndisplay:inline-block\;\nvertical-align:middle\;\ntext-align:center\;\nwhite-space:nowrap}\n";
HTML +="</style>\n\n</head>\n\n<body>\n<h1>Robojax ESP32 Stepper ESPSTP-2 </h1>\n";
if(dirStatus !=STOP && activeButton !=customValueButtonID ){
HTML +="\n\t<h2><span style=\"background-color: #FFFF00\">";
HTML +=statusTitle[activeButton];
HTML +=String(angles[activeButton]);
HTML +=topTitle1;
HTML +=directionTitle[directions[activeButton]-1]; //subtract 1 to get proper title
HTML +="</span></h2>\n";
HTML +="\n\t<h2>";
HTML +=topTitle2;
HTML +=String(speedFactors[activeButton]);
HTML +="<span style=\"background-color: #FFFF00\"> (";
float timeTakes =(float)speedFactors[activeButton] * float(angles[activeButton]) * ((float)4/(float)360);//calculat the time that takes to move to that angle
HTML +=String(timeTakes);
HTML +=" seconds)";
HTML +="</span></h2>\n";
}if(activeButton ==customValueButtonID ){
HTML +="\n\t<h2><span style=\"background-color: #FFFF00\">";
HTML +=customMainTitle;
HTML +=String(goToAngle);
HTML +=topTitle1;
HTML +=directionTitle[dirStatus-1]; //subtract 1 to get proper title
HTML +="</span></h2>\n";
HTML +="\n\t<h2>";
HTML +=topTitle2;
HTML +=String(speedValue);
HTML +="<span style=\"background-color: #FFFF00\"> (";
float timeTakes =(float)speedValue * float(goToAngle) * ((float)4/(float)360);//calculat the time that takes to move to that angle
HTML +=String(timeTakes);
HTML +=" seconds)";
HTML +="</span></h2>\n";
}else if(dirStatus ==STOP)
{
HTML +="\n\t<h2><span style=\"background-color: #FFFF00\">";
HTML +=motorStopped;
HTML +="</span></h2>\n";
}
HTML +="\t<div class=\"btn\">\n\t\t<a class=\"angleButton\" style=\"background-color:#";
HTML +="f59898";//set the color of buttons if active or not
HTML +="\t\" href=\"/stop";
HTML +="\">";
HTML +=stopPushButtonTitle;//tilte on button
HTML +="</a>\t\n\t</div>\n\n";
for (byte i = 0; i < (sizeof(angles) / sizeof(angles[0])); i++) {
HTML +="\t<div class=\"btn\">\n\t\t<a class=\"angleButton\" style=\"background-color:#";
if(i ==activeButton)
{
HTML +="f59898";//set the color of buttons if active or not
}else{
HTML +="90ee90";//set the color of buttons if active or not
}
HTML +="\t\" href=\"/go?";
HTML +="angle=";
HTML +=angles[i];
HTML +="\">";
HTML +=angles[i];//tilte on button
HTML +="° "; //degree symbol for HTML °
HTML +=directionTitle[directions[i]-1];
HTML +="</a>\t\n\t</div>\n\n"; //degree symbol for HTML °
}
//custom angle
HTML +="<form action=\"/go\" method=\"get\">\n";
HTML +="<label for=\"angle\">\n";
HTML += topTitle3;
HTML +="</label> \n";
HTML +="<input type=\"text\" id=\"angle\" name=\"angle\" value=\"\n";
HTML +=String(goToAngle);
HTML +="\" maxlength=\"4\" size=\"4\"> \n";
HTML +="<input type=\"radio\" id=\"cw\" \n";
if( dirStatus ==1){
HTML +="checked=\"checked\"";
}
HTML +=" name=\"d\" value=\"1\">\n";
HTML +="<label for=\"cw\">CW</label>\n";
HTML +="<input type=\"radio\" id=\"ccw\" \n";
if( dirStatus ==2){
HTML +="checked=\"checked\"";
}
HTML +=" name=\"d\" value=\"2\">\n";
HTML +="<label for=\"female\">CCW</label>\n";
HTML +="<label for=\"spd\">\n";
HTML +=topTitle5;
HTML +="</label> \n";
HTML +="<input type=\"text\" id=\"spd\" name=\"s\" value=\"1\" maxlength=\"2\" size=\"4\"><br>\n";
HTML +="<input type=\"submit\" value=\"\n";
HTML +=topTitle6;
HTML +="\">\n";
HTML +="</form> \n\n";
HTML +="\t\n</body>\n</html>\n";
server.send(200, "text/html", HTML);
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
}//handleRoot()
void handleNotFound() {
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
}//end of handleNotFound()
void setup(void) {
//Robojax.com 28BYJ-48 Stepper Motor Control
pinMode(Pin1, OUTPUT);//define pin for ULN2003 in1
pinMode(Pin2, OUTPUT);//define pin for ULN2003 in2
pinMode(Pin3, OUTPUT);//define pin for ULN2003 in3
pinMode(Pin4, OUTPUT);//define pin for ULN2003 in4
Serial.begin(115200);//initialize the serial monitor
Serial.println("Robojax 28BYJ-48 Stepper Motor Control");
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: http://");
Serial.println(WiFi.localIP());
//multicast DNS //Robojax.com 28BYJ-48 Steper Motor Control
if (MDNS.begin("robojaxESP32")) {
Serial.println("MDNS responder started");
Serial.println("access via http://robojaxESP32");
}
server.on("/", handleRoot);
server.on("/go", HTTP_GET, motorControl);
server.on("/stop",HTTP_GET, stopMotor);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}//end of setup
void loop(void) {
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
server.handleClient();
stepVale = (SPR * goToAngle)/360 ;
if(poleStep>7){
poleStep=0;
}
if(poleStep<0){
poleStep=7;
}
if(dirStatus ==CCW){
poleStep++;
count++;
if(count+correction_CCW <= stepVale)
{
driveStepper(poleStep);
}else{
driveStepper(8);
}
//full explannation at Arduino Course on Udemy.com see link above
}else if(dirStatus ==CW){
poleStep--;
count++;
if(count+correction_CW <=stepVale)
{
driveStepper(poleStep);
}else{
driveStepper(8);
}
}else{
driveStepper(8);
}
delay(speedValue);
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
}//end of loop
/*
* motorControl()
* updates the motor parameters upon receiving request from web interface
* returns nothing
* written by Ahmad Shamshiri
* on Wednesday Jun 13, 2020 in Ajax, Ontario, Canada
* www.robojax.com
*/
void motorControl() {
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2
//Watch details at my Arduino Course at Udemy.com
//see this https://www.arduino.cc/reference/en/language/variables/utilities/sizeof/
for (byte i = 0; i < (sizeof(angles) / sizeof(angles[0])); i++) {
if(server.arg("angle") == String(angles[i]) )
{
goToAngle =angles[i];
dirStatus =directions[i];
count =0;
activeButton =i;
speedValue=speedFactors[i];
}//if
}//for
//Watch details at my Arduino Course at Udemy.com
if(server.arg("d").toInt() >0 )
{
goToAngle =server.arg("angle").toInt();
dirStatus =server.arg("d").toInt();
count =0;
activeButton =customValueButtonID;
speedValue=server.arg("s").toInt();
}
handleRoot();
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2 code
}//motorControl end
/*
* @brief sends signal to the motor
* @param "c" is integer representing the pol of motor
* @return does not return anything
*
* www.Robojax.com code June 2019
*/
void driveStepper(int c)
{
//Watch details at my Arduino Course at Udemy.com
digitalWrite(Pin1, pole1[c]);
digitalWrite(Pin2, pole2[c]);
digitalWrite(Pin3, pole3[c]);
digitalWrite(Pin4, pole4[c]);
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2 code
}//driveStepper end here
/*
* @brief stops the motor immediately
* @param none
* @return does not return anything
* written by Ahmad Shamshiri
* www.Robojax.com code June 13, 2020 in Ajax, Ontario, Canada
*/
void stopMotor()
{
//Robojax.com ESP32 Stepper Push button Any Angle ESPSTP-2 code
//Watch details at my Arduino Course at Udemy.com
dirStatus=STOP;
handleRoot();
}//stopMotor()
Code Explained
Change The SSID And PASSWORD To Your Internet Details
const char *ssid = "SSIDHERE";
const char *password = "PASSOWORDHERE";
There Are Custom Angle Already Set But You Can Set Your Own By Changing The Code. You Can Add The Angle By Adding A Comma Then Space Then Your Angle
long angles[] = {360, 270, 90, 20, 287};//angles of each push button
Make Sure You Set Weather It Turns Clockwise Or Counter Clockwise By Adding CW Or CCW
int directions[] ={CW, CCW, CW, CCW, CW};//direction of eacch push button
You Can Set The Speed Of It By Adding A Number 1 Thorough 10, 1 Being The Fastest And 10 Being The Slowest
int speedFactors[] = {10, 1, 4, 10, 2, 1, 1};//speed for each push button
How to Start
After You Upload The Code Open Serial Monitor By Pressing CONTROL+SHIFT+M Or By Going To TOOLS Then Serial Monitor. Make Sure The Baud Is Set To 115200
Next
After You Open Serial Monitor Unplug Then Plug Back In Your ESP32 You Will See A Link Go To That Link And You Will See The Image Above
Help
If You Need Any Help Or Have Any Questions Post A Comment Below Or Join My Discord Server https://discord.gg/Cq7tSEfaC2