-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2dPrinterESP.ino
223 lines (199 loc) · 6.86 KB
/
2dPrinterESP.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* Some code and suggested libraries were taken from:
* https://randomnerdtutorials.com/esp32-async-web-server-espasyncwebserver-library/
* The only bits that were used from the above link are the suggested libraries, the <head> section of the html code
* and the basic GET request sending logic. The rest of the code is of my doing and is purpose-built for this project :)
*/
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
// ENA is the enable pin to control DC motor speed (x-axis), set to GPIO 16
// STEPDELAY is in milliseconds to delay stepper and DC motor
#define ENA 15
#define STEPDELAY 100
// pin definitions and other variables
// bools are used to call stepX/stepY functions in loop() so they can run continuously and at the same time
volatile bool xMotorDir { 0 };
volatile bool yMotorDir { 0 };
volatile bool xMotorStop { true };
volatile bool yMotorStop { true };
const int IN1_DC { 18 }; // IN1 pin to control OUT1 for DC motor (x-axis)
const int IN2_DC { 19 }; // IN2 pin to control OUT2 for DC motor (x-axis)
// STEP and DIRECTION pins for stepper driver for Nema 17/SM24240 motor
const int DIR { 13 };
const int STEP { 12 };
// ssid and password for local network to host web server on, also parameters to send with GET requests to ESP
const char* ssid { "nubblocal" };
const char* password { "fgzd4823" };
const char* param_1 { "motor" }; // 0 = x-axis/DC, 1 = y-axis/Stepper
const char* param_2 { "dir" }; // same rules as stepX/Y functions, 1 on dc/step = right/down, 0 on dc/step = left/up, 2 = stop motor
AsyncWebServer server(80); // start web server on port 80 for request/response to clients and web servers
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>2DPrinter Local ESP32 Web Server</title>
<meta name="viewport" content="width=device-width, inital-scale=1">
<link rel="icon" href="data:,">
<style>
h1 {font-family: Courier New}
button {font-family: Courier New}
p {font-family: Courier New}
</style>
</head>
<body>
<h1>2DPrinter async web server!!!</h1>
<!-- direction buttons below!-->
<button type="button" onclick="sendRequest(1,0)">Move Up</button>
<button type="button" onclick="sendRequest(1,1)">Move Down</button>
<button type="button" onclick="sendRequest(0,1)">Move Right</button>
<button type="button" onclick="sendRequest(0,0)">Move Left</button>
<button type="button" onclick="sendRequest(0,2)">Turn Off DC</button>
<button type="button" onclick="sendRequest(1,2)">Turn Off Stepper</button>
<p>Peak website design right here</p>
<!-- Below function opens new GET request then sends request with motor and dir after button presses above -->
<!-- Need to test for function scope, whether or not we need to move it around -->
<script>
function sendRequest(motor, dir)
{
var xhr = new XMLHttpRequest();
xhr.open("GET", "/update?motor="+motor+"&dir="+dir, true);
xhr.send();
}
</script>
</body>
</html>
)rawliteral";
void serverNotFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "Page Not Found");
}
// controls DC motor of gantry belt (x-axis) in small steps to mimic stepper motor (micro/millisecond delay)
void stepX(bool direction)
{
if (!(direction)) // drive left
{
digitalWrite(IN1_DC, LOW);
digitalWrite(IN2_DC, HIGH);
delay(STEPDELAY);
}
else if (direction) // drive right
{
digitalWrite(IN1_DC, HIGH);
digitalWrite(IN2_DC, LOW);
delay(STEPDELAY);
}
}
// controls stepper motor of screw/nut + metal rod mechanism
void stepY(bool direction)
{
if (!(direction)) // drive clockwise/up
{
digitalWrite(DIR, LOW);
digitalWrite(STEP, HIGH);
delay(STEPDELAY);
digitalWrite(STEP, LOW);
delay(STEPDELAY);
}
else if (direction) // drive counterclockwise/down
{
digitalWrite(DIR, HIGH);
digitalWrite(STEP, HIGH);
delay(STEPDELAY);
digitalWrite(STEP, LOW);
delay(STEPDELAY);
}
}
void setup()
{
pinMode(IN1_DC, OUTPUT);
pinMode(IN2_DC, OUTPUT);
pinMode(STEP, OUTPUT);
pinMode(DIR, OUTPUT);
Serial.begin(9600);
// set speed for DC motor
analogWrite(ENA, 160);
// start wifi connection of esp32 to local network,
WiFi.begin(ssid, password);
Serial.print("Connecting to local network...");
while (WiFi.status() != WL_CONNECTED) // not connected to wifi yet
{
Serial.print(",");
delay(500);
}
Serial.println();
Serial.print("Connected successfully at IP: ");
Serial.println(WiFi.localIP());
// send first request to server and turn it on, server set at root directory, GET requests used handled by AsyncServer. functio
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send(200, "text/html", index_html); // sends html code above as web servers' webpage
});
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request)
{
// construct two instances of String class for both params on GET request received by esp32
String motorParam;
String dirParam;
if (request->hasParam(param_1) && request->hasParam(param_2))
{
// get parameters sent from GET request
motorParam = request->getParam(param_1)->value();
dirParam = request->getParam(param_2)->value();
// determine the motor to control and move it accordingly
if (motorParam.toInt() == 0)
{
if (dirParam.toInt() == 2)
{
// shut off DC motor
xMotorStop = true;
Serial.println("DC Motor Off!");
}
else
{
// compare val of motorParam to drive either left or right if 1 or 0
// 1 = right, 0 = left
xMotorStop = false;
dirParam.toInt() ? xMotorDir = true : xMotorDir = false;
Serial.println("Moving DC Motor!");
}
}
if (motorParam.toInt() == 1)
{
if (dirParam.toInt() == 2)
{
yMotorStop = true;
Serial.println("Stepper Motor Off!");
}
else
{
// 1 = cc/down, 0 = clockwise/up
yMotorStop = false;
dirParam.toInt() ? yMotorDir = true : yMotorDir = false;
Serial.println("Moving Stepper Motor!");
}
}
}
request->send(200, "text/plain", "OK"); // send response after successful request
});
server.onNotFound(serverNotFound);
server.begin(); // starts serving web page index_html on web server
}
void loop() // drive motors continuously depending on request info from web server
{
if (xMotorStop) // 1 = right, 0 = left
{
digitalWrite(IN1_DC, LOW);
digitalWrite(IN2_DC, LOW);
}
else if (!(xMotorStop))
{
stepX(xMotorDir);
}
if (yMotorStop) // 1 = cc/down, 0 = clockwise/up
{
; // null statement
}
else if (!(yMotorStop))
{
stepY(yMotorDir);
}
}