๐ฌ Membuat Chat WhatsApp-like dengan 2 ESP8266
Tutorial Lengkap: Chat Offline via WiFi Menggunakan NodeMCU ESP8266 + Arduino CLI
๐ฏ Hasil Akhir: Dua smartphone terhubung ke ESP8266 berbeda, bisa chatting real-time seperti WhatsApp tanpa koneksi internet!
๐ Daftar Isi
๐ 1. Alat dan Bahan
| No | Komponen | Jumlah | Fungsi |
|---|---|---|---|
| 1 | NodeMCU ESP8266 | 2 buah | ESP A (Server) & ESP B (Client) |
| 2 | Kabel USB Micro | 2 buah | Upload kode dan power |
| 3 | Powerbank/Charger HP | 2 buah | Sumber daya setelah upload |
| 4 | Smartphone | 2 buah | Untuk chatting via browser |
| 5 | WiFi Router/AP | 1 buah | Jaringan lokal (SSID: shereen) |
⚠️ Catatan Penting: Tidak membutuhkan komponen tambahan apapun! Hanya colok USB, upload kode, dan langsung bisa dipakai.
๐ง 2. Konsep Kerja Sistem
┌─────────────────┐ WiFi ┌─────────────────┐
│ ESP A │◄─────────────────────────►│ ESP B │
│ (Server) │ │ (Client) │
│ 192.168.2.235 │ │ 192.168.2.246 │
└────────┬────────┘ └────────┬────────┘
│ Web Server │ Web Server
│ │
┌────▼────┐ ┌────▼────┐
│ HP 1 │ │ HP 2 │
│ Browser │ │ Browser │
└─────────┘ └─────────┘
Alur Kerja:
- Kedua ESP8266 terhubung ke WiFi yang sama (SSID: shereen)
- Masing-masing ESP menjalankan WebServer di port 80
- Smartphone membuka alamat IP ESP via browser (Chrome/Safari)
- Saat HP 1 mengirim pesan → ESP A menyimpan dan mengirim ke ESP B via HTTP Request
- ESP B fetch data dari ESP A setiap 1 detik untuk mendapatkan pesan terbaru
- HP 2 melihat pesan yang di-fetch oleh ESP B
- Begitu juga sebaliknya, chat dua arah real-time!
๐ฑ 3. Kode ESP A (Server Utama)
File: esp_a.ino (simpan di folder esp_a/)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server(80);
String chat = "";
void handleRoot() {
String h = "<!DOCTYPE html><html><head>";
h += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
h += "<style>";
h += "body{font-family:Arial;margin:10px;background:#e5ddd5;}";
h += ".chat-box{background:white;padding:15px;height:400px;overflow-y:scroll;border-radius:10px;}";
h += ".msg{margin:5px 0;padding:10px;border-radius:8px;max-width:80%;clear:both;}";
h += ".sent{background:#dcf8c6;float:right;}";
h += ".received{background:white;float:left;border:1px solid #ddd;}";
h += "input{width:70%;padding:12px;border:none;border-radius:20px;}";
h += "button{padding:12px 20px;background:#128c7e;color:white;border:none;border-radius:20px;}";
h += "</style></head><body>";
h += "<h2>๐ฑ ESP A (Aku)</h2>";
h += "<div class='chat-box' id='c'>" + chat + "</div>";
h += "<input id='m' placeholder='Ketik pesan...'>";
h += "<button onclick='s()'>Kirim</button>";
h += "<script>";
h += "function s(){";
h += " var m=document.getElementById('m').value;";
h += " if(m=='')return;";
h += " fetch('/send?msg='+encodeURIComponent(m));";
h += " document.getElementById('m').value='';";
h += " setTimeout(l,300);";
h += "}";
h += "function l(){";
h += " fetch('/get').then(r=>r.text()).then(d=>{";
h += " document.getElementById('c').innerHTML=d;";
h += " });";
h += "}";
h += "setInterval(l,1000);";
h += "</script></body></html>";
server.send(200, "text/html", h);
}
void handleSend() {
String m = server.arg("msg");
m.replace("+", " ");
chat += "<div class='msg sent'>" + m + "</div>";
server.send(200, "text/plain", "OK");
}
void handleGet() {
server.send(200, "text/plain", chat);
}
void handleReceive() {
String m = server.arg("msg");
m.replace("+", " ");
chat += "<div class='msg received'>" + m + "</div>";
server.send(200, "text/plain", "OK");
}
void setup() {
WiFi.begin("shereen", "87654321");
while(WiFi.status() != WL_CONNECTED) delay(500);
server.on("/", handleRoot);
server.on("/send", handleSend);
server.on("/get", handleGet);
server.on("/receive", handleReceive);
server.begin();
Serial.begin(115200);
Serial.println();
Serial.print("ESP A IP: ");
Serial.println(WiFi.localIP());
}
void loop() {
server.handleClient();
delay(1);
}
✅ Fungsi ESP A:
- Web Server utama penyimpan chat
- Menerima pesan dari HP 1 dan ESP B
- Menyediakan endpoint
/getuntuk di-fetch ESP B - Tampilan UI WhatsApp-like
๐ฑ 4. Kode ESP B (Client dengan Fetch)
File: esp_b.ino (simpan di folder esp_b/)
⚠️ PENTING: Ganti String ipA = "192.168.2.235"; dengan IP ESP A kamu!
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
ESP8266WebServer server(80);
String chat = "";
String ipA = "192.168.2.235"; // ⚠️ GANTI DENGAN IP ESP A!
String lastFetch = "";
void handleRoot() {
String h = "<!DOCTYPE html><html><head>";
h += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
h += "<style>";
h += "body{font-family:Arial;margin:10px;background:#e5ddd5;}";
h += ".chat-box{background:white;padding:15px;height:400px;overflow-y:scroll;border-radius:10px;}";
h += ".msg{margin:5px 0;padding:10px;border-radius:8px;max-width:80%;clear:both;}";
h += ".sent{background:#dcf8c6;float:right;}";
h += ".received{background:white;float:left;border:1px solid #ddd;}";
h += "input{width:70%;padding:12px;border:none;border-radius:20px;}";
h += "button{padding:12px 20px;background:#128c7e;color:white;border:none;border-radius:20px;}";
h += "</style></head><body>";
h += "<h2>๐ฑ ESP B (Aku)</h2>";
h += "<div class='chat-box' id='c'>" + chat + "</div>";
h += "<input id='m' placeholder='Ketik pesan...'>";
h += "<button onclick='s()'>Kirim</button>";
h += "<script>";
h += "function s(){";
h += " var m=document.getElementById('m').value;";
h += " if(m=='')return;";
h += " fetch('/send?msg='+encodeURIComponent(m));";
h += " document.getElementById('m').value='';";
h += " setTimeout(l,300);";
h += "}";
h += "function l(){";
h += " fetch('/get').then(r=>r.text()).then(d=>{";
h += " document.getElementById('c').innerHTML=d;";
h += " });";
h += "}";
h += "setInterval(l,1000);";
h += "</script></body></html>";
server.send(200, "text/html", h);
}
void handleSend() {
String m = server.arg("msg");
m.replace("+", " ");
chat += "<div class='msg sent'>" + m + "</div>";
// Kirim pesan ke ESP A
WiFiClient c;
HTTPClient http;
http.begin(c, "http://" + ipA + "/receive?msg=" + m);
http.GET();
http.end();
server.send(200, "text/plain", "OK");
}
void handleGet() {
// AMBIL DATA DARI ESP A (FETCH)
WiFiClient c;
HTTPClient http;
http.begin(c, "http://" + ipA + "/get");
int code = http.GET();
if(code == 200) {
String newChat = http.getString();
if(newChat != lastFetch) {
chat = newChat;
lastFetch = newChat;
}
}
http.end();
server.send(200, "text/plain", chat);
}
void handleReceive() {
String m = server.arg("msg");
m.replace("+", " ");
chat += "<div class='msg received'>" + m + "</div>";
server.send(200, "text/plain", "OK");
}
void setup() {
WiFi.begin("shereen", "87654321");
while(WiFi.status() != WL_CONNECTED) delay(500);
server.on("/", handleRoot);
server.on("/send", handleSend);
server.on("/get", handleGet);
server.on("/receive", handleReceive);
server.begin();
Serial.begin(115200);
Serial.println();
Serial.print("ESP B IP: ");
Serial.println(WiFi.localIP());
}
void loop() {
server.handleClient();
delay(1);
}
✅ Fungsi ESP B:
- Web Server untuk HP 2
- Mengirim pesan ke ESP A via
/receive - Fetch chat dari ESP A setiap kali HP 2 membuka halaman
/get - Tidak menyimpan chat permanen (mengandalkan ESP A sebagai server utama)
๐ Kunci Keberhasilan: ESP B tidak menerima pesan langsung dari ESP A. Sebagai gantinya, ESP B mengambil (fetch) seluruh history chat dari ESP A setiap 1 detik melalui endpoint
/get. Ini solusi untuk ESP yang sering restart!
๐ป 5. Cara Upload dengan Arduino CLI
5.1 Install Arduino CLI
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
5.2 Install Board ESP8266
arduino-cli core update-index arduino-cli core install esp8266:esp8266
5.3 Buat Folder dan Simpan Kode
# Buat folder (NAMA FOLDER HARUS SAMA DENGAN NAMA FILE!) mkdir -p ~/esp_a mkdir -p ~/esp_b # Simpan kode ESP A ke ~/esp_a/esp_a.ino # Simpan kode ESP B ke ~/esp_b/esp_b.ino
⚠️ PENTING! Arduino CLI mengharuskan nama folder = nama file!
✅ BENAR:
❌ SALAH:
✅ BENAR:
~/esp_a/esp_a.ino❌ SALAH:
~/chat/esp_a.ino
5.4 Upload ESP A
cd ~/esp_a arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 esp_a.ino arduino-cli upload -p /dev/ttyUSB0 --fqbn esp8266:esp8266:nodemcuv2 esp_a.ino arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200
๐ Catat IP ESP A! (misal: 192.168.2.235), lalu tekan Ctrl+C
5.5 Upload ESP B
cd ~/esp_b # ⚠️ EDIT esp_b.ino dulu! Ganti ipA dengan IP ESP A nano esp_b.ino arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 esp_b.ino arduino-cli upload -p /dev/ttyUSB0 --fqbn esp8266:esp8266:nodemcuv2 esp_b.ino arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200
๐ Catat IP ESP B! (misal: 192.168.2.246), lalu tekan Ctrl+C
๐ฑ 6. Cara Menggunakan
๐ Langkah Mudah:
- Colok ESP A ke powerbank/charger HP
- Colok ESP B ke powerbank/charger HP
- HP 1: Buka Chrome/Safari, ketik
http://192.168.2.235 - HP 2: Buka Chrome/Safari, ketik
http://192.168.2.246 - Mulai chat! Ketik pesan, tekan Kirim ๐
Tampilan Interface:
┌──────────────────────────────────┐ │ ๐ฑ ESP A (Aku) │ ├──────────────────────────────────┤ │ ┌──────────────────────────────┐ │ │ │ Halo! │ │ │ │ │ │ Hai juga! │ │ │ │ Gimana kabar? │ │ │ │ │ │ Baik, kamu? │ │ │ └──────────────────────────────┘ │ │ ┌──────────────────────┐ ┌─────┐ │ │ │ Ketik pesan... │ │Kirim│ │ │ └──────────────────────┘ └─────┘ │ └──────────────────────────────────┘
๐ง 7. Tips dan Troubleshooting
❌ "Serial port busy"
sudo fuser -k /dev/ttyUSB0
❌ "main file missing from sketch"
Pastikan nama folder = nama file .ino! Contoh: esp_a/esp_a.ino
❌ ESP restart terus (IP muncul berkali-kali)
Solusi:
- Gunakan powerbank/charger HP, jangan USB laptop
- Ganti kabel USB yang lebih bagus
- Tambahkan kapasitor 100ยตF antara Vin dan GND (opsional)
❌ ESP B tidak menerima pesan dari ESP A
Solusi: ESP B sudah didesain untuk fetch langsung dari ESP A! Cukup refresh halaman atau tunggu 1 detik, pesan akan muncul.
❌ Tampilan rusak/tanda tanya di HP
- Refresh browser (F5 atau pull down di HP)
- Clear cache browser
- Pastikan WiFi HP terhubung ke jaringan yang sama
๐ก Tips Tambahan:
- Beri label "A" dan "B" pada ESP agar tidak tertukar
- Gunakan kabel USB berkualitas untuk performa stabil
- Simpan kode di cloud (GitHub/GDrive) sebagai backup
- IP ESP bisa berubah jika router restart, cek ulang via Serial Monitor
๐ Penutup
Selamat! Kamu telah berhasil membuat sistem chat offline menggunakan 2 ESP8266. Sistem ini bisa dikembangkan lebih lanjut:
- ✅ Enkripsi pesan dengan AES
- ✅ Simpan history ke SPIFFS (flash memory ESP)
- ✅ Notifikasi suara saat pesan masuk
- ✅ Kirim emoji & gambar
- ✅ Grup chat dengan 3+ ESP8266
- ✅ Integrasi Telegram Bot
๐ง Spesifikasi Sistem:
WiFi SSID: shereen | Password: 87654321
ESP A IP: 192.168.2.235 | ESP B IP: 192.168.2.246
Protokol: HTTP | Library: ESP8266WiFi, ESP8266WebServer
WiFi SSID: shereen | Password: 87654321
ESP A IP: 192.168.2.235 | ESP B IP: 192.168.2.246
Protokol: HTTP | Library: ESP8266WiFi, ESP8266WebServer
๐
Tutorial by: Arif
Project: Chat WhatsApp-like ESP8266
© 2026 - Happy Making! ๐
Project: Chat WhatsApp-like ESP8266
© 2026 - Happy Making! ๐






0 komentar:
Posting Komentar