Hibah Pembelajaran Berdampak UNS 2026 · Skema Membangun Desa
Desa Karanggeneng, Boyolali Fakultas Teknik UNS

Publikasi

ESP32 Samoto Monitor + Siren (Firmware esp32-v2.3)

Arsitektur dan alur kerja firmware ESP32: monitoring inverter Samoto, pengukuran arus ACS712, dan kontrol sirine darurat.

ESP32 Samoto Monitor + Siren (firmware esp32-v2.3)

Dokumen ini merangkum arsitektur sistem dan alur kerja firmware, disiapkan untuk bahan update progress dan pembuatan flow chart.


1. Gambaran Umum

Sistem ini adalah node berbasis ESP32 yang punya tiga fungsi utama:

  1. Monitoring inverter Samoto lewat komunikasi serial (protokol perintah Q1).
  2. Pengukuran arus AC nyata pada sisi beban memakai sensor ACS712 30A (metode RMS), lalu dihitung daya nyata (watt).
  3. Kontrol sirine / alarm darurat lewat relay SSR (FOTEK), bisa dipicu dari tombol fisik, perintah server, atau serial monitor.

ESP32 berkomunikasi ke server lewat USB Serial (115200 baud) dengan format blok teks nama- ... -nama. Server menerima telemetri dan status sirine, sekaligus bisa mengirim perintah balik (on/off/query sirine). Data telemetri dicatat ke SQLite di sisi server.


2. Arsitektur Sistem

2.1 Lapisan Sistem

Lapisan Komponen Peran
Sensor / sumber data Inverter Samoto Sumber data tegangan grid, tegangan output, frekuensi, beban, suhu, tegangan baterai, status backup
Sensor ACS712 30A Sumber data arus beban AC (RMS)
Tombol darurat Input manual pemicu sirine
Antarmuka hardware MAX3232 Konversi level RS232 inverter ke level TTL ESP32
Voltage divider 10k:20k Menurunkan output ACS712 (5 V) ke level aman ADC ESP32 (3.3 V)
Transistor NPN + R 1k Driver basis untuk relay SSR
Pengendali ESP32 Akuisisi data, pengolahan, logika sirine, komunikasi ke server
Aktuator SSR FOTEK + sirine Membunyikan alarm
LED onboard Indikator sirine aktif
Server Parser serial + SQLite Menerima blok telemetri/status, menyimpan data, mengirim perintah

2.2 Pemetaan Pin

Fungsi Pin ESP32 Keterangan
RX2 GPIO 16 Dari TX inverter (lewat MAX3232)
TX2 GPIO 17 Ke RX inverter (lewat MAX3232)
ACS712 GPIO 34 Input ADC via divider 10k:20k
Relay SSR GPIO 4 Basis NPN via R 1k, active HIGH
Tombol GPIO 13 Ke GND, INPUT_PULLUP, interrupt FALLING
LED GPIO 2 LED onboard

2.3 Jalur Komunikasi

Jalur Media Baud Arah Isi
ESP32 <-> Inverter UART2 (via MAX3232) 9600 Dua arah Kirim Q1\r, terima string status (...)
ESP32 <-> Server UART0 / USB Serial 115200 Dua arah Blok telemetri, state, danger (keluar); blok cmd, ping (masuk)

2.4 Komponen Software (Modul dalam Firmware)

  1. Modul Sirine (sirenActivate, sirenDeactivate, sirenTick, sendState, sendDanger)
  2. Modul Sensor Arus (readSensorVolt, calibrateACS712, readCurrentRMS)
  3. Modul Inverter (readSamotoQ1)
  4. Modul Telemetri (sendTelemetry)
  5. Modul Parser Perintah Server (pollSerial, handleLine)
  6. Modul Tombol (ISR onButton dengan debounce 200 ms)
  7. Main loop (penjadwalan semua modul di atas tanpa blocking panjang)

2.5 Parameter Utama

Parameter Nilai
Interval telemetri 60 detik
Durasi sirine 10 detik
Batas maksimum sirine (fail-safe) 10 detik
Interval laporan state saat sirine ON 1 detik
Interval laporan state saat IDLE 10 detik
Sensitivitas ACS712 66 mV/A
Rasio divider 20k / (10k + 20k) = 0.667
Durasi sampling RMS 200 ms (10 siklus 50 Hz)
Oversampling ADC 8x per sampel
Batas noise arus 0.05 A (di bawahnya dianggap 0 A)
Debounce tombol 200 ms

3. Alur Kerja (untuk Flow Chart)

3.1 Alur Utama (Level Tertinggi)

  1. MULAI: ESP32 dinyalakan.
  2. Jalankan SETUP (lihat 3.2).
  3. Masuk LOOP tak berhingga (lihat 3.3).

3.2 Alur SETUP (Inisialisasi)

  1. Buka Serial server 115200 baud.
  2. Set pin relay sebagai output, relay dimatikan (sirine OFF).
  3. Set pin LED sebagai output, LED mati.
  4. Set pin tombol INPUT_PULLUP, pasang interrupt FALLING ke onButton.
  5. Buka Serial2 ke inverter 9600 baud (8N1, RX=16, TX=17).
  6. Set ADC resolusi 12 bit dan atenuasi 11 dB pada pin ACS712.
  7. Tunggu 500 ms.
  8. Kalibrasi ACS712 (lihat 3.7).
  9. Cetak banner firmware dan versi.
  10. Kirim state awal sirine ke server.
  11. Lanjut ke LOOP.

3.3 Alur LOOP (berulang terus)

Setiap iterasi loop menjalankan urutan berikut:

  1. Poll serial dari server (pollSerial): baca karakter masuk, susun jadi baris, proses tiap baris lengkap lewat handleLine (lihat 3.6).
  2. Cek timeout sirine (sirenTick): jika sirine ON dan waktu habis, matikan sirine dengan sumber "timeout".
  3. Update LED sesuai status sirine.
  4. Cek flag tombol:
    • Jika flag aktif: reset flag, kirim blok danger ke server.
    • Jika sirine sedang OFF: aktifkan sirine (sumber "esp32", durasi 10 detik).
    • Jika sirine sudah ON: tidak ada aksi tambahan (sirine tidak diperpanjang).
  5. Cek waktu telemetri: jika sudah >= 60 detik sejak telemetri terakhir, catat waktu lalu jalankan kirim telemetri (lihat 3.5).
  6. Cek waktu laporan state: tentukan interval (1 detik jika sirine ON, 10 detik jika OFF). Jika sudah lewat, kirim state ke server.
  7. Kembali ke langkah 1.

3.4 Alur Tombol Darurat (Interrupt)

  1. Tombol ditekan, pin turun ke LOW (FALLING).
  2. ISR onButton jalan: ambil waktu sekarang.
  3. Jika selisih dari penekanan sebelumnya > 200 ms: set btnFlag = true dan simpan waktu. Jika tidak: abaikan (debounce).
  4. Flag diproses di main loop (langkah 4 pada 3.3).

3.5 Alur Kirim Telemetri

  1. Baca inverter (readSamotoQ1, lihat 3.8).
  2. Baca arus RMS dari ACS712 (lihat 3.9), simpan ke lastIrms.
  3. Baca suhu internal ESP32. Jika NaN atau di luar rentang -20 sampai 120 C, ganti nilai default 40 C.
  4. Tentukan tegangan output yang dipakai: pakai v_out inverter jika pembacaan valid, jika tidak pakai default 220 V.
  5. Hitung daya nyata: wl = v_out x Irms.
  6. Kirim blok ke server:
    • Buka blok start-
    • Field: vac, vout, fr, tups, tesp, vbat, load, wl, i, bk
    • Field yang bergantung pembacaan inverter dikirim - jika pembacaan gagal (invalid)
    • Tutup blok -end

3.6 Alur Parser Perintah dari Server

Input masuk karakter demi karakter, baris selesai saat ketemu \n atau \r (maks 160 karakter per baris). Tiap baris diproses handleLine:

  1. Jika baris = cmd-: masuk mode cmd, kosongkan aksi.
  2. Jika baris = -cmd: tutup blok cmd. Jika mode cmd, baca aksi (trim, lowercase):
    • on: aktifkan sirine (sumber "server", 10 detik)
    • off: matikan sirine (sumber "server")
    • query: kirim state
    • Reset mode.
  3. Jika baris = ping-: masuk mode ping.
  4. Jika baris = -ping: reset mode, kirim state (berfungsi sebagai heartbeat/jawaban ping).
  5. Jika baris = cal (tanpa peduli huruf besar/kecil): jalankan kalibrasi ACS712 ulang.
  6. Jika baris = siren: toggle sirine (sumber "serial").
  7. Jika sedang mode cmd dan baris berformat kunci: nilai: jika kunci = aksi, simpan nilainya sebagai aksi.

Contoh perintah dari server:

cmd-
aksi: on
-cmd

3.7 Alur Kalibrasi ACS712

  1. Ambil 2000 sampel tegangan sensor (jeda 300 us), hitung rata-rata sebagai offsetV (titik nol DC, idealnya sekitar 2.5 V).
  2. Ambil 2000 sampel lagi, hitung selisih terhadap offset, kuadratkan, rata-ratakan, akar kuadratkan sebagai noise floor (RMS noise saat tanpa beban).
  3. Cetak offset dan noise floor ke serial.

Catatan: kalibrasi harus dilakukan saat tidak ada beban terpasang.

3.8 Alur Baca Inverter Samoto (Q1)

  1. Kosongkan buffer Serial2.
  2. Kirim Q1\r ke inverter.
  3. Kumpulkan karakter respons sampai ketemu CR/LF (ada timeout 300 ms tanpa data baru).
  4. Cari karakter ( di string. Jika tidak ada: tandai valid = false, selesai (gagal).
  5. Parse (sscanf) ke: tegangan grid, tegangan fault, tegangan output, load %, frekuensi, tegangan cell, suhu, status.
  6. Jika minimal 7 field berhasil terbaca:
    • Hitung tegangan baterai = v_cell x 6
    • Mode backup = true jika karakter pertama status = 1
    • Tandai valid = true
  7. Jika tidak: valid = false.

3.9 Alur Baca Arus RMS

  1. Selama 200 ms: baca tegangan sensor (rata-rata 8 sampel ADC, dibagi rasio divider), kurangi offsetV, kuadratkan, akumulasi.
  2. Hitung mean square = jumlah kuadrat / jumlah sampel.
  3. Kurangi kontribusi noise: sigSq = meanSq - noiseFloor^2 (minimal 0).
  4. Hitung Irms = sqrt(sigSq) / 0.066 x CAL_FACTOR.
  5. Jika Irms < 0.05 A: dianggap 0 A.

3.10 Alur Kontrol Sirine

Aktivasi (sirenActivate):

  1. Jika durasi = 0 atau melebihi batas maksimum: pakai durasi default (10 detik).
  2. Set status ON, simpan sumber, hitung waktu berakhir.
  3. Nyalakan relay, update LED.
  4. Kirim state ke server.

Deaktivasi (sirenDeactivate):

  1. Set status OFF, simpan sumber.
  2. Matikan relay, update LED.
  3. Kirim state ke server.

Timeout otomatis (sirenTick, dicek tiap loop): jika sirine ON dan waktu sudah lewat, panggil deaktivasi dengan sumber "timeout".

Sumber pemicu sirine: esp32 (tombol fisik), server (perintah cmd), serial (ketik siren), timeout (hanya untuk OFF otomatis).


4. Format Protokol Serial ke Server

Setiap pesan berbentuk blok: baris pembuka nama-, isi kunci: nilai, baris penutup -nama.

4.1 Dari ESP32 ke Server

Telemetri (tiap 60 detik):

start-
vac: 220.0
vout: 220.0
fr: 50.0
tups: 30.0
tesp: 40.0
vbat: 13.20
load: 25
wl: 150.0
i: 0.682
bk: 0
-end

Catatan: pembuka memakai start-, penutup memakai -end.

State sirine (1 detik saat ON, 10 detik saat IDLE, dan setiap ada perubahan):

state-
siren: on
sumber: server
sisa: 8
durasi: 10
cap: 10
-state

Danger (saat tombol darurat ditekan):

danger-
siren: 1
durasi: 10
-danger

4.2 Dari Server ke ESP32

Blok Isi Efek
cmd- ... -cmd aksi: on / off / query Nyalakan, matikan, atau minta state sirine
ping- ... -ping (kosong) ESP32 membalas dengan blok state

4.3 Arti Field Telemetri

Field Arti Sumber
vac Tegangan grid / input PLN Inverter
vout Tegangan output inverter Inverter
fr Frekuensi Inverter
tups Suhu inverter Inverter
tesp Suhu internal ESP32 ESP32
vbat Tegangan baterai (v_cell x 6) Inverter (dihitung)
load Beban inverter (%) Inverter
wl Daya nyata (W) = vout x Irms ACS712 + inverter
i Arus beban (A RMS) ACS712
bk Mode backup (1 = pakai baterai) Inverter

5. Mekanisme Pengaman (Fail-safe)

  1. Batas durasi sirine (SIREN_MAX_SEC): sirine tidak bisa menyala lebih lama dari batas ini, meski perintah meminta lebih.
  2. Timeout otomatis: sirine selalu mati sendiri setelah waktu habis, tidak bergantung pada server.
  3. Relay mati saat boot: relay dipastikan OFF di awal setup.
  4. Debounce tombol: mencegah pemicu ganda akibat bouncing.
  5. Fallback data tidak valid: jika inverter tidak merespons, field terkait dikirim - dan perhitungan watt memakai 220 V default.
  6. Validasi suhu ESP32: nilai tidak masuk akal diganti default.
  7. Batas panjang baris serial (160 karakter): mencegah buffer membengkak.
  8. Pengurangan noise floor dan batas 0.05 A: mencegah pembacaan arus palsu saat tanpa beban.

6. Ringkasan Satu Paragraf (untuk Update Progress)

Firmware ESP32 (versi esp32-v2.3) berfungsi sebagai node monitoring dan alarm. ESP32 membaca data inverter Samoto lewat UART2 dengan perintah Q1 (via MAX3232), mengukur arus beban AC memakai ACS712 dengan metode RMS yang dikalibrasi offset dan noise floor, lalu menghitung daya nyata. Seluruh data dikirim ke server tiap 60 detik lewat USB Serial dalam format blok key-value. Selain itu, ESP32 mengendalikan sirine lewat relay SSR yang dapat dipicu dari tombol darurat, perintah server, atau serial monitor, dilengkapi timeout otomatis dan batas durasi sebagai pengaman. Status sirine dilaporkan berkala ke server, dan server dapat mengirim perintah on, off, query, serta ping.


7. Catatan Temuan saat Telaah Kode

Beberapa hal yang sebaiknya dicek/dirapikan sebelum update progress:

  1. Interval telemetri tidak konsisten: konstanta bernilai 60000 ms (60 detik), tetapi komentar di kode menyebut "tiap 10 dtk". Sesuaikan salah satunya, dan pastikan angka di dokumentasi/flow chart sama dengan nilai sebenarnya.
  2. Durasi sirine = batas maksimum (sama-sama 10 detik): artinya fitur cap belum punya ruang gerak. Kalau ingin durasi bisa diatur, naikkan SIREN_MAX_SEC.
  3. Blok telemetri memakai penanda start- dan -end, sedangkan blok lain memakai nama yang sama di pembuka dan penutup (state-/-state). Pastikan parser di server memang menangani pasangan start/end ini.
  4. Pembacaan telemetri bersifat blocking sekitar 0.2 sampai 0.5 detik (sampling RMS 200 ms + tunggu respons inverter maks 300 ms). Selama itu, tombol tetap tertangkap (interrupt), tetapi pemrosesannya tertunda sampai loop berikutnya. Masih aman untuk kasus ini.
  5. Baud inverter di kode = 9600, sedangkan catatan awal proyek menyebut 2400. Pastikan sesuai spesifikasi inverter yang dipakai.
  6. LED: kode memakai LED biasa di GPIO 2. Jika board yang dipakai ESP32-S3 dengan LED RGB onboard, bagian ledUpdate perlu disesuaikan.
  7. Ping tidak mengirim data khusus: respons ping hanya blok state. Itu cukup sebagai heartbeat, tetapi sebutkan demikian di penjelasan.