简介在工业现场数据对接项目中KEPServer与MySQL、西门子PLC之间的数据联通是常见又容易出错的环境这份doc文档正好围绕这些场景提供了系统化的配置参考。文档重点覆盖了主备切换、MySQL与西门子PLC双向读写、后台服务设置以及地址值填写四类问题面向工业自动化工程师、系统集成商和负责工控数据链路的运维人员适合在搭建数据采集、反控PLC或高可用冗余系统时查阅。资源包共包含1个doc文件压缩后仅1.9MB携带方便目前已有728人浏览学习。内容按目录模块展开从Kepserver使用配置、功能解析到连接访问MySQL、连接西门子S7-1500 PLC、Data logger数据映射、MySQL反控PLC均有图文说明其中还涉及32位ODBC驱动配置、通道/设备/标记三层结构、静态表与动态表选择、触发器设置及QC验证等实操细节。补充部分单独整理了地址值录入方式、主备切换流程和后台服务启停方法能帮助读者快速定位所需章节减少驱动位数不符、数据源权限不足、地址匹配错误等常见问题提升项目调试效率文档目录结构清晰每个模块均可独立参考既适合新手按顺序学习也适合老手针对某一步骤快速查阅。1. Kepserver 主备、MySQL 双向读写、后台服务一次说清三个项目坎现场交付时甲方提得最多的不是“能不能连上”而是这三句话服务器能不能坏一台不宕机历史数据和配方能不能直接进 MySQL我人在办公室能不能直接改西门子里面的参数。Kepserver 作为上位机网关主备冗余、MySQL 双向读写、后台服务这三个需求经常同时压在一个项目上。这篇文章不是给你讲概念是把这三个坎的选型、配置步骤和填写格式都摆出来照着做就能跑通。适合的读者是真正在调试现场、对着 OPC 客户端等数据的工程师。新手可以按步骤走熟手重点看地址格式和主备下的数据库冲突这两块最容易翻车。2. Kepserver 主备冗余先定架构再开配置界面主备不是简单装两台软件然后把配置拷一遍。Kepserver 的主备功能依赖授权插件和一套同步机制如果一上来就两边同时激活通道轻则数据紊乱重则 MySQL 里出现双写冲突。先想清楚要备什么再动手配置。2.1 主备的本质两个 Kepserver 实例互为镜像常见做法是用官方 Redundancy 插件。它把两台机器上的 Kepserver 分成主和备主实例对外提供 OPC 服务备实例实时同步主实例的工程文件和运行数据。心跳检测一般走 TCP默认端口和心跳间隔可以调。客户端连接的不是某台固定 IP而是虚拟名称Alias这样故障切换时客户端不用改配置。这里要分清“项目同步”和“运行数据同步”。项目同步解决的是 Tag 定义、通道配置的一致性备机启动时从主机拉一次之后改动实时推送。运行数据同步解决的是客户端读取的缓存值一致比如 PLC 故障前读到的最后状态。如果你的项目只要求“PLC 断线后能自动切到备机”运行数据同步可以放宽但如果你做的是连续过程控制建议打开不然切换后备用服务器读到的是初始化值。选型的另一个分支是用 Windows 故障转移集群把 Kepserver 做成集群资源。这种方案的优点是和操作系统级高可用统一缺点是对虚拟 IP、共享存储、域名依赖要求高中小项目划不来。我做过的项目 90% 用 Keeperver 自带冗余就够了别为了“高可用”硬上集群。2.2 配置主备的实操顺序从授权到故障切换安装时两台机器都要装同一个版本的 Kepserver并且导入 Redundancy 授权。主备授权是分开的只给主机插授权一样会失效。然后按以下顺序配置1. 两台机器互相之间 IP 能 ping 通主机名能解析Windows 防火墙放行 Kepware 相关端口。 2. 在主机的 KepserverAdmin 里创建配置完成通道、设备、Tag 定义。 3. 在工具栏打开 Redundancy 配置添加备机地址指定同步模式项目运行数据。 4. 设置心跳周期和切换判定次数一般心跳周期 5 秒连续丢失 3 次判定故障。 5. 定义虚拟名称例如 KEPHA客户端连接时填这个名称而不是 IP。 6. 启动两台服务观察 Dashboard 里主备状态手动停掉主机测试切换。关键参数在冗余设置里别只看默认值。心跳周期如果低于 3 秒网络抖动会导致频繁切换高于 10 秒PLC 断线后备机要等很久才接管中间这段数据就断了。判定次数建议设置成 2 到 3 次避免单次丢包就切换。测试切换时我发现一个容易忽略的点OPC 客户端里有缓存连接比如 C# 的 OPC DA 组件它会持续向主实例请求切换后不一定自动连上虚拟名称。要确认客户端支持“重试其他服务器”否则你这边切换成功客户端还挂着死连接。2.3 主备环境下 MySQL 连接和文件存储的注意事项主备两台 Kepserver 同时连接同一个 MySQL最容易出现双写。比如 Data Logger 插件在主备上都开启了故障切换时两边各写各的表里出现重复记录。常见做法是只在主实例上启用数据库写入备实例的 Data Logger 保持禁用切换动作由冗余插件触发后再激活。具体设置因版本而异但原则一致任何写 MySQL 的插件必须在主备两边有明确的主备激活条件。另外Kepserver 的主备需要访问共享目录用于同步工程文件通常是 Windows 共享。这里注意 MySQL 的 ODBC 连接池如果被两台机器复用可能出现连接串纠缠。结论就是数据库连接不要让两台实例共用同一个连接账号去写同一张表可以给主备各配一个 MySQL 账号或者干脆备机只读。3. MySQL 与 Kepserver 双向读写数据库既是“下游”也是“上游”很多工程师把 MySQL 当成历史数据存储的“垃圾场”只写不读。但 Keverver 和 MySQL 的双向读写说的是把数据库表也当成一个数据源从 MySQL 读取配方下发到 PLC把 PLC 状态写回 MySQL。实现方式有三种按项目需求选。3.1 用 ODBC 驱动把 MySQL 表映射成 OPC Tag读和写Kepserver 里有一个 ODBC Client 驱动它能把数据库查询或表操作变成 OPC Tag这样你在 OPC Quick Client 里就能直接读写 MySQL 表。这是纯粹的“数据库当设备”玩法。配置步骤1. 安装 MySQL Connector/ODBC注意挑 32 位还是 64 位跟 Kepserver 安装版本匹配。 2. 打开 Windows 的 ODBC 数据源管理器新建系统 DSN填服务器 IP、端口、用户名、密码和数据库名。 3. 在 KepserverAdmin 里新建通道驱动选 ODBC Client设备名指向刚才的 DSN。 4. 在设备下新建 Tag地址栏填 SQL 语句例如查询SELECT value FROM recipe WHERE id1。 5. 想写 MySQL地址栏填 UPDATE recipe SET value? WHERE id1然后通过 OPC 写入请求传参数。这里有个细节Kepware 的 ODBC 驱动地址不是寄存器号而是 SQL。不同小版本的语法有差别有的版本只支持一条查询语句有的版本支持把存储过程当地址用。稳妥做法是先建一个最简单的表测试再看日志里报的 SQL 错误。参数设计上建议配合“轮询周期”。ODBC 驱动的查询会执行得很频繁如果 MySQL 表很大每次全表扫描会把 CPU 跑满。把表按 id 加上索引查询语句最好使用 WHERE 主键。不要直接映射整张表除非你的表小于几百行。3.2 用 Data Logger 做 PLC 到 MySQL 的历史落库如果要长期记录 PLC 数据比如几分钟采一次温度、压力用 Data Logger 插件更专业。它从 OPC 服务器订阅 Tag按照配置的周期写入 MySQL。它不是把数据变成 Tag而是作为 OPC 客户端去消费数据。我一般这样配在 Kepserver 里先建好到西门子的通道Tag 地址先确认能读出来再打开 Data Logger 插件新建一个记录器选择数据源是本地 OPC 服务器指定要采集的 Tag 列表然后配置 MySQL 连接字符串和目标表。这样 PLC 写到 Kepserver 的每个值都会被 Data Logger 周期写进 MySQL。字段映射是关键点。它默认把时间戳、质量、值都写进去。但表字段要提前定好比如 value_time、plc_value、quality。注意 Data Logger 只做“单向写”不负责把 MySQL 数据读回来。如果你需要从 MySQL 读到 PLC得用 3.1 的 ODBC 驱动或者走 3.3 的后台转发服务。3.3 真正“双向”的方案一个后台转发服务C# 核心代码当“从 MySQL 更改一个值PLC 立刻收到”这种需求出现时最好的方案不是靠 Kerver 配置而是写一个后台服务做转发。它作为 OPC 客户端连 Kepserver又作为数据库客户端连 MySQL代码里自己决定什么时候读、什么时候写。下面是一个 C# 程序的核心骨架用 OPCDAAuto 组件连接 Kepserver再把读到的值写进 MySQL反过来从 MySQL 读出的值再写回 OPC 通道。// 连接 Kepserver读取 PLC 侧 Tag var server new OPCServer(); server.Connect(Kepware.OPC.Server); var group server.OPCGroups.Add(BridgeGroup); group.UpdateRate 1000; // 1秒订阅一次 var item group.OPCItems.AddItem(SiemensPLC.DB10.DBD0, 0); // 读到值写入 MySQL using (var conn new MySqlConnection(server127.0.0.1;uidbridge;pwdxxx;databasescada)) { conn.Open(); var cmd new MySqlCommand( INSERT INTO plc_value(tag, value, ts) VALUES(tag,value,ts), conn); cmd.Parameters.AddWithValue(tag, item.ItemID); cmd.Parameters.AddWithValue(value, item.Value); cmd.Parameters.AddWithValue(ts, DateTime.Now); cmd.ExecuteNonQuery(); } // 反向从 MySQL 读到配方值再写回 Kepserver using (var conn new MySqlConnection(...)) { var cmd new MySqlCommand(SELECT target_value FROM recipe WHERE id1, conn); var target Convert.ToInt32(cmd.ExecuteScalar()); var writeItem group.OPCItems.AddItem(SiemensPLC.DB10.DBD4, 1); writeItem.Write(target); }这段代码里的参数说明OPCServer.Connect(Kepware.OPC.Server)是连接本机 Kepserver 的 ProgID远程的话要配置 DCOM。OPCItems.AddItem的第二个参数是客户句柄随便填但不要重复。UpdateRate是订阅周期和 Data Logger 的落库周期不要冲突否则数据被采样两次。反向写入时注意别把Write放进同样的订阅事件里容易死循环PLC-MySQL 写完后又被 MySQL-PLC 那部分触发重新写 PLC。这个服务本身要长时间跑所以我第 5 章会专门说怎么把它跑成 Windows 后台服务而不是开一个控制台窗口挂着。4. 西门子双向读写从 PLC 侧设置到 Kepserver 的 Tag 地址西门子双向读写这部分90% 的失败发生在 PLC 侧而不是 Kepserver。S7-1200、S7-1500 默认开启“优化块访问”Kepserver 想要用绝对地址读 DB 块必须先改这个设置。还有一个高频坑CPU 属性里没勾选允许 PUT/GET导致 OPC 状态显示 Bad。4.1 西门子 PLC 侧要开的三道门PUT/GET、优化块访问、DB 权限以 S7-1200/1500 为例在 TIA Portal 里CPU 属性中的“防护与安全”-“连接机制”可以勾选“允许来自远程对象的 PUT/GET 通信访问”。如果不勾选Kepserver 的 S7 驱动根本无法建立连接现象是 OPC Quick Client 里 Quality 一直是 Bad连 PLC 版本都读不到。第二个是 DB 块的“优化块访问”。TIA 建数据块默认勾选“优化的块访问”这种 DB 没有固定的偏移地址Kepserver 不知道 DBD0 对应哪个变量。必须右键数据块属性把“优化的块访问”取消然后重新下载。注意下载后 PLC 里的变量名和地址映射关系会生成一个偏移表你可以在“监视”或“转存”里看到比如 Tag1 对应 DBD0Tag2 对应 DBD4。第三是 DB 的访问权限。有些项目把 PLC 程序做了保护Kepserver 能连上但读不了 DB 内容检查 DB 块的“访问模式”里是否启用了“CPU 不知道的 DB”访问保护。这道门不打开地址格式再怎么调都白搭。4.2 Kepserver 里 Siemens 驱动的设备与 Tag 配置新建通道时S7-300/400 常用Siemens TCP/IPS7-1200/1500 用Siemens S7-1200/1500这类独立驱动。通道建完后添加设备设备地址栏填 PLC 的 IP比如 192.168.0.1。注意有些驱动还需要在设备属性里填机架号和插槽号。S7-300/400 的机架号一般填 0插槽号要看 CPU 所在位置直接挂导轨上一般 2用 CP343 以太网模块时可能 4。填错的表现是标签状态 Bad。S7-1200/1500 通常不需要填写 Rack/Slot因为你走的是集成 PN 口不是通信处理器。在设备下面新建 Tag 时DataType 一定选对。I/Q/M 布尔量选 Boolean模拟量选 Word 或 DWord浮点选 Float。这个选错不会报错但到上位机里会解析成乱数。这是比地址格式更隐蔽的坑。4.3 典型读写场景的地址写法DB 块、M 区、I/Q地址填写格式直接决定了读写是否成功也最容易产生“看起来对了实际错了”的情况。我这里给出一张常用格式表以Siemens S7-1200/1500和Siemens TCP/IP驱动为参考。数据区域位/字节/字/双字Kepserver 地址示例说明M 区位M0.0第 0 个字节的第 0 位M 区字MW10从字节 10 开始的 16 位M 区双字MD20从字节 20 开始的 32 位I 区位I0.0输入点Q 区字QW4输出字DB 块位DB1.DBX0.0数据块 1第 0 字节第 0 位DB 块双字DB1.DBD0数据块 1从字节 0 开始的 32 位DB 块浮点DB1.DBD8从 DB1 偏移 8 开始的 Float需要注意几点DB 地址DB1.DBD0中的 DB1 是数据块编号必须和你 TIA 里的块号一致不是通道名。DBD0的偏移是字节偏移不是“第几个变量”。如果你 DB 里先放了一个 BOOL再加一个 REALREAL 的偏移不是 0而是要看对齐。TIA 会按 4 字节对齐填充所以第二个变量可能跑到 DBD4 或 DBD8最稳的做法是看 PLC 的偏移表。读写双向权限需要在 Tag 属性里设置 Access Mode有的版本默认 Read Only你写不进去时先查这一项而不是怀疑地址写错。对于 M 区MB10、MW10、MD10 可以共存但它们重叠了别同时用于不同变量否则数据会相互覆盖。5. 把整套链路跑在后台Kepserver 服务、ODBC 源与自启脚本现场电脑不可能一直有人登录Windows 桌面不启动Kepserver 和控制程序要自动跑。这里说的后台服务不只是“最小化窗口”而是服务级运行。5.1 Kepserver 自身作为 Windows 服务运行的配置Kepserver 安装时可以选“作为服务运行”如果安装时漏了也可以到服务管理器里找到 Kepware 相关服务改为自动启动。我一般在安装时就选服务模式并给服务指定一个专门账户比如SCADAService不要用本地系统账户因为数据库网络权限、共享目录映射都容易出问题。服务模式下Kepserver 的界面会变成灰色或不可见这也是正常的。调试时可以去安装目录启动KepserverAdmin它有独立的配置面板不依赖桌面登录。OPC Quick Client 在服务模式下使用有个麻烦如果你用本地账户跑 Quick Client它连接 Kepserver 可能弹出 DCOM 权限问题。解决办法是在组件服务里给Everyone加“远程激活”权限但这是最大的安全口子项目现场可接受的话再做。5.2 为 MySQL ODBC 配置系统 DSN而不是用户 DSN这是服务连不上 MySQL 的高频原因。你在桌面登录时用 ODBC 数据源管理器配的是“用户 DSN”但 Kepserver 服务跑在另一个会话和账户下它看不到用户 DSN只能看到“系统 DSN”。我一般这样操作在 ODBC 管理器里切到“系统 DSN”页新建 MySQL ODBC 连接填入 MySQL 地址、端口 3306、用户名密码Test 一下。注意连接器选 ANSI 还是 UnicodeKepserver 是 32 位的就必须装 32 位 MySQL ODBC 驱动但 Windows 64 位默认的 ODBC 管理器是 64 位的需要运行C:\Windows\SysWOW64\odbcad32.exe才是 32 位管理器别记错。配置完系统 DSN 后可以在 Kepserver 的 ODBC 通道里测试连接。如果连接时报错“Data source name not found”几乎都是用户 DSN 和系统 DSN 搞混或者位数不对。5.3 后台转发服务的部署与开机自启第 3 章写的 C# 转发程序不能一直开着 debug 窗口。用 Windows 服务把它托管起来可以用sc.exe命令创建一个服务也可以借助 NSSM 这类工具把 exe 包装成服务。常见做法是用 NSSM一个命令就搞定nssm install SCADABridge C:\scada\SCADABridge.exe nssm set SCADABridge AppParameters --config C:\scada\config.ini nssm set SCADABridge AppDirectory C:\scada nssm set SCADABridge DisplayName SCADA MySQL-PLC Bridge service SCADABridge start这里的参数说明AppDirectory很重要程序如果有相对路径读取配置文件不设置会找不到。AppParameters里--config指定的配置项要能覆盖 ODBC DSN、OPC 服务器名、要转发的 Tag 列表。启动后到服务管理器查看状态如果服务报“1053 超时”通常是因为服务启动时不连接 OPC 或者 MySQL里面没做“服务快速的启动确认”。这时简化 OnStart把连接逻辑放到后台线程里。另外C# 的转发服务如果里用OPCDAAuto在服务模式运行同样会遇到 DCOM 问题。可以做成一个独立的批处理步骤启动服务前先确保 Kepserver 服务已启动和 Tomcat? 不需要但需要调用CoInitializeSecurity设置后台线程的 COM 安全模型代码里改成// 服务 OnStart 里初始化 COM Thread thread new Thread(() { var server new OPCServer(); // ...连接逻辑 }); thread.SetApartmentState(ApartmentState.STA); thread.Start();不加这行极大概率在服务器上卡死但在你自己的开发机里跑得倍儿顺。这也是“玄学”里常见的一种项目现场一装服务就黑匣子多半是这个原因。还有一点Kepserver 服务、MySQL 服务、转发服务三者的自动启动顺序不好控制。MySQL 不启动时转发服务可能会疯狂重试导致 CPU 飙高。用 Windows 服务管理器里的“恢复”选项卡设置“服务失败后延迟 30 秒重启”别写死为一直快速重启。6. 地址填写避坑这是新手最容易丢分的地方最后把我在现场遇到最多的地址填写错误总结成几条血泪经验。每条都是真实翻车场景按“现象-原因-解决”写清楚。1. 现象DB1.DBD0 在 TIA 里明明存在Kepserver 读出来全是 0Quality 还很好。原因S7-1500 的 DB 块开了“优化的块访问”绝对地址无法生成Kepserver 读到的地址是空的或者读到的是上一次下载的旧偏移。解决取消“优化的块访问”重新编译下载再读取 DB 偏移表核对。这个坑最隐蔽因为不报错。2. 现象M0.0 能读DB1.DBX0.0 也能读但 DB1.DBW0 读到的是振荡值。原因DBW0 是字节 0 和 1 组成的字而 PLC 里 DB1.DBX0.0 和 DB1.DBX3.0 可能不连续中间穿插了别的数据。解决不要凭感觉写偏移去 TIA 里打开数据块右下角属性把“Address”列显示出来按实际偏移写。3. 现象MySQL 的 ODBC Tag 能读写 SQL 时一直报错。原因Kepserver 的 ODBC 驱动里写操作一般要用 UPDATE 并带?占位符而很多人直接用 SELECT 当写地址。解决查看日志里的 SQL 错误把地址改为UPDATE table SET value? WHERE key?并在 OPC 客户端的写入参数里传两个值。4. 现象服务模式下所有 Tag 都 Bad但手动启动界面时一切正常。原因DSN 用的是用户 DSN或者 Kepserver 服务登录账户没有访问 MySQL 的网络权限。解决把 DSN 改成系统 DSN确认服务账户能通过 ODBC 测试连接再用 32 位 ODBC 管理器排查。5. 现象主备切换后数据库突然不写数据了但 Kafka/OPC 都正常。原因备机上的 Data Logger 或 ODBC 写入没有跟随主备状态启用切换后的实例继承了禁用状态。解决检查主备冗余设置里有没有“当本机变为主服务器时启用此插件”的选项没有的话在客户端的事件里补一个切换回调手动启停写入。这些坑没什么技术门槛但每个都足够让交付拖一个星期。希望帮到你至少在遇到 Bad 状态的时候先按这几条排查一轮。本文还有配套的精品资源点击获取