Skip to content

Example 46: Modbus Stepper Motor Control ​

Experiment Overview ​

Controls an RS485 stepper motor driver via Modbus RTU protocol, enabling remote precision positioning, speed adjustment, and direction control. Suitable for industrial automation, smart agriculture (roller blinds/irrigation valves), precision positioning, and similar scenarios.

Hardware Wiring ​

RS485 Communication Wiring ​

ESP32 PinTTL-to-RS485 ModuleDescription
GPIO 16TXDSerial transmit
GPIO 17RXDSerial receive
GPIO 4 (optional)DE/REDirection control
3.3VVCCPower
GNDGNDGround

RS485 to Stepper Motor Driver ​

RS485 ModuleStepper Motor DriverDescription
A+RS485-ADifferential signal positive
B-RS485-BDifferential signal negative

Stepper Motor Driver to Motor ​

DriverStepper MotorDescription
A+A phase +Motor coil A
A-A phase -Motor coil A
B+B phase +Motor coil B
B-B phase -Motor coil B
VCCExternal Power12-48V DC

Stepper motor drivers (e.g., DM542, TB6600 RS485 version) require independent power supply; voltage depends on motor model.

JSON Configuration Example ​

Status Read Configuration ​

json
{
  "id": "modbus_stepper",
  "name": "Modbus Stepper Motor",
  "type": 1,
  "enabled": false,
  "pins": [16, 17],
  "params": {
    "baudRate": 9600,
    "dataBits": 8,
    "parity": "none",
    "stopBits": 1,
    "dePin": 4,
    "protocol": "modbus_rtu",
    "slaveId": 1,
    "function": 3,
    "startRegister": 0,
    "registerCount": 4,
    "interval": 2000,
    "dataMap": [
      { "register": 0, "name": "position", "scale": 1, "unit": "steps" },
      { "register": 1, "name": "speed", "scale": 1, "unit": "RPM" },
      { "register": 2, "name": "status", "scale": 1, "unit": "" },
      { "register": 3, "name": "error", "scale": 1, "unit": "" }
    ]
  }
}

Control Write Configuration ​

json
{
  "id": "modbus_stepper_ctrl",
  "name": "Stepper Motor Control",
  "type": 1,
  "enabled": false,
  "pins": [16, 17],
  "params": {
    "protocol": "modbus_rtu",
    "slaveId": 1,
    "function": 6,
    "startRegister": 100,
    "registerCount": 3,
    "interval": 0,
    "controlMap": [
      { "register": 100, "name": "target_position", "min": -32768, "max": 32767 },
      { "register": 101, "name": "target_speed", "min": 0, "max": 3000 },
      { "register": 102, "name": "command", "values": { "start": 1, "stop": 2, "home": 3, "reset": 4 } }
    ]
  }
}

Parameter Description ​

ParameterDescription
slaveIdDriver slave address (DIP switch setting)
function3=read registers, 6=write single register, 16=write multiple registers
controlMapControl register mapping, defines writable fields
target_positionTarget position (steps, signed)
target_speedTarget speed (RPM)
commandMotion command: start/stop/home/reset

Control Commands ​

Send control via MQTT:

json
[{"id": "modbus_stepper_ctrl", "value": "target_position:2048,target_speed:100,command:1"}]
  • target_position: Target steps (positive=forward, negative=reverse)
  • target_speed: Running speed in RPM
  • command: 1=start, 2=stop, 3=home, 4=reset alarm

Slide Table Boundary Protection ​

When using a Modbus stepper motor for a linear slide table, it is recommended to enable soft limits in the Modbus sub-device configuration:

json
{
  "name": "Slide Stepper Motor",
  "sensorId": "slide_motor",
  "deviceType": "motor",
  "slaveAddress": 8,
  "motorRegs": [0, 1, 2, 5, 7],
  "motorMinPosition": 0,
  "motorMaxPosition": 10000,
  "motorCurrentPosition": 0,
  "motorMoveStep": 1600,
  "motorLastPulse": 1600,
  "enabled": true
}
  • motorMinPosition: Left boundary, in steps.
  • motorMaxPosition: Right boundary, in steps.
  • motorCurrentPosition: Current estimated position; typically set to 0 after homing.
  • motorMoveStep: Default steps per forward/reverse command.
  • motorLastPulse: Most recent setPulse count; used as fallback step size when rule does not specify pulses.

When soft limits are enabled, the system calculates the next position before sending forward/reverse commands. If it would exceed the left or right boundary, the pulse count is automatically reduced to stay within bounds; if the current position is already at a boundary, the action is rejected. Hardware limit switches and emergency stop must still be retained; software limits cannot replace physical safety protection.

Peripheral Execution Linkage ​

Periodic Back-and-Forth Motion ​

json
{
  "name": "Stepper Motor Back-and-Forth",
  "enabled": true,
  "triggers": [
    { "triggerType": 1, "timerMode": 0, "intervalSec": 10 }
  ],
  "actions": [
    { "actionType": 17, "targetPeriphId": "modbus_stepper_ctrl", "actionValue": "100:2048" },
    { "actionType": 17, "targetPeriphId": "modbus_stepper_ctrl", "actionValue": "102:1", "syncDelayMs": 200 }
  ]
}

actionValue uses the "register:value" format. For example, "100:2048" writes 2048 to register 100.

Button-Triggered Homing ​

json
{
  "name": "Button Homing",
  "enabled": true,
  "triggers": [
    { "triggerType": 4, "triggerPeriphId": "btn1", "eventId": "button_click" }
  ],
  "actions": [
    { "actionType": 17, "targetPeriphId": "modbus_stepper_ctrl", "actionValue": "102:3" }
  ]
}

Temperature Linkage (with Temperature-Controlled Roller Blind) ​

json
{
  "name": "High Temp Open Blind",
  "enabled": true,
  "triggers": [
    {
      "triggerType": 5,
      "triggerPeriphId": "modbus_th",
      "intervalSec": 30,
      "operatorType": 2,
      "compareValue": "32"
    }
  ],
  "actions": [
    { "actionType": 17, "targetPeriphId": "modbus_stepper_ctrl", "actionValue": "100:5000" },
    { "actionType": 17, "targetPeriphId": "modbus_stepper_ctrl", "actionValue": "102:1", "syncDelayMs": 200 }
  ]
}

operatorType: 2 means “greater than”; this rule triggers above 32°C.

Notes ​

  1. Driver Selection: Ensure the driver supports RS485 Modbus RTU protocol (not pulse/direction type)
  2. Register Addresses: Different brands define registers differently; always consult the corresponding manual
  3. Motion Safety: Limit switches are recommended to prevent mechanical damage from over-travel
  4. Emergency Stop: Hardware emergency stop button is essential; cannot rely on software stop alone
  5. Communication Timeout: Stepper motor execution takes time; polling interval should be ≥ 2000ms
  6. Independent Power: Motor driver power supply must be completely isolated from ESP32 power; share ground only

FastBee | fastbee.cn