Pemetaan register Modbus adalah konvensi yang menentukan bagaimana sebuah perangkat mengekspos bit dan nilainya, function code mana yang membaca atau menulis masing-masing, dan bagaimana angka pada datasheet diterjemahkan menjadi alamat yang sebenarnya melintas di jalur komunikasi. Sebagian besar kerumitan integrasi (membaca nilai yang salah, alamat yang meleset satu, atau float yang tampak seperti sampah) berakar pada salah paham terhadap salah satu dari tiga hal: empat model data, alamat protokol berbasis 0 versus alamat dokumentasi berbasis 1, serta urutan byte dan word dari nilai multi-register. Panduan ini membahas masing-masing agar Anda dapat memetakan sebuah perangkat dengan benar sejak percobaan pertama.
Empat model data Modbus
Spesifikasi Modbus Application Protocol mendefinisikan empat tabel data utama. Dua di antaranya berukuran satu bit dan dua lainnya berupa register 16-bit. Dua bersifat read-only dan dua bersifat read/write. Secara historis, keempatnya dipetakan ke sebuah digit referensi awal (0xxxx, 1xxxx, 3xxxx, 4xxxx) yang masih Anda temukan di banyak datasheet, meskipun digit tersebut hanyalah penyingkat untuk dokumentasi, bukan bagian dari frame yang sebenarnya.
| Model data | Prefiks referensi | Ukuran | Akses | Penggunaan umum |
|---|---|---|---|---|
| Coils | 0xxxx | 1 bit | Baca / Tulis | Output relay, perintah on/off, flag enable |
| Discrete Inputs | 1xxxx | 1 bit | Hanya baca | Input digital, limit switch, bit status |
| Input Registers | 3xxxx | 16 bit | Hanya baca | Pengukuran langsung: tegangan, arus, suhu |
| Holding Registers | 4xxxx | 16 bit | Baca / Tulis | Setpoint, konfigurasi, akumulator, dan sering kali juga pengukuran |
Pembagian ini bersifat logis, bukan fisik. Banyak perangkat nyata, termasuk sebagian besar power meter Modbus, menempatkan setiap pengukuran di holding register alih-alih input register karena holding register didukung secara universal oleh master polling. Model data yang digunakan sebuah perangkat adalah keputusan vendor, jadi selalu percayai peta perangkat ketimbang ekspektasi teoretis. Untuk perbedaan antara transport RTU dan TCP yang membawa model-model ini, lihat Modbus RTU vs Modbus TCP.
Function code: mencocokkan kata kerja dengan datanya
Sebuah request Modbus terdiri atas function code ditambah alamat awal dan kuantitas. Setiap model data memiliki kode bacanya sendiri, dan model yang dapat ditulis menambahkan kode tulis tunggal dan jamak. Inilah delapan kode yang Anda tangani dalam praktik.
| Kode (des / heks) | Nama | Bekerja pada | Arah |
|---|---|---|---|
| 01 / 0x01 | Read Coils | Coils (0xxxx) | Membaca bit |
| 02 / 0x02 | Read Discrete Inputs | Discrete Inputs (1xxxx) | Membaca bit |
| 03 / 0x03 | Read Holding Registers | Holding Registers (4xxxx) | Membaca word 16-bit |
| 04 / 0x04 | Read Input Registers | Input Registers (3xxxx) | Membaca word 16-bit |
| 05 / 0x05 | Write Single Coil | Coils (0xxxx) | Menulis satu bit |
| 06 / 0x06 | Write Single Register | Holding Registers (4xxxx) | Menulis satu word |
| 15 / 0x0F | Write Multiple Coils | Coils (0xxxx) | Menulis blok bit |
| 16 / 0x10 | Write Multiple Registers | Holding Registers (4xxxx) | Menulis blok word |
Dua pasangan paling sering menyebabkan polling gagal. Function code 04 membaca input register, bukan holding register, sehingga mengarahkan FC04 ke peta 4xxxx akan menghasilkan respons kosong atau illegal data address. Selain itu, tidak ada kode tulis untuk input register maupun discrete input karena keduanya read-only secara definisi. Jika sebuah master perlu menulis suatu nilai, nilai tersebut harus berada di coil atau holding register.
Offset pengalamatan 0-based versus 1-based
Satu poin ini adalah penyebab paling umum dari kesalahan off-by-one dalam integrasi Modbus. Protocol data unit (PDU) yang melintas di jalur komunikasi menggunakan alamat berbasis 0. Nomor referensi pada datasheet biasanya berbasis 1 dan menyertakan digit model di depan. Untuk mengonversi alamat terdokumentasi menjadi alamat PDU, buang prefiks model lalu kurangi satu.
- Datasheet menyebut holding register 40001 → alamat PDU 0 dengan function code 03.
- Datasheet menyebut holding register 40108 → alamat PDU 107 (40108 dikurangi 40001).
- Datasheet menyebut discrete input 10005 → alamat PDU 4 dengan function code 02.
Jebakannya adalah sebagian vendor sudah menerbitkan alamat PDU berbasis 0, sebagian menerbitkan nomor referensi berbasis 1, dan sebagian lagi menerbitkan keduanya di kolom bersebelahan tanpa memberi label mana yang mana. Sebelum memercayai peta mana pun, baca satu register yang nilainya dapat Anda prediksi (versi firmware atau nilai nameplate yang tetap) dan pastikan apakah Anda perlu menerapkan offset minus satu. Jika sebuah nilai yang sudah diketahui muncul satu register terlalu tinggi atau terlalu rendah, Anda telah menemukan ketidaksesuaian basisnya. Pola kesalahan ini dan yang terkait dibahas dalam troubleshooting error komunikasi Modbus.
Register 16-bit dan nilai 32-bit yang menempati dua register
Sebuah register Modbus tepat berukuran 16 bit, sehingga menampung integer tak bertanda dari 0 hingga 65535 atau integer bertanda dari -32768 hingga 32767. Apa pun yang lebih besar, termasuk integer 32-bit atau float presisi tunggal IEEE 754, harus menempati dua register berurutan, dan nilai 64-bit menempati empat. Protokol itu sendiri tidak mengenal konsep tipe data. Ia hanya memindahkan word 16-bit, dan maknanya sepenuhnya merupakan kontrak antara perangkat dan master yang didefinisikan oleh register map.
Karena spesifikasi tidak pernah menstandarkan cara mengurutkan kedua register tersebut, ada empat kombinasi yang ditemui di lapangan. Variabel pertama adalah urutan byte di dalam setiap register (big-endian, default Modbus, mengirim byte tinggi terlebih dahulu). Variabel kedua adalah urutan word: apakah register orde-tinggi datang lebih dulu (urutan word big-endian) atau register orde-rendah datang lebih dulu (word swap, sering dilabeli “little-endian” atau “Daniel/Enron” pada berbagai tool).
| Nama urutan | Urutan register | Susunan byte untuk 0x12345678 | Umum pada |
|---|---|---|---|
| Big-endian (ABCD) | Word tinggi dulu | 12 34 / 56 78 | Default Modbus, banyak meter |
| Little-endian (DCBA) | Word rendah dulu, byte ditukar | 78 56 / 34 12 | Sebagian controller |
| Big-byte / word swap (BADC) | Word tinggi dulu, byte ditukar | 34 12 / 78 56 | Pustaka PLC tertentu |
| Word swap (CDAB) | Word rendah dulu, byte utuh | 56 78 / 12 34 | Schneider, banyak gateway |
Uji praktisnya: baca sepasang register yang nilai sebenarnya Anda ketahui, misalnya sebuah meter yang membaca tegangan jaringan stabil di sekitar 230 V. Jika float yang didekode terbaca 230,1 maka urutannya sudah benar. Jika terbaca angka liar seperti 4.7e34 atau nilai negatif, coba word swap lebih dulu karena CDAB versus ABCD adalah ketidaksesuaian yang paling sering terjadi. Kunci urutannya sekali, dokumentasikan di peta, dan terapkan ke setiap field 32-bit pada perangkat tersebut. Sebuah bridge Modbus-ke-MQTT yang dapat dikonfigurasi seperti gateway SURIOTA SRT-MGATE-1210 memungkinkan Anda mengatur urutan word dan byte per blok register sehingga float tiba di broker sudah terangkai dengan benar, yang menghilangkan tebak-tebakan dari aplikasi di hulu.
Kode exception Modbus
Ketika sebuah request tidak valid atau di luar rentang, slave membalas dengan function code yang di-OR dengan 0x80 disertai satu byte kode exception. Mengenali kode-kode ini mempercepat debugging jauh lebih efektif daripada sekadar packet capture.
| Kode | Nama | Penyebab umum |
|---|---|---|
| 01 | Illegal Function | Perangkat tidak mendukung function code tersebut |
| 02 | Illegal Data Address | Alamat atau kuantitas di luar peta perangkat (sering kali offset 0/1) |
| 03 | Illegal Data Value | Nilai atau jumlah tidak diizinkan untuk register tersebut |
| 04 | Slave Device Failure | Kesalahan internal perangkat saat memproses |
| 05 | Acknowledge | Request diterima, pemrosesan panjang sedang berlangsung |
| 06 | Slave Device Busy | Perangkat sibuk, coba lagi nanti |
| 0B | Gateway Target Failed | Gateway mencapai bus tetapi slave target tidak merespons |
Exception 02 pada pembacaan yang Anda yakini valid hampir selalu berarti basis pengalamatan salah. Exception 0B pada bridge TCP-ke-RTU menunjuk ke sisi hilir di jalur serial, bukan ke request TCP Anda. Setelah peta, function code, dan urutan word beres, memindahkan nilai yang telah terangkai ke platform IoT adalah langkah berikutnya, yang dibahas dalam panduan gateway Modbus RTU ke MQTT kami.
Pertanyaan yang Sering Diajukan
Mengapa function code 03 gagal tetapi 04 berhasil pada perangkat yang sama?
Perangkat menyimpan pengukurannya di input register (3xxxx), yang dibaca dengan function code 04. Function code 03 menargetkan holding register (4xxxx). Jika alamat-alamat tersebut tidak terisi, perangkat mengembalikan exception illegal data address. Cocokkan function code dengan model data yang tercantum di register map.
Bagaimana saya tahu apakah perangkat saya menggunakan pengalamatan 0-based atau 1-based?
Baca sebuah register dengan nilai tetap yang sudah diketahui seperti versi firmware atau konstanta nameplate. Jika nilainya muncul satu alamat lebih tinggi dari yang terdokumentasi, peta itu berbasis 1 dan Anda harus mengurangi satu untuk mendapatkan alamat PDU. Banyak tool master memiliki kotak centang untuk offset ini.
Float 32-bit saya terbaca sebagai angka sangat besar atau negatif. Apa yang salah?
Kedua register hampir pasti berada dalam urutan word yang salah. Tukar register tinggi dan rendah (CDAB versus ABCD) lalu dekode ulang terhadap nilai yang dapat Anda prediksi, seperti tegangan yang sudah diketahui. Jika masih salah, coba pula menukar byte di dalam setiap register.
Bisakah saya menulis ke input register atau discrete input?
Tidak. Input register (3xxxx) dan discrete input (1xxxx) bersifat read-only secara definisi dalam spesifikasi Modbus, sehingga tidak ada function code tulis untuk keduanya. Data yang dapat ditulis harus berada di coil (menggunakan FC05 atau FC0F) atau holding register (menggunakan FC06 atau FC10).