
本项目构建了一个集成了RT-Thread实时操作系统的运动控制系统原型。系统通过双总线架构控制伺服电机与IO设备,并提供了基于Web的3D可视化监控界面。
核心功能架构
- 前端可视化层:采用
Three.js 技术栈,在Web端实现了机械臂运行状态的3D实时展示。
- 通信层:系统通过 MQTT 协议与主控设备进行双向数据交互,构建了稳定的上下行通信链路。
- 控制层(睿擎派):
- 通过 EtherCAT 总线 驱动伺服系统,实现对电机的精准位置、速度闭环控制,从而驱动机械臂完成指定动作。
- 通过 Modbus RTU 总线 连接IO模块,控制外围设备(如灯具)的开关状态。
RT-Thread使用情况
系统基于以RT-Thread为核心的睿擎工业平台进行开发,硬件主控模块为睿擎派,开发环境为RuiChing Studio。该平台是针对工业场景设计的软硬件一体化方案,整合了数据采集、通信、控制、工业协议、AI及显示六大功能。
本系统的嵌入式软件开发,融合了三个官方示例工程:
- 03_network_mqtt
- 06_bus_modbus_rtu_master
- 06_bus_ethercat_master_csp

硬件选型
- 主控系统:睿擎派

- 伺服驱动器:汇川 IS620NS1R6I

- 伺服电机:汇川 ISMH1 20B30CB

- IO模块:叶帆科技 YF3210-Q4 四路继电器模块

- 执行器:12V-24V LED灯泡

硬件连接拓扑

通信协议约定
WEB前端与睿擎派设备通过MQTT协议通信,主要实现远程控制伺服电机启停、速度、方向以及灯光开关。
1. 南向控制指令(JSON格式)
由Web端发布至Topic: /mqtt/command
{
“cmd”: “state”,
“argv”: 0
}
cmd 与 argv 对应关系:
“state” – 电机状态 (0:停止, 1:运行)
“dir” – 运转方向 (0:逆时针, 1:顺时针)
“pos” – 运转步长/脉冲数 (建议范围:1000 ~ 10000)
“led” – 灯状态 (0:关闭, 1:打开)
2. 北向状态上报(JSON格式)
由设备端每秒发布至Topic: /mqtt/message
{
“state”: 0, //电机状态
“dir”: 0, //运转方向
“pos”: 1000, //目标步长(脉冲)
“led”: 0, //灯状态
“error_word”: 0, //故障字
“status_word”: 0, //伺服运行状态字
“cur_pos”: 0, //电机当前位置(脉冲)
“cur_speed”: 0, //电机当前限速(脉冲/秒)
“cur_torque”: 0, //电机当前转矩
“voltage”: 0.0, //母线电压
“current”: 0.0, //相电流
“temp”: 0.0, //电机温度
“speed”: 0 //实际转速(rpm)
}
status_word 说明:
0x0023:伺服已上电,就绪
0x0027:伺服准备运行
0x0037:伺服正在运行
0x0080:伺服故障
软件开发详解
一、 睿擎派嵌入式系统开发
(1) 新建项目
基于较为复杂的 06_bus_ethercat_master_csp 示例工程创建新项目 YFMechPilot,并额外集成MQTT与Modbus RTU功能。

(2) 配置以太网接口
修改默认网口0的IP地址等信息,以适配实际网络环境,并部署到睿擎派硬件。

(3) 集成功能模块
从 06_bus_modbus_rtu_master 和 03_network_mqtt 项目中分别拷贝 modbus_rtu_master_example.c 与 paho_mqtt_example.c 文件至本项目,并重命名为 modbus_rtu_master.c 和 paho_mqtt.c。

(4) 关键代码修改
1. Modbus RTU控制LED (modbus_rtu_master.c)
增加函数,通过Modbus RTU协议控制继电器模块的第二路通道,实现对LED灯的开闭控制。
int led_control(int state){
modbus_t *ctx;
int rc;
led_status = state;
ctx = modbus_new_rtu(“/dev/uart5”, 9600, ‘N’, 8, 1);
if (ctx == NULL){
rt_kprintf(“Unable to create the libmodbus context\n”);
return -1;
}
modbus_set_slave(ctx, 1);
modbus_set_response_timeout(ctx, 1, 0);
modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
modbus_rtu_set_rts(ctx, RS485_RTS_PIN, MODBUS_RTU_RTS_UP);
if (modbus_connect(ctx) == -1){
rt_kprintf(“Connection failed\n”);
modbus_free(ctx);
return -1;
}
// 控制第二路继电器
rc = modbus_write_bit(ctx,1,state);
if (rc == -1){
rt_kprintf(“Failed to modbus_write_bit\n”);
modbus_close(ctx);
modbus_free(ctx);
return -1;
}
rt_kprintf(“modbus_write_bit rc=%d\n”, rc);
modbus_close(ctx);
modbus_free(ctx);
return 0;
}
2. MQTT客户端配置与消息处理 (paho_mqtt.c)
- 配置MQTT服务器地址(可使用EMQ提供的公共测试服务器)。
- 修改订阅与发布主题。
#define MQTT_SUBTOPIC “/mqtt/command”
#define MQTT_PUBTOPIC “/mqtt/message”
- 在
mqtt_sub_callback 函数中,解析Web端下发的JSON控制指令,并执行相应操作(控制电机状态、方向、步长及LED)。
static void mqtt_sub_callback(MQTTClient *c, MessageData *msg_data){
// … (JSON解析与字段校验)
const char *cmd = cmd_item->valuestring;
int argv = argv_item->valueint;
// 根据cmd执行不同控制逻辑
if (strcmp(cmd, “state”) == 0){
servo_run = argv; // 控制启停
} else if (strcmp(cmd, “dir”) == 0){
servo_dir = argv; // 控制方向
} else if (strcmp(cmd, “pos”) == 0){
if (argv >= 1000 && argv <= 10000){
motor_v = argv; // 设置步长(速度)
}
} else if (strcmp(cmd, “led”) == 0){
if (argv == 0 || argv == 1){
led_control(argv); // 控制LED
}
}
cJSON_Delete(root);
}
3. EtherCAT主站数据扩展 (ethercat_csp.c)
- 扩展TPDO结构体,增加母线电压、相电流、电机温度、实际转速等监控字段。
struct tpdo_csp{
uint16_t error_word;
uint16_t status_word;
int32_t cur_pos;
int32_t cur_speed;
int16_t cur_torque;
// 新增字段
uint16_t voltage; // 母线电压 (0.1V)
int16_t current; // 相电流 (0.1A)
uint16_t temp; // 电机温度 (1℃)
int16_t speed; // 实际转速 (rpm)
};
- 对应扩展
slave1_input_pdo_entries 和 slave_pdos 的定义。
- 在主控制循环中,每隔1秒将伺服驱动器的实时状态数据(包括扩展字段)封装到消息中,通过RT-Thread的邮箱机制发送给专门的数据上报任务,避免阻塞电机控制。
if (rt_tick_get() – last_ms > 1000){
last_ms = rt_tick_get();
servo_status_msg_t *msg = rt_malloc(sizeof(servo_status_msg_t));
if (msg != RT_NULL){
rt_enter_critical();
// 拷贝所有状态数据到msg
msg->servo_run = servo_run;
msg->error_word = tmap->error_word;
// … (拷贝其他字段)
msg->speed = tmap->speed;
rt_exit_critical();
rt_mb_send(status_mailbox, (rt_ubase_t)msg); // 发送到邮箱
}
}
- 创建独立的
servo_status_task 任务,从邮箱接收数据,转换为JSON格式后通过MQTT发布,实现了控制与上报的解耦。
static void servo_status_task(void *param){
servo_status_msg_t *msg = RT_NULL;
while (1){
// 等待邮箱消息
if (rt_mb_recv(status_mailbox, (rt_ubase_t *)&msg, RT_WAITING_FOREVER) == RT_EOK){
char *json_str = msg_to_json(msg); // 生成JSON
if (json_str != NULL){
mq_publish(json_str); // MQTT发布
rt_free(json_str);
}
rt_free(msg); // 释放内存
}
}
}
二、 Web前端开发(Vue 3 + Three.js)
前端系统构建了一个集3D可视化、远程控制、实时监控于一体的Web应用。
1. 核心目标
- 直观展示伺服电机与机械臂的运行状态。
- 提供人机交互界面,远程执行启停、调速、换向、灯光控制。
- 通过MQTT实时同步设备数据,驱动3D场景联动更新。
- 具备通信异常检测与自动安全处理机制。
2. 技术栈与架构
- 框架:Vue 3 (Composition API) 负责UI与状态管理。
- 3D渲染:Three.js 用于加载模型(FBX)、构建场景、控制动画。
- 通信:
mqtt.js 库连接MQTT服务器,实现双向通信。
- 数据流:
- 下行:订阅
/mqtt/message,解析设备状态,更新Vue响应式数据并驱动3D动画。
- 上行:用户操作触发
sendMqttCommand,发布 {cmd, argv} 到 /mqtt/command。
3. 关键功能实现
- 3D场景与动画:使用
AnimationMixer 控制电机与机械臂模型动画,速度(pos)、方向(dir)实时映射到动画的 timeScale。
- 状态联动:根据
status_word 切换运行状态提示;根据 led 状态控制场景中点光源与灯泡模型明灭。
- 控制面板:提供按钮组件,调用
sendMqttCommand 发送对应指令。
- 数据监控面板:实时显示转速、扭矩、电压、温度等数据,并将状态码转换为中文描述。
- 安全机制:设置心跳超时检测(3秒),超时或MQTT连接断开时自动停止所有动画并告警。
系统演示与部署
效果展示


部署与运行步骤
- 将编译好的嵌入式程序部署到睿擎派。
- 在睿擎派终端依次执行:
mqtt_init # 初始化MQTT连接
ect_csp # 初始化EtherCAT主站与伺服驱动器

- 在浏览器中打开Web前端应用URL。
- 在Web界面中进行电机启停、调速、换向、灯光开关等操作,观察3D机械臂的同步响应与实时数据变化。

演示视频与代码