当前位置:首页 > 通信技术 > 通信技术
[导读]在小型自动化产线中,经常需要把多台温湿度、压力、流量传感器通过RS485总线汇总到FX3U PLC,再由上位机(PC/网关)统一轮询读取。三菱FX系列内置编程口默认走MC协议(9600/7/E/1),但若传感器是自定义串口协议或第三方非标设备,更实用的做法是:PLC侧用RS指令做无协议通信,自定义"帧头+站号+功能码+数据+CRC"的轻量协议,把多传感器数据汇聚到D寄存器区,再由上位机读取。本文以FX3U-485-BD + RS485总线为例,给出可落地的完整方案。


在小型自动化产线中,经常需要把多台温湿度、压力、流量传感器通过RS485总线汇总到FX3U PLC,再由上位机(PC/网关)统一轮询读取。三菱FX系列内置编程口默认走MC协议(9600/7/E/1),但若传感器是自定义串口协议或第三方非标设备,更实用的做法是:PLC侧用RS指令做无协议通信,自定义"帧头+站号+功能码+数据+CRC"的轻量协议,把多传感器数据汇聚到D寄存器区,再由上位机读取。本文以FX3U-485-BD + RS485总线为例,给出可落地的完整方案。

一、硬件连接与通信参数

FX3U本体不带RS485,需加装FX3U-485-BD通信板。RS485为差分信号,总线拓扑下所有站点A-A、B-B并联,末端并联120Ω终端电阻,屏蔽层单点接地。

通信参数通过特殊寄存器D8120配置,必须在PLC上电初始化时写入一次:

MOV H0081 D8120   ; 9600bps, 8数据位, 1停止位, 无校验, 无协议, RS485

H0081的位含义:bit0-3=0(无协议)、bit4-6=8位数据、bit7=无校验、bit8=1停止位、bit9-11=9600bps。D8120写入后需断电重启生效。

⚠️ 注意:FX编程口(RS422)默认是9600/7/E/1的MC协议,D8120只控制通道1的RS指令无协议通信,两者参数相互独立,别混淆。

二、自定义协议帧格式

为支持多传感器轮询,定义如下帧格式(16进制):

字段 长度 说明

Header 1B 固定0xAA

SlaveID 1B 传感器站号 0x01-0x0F

Function 1B 0x01=读数据,0x02=写命令

Length 1B 数据域字节数

Data N×B 传感器数据(如温度、湿度、状态)

CRC16 2B Modbus式CRC校验

PLC作为主站,主动向各站号传感器发送读命令,收到应答后解析并存入D区。

三、PLC侧RS指令编程

FX3U的RS指令(FNC 80)是实现无协议通信的核心:

RS D100 D0 D200 D1

D100:发送数据起始地址

D0:发送数据长度(点数)

D200:接收数据起始地址

D1:接收数据最大长度

关键特殊软元件:

M8122:发送请求标志,置ON触发发送,发送完成后自动复位(切勿在程序中手动复位)

M8123:接收完成标志,置ON后必须手动复位,否则无法接收下一帧

M8129:超时标志

M8161:8位/16位处理模式切换

梯形图核心逻辑(ST语言示意):

// 初始化

IF M8002 THEN

   MOV H0081 D8120;       // 配置通信格式

   MOV K0 D0;             // 发送长度初始0

END_IF;


// 轮询触发(每500ms轮询下一个传感器)

IF T0 THEN

   INC D10;               // 当前站号指针

   AND D10 K0F;           // 限制在1-15

   CALL P0;               // 调用组帧子程序

END_IF;


// 组帧子程序P0:把 0xAA + StationID + 0x01 + Len + CRC 写入D100~

P0:

   MOV K0AA H0 D100;      // 帧头

   MOV D10 D101;          // 站号

   MOV K01 D102;          // 功能码:读

   MOV K02 D103;          // 数据长度

   CALL CRC16;            // 计算CRC16写入D104,D105

   MOV K6 D0;             // 发送6字节

   SET M8122;             // 触发发送

   RET;


// 接收处理

IF M8123 THEN

   // 解析D200~D205,提取传感器数据

   MOV D201 D300;         // 例如温度存入D300

   MOV D202 D301;         // 湿度存入D301

   RST M8123;             // 必须手动复位!

END_IF;

M8123必须手动复位是新手最常踩的坑——不复位,下一帧数据永远不会进来。

四、上位机Python轮询读取

上位机通过编程口(MC协议)或RS485监听PLC汇总的D区数据。若直接对接传感器,则用Python模拟PLC的主站行为:

import serial, time, crcmod


class SensorPoller:

   def __init__(self, port='/dev/ttyS0', baud=9600):

       self.ser = serial.Serial(port, baud, bytesize=8,

                                parity='N', stopbits=1, timeout=1)

       self.crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF)


   def read_sensor(self, slave_id):

       # 组帧: AA + ID + 01 + 00 + CRC_L + CRC_H

       frame = bytes([0xAA, slave_id, 0x01, 0x00])

       crc = self.crc16(frame)

       frame += bytes([crc & 0xFF, crc >> 8])

       self.ser.write(frame)


       # 等待应答

       resp = self.ser.read(12)  # 假设应答12字节

       if len(resp) < 6 or resp[0] != 0xAA:

           return None

       # 校验CRC

       if self.crc16(resp[:-2]) & 0xFFFF != (resp[-2] | resp[-1] << 8):

           return None

       return resp[4:-2]  # 返回数据域


   def poll_all(self, slave_ids):

       results = {}

       for sid in slave_ids:

           data = self.read_sensor(sid)

           if data:

               results[sid] = {

                   'temp': data[0] * 256 + data[1],   # 大端温度

                   'humidity': data[2],

                   'status': data[3]

               }

           else:

               results[sid] = {'error': 'timeout'}

           time.sleep(0.05)  # 帧间隔,避免总线冲突

       return results


# 使用示例

poller = SensorPoller('/dev/ttyS0')

data = poller.poll_all([0x01, 0x02, 0x03, 0x04])

print(data)

关键点:

每帧之间需留20-50ms间隔,RS485半双工总线避免冲突

CRC16校验必须软硬件一致,传感器端通常用Modbus CRC

超时重发机制:连续3次失败标记传感器离线

五、PLC D区数据上交上位机

如果不想在上位机直接轮询传感器,而是让PLC做汇聚,上位机只需读D区:

# 使用python-snap7或自编MC协议读取D300~D320

# 这里以伪代码示意

for i in range(21):

   value = read_plc_d_register(300 + i)

   print(f"D{300+i} = {value}")

PLC程序需周期性地把各传感器最新值刷新到D300开始的连续寄存器区,配合时间戳和状态字。

六、调试三步走

串口调试助手验证:先用SSCOM/XCOM模拟主站,向传感器发帧,确认应答格式和CRC

PLC端RS指令单步:监视D100~D105发送内容、D200~D205接收内容,用M8123的ON/OFF确认接收正常

总线抓包:RS485总线挂逻辑分析仪或USB-RS485适配器,抓全帧分析时序

七、高频踩坑

⚠️ 坑1:D8120配置错误——MCU和PC端参数必须完全一致(波特率、数据位、校验、停止位),否则满屏乱码。

⚠️ 坑2:M8123未复位——接收一帧后必须RST M8123,否则后续数据全部丢失。

⚠️ 坑3:M8122手动复位——M8122发送完成后自动OFF,程序中若手动RST会打断发送过程。

⚠️ 坑4:RS485方向控制——DE/RE引脚时序要精确,发送完最后一字节再切换为接收,否则末尾字节丢失。

写在最后

用FX3U的RS指令做自定义协议的多传感器轮询,本质是把PLC变成"串口网关"——前端用自定义轻量协议与传感器对话,后端把汇聚数据放入D区供上位机读取。这套方案的成本极低(一片FX3U-485-BD约百元),却能稳定管理RS485总线上的十余个传感器节点。相比直接使用Modbus RTU从站协议,自定义协议更灵活:你可以把设备状态、报警标志、采样时间戳打包进一帧,减少轮询次数。当你的产线从"3个传感器"扩展到"30个传感器"时,只需在PLC轮询表里多加几条CALL,上位机侧逻辑零改动——这才是模块化设计真正的威力。

对于FX5U等新型号,无协议通信升级为RS2指令,并支持Modbus RTU主站ADPRW指令,若传感器原生支持Modbus,直接用ADPRW更省力;若是非标串口设备,RS2的自由度与RS指令一致,程序思路完全可迁移。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭