05. MODBUS Basics
If RS-232 was point-to-point between two devices, MODBUS is the industrial-standard protocol where one master reads/writes many slaves at the register level. With a PC alone you run a virtual slave and, as master, read/write the four register types (Discrete Input·Coil·Input Register·Holding Register) and Function Codes (01–06,15,16) — confirming you can't write to read-only registers.
What you'll learn
- 1Explain the MODBUS Master(Client)↔Slave(Server) request/response structure
- 2Compare Modbus RTU vs TCP physical layer·error checking (HIWIN RTU=RS485)
- 3Distinguish the four registers' bit width·permission·value range
- 4Map Function Codes (01–06,15,16) to registers
Introduction
In MODBUS, a Master(Client) sends a Demand and a Slave(Server) sends a Response. Every slave receives the command, but only the device with the addressed ID executes and replies. A HIWIN robot can be master (controlling a gripper·sensor) or slave (controlled by a PLC).
Key concepts
1) RTU vs TCP
| Aspect | Modbus RTU | Modbus TCP |
|---|---|---|
| Physical | serial RS485 (HIWIN) | Ethernet |
| Data | binary transfer | encapsulated in TCP/IP |
| Error check | CRC required | TCP layer checks (no CRC) |
This practice uses Modbus TCP (127.0.0.1) on one PC. The data model (four registers·Function Codes) is identical to RTU, so it applies directly to RS485 RTU.
2) The four data registers
| Register | Width | Permission | Range |
|---|---|---|---|
| Discrete Input | 1 bit | read-only (R) | 0~1 |
| Coil | 1 bit | read/write (R/W) | 0~1 |
| Input Register | 16 bit | read-only (R) | -32768~32767 |
| Holding Register | 16 bit | read/write (R/W) | -32768~32767 |
3) Function Codes & the 4-part data
01=read Coil·02=read DI·03=read HR·04=read IR·05=write single Coil·06=write single HR·15=write multiple Coil·16=write multiple HR. Rule: 01/02=bit read, 03/04=word read, 05/06=single write, 15/16=multiple write. Read-only (DI·IR) have no write codes. A command has 4 parts: ① Address ② Function code ③ Data ④ Error check (CRC, omitted on TCP).
Core example
With RobotMaster, read each register type (02/01/04/03), then write to the R/W ones (Holding 06·Coil 05) and read back to confirm.
with RobotMaster(host, port, unit) as m:
di = m.read_discrete(0, 8) # FC02 Discrete Input
co = m.read_coils(0, 8) # FC01 Coil
ir = m.read_input(524, 1)[0] # FC04 Input Register (motion state)
hr = m.read_holding(100, 1)[0]# FC03 Holding Register (speed setting)
m.write_holding(100, 50) # FC06 Holding write
assert m.read_holding(100, 1) == [50]
m.write_coil(300, 1) # FC05 Coil write (DO1 ON)read_* always returns a list (take [0] for a single value). Read-only Input Register·Discrete Input have no write_input/write_discrete methods at all (read-only enforced). Start the slave in a separate terminal: robot_server_sim.py --port 1502.
Common mistakes
Q. ConnectionError: failed to connect to slave.
A. Terminal A's slave isn't up or the port differs. Confirm robot_server_sim.py --port 1502 is running and the master also uses --port 1502.
Q. I want to write to an Input Register but there's no method.
A. By design, not a bug. Input Register·Discrete Input are read-only, so there's no write Function Code and no write_input/write_discrete in RobotMaster.
Q. read_holding(100,1) gives [50] which compares unequal to 50.
A. read_* always returns a list. Take the single value with m.read_holding(100,1)[0] before comparing.
Summary
- MODBUS is Master(demand)↔Slave(response); a command has Address·Function code·Data·CRC(omitted on TCP)
- RTU=RS485+binary+CRC required, TCP=Ethernet+encapsulation+TCP checks. HIWIN uses RS485 for RTU
- The four registers split into bit (DI=R, Coil=R/W) and word (IR=R, HR=R/W); permission is enforced
- Function Codes: 01/02=bit read, 03/04=word read, 05/06=single write, 15/16=multiple write
Exercises
- Read all four registers with 02/01/04/03 and confirm the output matches the Function Codes
- Write to Holding(06)·Coil(05), read back ✅, and confirm Input Register has no write method
- Explain which of RTU/TCP needs CRC and why
All lecture materials and example code (with simulators, homework, and answers) are openly available on GitHub.
View on GitHub ↗