Imported from slice-code/finger (
esp32-fpm10a-versi-3v3/AGENTS.md). Install upstream withnpx skills add slice-code/finger --skill esp32-fpm10a-versi-3v3. Copyright stays with the author.
AGENTS.md — ESP32 FPM10A (folder esp32-fpm10a-versi-3v3)
Firmware baku untuk board 3V3 dan 5V. Aturan proyek umum ada di /AGENTS.md root repo; dokumen ini khusus sketch di folder ini + changelog perilaku yang wajib dihormati saat edit.
Compile / upload (tidak berubah setelah pecah modul):
arduino-cli compile --fqbn esp32:esp32:esp32:PartitionScheme=no_ota_lfs \
/home/gugus/Documents/Project/pjtki/arduino/esp32-fpm10a-versi-3v3/esp32-fpm10a-versi-3v3.ino
arduino-cli upload --fqbn esp32:esp32:esp32:PartitionScheme=no_ota_lfs --port /dev/ttyUSB0 \
/home/gugus/Documents/Project/pjtki/arduino/esp32-fpm10a-versi-3v3/esp32-fpm10a-versi-3v3.ino
Arduino CLI/IDE menggabungkan semua *.ino di folder ini (file utama dulu, lalu alfabet). setup()/loop() harus di m12/m13 agar simbol modul sudah terdefinisi.
Struktur file
| File | Peran |
|---|---|
esp32-fpm10a-versi-3v3.ino |
includes, pin, globals, tema, BLE_DEVICE_NAME |
ble_handler.h |
NimBLE GATT (callback → flag; LittleFS hanya di loop) |
m01_lcd_ui.ino |
TFT: idle, scanning, match, nomatch, enroll UI |
m02_sensor_helpers.ino |
UART flush, LED 0x50/0x51, WDT wrap, waitFinger |
m03_fp_db.ino |
/fpmeta, /fphex, fingerprints.json rebuild |
m04_wifi_settings.ino |
/wifi.json, /settings.json |
m05_pending_storage.ino |
/attendance.jsonl, /pending_register.json |
m06_api_attn_sync.ino |
task upload absensi + sync worker |
m07_wifi_init.ino |
boot WiFi AP/STA |
m08_enroll.ino |
enroll + identify izin CPMI |
m09_autoscan.ino |
gate T-OUT + state machine autoscan |
m10_api_proxy.ino |
cache cabang/karyawan, sync template |
m11_recovery.ino |
reinit sensor, watchdog, WiFi reconnect |
m12_setup.ino |
setup() |
m13_loop.ino |
loop() + handler permintaan BLE |
partitions.csv |
partisi littlefs |
User_Setup.h |
TFT_eSPI pins |
Bedakan board hanya dengan nama BLE (sebelum #include "ble_handler.h" di file utama):
- 3V3: default
PJTKI-Finger(hapus override) - 5V:
#define BLE_DEVICE_NAME "PJTKI-Finger-5V"
Konstanta finger/gate/LED (BAKU — jangan tuning)
| Parameter | Nilai |
|---|---|
IR_CONFIRM_MS / IR_RELEASE_MS |
40 / 250 (2026-08-27, user: gate lebih cepat) |
IR_GATE_TIMEOUT_MS / IR_GATE_COOLDOWN_MS |
3000 / 2500 |
IR_REOPEN_MIN_MS |
80 — jangan tahan buka jika T-OUT sudah HIGH |
FALLBACK_POLL_MS |
1500 |
LED_WARMUP_MS |
120 |
LED_AUTO_OFF_MS |
5000 |
Loop autoscan delay() |
40 |
FINGER_CONFIRM_NEEDED |
1 |
FINGERPRINT_SECURITY_LEVEL |
2 |
| GPIO13 TCH | INPUT_PULLUP |
SCAN_WATCHDOG_MS |
20000 |
MAX_CONSECUTIVE_ERRORS |
8 |
| Baud detect | {57600, 9600, 19200, 38400} |
| Power-on / inter-baud | 3000 ms / 250 ms |
Jangan menyalin timing folder esp32-fpm10a-versi-5v/ (LED stuck). Jangan LEDcontrol(true) di irUpdateGate() — hanya wake LCD; LED sensor hanya setelah gate terbuka + verifikasi OK.
Changelog perilaku (2026-08-26) — wajib dihormati
1. Hemat RAM → LittleFS
- Absensi: tidak pakai array RAM besar →
/attendance.jsonl(streaming). - Meta finger: tidak pakai
fpDB[100]→/fpmeta/<id>.json+ cache 1 slot; hex di/fphex/<id>.hex. - Payload BLE besar: heap malloc/free (bukan BSS tetap), proses di loop.
- HTTP API: client plain HTTP bersama; hindari
WiFiClientSecuredi path absensi (hemat heap). - LCD footer kanan atas: sisa heap
"%lu kB"(ESP.getFreeHeap()/1024), refresh bersama jam.
2. Autoscan responsif
- Gate buka:
IR_CONFIRM40 ms; T-OUT HIGH tidak ditahanIR_REOPEN_MIN(user 2026-08-27). - Bukan timing 5V lama 15/200 +
LED_WARMUP30 (LED stuck).LED_WARMUPtetap 120. JanganLEDcontroldiirUpdateGate(). getImageNOFINGER + T-OUT masih HIGH → jangan tutup gate / matikan LED (sama enrollwaitFinger).- LED ON →
delay(LED_WARMUP_MS)lalugetImagedi iterasi yang sama (bukan break + cooldown loop). - Gate timeout saat jari masih di kaca → cooldown pendek (~200 ms), bukan 2.5 s penuh.
- Angkat jari saat cooldown → cooldown dibatalkan.
- LED auto-off jangan set
fingerMustRelease(itu mengunci scan tanpa hasil). - Setelah hasil (match/nomatch): deteksi angkat→tempel ulang membuka kunci; jangan
IR_REOPEN_MINmenahan tempel ulang setelah hold hasil. - Search autoscan: timeout
FP_AUTOSCAN_SEARCH_MS(2500) — jangan biarkan LCD “SCANNING” sampai 8 s. - Gagal
image2Tz/search → tampilkan GAGAL (bukanlcdShowIdlediam-diam). Retry capture 1× jika T-OUT masih HIGH. - Pakai
fpImage2Tz()(timeout perintah) bukanfinger.image2Tz()library yang bisa hang.
3. Setelah hapus finger (BLE delete / DELETE_EMP)
- Pause autoscan, matikan LED, flush UART,
deleteModel. JanganlcdShowIdle()/ autoscan sebelum hapus server selesai. - LCD HAPUS: Device → Sensor → Storage → Server (tunggu app
unregisterFinger+ perintahDELETE_DONE). Baru idle + autoscan langsung (tanpa delay 900 ms). Timeout 12 s jika app tidak ack. - Saat
deleteHoldUi: jangan buka/timeout gate diirUpdateGate()(timeout 3s tanpa getImage → cooldown 2.5s → sentuhan pertama mati). - Setelah selesai:
sensorResumeAfterDelete()— pinggetTemplateCount(resync UART) +sensorResumeIdle. Jika T-OUT masih HIGH,fingerMustRelease(angkat dulu). Jangan ubah konstanta gate/LED.
4. Setelah enroll sukses
- Arsip hex inline di akhir enroll (UpChar saat autoscan masih off); defer ke loop hanya jika gagal.
- Quiet post-enroll singkat (~400 ms), cooldown scan ~250 ms, tanpa gate cooldown 800 ms.
- Batas tunggu jari nempel post-enroll ~1.5 s (bukan 5 s).
- Setelah UpChar deferred (jika ada):
sensorResumeIdle("post-enroll-hex"). - UI: selama jeda tampilkan “Tunggu / Angkat jari” — jangan tampilkan BERHASIL dulu.
- BERHASIL hanya lewat
enrollPresentSuccessThenIdle()saat autoscan benar-benar resume, lalu idle. - Handler BLE enroll sukses: jangan
lcdShowIdle()segera (itu menghapus layar Tunggu). - Hex ke server: ESP
queueRegisterUpload+syncRequestNow()setelahenrollActive=false(bukan HP GET_TEMPLATE). Worker yang bangun saat enroll masih aktif wajib defer + kick ulang — jangan menungguuploadIntervalMinutes.
5. Autoscan vs CPMI
- Autoscan absensi harian hanya
KRY-*. - CPMI kena autoscan → LCD arahkan tab Izin; tidak tulis absensi harian.
- Izin keluar/masuk: app
POST /api/finger/izin/scansetelah identify BLE.
6. BLE / LittleFS
- Callback NimBLE: set flag + buffer saja; jangan buka LittleFS di callback.
bleEnsureAdvertising()cooldown ≥2 s; supervision timeout tetap ~4 s (jangan turunkan ke 1 s).- Set
ledOn=truehanya jikaLEDcontrol(true)==FINGERPRINT_OK; cleanup selaluledOn=false.
7. Purge lokal MD / sudah terbang (2026-08-27)
syncWorkerGET/api/finger/arduino/inactive(bukan diloop).- Hapus hanya sensor + LittleFS. Jangan
DELETEtemplate server. stalePurgeService()di loop: satu slot per iterasi, LCD BERSIH, tanpadeleteHoldUi/ack server.- Interval:
uploadIntervalMinutes+ cek pertama ~12 menit setelah WiFi.SYNC_NOWjuga memicu. - Jangan restore (
PUT_TEMPLATE) ID yang ada di daftar stale.
Storage LittleFS (ringkas)
| Path | Isi |
|---|---|
/settings.json |
apiBaseUrl, cabang, device, ir_enabled, jadwal, sync interval |
/wifi.json |
kredensial WiFi |
/fpmeta/<id>.json |
nama + employeeId per slot |
/fphex/<id>.hex |
template 512 hex chars |
/fingerprints.json |
cadangan rebuild (bukan mirror RAM) |
/attendance.jsonl |
absensi lokal NDJSON |
/pending_register.json |
enroll menunggu upload server |
/errors.log, /debug.log |
log |
Partisi: partitions.csv → littlefs. Jangan erase-flash untuk update firmware biasa. Jangan ganti LittleFS.h → SPIFFS.
Di mana edit apa
| Masalah | File utama |
|---|---|
| LCD stuck / teks salah | m01_lcd_ui.ino, m09_autoscan.ino, m08_enroll.ino |
| Lambat/tidak deteksi jari | m09_autoscan.ino (gate + SCAN_IDLE) |
| Enroll / UI success | m08_enroll.ino, m13_loop.ino (resume quiet) |
| Hapus finger macet scan | m13_loop.ino (BLE delete) + sensorResumeIdle di m02 |
| Hex / meta / sync template | m03_fp_db.ino, m10_api_proxy.ino |
| Absensi offline / sync | m05_pending_storage.ino, m06_api_attn_sync.ino |
| BLE UUID / write handler | ble_handler.h |
| Boot / BOD / WDT setup | m12_setup.ino |
| Reinit / watchdog | m11_recovery.ino |
Jangan lakukan
- Upload sketch folder
esp32-fpm10a-versi-5vke produksi. - Turunkan debounce/warmup/loop delay “biar cepat”.
- Hapus
fingerConfirm, gate T-OUT, atau verifikasiledOn. WiFi.mode(WIFI_OFF)saat deteksi sensor di ESP32.- Operasi jaringan blocking di
loop()/doAutoScan(). - Gabungkan kembali semua logika ke satu
.inotanpa alasan — pecahan modul untuk maintenance.