
1. 从 CODESYS 到数据落库RealPLC Agent 到底解决了什么问题搞工控的应该都有过这种时刻现场一台汇川 PLC 跑得好好的程序里几十上百个变量客户突然说要记录温度、压力、电机启停状态还得按小时汇总存数据库。这时候你打开 CODESYS翻出各种通信库、Modbus 映射表、OPC UA 配置一圈折腾下来半天没了变量一改还得重新对地址。RealPLC Agent 这个工具解决的恰恰就是这段最枯燥的衔接工作——把 CODESYS 工程里的变量结构直接吃进来自动生成采集配置让数据从 PLC 变量表一路顺到 MySQL 表里。这篇内容适合三类人看第一类是刚接触 CODESYS 的电气工程师手上的项目用的是汇川或者类似支持 CODESYS 平台的控制器想把运行数据存起来但不知道从哪下手第二类是做过组态或 SCADA、现在想换成更轻量采集方案的老手需要一份能直接抄的配置清单第三类是自动化集成商的技术负责人评估这个方案能不能嵌进自己的交付流程里。整篇不讲空泛概念重点放在 CODESYS 侧的符号配置怎么摆、库文件怎么生成、RealPLC Agent 怎么读变量、数据怎么进 MySQL以及那些文档里不会写、只有踩过才明白的细节。我先把这个方案的边界说清楚免得你照着做却发现方向不对。RealPLC Agent 不是替代 CODESYS 编程的它不参与逻辑控制只负责采集和转发。你的 PLC 逻辑该在 CODESYS 里写还在 CODESYS 里写Agent 只是站在旁边“旁听”变量值。它读取变量的方式依赖 CODESYS 暴露出来的符号信息所以符号配置这一步是整个链路的地基。地基建歪了后面怎么调都是白费。从数据流的角度看整条链路是这样的CODESYS 里定义全局变量并生成符号信息RealPLC Agent 通过通信协议常见是 Modbus TCP、ADS 或 OPC UA具体看你的 PLC 支持哪个拿到变量值然后按配置写入 MySQL。中间任何一个环节的命名、类型、地址对不上都会卡住。热词里出现的“plc-recorder 读取 codesys 变量”“mysql 的 alongwu 第三方库”这些其实都是同一条链路的不同环节标签从业者在搜索这些词的时候真实诉求基本都是“我想让变量值稳定落库但某一步卡住了”。这个方案的典型优势有三点。部署成本低不需要上一整套 SCADA 组态软件一台工控机或者树莓派级别的设备就能跑。配置可读性强采集点用变量名而不是裸地址来表达维护的时候看得懂。改动响应快PLC 侧加了变量只需要更新符号配置再同步一次不用大动干戈重新画通信映射表。这三点决定了它在中小规模数据采集场景里比传统方案更省事尤其是那种几十到几百个采集点、需要按时入库但不要求毫秒级实时性的项目。2. 核心原理拆解符号配置、变量寻址与数据通道2.1 CODESYS 符号配置为什么是整条链路的起点CODESYS 的变量在程序里是以符号名存在的比如GVL_Tank.fTemperature但在通信层面上PLC 只认地址。要让外部工具按符号名取值就必须有一份“符号到地址”的映射这份映射就是符号配置的产物。你可以把它理解成一本电话簿Agent 想找“张三”电话簿告诉它“张三的号码是 4001”于是它拨 4001。没有这本簿子Agent 只能挨个号码问“你是谁”效率低到没法用。CODESYS 生成符号信息一般走两个途径。一个是在工程里启用符号配置Symbol Configuration勾选需要对外暴露的变量然后编译生成.xml或类似格式的符号描述文件。另一个是通过 OPC UA 服务器功能直接对外发布变量节点Agent 连上后遍历节点树。两条路各有取舍前者适合变量固定、结构清晰的场景后者适合变量会动态增减、希望自动发现的场景。汇川 PLC 的 CODESYS 工程两种都支持但实测下来中小企业项目里符号配置那条路更稳因为它不依赖 PLC 侧的 OPC UA 授权和额外资源占用。这里有个非常关键的坑符号配置里能勾的变量必须是在“全局变量列表”GVL里定义的局部变量比如函数块内部的VAR默认不会出现在符号配置的可选清单里。我见过不少人把采集点写在某个功能块内部然后纳闷为什么符号配置里找不到——不是工具的问题是变量作用域的问题。解决办法很简单把需要采集的变量统一挪到 GVL 里或者通过功能块的输出引脚引出到全局变量。2.2 变量类型与字节对齐的隐藏影响符号配置里每个变量都带着数据类型和偏移地址数据类型决定了占多少字节偏移地址决定了从哪个位置开始读。听起来很直白但字节对齐这件事会咬人。CODESYS 在排布变量时为了访问效率会对某些类型做对齐处理比如一个BOOL后面跟一个REALREAL可能会从 4 字节边界开始导致中间空出几个字节。如果你的 Agent 侧是按“连续读取 N 个字节然后按顺序解析”的粗暴逻辑这些空隙就会被当成变量值读错。正确的做法是让 Agent 严格按照符号配置里给出的偏移和长度逐个取值而不是自己算连续区间。RealPLC Agent 在实际使用中就是按符号表逐项寻址的这样即使有空隙也不影响。但如果你用的是自己写的脚本去读就一定要解析符号文件里的偏移字段别偷懒用累加。我一般会在符号配置生成后用记事本打开看一眼确认Offset和Size字段和预期一致尤其注意BOOL密集排布的区域。另一个常见类型是字符串。CODESYS 里STRING默认长度是 80 字节WSTRING是 160 字节而且末尾有固定的结束符。采集字符串类型变量时字节数算错就会把后面的变量值一起吃进来。如果只是采集数值类变量建议干脆不要暴露字符串省得给自己找麻烦。真要采字符串就在 CODESYS 侧先处理好比如截断到固定长度或者转成数值编码。2.3 通信方式的选型逻辑从 PLC 到 Agent 这一段可选的方式主要有三种Modbus TCP、OPC UA、以及厂商私有的 ADS 类协议。选哪个不是拍脑袋要看你手上 PLC 的具体型号和授权情况。通信方式适用场景优点局限Modbus TCP变量已映射到保持寄存器通用性强几乎所有 PLC 支持需要手工维护寄存器地址映射变量名丢失OPC UA变量需按名访问结构较复杂保留符号名支持类型信息PLC 侧需支持并开启资源占用相对高私有 ADS同品牌生态内读取效率高支持符号寻址跨品牌兼容性差RealPLC Agent 对这三种都有对应的连接配置实际选型时我的建议是如果 PLC 本身支持 OPC UA 或者有配套的符号寻址通道优先用它因为符号名能一直保留到入库出问题好排查。如果只能用 Modbus TCP那就要在 CODESYS 侧多花功夫做寄存器映射把变量地址整理成一张对照表后期维护成本会明显上升。汇川 PLC 在很多型号上对符号寻址支持得不错这也是热词里“汇川 plc codesys”频繁出现的原因——大家用这个组合恰好是因为它在这条链路上比较顺。2.4 数据落库MySQL 表结构与写入节奏数据进了 Agent 之后最终要落到 MySQL。这里的核心设计点是表结构怎么定、写入频率怎么控。表结构我一般分两种思路宽表模式和窄表模式。宽表模式是一行对应一个采样时刻每个变量占一列比如ts, temp1, press1, motor_status...。优点是查询直观一个时间段的数据一条 SQL 就出来了。缺点是变量增减要改表结构采集点多了列数爆炸。窄表模式是一行对应一个“时刻 变量名 值”优点是变量增减不用动表结构灵活。缺点是查询和聚合要写得更绕单点数据量大时行数膨胀得快。对于采集点相对固定、数量在几十个以内的项目我倾向宽表简单直接。对于采集点会持续增加、或者变量来自多个设备的情况窄表更合适。RealPLC Agent 的写入配置里通常允许你指定表名和字段映射具体用哪种模式由你在 MySQL 侧建表时决定Agent 只负责按映射写数据。写入节奏上也要控制。别让 Agent 每个 PLC 扫描周期都往数据库写一次那样数据库很快就被冲垮。合理的做法是按时间间隔批量写入比如 1 秒或 5 秒一批或者按变化触发写入——只有值变了才落库。变化触发能大幅减少无效数据量但对“值长时间不变但需要证明设备在线”的场景不友好这时候可以加一条心跳记录每隔固定时间写一行时间戳。3. 手把手实操从零打通采集链路3.1 CODESYS 侧的准备工作第一步是在 CODESYS 工程里把要采集的变量集中到全局变量列表。新建一个 GVL命名要有规律比如GVL_Data然后把你关心的变量都放进去。命名我强烈建议用英文加下划线别用中文或者拼音缩写因为后面 Agent 侧、数据库字段都会引用这个名中文在跨系统传递时容易出编码问题。变量名要表达含义temp1这种就不如Tank1_Temperature清晰。第二步是打开符号配置。在工程树里找到 Symbol Configuration 对象双击进入勾选刚才那个 GVL然后勾选需要对外暴露的具体变量。这里有一个细节如果你希望 Agent 能读到变量的类型信息要把“支持 OPC UA”或对应选项打开这样生成的符号描述里会带类型元数据。全部勾好后编译工程符号文件会跟着生成路径一般在工程目录下的某个子文件夹里文件名类似Symbols.xml。第三步是确认 PLC 侧的通信端口已经开放。如果是 Modbus TCPCODESYS 里要添加 Modbus TCP Slave 设备并配置寄存器映射如果是 OPC UA要在 PLC 设置里启用服务器并设置端口。这一步经常被忽略结果是 Agent 那边连接一直超时。我的习惯是配置完先用一个通用的调试工具连一下确认端口通、有响应再去配 Agent这样能把问题域缩小到一半。3.2 生成库文件与符号描述的处理热词里“codesys 如何生成库文件”问的人不少这里要分清楚库文件Library和符号描述文件是两回事。库文件是给 CODESYS 工程编译用的.library文件里面封装的是功能块和函数符号描述文件是给外部工具读变量用的结构化描述。RealPLC Agent 需要的是后者不是前者。有些人把“生成库文件”理解成要给 Agent 生成一个专用库这是误解。如果你确实需要生成 CODESYS 库文件比如想把某段逻辑封装复用到多个工程流程是新建一个 Library 类型的工程把功能块写好然后在工程属性里设置版本号和命名空间最后编译输出.library。这个库给自己的工程用和 Agent 采集没有直接关系别把它当成采集链路的必要步骤。Agent 要的是符号配置编译后产出的那个 XML 或类似结构路径找对就行。拿到符号描述文件后可以直接用文本编辑器打开检查。里面每个变量应该能看到名字、数据类型、偏移、大小这几项。我一般会拿它和 Excel 里的采集点清单对一遍确认没有遗漏、没有多余的变量。这个对照动作花不了几分钟但能省掉后面调试时的大量猜谜时间。3.3 RealPLC Agent 的连接配置Agent 侧的配置一般分三块连接参数、变量映射、数据输出。连接参数这块你要填 PLC 的 IP、端口、协议类型以及超时和重试次数。超时别设太短工业现场网络抖动是常态设个 3 到 5 秒比较合适重试 2 到 3 次。协议类型要和 PLC 侧开放的方式一致选错了连不上。变量映射这块Agent 通常支持导入符号描述文件自动生成映射或者你手工填变量名和对应地址。有自动导入就用自动导入省事且不易错。导入后逐项核对变量名和数据类型重点检查BOOL、REAL、INT这几类最常用的类型有没有映射对。如果发现某个变量类型显示为未知多半是符号描述里缺类型信息回 CODESYS 侧把对应选项打开重新编译。数据输出这块填 MySQL 的连接信息、目标表名、字段映射关系。字段名和变量名的对应关系建议保持一定规则比如变量Tank1_Temperature对应字段tank1_temperature全小写加下划线方便写 SQL 时不用加引号。时区也要注意Agent 和 MySQL 如果时区设置不一致写进去的时间戳会漂这个后面问题排查章节细说。3.4 MySQL 表结构的建立与验证建表这件事给出一个宽表模式的参考结构CREATE TABLE plc_data ( id BIGINT AUTO_INCREMENT PRIMARY KEY, ts DATETIME(3) NOT NULL, tank1_temperature FLOAT, tank1_pressure FLOAT, motor1_status TINYINT, line_speed FLOAT, INDEX idx_ts (ts) );ts字段用DATETIME(3)保留毫秒精度因为工业数据对时间顺序比较敏感。给ts加索引是必须的否则按时间段查询会全表扫描。数值型字段用FLOAT还是DOUBLE看你精度要求一般FLOAT够用状态类用TINYINT省空间。表建好后先不急着让 Agent 大规模写入。手工插一行测试数据然后用查询语句确认能查出来、时间字段显示正常。再启动 Agent 小批量采集观察数据是不是按预期落进来。我会盯着看几分钟的表数据确认数值没有明显异常比如温度显示成几万、状态位一直是乱值这些往往是类型或字节序没对上导致的。确认无误后再放开采集频率。3.5 从测试到上线的过渡检查上线前有一套我必做的检查清单。PLC 侧符号配置的变量和实际采集需求逐条核对确认没有把调试用的临时变量也勾进去。Agent 侧连接断开重连是否正常工作可以手工拔一下网线再插上看 Agent 能否自动恢复采集。数据库侧确认存储空间够用按每天的数据量估算一下能存多久必要时上分区表或定期清理策略。还有一个容易漏的点是权限。Agent 用的数据库账号要有目标表的INSERT权限不要图省事给 root。账号权限最小化是基本习惯采集账号只给采集表的写权限即可改数据、删数据的权限都不给。这样即使 Agent 配置出问题也不会误伤其他数据。4. 踩坑实录常见问题与排查技巧4.1 连接类问题速查连接不上是最高频的问题我把常见的几种和排查路径整理成表。现象可能原因排查动作连接超时IP 或端口填错、防火墙拦截ping 通 PLC用调试工具测端口连接成功但读不到变量符号描述未导入或变量未勾选检查符号配置重新编译生成读取值全为零地址偏移对不上、字节序错核对符号文件里的偏移字段读到的值是乱码类型解析错误、字符串处理不当检查变量类型映射间歇性断连网络抖动、PLC 负载高增大超时和重试检查网络质量有一类问题特别隐蔽PLC 上电顺序导致的连接失败。如果 Agent 比 PLC 先启动Agent 初次连接时 PLC 还没就绪连接直接失败之后如果 Agent 没有重连逻辑就一直挂着不动了。解决办法是让 Agent 具备周期性重连能力或者给 Agent 配置启动延迟等 PLC 起来再连。这个细节在文档里通常一笔带过但在无人值守的现场是会出大事的。4.2 变量读取异常的处理思路变量读到了但值不对这一类问题的排查要按“先看类型、再看偏移、最后看字节序”的顺序来。类型问题最常见比如把REAL当INT解析读出来就是一个莫名其妙的大整数。偏移问题次之通常是符号描述和实际 PLC 程序版本不一致导致的——你改了 CODESYS 工程但没重新生成符号文件Agent 还在用旧映射偏移自然就错位了。字节序问题相对少但跨品牌设备时会出现大端小端没对齐浮点数读出来就是科学计数法里的怪值。我处理这类问题的习惯是拿单个变量做“单位测试”。先只配置一个变量用已知的物理值去验证比如手动把某个温度变量设成 25.0看 Agent 读出来是不是 25.0。一个变量通了再逐步加量。这样能把问题定位到具体变量而不是在一堆变量里大海捞针。4.3 数据库写入的典型故障数据写不进 MySQL先分清楚是连接问题还是 SQL 问题。连接问题看账号密码、端口、网络SQL 问题看表名、字段名、数据类型是否匹配。有一个坑是字段名和 MySQL 保留字撞车比如字段名叫order或者key不写反引号就会报语法错误。避开这种命名或者建表时统一用反引号包裹字段名。时区问题是另一个高频坑。MySQL 默认时区可能是 UTC而 Agent 写入用的是本地时间两边差 8 小时查出来的数据时间全对不上。解决办法是统一时区要么在 MySQL 连接串里指定时区要么把服务器和 Agent 都设成同一时区。我一般在 Agent 侧把时间统一转成 UTC 再写查询时再按需转成本地时间这样跨时区部署也不会乱。写入性能方面如果发现数据库写入延迟越来越高检查两件事一是是否每来一个值就单独写一次改成批量写二是表上是不是有太多索引拖慢了插入只保留查询必需的索引。数据量大的项目可以考虑先写入临时表再定期归档到主表减少主表的写压力。4.4 CODESYS 侧改动的同步问题PLC 程序改动是常态改了变量之后符号配置和 Agent 映射都得跟着更新。这里的坑在于“忘了同步”这个动作。我见过不止一次工程师在 CODESYS 里加了新变量、改了旧变量但符号文件没重新生成Agent 那边还是老配置结果新变量采不到旧变量采到的是错位的值。所以流程上要定一个规矩任何涉及采集变量的改动都必须走“改程序—重新编译符号—更新 Agent 映射—验证数据”这四步少一步都不行。如果采集点数量大手工同步映射很费时可以考虑把符号描述文件的解析和 Agent 配置生成做成脚本自动化。符号文件本身是结构化的文本写个脚本按需提取变量名和地址生成 Agent 的配置文件变量一多就能体现出价值。这一步属于进阶优化项目稳定运行后再做也不迟。4.5 长时间运行的稳定性维护采集系统跑起来容易稳定跑几个月不容易。长期运行我关注几个指标Agent 进程内存占用是否持续增长数据库表数据量是否超出预期采集延迟是否逐渐变大。内存持续增长通常是连接句柄或者日志缓存没释放定期重启能缓解但治标不治本得看 Agent 是否有对应的日志级别设置把调试日志关掉能省不少内存。数据量控制上设定一个保留策略比如只保留最近 90 天的明细数据更早的做聚合归档。聚合表按小时或按天存平均值、最大值、最小值这样既保留了趋势又控制了主表规模。这个策略在建表阶段就该想好别等数据堆到几个 G 才动手那时清理和迁移都麻烦。日志这块也值得说一句。Agent 的日志要分级正常运行只记错误和关键事件调试时才开详细日志。日志文件要设滚动策略不然一个日志文件涨到几个 G排查时打开都卡。我一般按天滚动保留最近两周够用又不会占太多空间。5. 关于这套方案的选型体会与扩展方向说到选型我的实际体会是RealPLC Agent 这类轻量采集工具最适合的场景是采集点规模中等、实时性要求不苛刻、团队没有专职 SCADA 维护人员的项目。如果你的项目要求毫秒级响应、需要复杂的报警联动和画面组态那还是老老实实上完整的 SCADA 系统工具和需求要匹配硬用小马拉大车只会让后期维护痛苦。汇川 PLC 配合 CODESYS 再用这套方案做采集在我经手的几个项目里跑得比较顺核心原因就是符号寻址这条链路打通之后变量名的可读性一直保留到数据库出了问题能一路追溯回去。相比之下纯 Modbus 寄存器映射的方案一旦变量多了维护成本会指数上升。后续如果要把这套东西做得更完善我会往两个方向扩展。一个是采集侧的自动化同步把 CODESYS 符号文件的解析和 Agent 配置生成脚本化变量改动后一键同步。另一个是消费侧的可视化数据进了 MySQL 之后用 Grafana 之类的工具直接看图省去自己写查询页面的功夫。这两步做完一个中小规模的 PLC 数据采集与展示链路就完整了投入不大覆盖面却挺广。数据库类库那些第三方封装比如热词里提到的 alongwu 那类可以作为快速接入的辅助但底层还是建议先理解原生连接和 SQL 写法依赖封装能提速理解原理才能排错。