Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SC3U Modbus TCP 只读核心模块

本项目为雷赛 SC3U-60A12D PLC 提供独立的 C++17 Modbus TCP 读取核心模块。它用于上位机读取 PLC 的本体输入、M 辅助继电器和 D 字寄存器;后续 Qt 客户端只需链接 sc3u_modbus,无需依赖 QtNetwork。

安全边界:项目没有实现 Modbus 写线圈或写寄存器功能,不会经由网络改变 PLC 状态、输出或运动控制命令。

能力范围

Qt 客户端 / 控制台程序
          │ 调用 C++ 接口
          ▼
sc3u_modbus(持久 TCP 连接、报文校验、地址解析)
          │ Modbus TCP,只读功能码 01 / 02 / 03 / 04
          ▼
SC3U-60A12D(Modbus TCP 从站)
          │
          ├─ X:现场传感器与开关量输入
          ├─ M:PLC 内部布尔状态
          └─ D:PLC 内部 16 位数值

核心模块只保留以下读取功能:

方法 Modbus 功能码 读取对象
readCoils / readMbits 0x01 M、Y、B、S 等线圈;本项目优先封装 M
readDiscreteInputs / readXbits 0x02 X 本体输入
readHoldingRegisters / readDwords 0x03 D、R 字寄存器;本项目优先封装 D
readInputRegisters 0x04 输入寄存器

地址映射

LeadStudio V3.1 默认采用“通讯地址兼容模式一”。此模式下软元件编号并不总是等于 Modbus 地址,模块通过 AddressResolver 统一换算,禁止调用方自行猜测偏移。

PLC 变量 截图中的地址 功能码 模式一 Modbus 地址 说明
RC_FeedRightRev M721 0x01 0x0AD1 布尔状态
RC_FeedRightValue D610 0x03 0x1262 INT,有符号 16 位
RC_FeedLeftValue D611 0x03 0x1263 INT,有符号 16 位
本体输入 X0X43 0x02 0x0400 起连续 36 位 传感器/开关量输入

模式一存在不连续区间:M1535M1536D4095D4096 之间不能用一条 Modbus 请求连续读取。核心模块会主动拒绝跨越这些边界的高层 readMbitsreadDwords 请求,调用方应拆分为两次读取。

若 PLC 工程切换到“模式二”,调用时必须显式传入 sc3u::AddressMode::ModeTwo。例如:

const auto flags = client.readMbits(721, 1, sc3u::AddressMode::ModeTwo);

构建

MinGW

cmake -S . -B build -G Ninja -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Debug
cmake --build build --parallel 2
ctest --test-dir build --output-on-failure

MSVC

在“x64 Native Tools Command Prompt for VS”中执行:

cmake -S . -B build-msvc -G Ninja -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Debug
cmake --build build-msvc --parallel 2
ctest --test-dir build-msvc --output-on-failure

运行最小示例

先确认 PLC IP,再运行:

.\build-msvc\sc3u_read_demo.exe 192.168.1.3

示例会建立一条 TCP 连接,并只读输出:

  • X0X43 的 36 路本体输入;
  • M721,即截图中的 RC_FeedRightRev
  • D610D611,即截图中的两个 INT 数值变量。

192.168.1.3 只是硬件手册中的 eth0 出厂地址;实际运行必须以现场配置为准。

详细日志

每个 sc3u::Client 默认将详细通信日志输出到控制台,包含连接、M/X/D 地址映射、Modbus 请求/响应帧、事务号、响应校验、异常和断线。原始报文以十六进制输出,便于将上位机日志与抓包结果对照。

控制台输出无需额外配置:

sc3u::Client client({"192.168.1.3", 502, 1, std::chrono::milliseconds{3000}});

仅写入指定文件:

sc3u::Endpoint endpoint{"192.168.1.3", 502, 1, std::chrono::milliseconds{3000}};
endpoint.logging.destination = sc3u::LogDestination::File;
endpoint.logging.filePath = "log/plc.log";
sc3u::Client client(std::move(endpoint));

日志文件的父目录不存在时会自动创建;文件以追加方式写入,不会覆盖既有现场记录。

同时写入控制台与文件:

endpoint.logging.destination = sc3u::LogDestination::ConsoleAndFile;

若高频轮询导致日志量过大,可保留连接和错误日志,但关闭原始报文输出:

endpoint.logging.includeRawFrames = false;

Qt 集成

核心库没有 Qt 依赖。Qt 工程使用 CMake 时,可将本项目作为子目录并链接目标:

add_subdirectory(path/to/upper)
target_link_libraries(your_qt_target PRIVATE sc3u_modbus)

在 Qt 的工作线程中创建并使用一个 sc3u::Client。同一个实例不要跨线程共享:它维护持久 TCP 连接和递增事务编号,跨线程并发调用会破坏请求与响应的对应关系。

sc3u::Client client({"192.168.1.3", 502, 1, std::chrono::milliseconds{3000}});

const auto sensors = client.readXbits("X0", 36);
const auto enabled = client.readMbits(721, 1);
const auto feedValues = client.readDint16(610, 2);

PLC 侧前提

  1. 在 LeadStudio 的“设备 -> 系统配置”中确认“通讯地址兼容模式”为“模式一”。
  2. Ethernet 下添加并启用 ModbusTcpSlave,PLC 作为 Modbus TCP 服务端。
  3. 确认 PLC 的实际 IP;客户端默认使用端口 502、站号 1
  4. 将上位机网卡设置为与 PLC 相同网段,且不与任何现有设备冲突。
  5. 先在 LeadStudio 在线监控中确认目标 X/M/D 变量确实随现场传感器变化;通信模块只能读取 PLC 当前已采集的数据。

技术选型与风险

为什么采用独立 C++ 套接字实现

  • 原因:核心层不绑定 Qt,Qt Widgets、Qt Quick、命令行工具或服务程序都可复用。
  • 优势:没有第三方运行时依赖;使用持久 TCP 连接,避免高频轮询时反复握手;对 MBAP 长度、事务编号、站号、功能码和响应字节数逐项校验;默认详细日志便于现场定位。
  • 风险:地址兼容模式或 Modbus 从站未正确配置时,会出现超时或非法地址异常;高频轮询时保留原始报文会产生较多日志;现场网络应与办公网络隔离,避免非授权设备访问 PLC。

故障定位顺序

  1. 超时或连接失败:检查网线、交换机、电脑与 PLC 网段、PLC IP、端口 502 与 Modbus TCP 从站使能状态。
  2. Modbus 异常码:检查地址兼容模式、功能码与软元件类型是否匹配,以及是否跨越模式一的地址断层。
  3. 能读取但数值不对:确认变量数据类型;D610 是有符号 INT,模拟量还需要按 PLC 程序的量程和比例换算。
  4. 输入不变化:先在 LeadStudio 中确认对应 X 输入灯、变量或程序映射是否变化,再检查上位机读取。

本地验证

以下验证已由本地自动执行:

  • MinGW 与 MSVC 均可编译;
  • CTest 覆盖地址映射、M/D 地址断层、请求帧、位/字解析和 Modbus 异常响应;
  • 回环模拟 PLC 覆盖真实 TCP 连接、M721 -> 0x0AD1 请求及响应解析;
  • 源文件为 UTF-8 无 BOM,公开接口不包含 Modbus 写功能码。

真实 PLC 尚未连接到开发环境,因此现场仍需执行“运行最小示例”完成最终联机验证。

资料来源

About

SC3U-60A12D上位机程序

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages