বর্তমান সময়ের IoT ডেভেলপমেন্টে Web-based Control এবং Real-Time Monitoring একটি অত্যন্ত গুরুত্বপূর্ণ বিষয়। অনেকেই মনে করেন, একটি Web Server তৈরি করতে হলে শক্তিশালী মাইক্রোকন্ট্রোলার বা জটিল IoT প্ল্যাটফর্ম প্রয়োজন। বাস্তবে কিন্তু খুব সাধারণ একটি মাইক্রোকন্ট্রোলার দিয়েও এই কাজটি করা সম্ভব—যদি সঠিকভাবে WiFi মডিউল ব্যবহার করা যায়।

এই টিউটোরিয়ালে আমরা দেখবো কীভাবে একটি Arduino Nano–কে একটি Web Server ভিত্তিক IoT সিস্টেমে রূপান্তর করা যায়, যেখানে আলাদা করে কোনো Cloud Platform বা Mobile App ব্যবহার করতে হবে না। এখানে DT-06 WiFi Module ব্যবহার করে Arduino Nano থেকে সরাসরি একটি Web Server তৈরি করা হবে, যার মাধ্যমে রিমোটলি Relay Control করা যাবে এবং একই সাথে Temperature ও Humidity Data রিয়েল-টাইমে মনিটর করা সম্ভব হবে।
প্রয়োজনীয় কম্পোনেন্ট
প্রথমেই প্রোজেক্টটি তৈরি করতে আমাদের কিছু কম্পোনেন্ট প্রয়োজন হবে। নিচের লিস্টে কম্পোনেন্টগুলো নাম, পরিমাণ এবং Purchase লিংক নিচে দেওয়া হলো।
DT-06 কাস্টম ফার্মওয়্যার
DT-06 WiFi মডিউলে যেহেতু On-board USB to UART কনভার্টার নেই, তাই সরাসরি USB কেবল দিয়ে ফার্মওয়্যার আপলোড করা সম্ভব নয়। এ কারণে নিচে দেওয়া সার্কিট ডায়াগ্রাম অনুযায়ী একটি CP2104 USB to UART Module ব্যবহার করে DT-06–এর সাথে সংযোগ স্থাপন করতে হবে। এই USB to UART মডিউলটি মূলত কম্পিউটার এবং DT-06–এর মধ্যে সিরিয়াল কমিউনিকেশনের ব্রিজ হিসেবে কাজ করবে, যার মাধ্যমে ফার্মওয়্যার আপলোড এবং ডিবাগিং করা যাবে।
সার্কিট ডায়াগ্রাম

অনেক সময় দেখা যায়, শুধু USB to UART মডিউল থেকে পাওয়া পাওয়ার DT-06–এর জন্য যথেষ্ট নাও হতে পারে, বিশেষ করে WiFi ইনিশিয়ালাইজেশনের সময়। এমন পরিস্থিতিতে যদি মডিউলটি সঠিকভাবে পাওয়ার আপ না হয় বা আপলোডের সময় সমস্যা দেখা দেয়, তাহলে Breadboard Power Supply Stick ব্যবহার করে External 3.3V পাওয়ার সাপ্লাই প্রদান করতে হবে।

DT-06 প্রোগ্রামিং Mode
DT-06 WiFi মডিউলে ফার্মওয়্যার আপলোড করার আগে একটি গুরুত্বপূর্ণ ধাপ হলো মডিউলটিকে প্রোগ্রামিং মোডে নেওয়া। প্রোগ্রামিং মোডে না থাকলে DT-06 কোনোভাবেই নতুন ফার্মওয়্যার গ্রহণ করবে না। তাই আপলোড প্রক্রিয়া শুরু করার আগে এই বিষয়টি নিশ্চিত করা অত্যন্ত জরুরি।

উপরে দেওয়া এনিমেশন ফাইলটি ধাপে ধাপে ফলো করলে সহজেই DT-06 মডিউলটিকে প্রোগ্রামিং Mode নেয়া যাবে।
DT-06 Code
নিচের কোডটি কপি করে Arduino IDE–এর কোড এডিটরে পেস্ট করতে হবে। কোডে নিজের WiFi Credentials (SSID এবং Password) সেট করুন। (Arduino IDE–তে কীভাবে ESP8266 Board Package ইন্সটল করতে হবে, সে বিষয়ে বিস্তারিত জানতে পূর্বের টিউটোরিয়ালটি এই লিংক থেকে দেখে নিতে পারেন।)
#include <ESP8266WiFi.h>
WiFiServer server(80);
float temp = 0.0, hum = 0.0;
const char* ssid = "YOUR_WIFI_SSID";
const char* pass = "YOUR_WIFI_PASSWORD";
void setup() {
Serial.begin(9600);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) delay(500);
IPAddress ip = WiFi.localIP();
Serial.print("IP=");
Serial.print(ip[0]);
Serial.print(".");
Serial.print(ip[1]);
Serial.print(".");
Serial.print(ip[2]);
Serial.print(".");
Serial.println(ip[3]);
server.begin();
}
void loop() {
// Read sensor data from Nano
if (Serial.available()) {
String line = Serial.readStringUntil('\n');
line.trim();
int tPos = line.indexOf("T=");
int hPos = line.indexOf(",H=");
if (tPos != -1 && hPos != -1) {
temp = line.substring(tPos + 2, hPos).toFloat();
hum = line.substring(hPos + 3).toFloat();
}
}
WiFiClient client = server.available();
if (!client) return;
String req = client.readStringUntil('\r');
client.flush();
// ---------- API ENDPOINT ----------
if (req.indexOf("GET /data") >= 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json; charset=utf-8");
client.println();
client.print("{\"temp\":");
client.print(temp, 1);
client.print(",\"hum\":");
client.print(hum, 1);
client.println("}");
return;
}
// ---------- RELAY CONTROL ----------
if (req.indexOf("/on") != -1) Serial.print('1');
if (req.indexOf("/off") != -1) Serial.print('0');
// ---------- MAIN PAGE ----------
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html; charset=utf-8");
client.println();
client.println(R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather Monitoring</title>
<style>
body {
margin: 0;
height: 100vh;
font-family: Arial, Helvetica, sans-serif;
background: linear-gradient(180deg, #8fd3f4, #84fab0);
display: flex;
align-items: center;
justify-content: center;
}
.card {
width: 340px;
padding: 26px;
border-radius: 28px;
background: linear-gradient(180deg, #d9f3ff, #bfe9ff);
box-shadow:
0 20px 40px rgba(0,0,0,0.25),
inset 0 1px 0 rgba(255,255,255,0.6);
text-align: center;
color: #05386b;
}
.title {
font-size: 20px;
font-weight: 700;
letter-spacing: 1px;
}
.subtitle {
font-size: 13px;
opacity: 0.8;
margin-bottom: 18px;
}
.temp {
font-size: 72px;
font-weight: 300;
line-height: 1;
margin-bottom: 6px;
}
.unit {
font-size: 26px;
}
.humidity {
font-size: 17px;
margin-bottom: 26px;
}
/* Fan Control Buttons */
.buttons {
display: flex;
justify-content: center;
gap: 20px;
}
.btn {
width: 96px;
height: 96px;
border-radius: 50%;
border: none;
font-size: 14px;
font-weight: bold;
color: white;
cursor: pointer;
box-shadow: 0 10px 18px rgba(0,0,0,0.25);
}
.btn-on {
background: linear-gradient(135deg, #00c6ff, #0072ff);
}
.btn-off {
background: linear-gradient(135deg, #9e9e9e, #616161);
}
.btn:active {
transform: scale(0.92);
box-shadow: 0 6px 10px rgba(0,0,0,0.2);
}
.footer {
margin-top: 18px;
font-size: 12px;
opacity: 0.7;
}
</style>
<script>
function loadData() {
fetch('/data')
.then(r => r.json())
.then(d => {
document.getElementById('temp').innerHTML = d.temp.toFixed(1);
document.getElementById('hum').innerHTML = d.hum.toFixed(1);
});
}
setInterval(loadData, 30000);
window.onload = loadData;
</script>
<script>
function fan(state){
fetch(state ? '/on' : '/off');
}
</script>
</head>
<body>
<div class="card">
<div class="title">WEATHER MONITORING</div>
<div class="subtitle">Smart Fan Control</div>
<div class="temp">
<span id="temp">--</span><span class="unit">℃</span>
</div>
<div class="humidity">
Humidity: <b><span id="hum">--</span>%</b>
</div>
<div class="buttons">
<button class="btn on" onclick="fan(1)">FAN ON</button>
<button class="btn off" onclick="fan(0)">FAN OFF</button>
</div>
<div class="footer">
Auto update every 30 seconds
</div>
</div>
</body>
</html>
)rawliteral");
}
এখন Board Type হিসেবে Generic ESP8285 Module সিলেক্ট করে এবং সঠিক COM Port নির্বাচন করুন।

আপলোড বাটন ক্লিক করে, কোডটি আপলোড করুন।

আরডুইনো সেট-আপ
এই পর্যায়ে Arduino Nano এর সাথে DT-06, Relay Module এবং DHT22 সেন্সর নিচের ডায়াগ্রাম অনুযায়ী সংযোগ দিয়ে নিই।

নিচের কোডটি কপি করে Arduino IDE তে পেস্ট করি। বোর্ড হিসেবে Arduino Nano এবং সঠিক COM Port সিলেক্ট করে, কোডটি আপলোড করে দেই।
#include <DHT.h>
#define DHTPIN 4
#define DHTTYPE DHT22
#define RELAY 13
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
delay(2000); // allow ESP boot
pinMode(RELAY, OUTPUT);
digitalWrite(RELAY, LOW);
dht.begin();
Serial.println("NANO_READY"); // handshake
}
void loop() {
// ---------- RECEIVE FROM ESP ----------
if (Serial.available()) {
String line = Serial.readStringUntil('\n');
line.trim();
if (line == "1") digitalWrite(RELAY, HIGH);
else if (line == "0") digitalWrite(RELAY, LOW);
else if (line.startsWith("IP=")) {
Serial.println();
Serial.print("ESP8266 IP ADDRESS = ");
Serial.println(line.substring(3));
Serial.println("--------------------------------");
}
}
// ---------- DHT READ EVERY 30s ----------
static unsigned long timer = 0;
if (millis() - timer >= 30000) {
timer = millis();
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(t) || isnan(h)) return;
Serial.print("T=");
Serial.print(t, 1);
Serial.print(",H=");
Serial.println(h, 1);
}
}
Output
এখন Arduino IDE থেকে Serial Monitor অন করুন এবং Arduino Nano–কে একবার Reset দিন। কিছুক্ষণের মধ্যেই Serial Monitor–এ “NANO Ready” মেসেজটি দেখা যাবে। এই পর্যায়ে DT-06 WiFi মডিউলটি Reset দিলে অল্প সময়ের মধ্যেই Serial Monitor–এ একটি IP Address প্রিন্ট হবে।

এই IP Address টি কপি করে ব্রাউজারের Address Bar–এ পেস্ট করে Enter চাপলেই একটি সুন্দর Web Interface ওপেন হবে। এখান থেকেই আপনি Arduino Nano–এর সাথে সংযুক্ত Relay-টি কন্ট্রোল করতে পারবেন, পাশাপাশি Temperature এবং Humidity ডেটাও রিয়েল-টাইমে দেখতে পাবেন।

