14. Interface and Application¶
Overview¶
This week, I made a interface for controling my servos for my final project using an httml web interface on the esp32c3.
Group Work¶
This week me and my partner Andrew compared to interfacing softwares. I chose to look at MIT app. It was a simple program for making interfaces but I could see myself implementing my web server into it for a more semless controler.
Learing about interfaces¶
I have already had previous experience using the esp32 web servers since I had used one for a porject in school a few months prior. Heres a link to that experiance. Because of that, I was able to make an interface quickly for controlling a servo. I used my output board to test out my interface. I wanted to try out processing origanlly to try and learn something new but when I tried to download it this popped up:
Block Digaram¶
The block diagram illustrates the workflow and communication between components in my servo control system using the ESP32-C3. The ESP32-C3 microcontroller serves as the central processing unit, hosting a lightweight HTTP web server that communicates over Wi-Fi.
Users interact with the servo motor through a web-based interface accessible via any browser connected to the same network. The interface sends HTTP GET requests containing angle commands or special actions (like the “wag tail” command) to the ESP32-C3 server. Upon receiving these requests, the ESP32 parses the command strings, extracts the desired servo angle, and adjusts the PWM signal to the servo motor accordingly.
The servo motor is connected directly to one of the ESP32 GPIO pins configured to output servo control pulses. This closed loop—from user input, through Wi-Fi and web server, to servo actuation—allows real-time, wireless control of the servo position. The block diagram visually represents this interaction flow between the web interface, Wi-Fi network, microcontroller, and servo actuator, highlighting the system’s modular and networked design.
Because of that I decided to make another web server on httml using the esp32c3 on my output board. Heres what the block diagram looked like:
Board and Interface¶
Heres what the interface looks like:
Code¶
#include <WiFi.h>
#include <ESP32Servo.h>
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
Servo myServo;
const int servoPin = 3; // Servo on GPIO 3
WiFiServer server(80);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi...");
}
Serial.print("Connected. IP: ");
Serial.println(WiFi.localIP());
myServo.setPeriodHertz(50); // Standard 50Hz servo
myServo.attach(servoPin, 500, 2400); // Calibrate for your servo
myServo.write(90); // Start centered
server.begin();
}
void wagTail() {
for (int i = 0; i < 2; i++) {
myServo.write(60); // Move to one side
delay(200);
myServo.write(120); // Move to the other side
delay(200);
}
myServo.write(90); // Return to center
}
void loop() {
WiFiClient client = server.available();
if (client) {
String req = client.readStringUntil('\r');
client.flush();
if (req.indexOf("angle=") != -1) {
int angleIndex = req.indexOf("angle=") + 6;
int angle = req.substring(angleIndex).toInt();
angle = constrain(angle, 0, 180);
myServo.write(angle); // Move servo to mapped angle
}
if (req.indexOf("/wag") != -1) {
wagTail();
}
String html = R"rawliteral(
<html><head>
<style>
body { text-align: center; font-family: sans-serif; }
#joystick {
width: 200px; height: 200px;
border: 2px solid #555;
border-radius: 50%;
margin: 30px auto;
position: relative;
touch-action: none;
}
#stick {
width: 50px; height: 50px;
background: #2196F3;
border-radius: 50%;
position: absolute;
top: 75px; left: 75px;
touch-action: none;
cursor: pointer;
}
button {
padding: 10px 20px;
font-size: 16px;
margin-top: 20px;
}
</style>
</head><body>
<h2>ESP32-C3 Servo Joystick</h2>
<div id="joystick"><div id="stick"></div></div>
<button onclick="fetch('/wag')">🐶 Wag Tail</button>
<script>
const joystick = document.getElementById("joystick");
const stick = document.getElementById("stick");
const radius = 100;
const center = { x: radius, y: radius };
let dragging = false;
function updateStick(clientX, clientY) {
const rect = joystick.getBoundingClientRect();
const dx = clientX - rect.left - center.x;
const dy = clientY - rect.top - center.y;
const dist = Math.min(Math.sqrt(dx * dx + dy * dy), radius - 25);
const angleRad = Math.atan2(dy, dx);
const angle360 = (angleRad * 180 / Math.PI + 360) % 360;
const mapped = Math.round(angle360 / 2); // 360° → 180°
fetch("/?angle=" + mapped);
const x = center.x + dist * Math.cos(angleRad) - 25;
const y = center.y + dist * Math.sin(angleRad) - 25;
stick.style.left = `${x}px`;
stick.style.top = `${y}px`;
}
function resetStick() {
stick.style.left = "75px";
stick.style.top = "75px";
fetch("/?angle=90");
}
// Mouse
stick.addEventListener("mousedown", e => { dragging = true; e.preventDefault(); });
document.addEventListener("mousemove", e => { if (dragging) updateStick(e.clientX, e.clientY); });
document.addEventListener("mouseup", () => { if (dragging) { dragging = false; resetStick(); } });
// Touch
stick.addEventListener("touchstart", e => { dragging = true; e.preventDefault(); });
document.addEventListener("touchmove", e => { if (dragging) updateStick(e.touches[0].clientX, e.touches[0].clientY); });
document.addEventListener("touchend", () => { if (dragging) { dragging = false; resetStick(); } });
</script>
</body></html>
)rawliteral";
client.print("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
client.print(html);
client.stop();
}
}
Video¶
Test with Simple Code¶
Final Code Test¶
Reflection¶
This week’s tasks were straightforward, and I successfully set up the initial interface without significant issues. Moving forward, I plan to develop a more robust and polished interface using the ESP RainMaker platform, which offers advanced cloud integration, device provisioning, and secure communication out of the box. Compared to traditional interfacing methods such as custom-built web dashboards or Bluetooth serial connections, ESP RainMaker provides a scalable and standardized approach to IoT device management, reducing development overhead and enhancing reliability. Prioritizing the completion of the core project functionality remains essential before migrating to this enhanced interface.