Panduan Build Prototipe
Langkah demi langkah dari board kosong sampai Bunai bisa menjawab suara Bahasa Indonesia — dimulai dari dev board di atas meja (belum perlu PCB). Urutan: buktikan otak AI dulu, baru firmware, lalu satukan.
Estimasi: P0–P1 ± 2–4 minggu untuk PoC end-to-end. Perintah ditulis untuk Linux (Armbian di H618) & ESP-IDF.
0Prasyarat & Alat
🔧 Hardware (fase PoC)
- Orange Pi Zero 2W (H618, 4GB) + microSD 32GB A2 (OS+model)
- ESP32-S3 DevKitC-1 (N16R8)
- INMP441 (mic I2S) + MAX98357A (amp) + speaker 8Ω
- OLED I2C (SH1107/SSD1306), DS3231, breadboard + jumper
- Power: USB-C 5V/3A, multimeter, (opsi) LiPo 4000mAh + BQ25895 modul
- Kabel USB-C data, USB-UART (CP2102) untuk debug
💻 Software & skill
- Linux host (atau WSL) untuk build
- ESP-IDF v5.x (toolchain ESP32-S3)
- Git, CMake, Python 3.10+, dasar C & Python
- Dasar I2S/I2C/serial & pembacaan datasheet
- Akun Hugging Face (unduh model GGUF)
1Bench Setup
Siapkan OS H618
Flash Armbian (Debian, Orange Pi Zero 2W) ke microSD pakai balenaEtcher. Boot, login serial/SSH.
# cek board & RAM
cat /proc/cpuinfo | grep -i model ; free -h
sudo apt update && sudo apt -y full-upgradePasang dependensi build
sudo apt install -y build-essential cmake git python3-pip \
python3-venv libsndfile1 ffmpeg portaudio19-dev wgetSiapkan ESP-IDF di host
mkdir -p ~/esp && cd ~/esp
git clone -b v5.2.1 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf && ./install.sh esp32s3
. ./export.sh # aktifkan environment (tiap sesi)hello_world ke ESP32-S3.2Otak AI (H618)
Buktikan LLM + STT + TTS Bahasa Indonesia berjalan layak di H618 sebelum menyentuh hardware lain.
2.1 LLM — llama.cpp + Qwen2.5
Build llama.cpp
git clone https://github.com/ggml-org/llama.cpp ~/llama.cpp
cd ~/llama.cpp
cmake -B build -DGGML_NATIVE=ON
cmake --build build -j4Unduh model (GGUF Q4)
pip install -U "huggingface_hub[cli]"
mkdir -p ~/models
huggingface-cli download Qwen/Qwen2.5-1.5B-Instruct-GGUF \
qwen2.5-1.5b-instruct-q4_k_m.gguf --local-dir ~/models
# + model cepat sebagai cadangan
huggingface-cli download Qwen/Qwen2.5-0.5B-Instruct-GGUF \
qwen2.5-0.5b-instruct-q4_k_m.gguf --local-dir ~/modelsUji + ukur kecepatan
./build/bin/llama-cli -m ~/models/qwen2.5-1.5b-instruct-q4_k_m.gguf \
-p "Jawab singkat: penyebab umum vibrasi pompa naik?" \
-n 60 -t 4 --no-display-prompt
# catat tokens/detik di output. Target ~4-6 t/s (1.5B), ~10-14 (0.5B)
./build/bin/llama-server -m ~/models/qwen2.5-1.5b-instruct-q4_k_m.gguf -t 4 --port 80812.2 STT — whisper.cpp (Bahasa Indonesia)
Build + unduh model
git clone https://github.com/ggml-org/whisper.cpp ~/whisper.cpp
cd ~/whisper.cpp && cmake -B build && cmake --build build -j4
bash ./models/download-ggml-model.sh base # multibahasa, ID didukungUji transkripsi Indonesia
# rekam 16kHz mono (atau pakai file uji)
arecord -r 16000 -c 1 -f S16_LE -d 4 uji.wav
./build/bin/whisper-cli -m models/ggml-base.bin -l id -f uji.wav
tiny (offload encoder ke GPU Mali / threads CPU di tahap optimasi).2.3 TTS — Piper (suara id_ID)
Install + unduh suara Indonesia
pip install piper-tts
# unduh voice id_ID dari rhasspy/piper-voices
huggingface-cli download rhasspy/piper-voices \
id/id_ID/--/medium/id_ID-...onnx id/id_ID/--/medium/id_ID-...onnx.json \
--local-dir ~/piper-voices
echo "Halo, saya Bunai. Siap membantu." | \
piper -m ~/piper-voices/id/id_ID/.../id_ID-...onnx -f halo.wav
aplay halo.wav
Nama file voice persis bisa berbeda — cek folder id/id_ID di repo voices.
2.4 Memori — SQLite + sqlite-vec
Install & uji embedding RAG
pip install sqlite-vec sentence-transformers
# embedding multibahasa kecil utk ID (e5-small / MiniLM)
# test_rag.py
import sqlite3, sqlite_vec
db=sqlite3.connect("bunai.db"); db.enable_load_extension(True)
sqlite_vec.load(db)
db.execute("CREATE VIRTUAL TABLE IF NOT EXISTS kvec USING vec0(embedding FLOAT[384])")
print("sqlite-vec OK:", db.execute("select vec_version()").fetchone())2.5 Orchestrator minimal
Rangkai jadi pipeline suara→jawaban
# orchestrator.py (alur inti)
text = whisper_transcribe("uji.wav", lang="id") # STT
intent = route(text) # regex → fallback LLM
if intent in ("jadwal","catatan"):
fields = llm_extract(text) # function-call JSON
db_insert(intent, fields); answer = konfirmasi(fields)
else:
ctx = rag_search(text) # sqlite-vec
answer = llm_answer(text, ctx, system=PERSONA_ID) # Qwen2.5
tts_say(answer) # Piper → wav3Firmware ESP32-S3
Struktur proyek & build
. ~/esp/esp-idf/export.sh
idf.py create-project bunai_fw && cd bunai_fw
idf.py set-target esp32s3
idf.py build flash monitorUji mic I2S (INMP441)
Wiring: SCK→GPIO4, WS→GPIO5, SD→GPIO6, VDD→3V3, GND+L/R→GND. Baca buffer I2S, cetak level RMS ke monitor untuk pastikan mic hidup.
Uji OLED + tombol
I2C SDA→GPIO17, SCL→GPIO18 (pull-up 4.7k). Pakai u8g2 untuk teks "BUNAI siap". Baca tombol PTT (GPIO1, pull-up internal, aktif-LOW).
Wake-word "Hai Bunai" (ESP-SR)
# tambah komponen esp-sr
idf.py add-dependency "espressif/esp-sr"
# pakai WakeNet; untuk wake-word custom "Hai Bunai" daftarkan
# lewat tool kustomisasi Espressif, atau mulai dgn wake word bawaan
Audio playback (MAX98357A)
I2S TX: BCLK→GPIO7, LRC→GPIO8, DIN→GPIO9, SD→GPIO10, VDD→5V. Putar nada uji / WAV dari flash untuk pastikan speaker bunyi.
4Hubungkan Dua Otak
Jalur fisik
Hubungkan USB native ESP32-S3 (GPIO19/20) ke port USB H618 → muncul sebagai /dev/ttyACM0 di Linux (USB-CDC). Tambah 1 kabel GPIO21(ESP)→pin wake H618 dan READY balik ke GPIO14.
Protokol terbingkai
# frame: [0xAA][len:2][type:1][payload][crc16]
# type: 'W'=wake 'A'=audio 'E'=audio_end 'D'=display 'T'=tts 'X'=action 'I'=idle 'P'=ping
# ESP kirim audio Opus 16kHz; RK balas display+tts
Uji loopback dulu: ESP kirim ping tiap 2s, RK balas pong. Pastikan CRC & framing stabil sebelum audio.
Streaming audio + wake
ESP rekam → encode Opus → kirim frame A sampai VAD selesai (E). H618 yang sedang suspend dibangunkan via GPIO wake (<1.5s), proses, kirim D(teks)+T(audio) balik. Setelah I(idle) + timeout → RK suspend lagi.
5Integrasi & Skill
Muat skema DB
sqlite3 ~/bunai.db < ai-engine/memory/schema.sql # 5 domain memoriImplement intent router + skill
Aturan cepat (regex) untuk pola jelas; sisanya klasifikasi LLM. Tiap skill mengembalikan jawaban + aksi DB:
| Skill | Pemicu contoh | Aksi |
|---|---|---|
| schedule | "besok jam 8…" | INSERT schedules + reminder→RTC |
| notes | "ingatkan beli…" | INSERT notes |
| qa | "suhu normal bearing?" | RAG + LLM jawab |
| troubleshoot | "vibrasi naik 20%…" | LLM analisis + langkah |
| briefing | tombol briefing | SQL agenda+tugas |
| memory | "proyek aktif saya?" | SQL/RAG recall |
Uji end-to-end 6 skenario
Jalankan keenam contoh dari dossier. Verifikasi: data tersimpan benar, reminder muncul, jawaban singkat & relevan, latensi sesuai target.
Suspend/resume otomatis
# H618 suspend-to-RAM saat idle
echo mem | sudo tee /sys/power/state # diuji manual dulu
# wake oleh GPIO dari ESP (konfigurasi wakeup source)6Tuning Audio & Daya
🎙️ Audio
- Set gain mic & AGC; uji di lingkungan berisik (pabrik).
- VAD ambang & timeout endpoint (hindari potong kalimat).
- Filter LC speaker; cek tidak ada dengung ground.
- Bandingkan whisper tiny vs base (latensi vs akurasi).
🔋 Daya
- Ukur arus tiap state (idle/aktif/suspend) dgn multimeter.
- Verifikasi target: idle ~75mA, suspend ~12mA (lihat dossier §7).
- Uji mode hemat (PTT-only, wake-word off).
- Profil termal H618 saat inferensi panjang; pasang heat-spreader.
7Troubleshooting
| Gejala | Kemungkinan | Solusi |
|---|---|---|
| LLM sangat lambat (<2 t/s) | thread salah / swap / model besar | -t 4, pastikan tak swap, pakai Q4_K_M / 0.5B |
| whisper transkrip ngawur | bukan 16kHz mono / bahasa salah | rekam S16_LE 16k mono, -l id |
| Piper tak ada suara ID | file voice salah | cek path id/id_ID, file .onnx + .json cocok |
| /dev/ttyACM0 tak muncul | USB native ESP belum aktif | aktifkan USB-CDC di menuconfig, cek kabel data |
| H618 tak bangun dari suspend | wake source belum diset | konfigurasi GPIO wakeup, cek level sinyal WAKE |
| OLED blank | alamat/pull-up I2C | scan I2C (0x3C), pasang pull-up 4.7k |
| Reset saat speaker keras | drop tegangan / brownout | bulk cap +5V, kabel daya pendek & tebal |
| Wake-word sering salah picu | sensitivitas tinggi | turunkan threshold WakeNet |
8Checklist Ringkas per Fase
P0 · Setup
- H618 boot + update
- ESP-IDF build hello_world
- Semua part diuji nyala
P1 · Otak AI
- llama.cpp + Qwen jalan, catat t/s
- whisper ID akurat
- Piper suara ID keluar
- sqlite-vec RAG OK
- Pipeline suara→jawaban offline
P1 · Firmware
- Mic I2S terbaca
- OLED + tombol
- Wake-word deteksi
- Speaker bunyi
P2 · Integrasi
- Link USB-CDC stabil (ping/pong)
- End-to-end PTT→jawaban
- 6 skill jalan
- Suspend/resume + alarm fail-safe
P3 · Tuning
- Arus sesuai target
- Mode hemat OK
- Termal aman
- Audio jernih di noise
Lanjut
- Pindah ke PCB (lihat Paket Skematik)
- Enclosure 3D-print
- Dashboard + OTA
- Uji lapangan
Project Bunai · Panduan Build v1.0 · 13 Juni 2026. Perintah dapat berubah sesuai versi tool; selalu cek README resmi llama.cpp / whisper.cpp / Piper / ESP-IDF.