← Back to Robot Communication series
🤖
MODBUS
MODBUS · Prereq: lesson 5

06. MODBUS SERVER (Robot = Slave)

Lesson 5 handled the four registers individually; this lesson combines them to control the robot. With the robot as Slave(Server) and an upstream PLC·PC as Master(Client), you run the command cycle: "command number → parameters → trigger → motion → response check → reset." This is how a PLC actually moves a HIWIN robot on site, and you also learn to split 32-bit coords·angles into Low/High words.

MODBUS Servercommand cycleHolding Registersplit_wordtriggerPTP
Duration
~2 hours
Level
📊 Intermediate
Prerequisite
🎯 Lesson 5
OUTCOME
In the robot=Slave structure, perform the 5-step command cycle (HR201→HR202~→HR200=1→IR check→HR200=0) and split 32-bit values into Low/High words to send PTP/LIN commands.

What you'll learn

  • 1Explain who commands and who moves in the robot=Slave Server, PLC=Master Client structure
  • 2Know how the robot's SO/SI/DI/DO·command·status registers map to the four register areas
  • 3Perform the 5-step command cycle (HR201→HR202~→HR200=1→IR200/IR524 check→HR200=0)
  • 4Split 32-bit coords·angles with split_word into Low/High words

Introduction

The Master (upstream PLC/PC) writes a command number·parameters·trigger to the robot's Holding Registers; the Slave (robot) reads them, actually moves, and fills Input Registers/Discrete Inputs with progress·position to respond. The robot only receives commands — the "controlled" side.

Key concepts

1) Register mapping — monitor vs command

AreaPermRobot meaning
Discrete InputRread SO(Run/Held/Fault/Ready)·DI
CoilR/WSI(Start/Hold/Stop/Enable)·DO
Input RegisterRread current speed·motion state·position
Holding RegisterR/Wwrite speed setting·command number·parameters

The master commands via the R/W areas (Coil·HR) and monitors via the R areas (DI·IR). Lesson 5's permission split becomes the "monitor vs command" split.

2) The 5-step command cycle (manual 5.3.3.5)

text
 ① HR[201] ← command number   (e.g. 0 = PTP)
 ② HR[202~] ← parameters       (motion type, 6-axis coords, speed, Tool/Base)
 ③ HR[200] ← 1                 (execution trigger)
 ④ robot moves → IR[524] 2(Run)→1(Idle), IR[200]=1(Success)
 ⑤ HR[200] ← 0                 (master resets → ready for next)
⚠️

Key rule: if you don't reset HR[200] to 0 in ⑤, the next command won't execute.

3) Splitting a 32-bit value into Low/High words

python
from word_tools import split_word
split_word(90000)   # → (24464, 1)  Low=90000%65536, High=90000//65536
# restore: 1×65536 + 24464 = 90000 → ×0.001 = 90.000°
# negative (-300mm) gives a negative High word (-5). RobotMaster.write_holding auto-encodes with & 0xFFFF

Joint angles·coords are integers in units of 0.001 (90.000°→90000). A 16-bit word holds -32768~32767, so a single word can't fit; it's split into Low/High words for 32-bit. Single commands fall into 17 categories: motion (000~006)·Tool/Base (101~104,201~204)·PR/Home (100·105·200·205).

Core example

As the master (PLC), PTP-move the robot slave's A1 joint to 90°, performing the 5-step cycle.

python
A1_low, A1_high = split_word(90000)        # (24464, 1) = 90.000°
with RobotMaster(host, port) as m:
    params = [0, 0, A1_low, A1_high, 0,0,0,0,0,0,0,0,0,0, 50, 100, 1, 2]
    m.write_holding(201, params)            # ①② HR201~218
    m.write_holding(200, 1)                 # ③ execution trigger
    while m.read_input(524,1)[0] != 2: pass          # ④-1 wait for Running
    while not (m.read_input(524,1)[0]==1 and m.read_input(200,1)[0]==1): pass  # ④-2 done
    m.write_holding(200, 0)                 # ⑤ reset trigger
ℹ️

A prior command's Success/Idle may linger, so a 2-step poll (wait for Running=2 first, then Idle+Success) is safest. IR[300,301]=[24464,1] → 1×65536+24464=90000 → 90.000°.

Common mistakes

Q. I wrote the trigger as 1 but the robot doesn't move.

A. You didn't reset the prior command's HR[200] to 0. Skipping step ⑤ leaves the slave in ack_wait, ignoring the next trigger (manual 5.3.3.5 key rule).

Q. struct.error 'H' format requires 0<=number<=65535 on a negative coord (X=-300mm).

A. split_word(-300000)=(27680,-5) has a negative High word. RobotMaster.write_holding auto-encodes with value & 0xFFFF (-5→65531), so with RobotMaster you need no extra handling.

Q. Coords·angles go in as wrong values.

A. Wrong L/H word order ([Low, High]) or motion type (HR202: Joint=0/Cartesian=1). Confirm you placed split_word() results in that order.

Summary

  • Robot=Slave Server, upstream PLC/PC=Master Client. Master commands via R/W, monitors via R
  • Command cycle: HR201=number → HR202~=params → HR200=1 → check IR200/IR524 → HR200=0 reset (required)
  • Coords·angles over 16 bits are split by split_word into Low/High; negative words auto-encode in RobotMaster
  • 17 single commands: motion (000~006)·T_STOP (005)·Tool/Base·PR/Home

Exercises

  1. Complete an A1=90° PTP cycle and decode IR[300,301] to confirm 90.000°
  2. Skip step ⑤ (HR200=0) to reproduce the next command being locked
  3. Encode X=-300mm Cartesian with split_word and confirm the auto unsigned conversion
Example code / lecture materials

All lecture materials and example code (with simulators, homework, and answers) are openly available on GitHub.

View on GitHub ↗