This project helps students measure the speed of a DC motor using a basic optical encoder or a Hall effect sensor with a magnet. Students will collect data on motor revolutions and calculate the speed in RPM using the ESP32 and MicroPython. This lays the foundation for closed-loop control and robotic feedback systems.
ESP32 GPIO26 —> IN1 (L298N)
ESP32 GPIO25 —> IN2 (L298N)
ESP32 GPIO14 —> ENA (PWM)
Sensor OUT —> GPIO34 (Input)
5V/3.3V —> Sensor VCC
GND —> Shared Ground
from machine import Pin, PWM, Timer
import socket
from time import ticks_ms, ticks_diff
import network
# Setup Wi-Fi
ssid = 'YOUR_SSID'
password = 'YOUR_PASSWORD'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while not wlan.isconnected():
pass
ip = wlan.ifconfig()[0]
print('Web interface at:', ip)
# Motor control
in1 = Pin(26, Pin.OUT)
in2 = Pin(25, Pin.OUT)
pwm = PWM(Pin(14), freq=1000)
pwm.duty(800)
# Sensor input
pulse_pin = Pin(34, Pin.IN)
pulse_count = 0
last_time = ticks_ms()
rpm_value = 0
# Interrupt handler
def count_pulse(pin):
global pulse_count
pulse_count += 1
pulse_pin.irq(trigger=Pin.IRQ_RISING, handler=count_pulse)
# Timer callback to calculate RPM
rpm_timer = Timer(0)
def calc_rpm(timer):
global pulse_count, last_time, rpm_value
now = ticks_ms()
dt = ticks_diff(now, last_time) / 1000
rpm_value = (pulse_count / dt) * 60
pulse_count = 0
last_time = now
rpm_timer.init(period=1000, mode=Timer.PERIODIC, callback=calc_rpm)
# Start motor
in1.on()
in2.off()
# HTML + Chart.js page
html = """<!DOCTYPE html>
<html>
<head>
<title>Motor RPM Dashboard</title>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
<style>
body { font-family: Arial; background: #111; color: white; text-align: center; }
canvas { background: #222; border-radius: 10px; margin-top: 30px; }
</style>
</head>
<body>
<h1>Real-Time Motor RPM</h1>
<canvas id='rpmChart' width='400' height='200'></canvas>
<script>
const ctx = document.getElementById('rpmChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{ label: 'RPM', data: [], borderColor: 'lime', fill: false }]
},
options: {
animation: false,
responsive: true,
scales: { y: { min: 0, title: { display: true, text: 'RPM' } }, x: { title: { display: true, text: 'Time' } } }
}
});
async function updateChart() {
const res = await fetch('/rpm');
const data = await res.json();
const t = new Date().toLocaleTimeString();
if(chart.data.labels.length > 20) { chart.data.labels.shift(); chart.data.datasets[0].data.shift(); }
chart.data.labels.push(t);
chart.data.datasets[0].data.push(data.rpm);
chart.update();
}
setInterval(updateChart, 1000);
</script>
</body>
</html>"""
# Web server
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
while True:
cl, addr = s.accept()
request = cl.recv(1024).decode()
if 'GET /rpm' in request:
cl.send('HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n')
cl.send('{{"rpm": {}}}'.format(round(rpm_value, 2)))
else:
cl.send('HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n')
cl.send(html)
cl.close()
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.
You can explore a wide range of microcontroller and electronics projects, including Arduino, ESP32, IoT, and more. Each project comes with downloadable code, detailed guides, and the necessary hardware list.