Week 14 — Code Files
Project 1 — Gesture Monitor
Arduino Code (ESP32-C3)
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const char* ssid = "DGI";
const char* password = "dgi@2024!";
WiFiServer server(8080);
WiFiClient client;
const int FLEX_PIN = A0;
const int BTN_PIN = D1;
void setup() {
Serial.begin(115200);
pinMode(BTN_PIN, INPUT_PULLUP);
Wire.begin(D4, D5);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED not found!");
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Connecting WiFi...");
display.display();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Connected!");
Serial.println(WiFi.localIP());
display.clearDisplay();
display.setCursor(0, 0);
display.println("WiFi Connected!");
display.println(WiFi.localIP());
display.display();
delay(2000);
server.begin();
Serial.println("Server started!");
}
void loop() {
// Accept new client
if (!client || !client.connected()) {
client = server.available();
if (client) Serial.println("Client connected!");
}
int flexValue = analogRead(FLEX_PIN);
int btnState = digitalRead(BTN_PIN);
String gesture = "BENDING";
if (flexValue > 2000) gesture = "OPEN";
else if (flexValue < 1500) gesture = "CLOSED";
// OLED
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Flex Value:");
display.setTextSize(2);
display.setCursor(0, 12);
display.println(flexValue);
display.setTextSize(1);
display.setCursor(0, 35);
display.println("Gesture:");
display.setTextSize(2);
display.setCursor(0, 45);
display.println(gesture);
display.display();
// Send data directly over TCP
if (client && client.connected()) {
client.println(gesture + "," + String(flexValue) + "," + String(btnState));
}
delay(100);
}
Python Tkinter App
import tkinter as tk
import socket
import threading
ESP32_IP = "172.16.20.205"
PORT = 8080
class GestureApp:
def __init__(self, root):
self.root = root
root.title("Vision Voice - Gesture Monitor")
root.geometry("400x300")
root.configure(bg="#1e1e2e")
tk.Label(root, text="Vision Voice", font=("Arial", 20, "bold"),
bg="#1e1e2e", fg="#cba6f7").pack(pady=10)
self.gesture_label = tk.Label(root, text="Gesture: --",
font=("Arial", 16), bg="#1e1e2e", fg="#a6e3a1")
self.gesture_label.pack(pady=5)
self.flex_label = tk.Label(root, text="Flex Value: --",
font=("Arial", 14), bg="#1e1e2e", fg="#89dceb")
self.flex_label.pack(pady=5)
self.btn_label = tk.Label(root, text="Button: --",
font=("Arial", 14), bg="#1e1e2e", fg="#f38ba8")
self.btn_label.pack(pady=5)
self.status_label = tk.Label(root, text="Connecting...",
font=("Arial", 10), bg="#1e1e2e", fg="#6c7086")
self.status_label.pack(pady=10)
self.running = True
threading.Thread(target=self.read_stream, daemon=True).start()
def read_stream(self):
while self.running:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((ESP32_IP, PORT))
self.root.after(0, lambda: self.status_label.config(
text="Connected ✓", fg="#a6e3a1"))
buffer = ""
while self.running:
data = sock.recv(128).decode("utf-8", errors="ignore")
if not data:
break
buffer += data
while "\n" in buffer:
line, buffer = buffer.split("\n", 1)
line = line.strip()
parts = line.split(",")
if len(parts) == 3:
gesture, flex, btn = parts
btn_text = "PRESSED" if btn.strip() == "0" else "OPEN"
self.root.after(0, self.update_ui, gesture, flex, btn_text)
sock.close()
except Exception as e:
self.root.after(0, lambda: self.status_label.config(
text="Reconnecting...", fg="#f9e2af"))
import time; time.sleep(2)
def update_ui(self, gesture, flex, btn_text):
self.gesture_label.config(text=f"Gesture: {gesture}")
self.flex_label.config(text=f"Flex Value: {flex}")
self.btn_label.config(text=f"Button: {btn_text}")
self.status_label.config(text="Connected ✓", fg="#a6e3a1")
root = tk.Tk()
app = GestureApp(root)
root.mainloop()
Project 2 — Servo Controller
Arduino Code (ESP32-C3)
#include <WiFi.h>
#include <ESP32Servo.h>
const char* ssid = "DGI";
const char* password = "dgi@2024!";
WiFiServer server(8888);
WiFiClient client;
Servo myServo;
const int SERVO_PIN = D0;
void setup() {
Serial.begin(115200);
myServo.attach(SERVO_PIN);
myServo.write(90);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Connected!");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
if (!client || !client.connected()) {
client = server.available();
if (client) Serial.println("Client connected!");
}
if (client && client.connected() && client.available()) {
String line = client.readStringUntil('\n');
line.trim();
int degree = line.toInt();
if (degree >= 0 && degree <= 180) {
myServo.write(degree);
Serial.println("Moving to: " + String(degree));
}
}
}
Python Tkinter App
import tkinter as tk
import socket
import threading
ESP32_IP = "172.16.20.205"
PORT = 8888
class ServoApp:
def __init__(self, root):
self.root = root
root.title("Servo Controller")
root.geometry("400x350")
root.configure(bg="#1e1e2e")
self.sock = None
self.connected = False
tk.Label(root, text="Servo Controller", font=("Arial", 20, "bold"),
bg="#1e1e2e", fg="#cba6f7").pack(pady=15)
tk.Label(root, text="Enter Degree (0 - 180):",
font=("Arial", 12), bg="#1e1e2e", fg="#cdd6f4").pack()
self.degree_entry = tk.Entry(root, font=("Arial", 16), width=8,
justify="center", bg="#313244", fg="#cdd6f4",
insertbackground="white")
self.degree_entry.pack(pady=10)
self.degree_entry.bind("<Return>", lambda e: self.send_degree())
self.slider = tk.Scale(root, from_=0, to=180, orient="horizontal",
length=300, bg="#1e1e2e", fg="#cdd6f4",
highlightbackground="#1e1e2e", troughcolor="#313244",
activebackground="#cba6f7",
command=self.slider_moved)
self.slider.set(90)
self.slider.pack(pady=5)
tk.Button(root, text="Move Servo", font=("Arial", 13, "bold"),
bg="#cba6f7", fg="#1e1e2e", padx=20, pady=8,
command=self.send_degree).pack(pady=10)
self.status_label = tk.Label(root, text="Connecting...",
font=("Arial", 10), bg="#1e1e2e", fg="#6c7086")
self.status_label.pack()
threading.Thread(target=self.connect, daemon=True).start()
def connect(self):
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(5)
self.sock.connect((ESP32_IP, PORT))
self.connected = True
self.root.after(0, lambda: self.status_label.config(
text="Connected ✓", fg="#a6e3a1"))
except Exception as e:
self.root.after(0, lambda: self.status_label.config(
text=f"Error: {e}", fg="#f38ba8"))
def send_degree(self):
try:
degree = int(self.degree_entry.get())
if 0 <= degree <= 180:
self._send(degree)
else:
self.status_label.config(text="Enter 0 to 180!", fg="#f38ba8")
except ValueError:
self.status_label.config(text="Numbers only!!", fg="#f38ba8")
def slider_moved(self, val):
if self.connected:
self._send(int(val))
def _send(self, degree):
try:
self.sock.sendall(f"{degree}\n".encode())
self.status_label.config(text=f"Moved to {degree}° ✓", fg="#a6e3a1")
self.slider.set(degree)
self.degree_entry.delete(0, tk.END)
self.degree_entry.insert(0, str(degree))
except Exception as e:
self.connected = False
self.status_label.config(text="Disconnected! Restart app.", fg="#f38ba8")
root = tk.Tk()
app = ServoApp(root)
root.mainloop()