ESP32 দিয়ে যেকোনো Load Control – WiFi + Bluetooth + Relay + Servo Project (বাংলায়)
ESP32 দিয়ে যেকোনো Load Control – WiFi + Bluetooth + Relay + Servo Project (বাংলায়)
আজকের টিউটোরিয়ালে আমরা দেখব কিভাবে ESP32 মাইক্রোকন্ট্রোলার ব্যবহার করে যেকোনো ধরনের Load (AC, DC এবং Servo Motor) নিয়ন্ত্রণ করা যায়।
ESP32 হলো একটি শক্তিশালী মাইক্রোকন্ট্রোলার যেখানে রয়েছে WiFi ও Bluetooth মডিউল, যা একে Arduino এর চেয়ে অনেক বেশি কার্যকর করে তুলেছে।
এই প্রোজেক্টের মাধ্যমে আপনি শিখবেন –
কিভাবে WiFi ও Bluetooth ব্যবহার করে Load Control করতে হয়
কিভাবে Relay Module এর মাধ্যমে AC ও DC Load Control হয়
কিভাবে Servo Motor ESP32 দিয়ে কন্ট্রোল করা যায়
এবং সবশেষে সার্কিট ডায়াগ্রাম ও কোড।
ESP32 Development Board
4-Channel Relay Module
Servo Motor (SG90 / MG995)
AC Load (Light/Fan)
DC Load (LED/Small Motor)
Jumper Wires
Breadboard / PCB
Power Supply
Circuit Diagram
ESP32 এর GPIO পিনগুলোকে Relay Module এর Input পিনের সাথে সংযোগ দিন।
Servo Motor এর Signal পিনকে ESP32 এর একটি PWM Supported GPIO তে যুক্ত করুন।
Relay Module এর আউটপুট দিয়ে আলাদা Power Source থেকে AC ও DC Load Control করা হবে।
WiFi ও Bluetooth এর মাধ্যমে Smartphone / Web Server থেকে On/Off কমান্ড পাঠানো হবে।
Code / Program
/*******************************************************
* Project : ESP32 IoT Control (WiFi + WebSocket + Bluetooth + Servo)
* Author : Electritrend
* Channel : Electritrend
* Date : 22 September 2025
*
* Description:
* ---------------------------------
* - Control LED1 & LED2 via WiFi, WebSocket & Bluetooth
* - Control Servo Motor (0°–180°) from Web, App, or BT
* - Get Device Status remotely
* - Auto fallback to Access Point mode if WiFi fails
*
* Hardware:
* ---------------------------------
* - ESP32 Development Board
* - LED1 on GPIO 25
* - LED2 on GPIO 26
* - Servo Motor on GPIO 27
*
* Copyright © 2025 Electritrend
* All rights reserved.
*
* ⚡ For tutorials, visit:
* 👉 YouTube: https://www.youtube.com/@ElectriTrendbd
* 👉 Website: https://sites.google.com/view/electritrend/home
*******************************************************/
#include <WiFi.h> // WiFi এর লাইব্রেরি
#include <WebServer.h> // HTTP ওয়েবসার্ভার লাইব্রেরি
#include <WebSocketsServer.h> // WebSocket সার্ভার লাইব্রেরি
#include "BluetoothSerial.h" // Bluetooth Serial লাইব্রেরি
#include <ESP32Servo.h> // Servo মোটর কন্ট্রোল লাইব্রেরি
// ===== WiFi Config =====
const char* ssid = "not_allow"; // আপনার WiFi নাম
const char* password = "#araf#arafin#alif"; // আপনার WiFi পাসওয়ার্ড
const char* ap_ssid = "ESP32_AP_Mode"; // WiFi AP Mode SSID (Backup)
const char* ap_password = "esp32pass"; // WiFi AP Mode Password (কমপক্ষে ৮ ক্যারেক্টার হতে হবে)
// ===== Hardware Pins =====
const int LED1 = 25; // LED1 পিন
const int LED2 = 26; // LED2 পিন
const int SERVO_PIN = 27; // Servo মোটরের পিন
// ===== Web Server =====
WebServer server(80); // HTTP সার্ভার (Port 80)
WebSocketsServer webSocket(81); // WebSocket সার্ভার (Port 81)
// ===== Bluetooth =====
BluetoothSerial SerialBT; // Bluetooth Serial অবজেক্ট
// ===== Servo =====
Servo myServo;
int servoPos = 0; // বর্তমান Servo এর এঙ্গেল (শুরুতে 0)
// ===== HTML Page Function =====
String htmlPage() {
// এখানে ওয়েবপেজের HTML কোড রাখা আছে
// (Bootstrap + CSS + JavaScript + WebSocket code)
// সার্ভার যখন ওয়েবপেজ সার্ভ করে তখন এই String পাঠানো হয়
String html = R"rawliteral(
<!DOCTYPE html>
<html lang="bn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>esp32 led + servo control</title>
<!-- Bootstrap CSS (Ready-made UI framework) -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Google Fonts (Custom font) -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<!-- Custom CSS -->
<style>
body {
font-family: 'Poppins', sans-serif; /* সুন্দর ফন্ট */
background: linear-gradient(135deg,#0f2027,#203a43,#2c5364); /* ব্যাকগ্রাউন্ড গ্রেডিয়েন্ট */
color: #fff;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container-card {
background: rgba(255,255,255,0.05); /* আধা ট্রান্সপারেন্ট ব্যাকগ্রাউন্ড */
border-radius: 18px;
padding: 26px;
width: 100%;
max-width: 820px;
box-shadow: 0 8px 24px rgba(0,0,0,0.45); /* শ্যাডো */
}
h2 {font-weight: 600; margin-bottom: 18px;}
.btn-coustom { /* সব বাটনের জন্য ডিজাইন */
width: 150px;
margin: 8px;
border-radius: 999px;
font-size: 16px;
}
.btn-coustom:hover {
transform: scale(1.04); /* হোভার করলে হালকা বড় হবে */
transition: transform .15s;
}
.status-box { /* স্ট্যাটাস বক্স */
display: flex;
gap: 18px;
justify-content: center;
align-items: center;
margin-top: 18px;
flex-wrap: wrap;
}
.status-itam { /* প্রতিটি স্ট্যাটাস কার্ড */
background: rgba(255,255,255,0.03);
padding: 14px 18px;
border-radius: 12px;
min-width: 160px;
display: flex;
gap: 12px;
align-items: center;
justify-content: center;
box-shadow: 0 6px 16px rgba(0,0,0,0.35);
}
.led-dot { /* LED স্ট্যাটাস ডট */
width: 18px;
height: 18px;
border-radius: 50%;
background: #444;
}
.led-dot.on {
background: #4caf50; /* সবুজ হলে অন */
box-shadow: 0 0 12px rgba(76,175,80,0.6);
}
.led-dot.off {
background: #6c6c6c; /* ধূসর হলে অফ */
}
.status-label { font-size: 14px; color: #e8f0f2; font-weight: 600;}
.small-muted {font-size: 12px; color: #bfcbd0; margin-top: 6px; text-align: center;}
.conn { /* সংযোগের স্ট্যাটাস */
display: inline-block;
margin-left: 8px;
padding: 6px 10px;
border-radius: 999px;
background: rgba(255,255,255,0.03);
font-size: 13px;
}
.conn.online {color: #bfffc4; border: 1px solid rgba(191,255,196,0.12);}
.conn.offline {color:#ffd6d6; border:1px solid rgba(255,214,214,0.08);}
</style>
</head>
<body>
<!-- প্রধান কার্ড -->
<div class="container-card">
<!-- টাইটেল + কানেকশন স্ট্যাটাস -->
<div class="d-flex justify-content-between align-items-center">
<h2>ESP32 Smart Dual Control LED + SERVO</h2>
<div id="connection" class="conn offline"> Disconnected</div>
</div>
<!-- LED কন্ট্রোল বাটন -->
<div class="d-flex justify-content-center my-3 flex-wrap">
<button class="btn btn-success btn-coustom" onclick="sendCmd('LED1_ON')"> LED 1 ON</button>
<button class="btn btn-danger btn-coustom" onclick="sendCmd('LED1_OFF')"> LED 1 OFF</button>
<button class="btn btn-success btn-coustom" onclick="sendCmd('LED2_ON')"> LED 2 ON</button>
<button class="btn btn-danger btn-coustom" onclick="sendCmd('LED2_OFF')"> LED 2 OFF</button>
</div>
<!-- Servo কন্ট্রোল বাটন -->
<div class="d-flex justify-content-center my-3 flex-wrap">
<button class="btn btn-info btn-coustom" onclick="sendCmd('SERVO:0')"> Servo 0°</button>
<button class="btn btn-info btn-coustom" onclick="sendCmd('SERVO:45')"> Servo 45°</button>
<button class="btn btn-info btn-coustom" onclick="sendCmd('SERVO:90')"> Servo 90°</button>
<button class="btn btn-info btn-coustom" onclick="sendCmd('SERVO:135')"> Servo 135°</button>
<button class="btn btn-info btn-coustom" onclick="sendCmd('SERVO:180')"> Servo 180°</button>
</div>
<!-- স্ট্যাটাস দেখানোর বক্স -->
<div class="status-box">
<!-- LED 1 স্ট্যাটাস -->
<div class="status-itam">
<div id="led1Dot" class="led-dot off"></div>
<div>
<div class="status-label"> LED 1</div>
<div id="led1Text" class="small-muted">Unknown</div>
</div>
</div>
<!-- LED 2 স্ট্যাটাস -->
<div class="status-itam">
<div id="led2Dot" class="led-dot off"></div>
<div>
<div class="status-label"> LED 2</div>
<div id="led2Text" class="small-muted">Unknown</div>
</div>
</div>
<!-- Servo স্ট্যাটাস -->
<div class="status-itam">
<div class="led-dot on"></div>
<div>
<div class="status-label"> SERVO</div>
<div id="servoText" class="small-muted">0°</div>
</div>
</div>
</div>
</div>
<!-- JavaScript অংশ -->
<script>
// WebSocket সার্ভার তৈরি (ESP32 এর 81 port)
var ws = new WebSocket('ws://' + location.hostname + ':81/');
// Connection status দেখানোর ফাংশন (Connected / Disconnected)
function setConnectionState(connected) {
var el = document.getElementById('connection');
if (connected) {
el.classList.remove('offline');
el.classList.add('online');
el.textContent = 'Connected';
} else {
el.classList.remove('online');
el.classList.add('offline');
el.textContent = 'Disconnected';
}
}
// যখন WebSocket কানেক্ট হয়
ws.onopen = function() {
setConnectionState(true); // UI তে Connected দেখাবে
try { ws.send('GET_STATUS'); } // ESP32 থেকে LED/Servo এর বর্তমান অবস্থা চাইবে
catch(e){}
};
// যখন কানেকশন বন্ধ হয়
ws.onclose = function() { setConnectionState(false); };
// যখন কোনো এরর হয়
ws.onerror = function() { setConnectionState(false); };
// ESP32 থেকে মেসেজ আসলে কী হবে
ws.onmessage = function(event) {
var msg = event.data.trim(); // রিসিভড ডেটা
console.log('Recv:', msg);
var parts = msg.split(/\s*[:\s]\s*/); // ডেটাকে key:value আকারে ভাগ করা
if (parts.length === 2) {
var key = parts[0].toUpperCase(); // যেমন LED1, LED2, SERVO
var val = parts[1].toUpperCase(); // যেমন ON, OFF, বা Servo angle
if (key === 'LED1' || key === 'LED2') updateStatus(key, val); // LED এর অবস্থা আপডেট
else if (key === 'SERVO') updateServo(val); // Servo angle আপডেট
}
};
// ESP32 এ কমান্ড পাঠানোর ফাংশন
function sendCmd(cmd) { ws.send(cmd); }
// LED এর অবস্থা আপডেট করার ফাংশন (UI তে dot + text)
function updateStatus(led, state) {
var dot = document.getElementById(led.toLowerCase() + 'Dot');
var txt = document.getElementById(led.toLowerCase() + 'Text');
if (state === 'ON') {
dot.classList.remove('off');
dot.classList.add('on');
txt.textContent = 'ON';
} else {
dot.classList.remove('on');
dot.classList.add('off');
txt.textContent = 'OFF';
}
}
// Servo এর এঙ্গেল UI তে দেখানোর ফাংশন
function updateServo(angle) {
document.getElementById('servoText').textContent = angle + "°";
}
</script>
</body>
</html>
)rawliteral";
return html;
}
// ===== Command Handler =====
void handleCommand(String cmd) {
// LED1 ON
if (cmd == "LED1_ON") {
digitalWrite(LED1, LOW); // LED1 অন করা
webSocket.broadcastTXT("LED1:ON"); // ওয়েবসকেটে মেসেজ পাঠানো
SerialBT.println("LED1:ON"); // Bluetooth এ মেসেজ পাঠানো
}
// LED1 OFF
else if (cmd == "LED1_OFF") {
digitalWrite(LED1, HIGH);
webSocket.broadcastTXT("LED1:OFF");
SerialBT.println("LED1:OFF");
}
// LED2 ON
else if (cmd == "LED2_ON") {
digitalWrite(LED2, LOW);
webSocket.broadcastTXT("LED2:ON");
SerialBT.println("LED2:ON");
}
// LED2 OFF
else if (cmd == "LED2_OFF") {
digitalWrite(LED2, HIGH);
webSocket.broadcastTXT("LED2:OFF");
SerialBT.println("LED2:OFF");
}
// Servo Command (যেমন "SERVO:90")
else if (cmd.startsWith("SERVO:")) {
int angle = cmd.substring(6).toInt(); // 6th character থেকে এঙ্গেল বের করা
if (angle >= 0 && angle <= 180) { // এঙ্গেল valid কিনা চেক করা
servoPos = angle;
myServo.write(servoPos); // Servo এ মুভ করা
webSocket.broadcastTXT("SERVO:" + String(servoPos)); // ওয়েবসকেটে পাঠানো
SerialBT.println("SERVO:" + String(servoPos)); // Bluetooth এ পাঠানো
}
}
// ডিভাইসের বর্তমান স্ট্যাটাস জানতে
else if (cmd == "GET_STATUS") {
String s1 = (digitalRead(LED1) == LOW) ? "LED1:ON" : "LED1:OFF";
String s2 = (digitalRead(LED2) == LOW) ? "LED2:ON" : "LED2:OFF";
webSocket.broadcastTXT(s1);
webSocket.broadcastTXT(s2);
webSocket.broadcastTXT("SERVO:" + String(servoPos)); // চাইলে Servo স্ট্যাটাসও পাঠাতে পারেন
SerialBT.println(s1);
SerialBT.println(s2);
}
}
// ===== WebSocket Event =====
void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
if (type == WStype_TEXT) { // যদি টেক্সট মেসেজ আসে
String cmd = String((char*)payload).substring(0, length);
cmd.trim(); // Extra স্পেস মুছে ফেলা
handleCommand(cmd); // Command হ্যান্ডল করা
}
}
// ===== Root Page Handler =====
void handleRoot() {
server.send(200, "text/html", htmlPage()); // ওয়েবপেজ সার্ভ করা
}
// ===== Setup =====
void setup() {
Serial.begin(115200);
// LED পিনগুলো আউটপুট মোডে সেট করা
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
digitalWrite(LED1, HIGH); // শুরুতে LED OFF (HIGH মানে OFF কারণ Active LOW)
digitalWrite(LED2, HIGH);
// Servo সেটআপ
myServo.attach(SERVO_PIN);
myServo.write(0);
servoPos = 0;
// WiFi Connect করার চেষ্টা
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED && millis() - start < 8000) {
delay(500); Serial.print(".");
}
// যদি WiFi কানেক্ট হয়
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi!");
Serial.print("ESP32 IP: "); Serial.println(WiFi.localIP());
}
// যদি WiFi Fail করে তবে Access Point চালু হবে
else {
Serial.println("\nWiFi Failed. Starting AP mode...");
WiFi.mode(WIFI_AP);
WiFi.softAP(ap_ssid, ap_password);
Serial.print("AP IP: "); Serial.println(WiFi.softAPIP());
}
// HTTP সার্ভার শুরু
server.on("/", handleRoot);
server.begin();
// WebSocket সার্ভার শুরু
webSocket.begin();
webSocket.onEvent(onWebSocketEvent);
// Bluetooth শুরু
if (!SerialBT.begin("ESP32_BT")) Serial.println("Bluetooth init failed!");
else Serial.println("Bluetooth started as ESP32_BT");
}
// ===== Loop =====
void loop() {
server.handleClient(); // HTTP রিকোয়েস্ট হ্যান্ডল করা
webSocket.loop(); // WebSocket আপডেট করা
// যদি Bluetooth থেকে কোন Command আসে
if (SerialBT.available()) {
String cmd = SerialBT.readStringUntil('\n');
cmd.trim();
if (cmd.length() > 0) handleCommand(cmd);
}
}
প্রোগ্রাম ফাইল ও সার্কিট ডায়াগ্রাম ডাউনলোড করুন এখান থেকে:
👇👇👇