Pendahuluan — Sensor Tanpa Router di Tengah
Sejauh ini, hampir semua artikel Seri 2 mengasumsikan router WiFi ada: ESP32 connect ke AP, lalu HTTP (#6), MQTT (#7), atau broker (#16).
Di lapangan, tidak selalu demikian. Greenhouse besar, gudang, atau kebun punya node sensor di ujung yang jauh dari router — sinyal WiFi lemah, tapi jarak antar board ESP32 dekat. Di sinilah ESP-NOW masuk: protokol peer-to-peer Espressif untuk kirim paket kecil antar ESP32 tanpa router.
Artikel Jalur D ini membahas pola paling umum: sensor node (ESP-NOW only) → gateway node (ESP-NOW + WiFi + MQTT) → broker → Grafana (#19). Ini pola sensor + gateway klasik untuk IoT lapangan.
Prasyarat: Paham koneksi WiFi ESP32 (#4), DHT22 (#5), dan dasar MQTT (#7). Disarankan baca REST vs MQTT (#20) untuk konteks kapan butuh infrastruktur penuh.
Apa Itu ESP-NOW?
ESP-NOW adalah protokol wireless proprietary Espressif, built-in di chip ESP32/ESP8266. Karakteristik utama:
- Tanpa router — komunikasi langsung antar MAC address
- Payload kecil — maksimal ~250 byte per paket
- Latency rendah — cocok untuk trigger, remote control, telemetry ringan
- Channel WiFi — kedua board harus di channel yang sama (1–13), meski tidak connect ke AP
- Enkripsi opsional — PMK/LMK untuk peer terenkripsi
ESP-NOW vs WiFi/MQTT vs LoRa
| Protokol | Jangkau | Infrastruktur | Cocok untuk |
|---|---|---|---|
| ESP-NOW | ~200 m LOS (tergantung antena) | 2+ ESP32, tanpa router | Sensor lokal → gateway dekat |
| WiFi + MQTT (#7) | Seluruh jaringan AP | Router + broker (#16) | Dashboard, multi-subscriber |
| REST (#6) | LAN AP | Router | Debug cepat, satu klien |
| LoRa (#26) | Kilometer | 2× ESP32 + modul SX1278 | Sensor sangat jauh, data jarang |
ESP-NOW bukan pengganti MQTT — ia mengisi celah antara node sensor dan gateway yang punya WiFi. Lihat juga perbandingan di #20.
Yang Kamu Butuhkan
- 2× ESP32 (DevKit v1 atau serupa) — satu sensor, satu gateway
- DHT22 di node sensor (opsional BME280 dari #13)
- Router WiFi hanya di gateway — untuk forward ke MQTT
- Kabel USB ×2 untuk flash & baca MAC address
Estimasi biaya: ~Rp 80–120rb per ESP32 + sensor — total ~Rp 200–250rb untuk lab dua node.
Arsitektur Sensor + Gateway
| Komponen | Peran | Koneksi |
|---|---|---|
| ESP32 Sensor + DHT22 | Baca suhu & kelembaban, kirim paket kecil | ESP-NOW saja — tanpa router WiFi |
| ESP32 Gateway | Terima paket ESP-NOW, publish ke MQTT | ESP-NOW + WiFi STA ke router |
| Mosquitto (#16) | Broker pusat | Topic kodingindonesia/esp32/dht22/data |
| Grafana (#19) | Dashboard histori (opsional) | Subscribe / Telegraf dari broker |
Alur data secara singkat:
[ ESP32 Sensor — DHT22 ]
|
| ESP-NOW (peer-to-peer, tanpa router)
| struct: suhu, kelembaban, unix
| deep sleep (#11) — hemat baterai
v
[ ESP32 Gateway ]
|
| WiFi STA → router rumah/kantor
| MQTT publish :1883
| topic: kodingindonesia/esp32/dht22/data
v
[ Mosquitto @ 192.168.1.50 ] (#16)
|
+-- mosquitto_sub / subscriber Python (#18)
+-- Grafana dashboard (#19)
Sensor node hemat daya: bangun → baca sensor → kirim ESP-NOW → tidur (deep sleep #11). Gateway selalu hidup, terima paket, publish MQTT dengan timestamp NTP (#34).
MAC Address & Pairing
Setiap ESP32 punya MAC address WiFi STA unik. Wajib dicatat sebelum pairing:
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.print("MAC STA: ");
Serial.println(WiFi.macAddress());
}
Flash sketch di atas ke kedua board — catat MAC gateway, misalnya 24:6F:28:AA:BB:02, dan MAC sensor 24:6F:28:AA:BB:01. Ganti placeholder di sketch berikut dengan nilai nyata dari Serial Monitor.
Pro tip: Tempel label fisik di tiap board (SENSOR / GATEWAY + MAC) agar tidak tertukar saat debug.
Struktur Data Bersama
Pakai struct yang sama di sender dan receiver — maksimal 250 byte:
typedef struct __attribute__((packed)) {
float suhu;
float kelembaban;
uint32_t unix; // opsional dari RTC/NTP di sensor; gateway bisa isi ulang
} sensor_packet_t;
Contoh nilai setelah gateway publish MQTT (konsisten Seri 2):
{"suhu":28.5,"kelembaban":65.2,"timestamp":"2026-07-02T14:30:00","unix":1782977400}
Sketch Sensor — ESP-NOW Sender
#include <esp_now.h>
#include <WiFi.h>
#include <DHT.h>
#define DHT_PIN 4
#define GATEWAY_MAC {0x24, 0x6F, 0x28, 0xAA, 0xBB, 0x02} // GANTI_MAC_GATEWAY
DHT dht(DHT_PIN, DHT22);
typedef struct __attribute__((packed)) {
float suhu;
float kelembaban;
uint32_t unix;
} sensor_packet_t;
uint8_t gatewayMac[] = GATEWAY_MAC;
void onSent(const uint8_t* mac, esp_now_send_status_t status) {
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "ESP-NOW OK" : "ESP-NOW GAGAL");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
dht.begin();
if (esp_now_init() != ESP_OK) {
Serial.println("esp_now_init gagal");
return;
}
esp_now_register_send_cb(onSent);
esp_now_peer_info_t peer = {};
memcpy(peer.peer_addr, gatewayMac, 6);
peer.channel = 1;
peer.encrypt = false;
esp_now_add_peer(&peer);
}
void loop() {
sensor_packet_t pkt;
pkt.suhu = dht.readTemperature();
pkt.kelembaban = dht.readHumidity();
pkt.unix = 1782977400; // production: NTP (#34)
esp_now_send(gatewayMac, (uint8_t*)&pkt, sizeof(pkt));
delay(5000);
}
Sketch Gateway — ESP-NOW Receiver + MQTT
Gateway: terima ESP-NOW, lalu publish ke broker 192.168.1.50 topic kodingindonesia/esp32/dht22/data — pola #7 + auth #16.
#include <esp_now.h>
#include <WiFi.h>
#include <PubSubClient.h>
const char* ssid = "GANTI_NAMA_WIFI";
const char* pass = "GANTI_PASSWORD_WIFI";
const char* mqtt_host = "192.168.1.50";
const char* mqtt_user = "kindo_esp32";
const char* mqtt_pass = "GANTI_PASSWORD_MQTT";
const char* topic = "kodingindonesia/esp32/dht22/data";
WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);
typedef struct __attribute__((packed)) {
float suhu;
float kelembaban;
uint32_t unix;
} sensor_packet_t;
void onRecv(const uint8_t* mac, const uint8_t* data, int len) {
if (len != sizeof(sensor_packet_t)) return;
sensor_packet_t pkt;
memcpy(&pkt, data, sizeof(pkt));
char json[128];
snprintf(json, sizeof(json),
"{\"suhu\":%.1f,\"kelembaban\":%.1f,\"unix\":%lu}",
pkt.suhu, pkt.kelembaban, (unsigned long)pkt.unix);
mqtt.publish(topic, json);
Serial.println(json);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) { delay(300); }
mqtt.setServer(mqtt_host, 1883);
mqtt.connect("kindo-espnow-gw", mqtt_user, mqtt_pass);
if (esp_now_init() != ESP_OK) return;
esp_now_register_recv_cb(onRecv);
}
void loop() {
if (!mqtt.connected()) mqtt.connect("kindo-espnow-gw", mqtt_user, mqtt_pass);
mqtt.loop();
}
Multi-Node & Topologi Star
Satu gateway bisa menerima data dari banyak sensor ESP-NOW. Pola umum di greenhouse atau gudang:
- Star topology — semua sensor kirim ke satu gateway; gateway publish MQTT dengan field
node_iddi JSON - Daftar peer — di gateway, panggil
esp_now_add_peeruntuk setiap MAC sensor - Di sensor — cukup satu peer (MAC gateway); tidak perlu tahu MAC sensor lain
Contoh payload gateway dengan identitas node:
{"node":"greenhouse-1","suhu":28.5,"kelembaban":65.2,"unix":1782977400}
Topic MQTT bisa diperluas: kodingindonesia/esp32/greenhouse-1/dht22/data — pola hierarki sama dengan artikel #7. Subscriber Python (#18) atau Telegraf (#19) bisa filter per node.
Pro tip: Batasi jumlah peer aktif (~20 pada ESP32) dan interval kirim agar gateway tidak kelebihan beban CPU saat WiFi + MQTT + ESP-NOW berjalan bersamaan.
Debugging ESP-NOW di Serial Monitor
Saat pertama kali setup, aktifkan log verbose di kedua board:
- Print MAC STA di
setup()— wajib sebelum pairing - Di sender: pantau callback
onSent—ESP_NOW_SEND_SUCCESSvs gagal - Di gateway: print panjang paket di
onRecv— harus sama dengansizeof(sensor_packet_t) - Cek
WiFi.channel()di gateway setelah connect — samakan dipeer.channelsensor - Matikan power save WiFi sementara jika paket hilang acak:
WiFi.setSleep(false)
Jika MQTT publish OK tapi ESP-NOW gagal, masalah ada di radio layer — jangan buru-buru ganti broker atau sketch MQTT.
Channel WiFi & Koeksistensi
ESP-NOW memakai channel radio yang sama dengan interface WiFi STA. Aturan praktis:
- Set
peer.channel = 1di kedua sisi — atau samakan dengan channel AP gateway - Gateway yang connect ke router: channel mengikuti AP — sensor harus set channel yang sama
- Gunakan
WiFi.channel()di gateway, print ke Serial, lalu hardcode di sensor (atau simpan di NVS #12)
Deep Sleep + ESP-NOW di Node Sensor
Kombinasi ideal untuk baterai: sensor tidak perlu maintain WiFi association — cukup WiFi.mode(WIFI_STA), init ESP-NOW, kirim, lalu esp_deep_sleep_start(). Pola detail di #11.
Pro tip: Setelah
esp_deep_sleep, ESP32 reboot — init ESP-NOW ulang disetup()setiap bangun.
Keamanan ESP-NOW
- Default
encrypt = false— OK untuk lab dalam ruangan - Produksi: set
peer.encrypt = true+ PMK (Primary Master Key) 16 byte sama di kedua firmware - Jangan broadcast MAC ke publik jika sistem kontrol (relay/pintu) — whitelist peer saja
- Gateway tetap amankan MQTT dengan TLS #17 jika ke internet
Integrasi Dashboard & Histori
Setelah gateway publish MQTT, alur sama dengan artikel sebelumnya:
ESP-NOW hanya menggantikan hop pertama (sensor → gateway); selebihnya stack MQTT biasa.
Checklist: Kapan Pakai ESP-NOW?
- Sensor jauh dari router, tapi dekat ke ESP32 lain? → ESP-NOW
- Butuh kirim < 250 byte, interval pendek? → ESP-NOW
- Butuh jangkau kilometer? → LoRa (#26), bukan ESP-NOW
- Butuh banyak subscriber langsung dari sensor? → MQTT (#7)
- Node baterai + gateway solar/USB? → ESP-NOW sensor + MQTT gateway
Uji Coba (Lab)
# 1. Catat MAC kedua board dari Serial Monitor
# 2. Flash sender ke sensor, receiver+MQTT ke gateway
# 3. Di laptop:
mosquitto_sub -h 192.168.1.50 -t "kodingindonesia/esp32/dht22/data" -v
- Power sensor — dalam 5 detik JSON muncul di
mosquitto_sub - Matikan sensor — stream berhenti; gateway tetap online
- Jauhkan sensor >30 m atau balik dinding — amati packet loss
- Ubah channel salah di sensor — tidak ada data (debug channel)
- Cek Grafana (#19) — titik suhu naik jika Telegraf/subscriber jalan
FAQ Singkat
- ESP-NOW butuh internet?
- Tidak. Hanya butuh dua ESP32 di jangkau radio. Internet/WiFi hanya di gateway jika mau forward MQTT.
- Bisa lebih dari 2 board?
- Ya — satu gateway bisa daftar banyak peer
esp_now_add_peer. Sensor broadcast ke gateway, atau star topology. - ESP8266 support ESP-NOW?
- Ya, tapi API sedikit berbeda. Artikel ini fokus ESP32.
- Bentrok dengan WiFi router?
- Tidak jika channel diselaraskan. Gateway connect WiFi + ESP-NOW simultan didukung ESP32.
Tips & Troubleshooting
- ESP-NOW GAGAL: MAC gateway salah atau channel beda — cek
onSentcallback - MQTT tidak publish: Gateway WiFi/MQTT bermasalah — debug terpisah dari ESP-NOW
- Data korup:
structtidakpackedsama di kedua sketch — ukuran harus identik - Range pendek: Normal di dalam bangunan; antena eksternal atau LoRa (#26) untuk jarak jauh
- Payload >250 byte: Pecah paket atau kirim field penting saja; atau pakai WiFi/MQTT
- MAC berubah? Tidak untuk STA — tapi tulis di label agar tidak tertukar board
Keamanan & Produksi
- Ganti
GANTI_NAMA_WIFI,GANTI_PASSWORD_WIFI,GANTI_PASSWORD_MQTT— jangan commit ke GitHub - Pakai NVS + WiFiManager (#12) di gateway untuk deploy lapangan
- Aktifkan enkripsi ESP-NOW jika data kontrol (relay, kunci)
- Placeholder MAC — selalu ganti dengan MAC nyata dari hardware kamu
Langkah Selanjutnya (Jalur D)
- LoRa SX1278 (#26): sensor jarak jauh (ratusan meter–km) menggantikan/perluas ESP-NOW
- MQTT TLS (#17) — amankan hop gateway → broker
- Deep sleep (#11) — optimalkan node sensor baterai
- Grafana (#19) — visualisasi data dari gateway MQTT
- Capstone greenhouse (#39) — multi-node ESP-NOW + pompa MQTT
Dengan ESP-NOW, kamu bisa menaruh sensor di sudut yang WiFi router tidak jangkau — asalkan ada gateway ESP32 di tengah yang menjembatani ke MQTT. Lanjutkan Seri 2 di halaman artikel Koding Indonesia.