基于Codex平台的上位机数据采集软件实战:从通信配置到部署交付

发布时间:2026/8/21 2:20:31
基于Codex平台的上位机数据采集软件实战:从通信配置到部署交付 在工业自动化项目中上位机软件作为连接物理设备与信息系统的桥梁其稳定性和可靠性至关重要。近期我完成了一个基于 Codex 平台开发的上位机数据采集软件项目并已成功交付客户实现了对多台 PLC 设备的稳定监控与数据采集。本文将复盘整个项目的核心实现过程从技术选型、架构设计、核心代码实现到部署交付为你提供一份完整的实战指南。无论你是刚接触上位机开发的新手还是希望了解 Codex 在工业场景应用的中高级开发者都能从中获得可直接复用的代码和工程经验。1. 项目背景与核心概念解析1.1 什么是上位机与数据采集软件在工业控制领域“上位机”通常指位于控制系统层级顶端的计算机或工控机。它负责监控、管理和控制下层的“下位机”如 PLC、单片机、传感器等。上位机软件的核心功能包括与下位机进行通信采集数据、处理数据如滤波、计算、展示人机界面HMI以及将数据存储或上传至服务器。“数据采集软件”则是上位机软件的核心组成部分专注于从各种工业总线如 Modbus、OPC UA、Profibus或网络协议如 TCP/IP中稳定、高效地读取设备数据。一个优秀的数据采集软件需要解决通信稳定性、数据准确性、高并发处理和异常恢复等问题。1.2 为什么选择 Codex 作为开发平台Codex 是一个功能强大的低代码/快速开发平台它并非特指某个单一产品。根据网络搜索信息存在多种名为“Codex”的开发工具或插件如某些 AI 代码辅助工具、VSCode 插件等。在本项目中我们选择的 Codex 是一个面向工业物联网和自动化应用的集成开发环境。它之所以适合上位机开发主要基于以下几点协议集成度高内置丰富的工业通信协议驱动如 Modbus RTU/TCP、OPC DA/UA、西门子 S7 协议等无需从零编写底层通信栈大大降低了开发难度和出错概率。可视化配置提供图形化的设备组态、数据点表配置和通信参数设置界面使非编程人员也能参与部分配置工作提升了开发效率。脚本引擎支持支持使用 Python、C# 或 JavaScript 等脚本语言编写复杂的业务逻辑、数据处理算法和自定义功能兼顾了灵活性与便捷性。跨平台潜力部分 Codex 运行时环境支持 Windows 和 Linux为未来部署到更廉价的工控机或边缘计算设备提供了可能。社区与生态拥有一定的用户社区和插件市场遇到问题时更容易找到解决方案或替代组件。注意网络上关于“codex could not start”、“codex couldn‘t load its resources”等错误通常与特定版本的 VSCode 插件或桌面客户端有关与本文讨论的工业上位机开发平台可能不是同一产品。在选择工具时务必明确其具体用途和官方文档。2. 开发环境与项目准备2.1 环境与工具清单本项目的开发环境基于 Windows 系统但核心设计思想适用于其他平台。操作系统Windows 10/11 专业版或 Windows Server 2019保证系统稳定性和对工业网卡的支持。开发平台Codex Studio (版本 2.8.x)。请根据官方指引从官网下载安装包。编程语言主要使用平台内置的图形化配置复杂逻辑使用 Python 3.8 脚本。数据库SQLite用于本地缓存和日志同时配置了向远程 MySQL 数据库同步的模块。测试设备4台西门子 S7-1200 PLC模拟实际产线设备1台用于模拟量采集的模块。网络环境独立的工业以太网交换机确保通信网络与办公网络隔离。2.2 Codex Studio 安装与初始配置下载与安装访问 Codex 官网下载对应操作系统的安装程序。安装过程与常规软件类似注意安装路径不要包含中文或空格。解决启动问题如果安装后遇到“could not start”或“couldn‘t load its resources”错误请尝试以下步骤以管理员身份运行安装程序或软件。检查系统是否安装了必要的运行时库如 .NET Framework、VC Redistributable。关闭杀毒软件或防火墙临时测试可能是安全软件拦截。查看安装目录的日志文件通常位于logs文件夹内寻找具体错误信息。创建新项目启动 Codex Studio新建一个“数据采集”类型的项目命名为PLC_DataCollector。2.3 项目结构规划在 Codex Studio 中一个典型的采集项目会包含以下核心部分我们可以在项目树中预先创建好对应的文件夹或节点PLC_DataCollector/ ├── 设备驱动 (Drivers)/ │ ├── S7_1200_1 (西门子驱动) │ ├── S7_1200_2 │ └── Modbus_RTU_1 (模拟量采集模块) ├── 数据点表 (Tags)/ │ ├── 设备1点位表.db │ └── 设备2点位表.db ├── 画面 (HMI)/ │ ├── 主监控画面.ui │ └── 报警历史画面.ui ├── 脚本 (Scripts)/ │ ├── 数据过滤.py │ ├── 报警处理.py │ └── 数据上传.py ├── 数据库连接 (Database Connections)/ │ ├── LocalSQLite.config │ └── RemoteMySQL.config └── 系统配置 (System Config)/ └── 项目配置.json3. 核心功能实现通信、采集与处理3.1 配置设备驱动与通信本项目需要连接4台 PLC。在 Codex 中每台设备作为一个独立的“驱动”实例进行配置。添加西门子 S7 驱动在“设备驱动”目录下右键选择“添加驱动” - “Siemens” - “S7 TCP/IP”。配置关键参数名称PLC_Line1IP 地址192.168.1.10第一台 PLC 的实际 IP机架号0槽号1采集周期1000ms 根据实际需求调整太快会增加网络负荷同理添加另外三台 PLC 的驱动分别命名为PLC_Line2,PLC_Line3,PLC_Line4。配置数据点表Tag 这是上位机与 PLC 数据地址的映射关系是采集的核心。在“数据点表”目录下为PLC_Line1创建一个新的点表文件。添加需要采集的点位例如DB10.DBD0-温度_反应釜1(REAL 类型)M10.0-电机_运行状态(BOOL 类型)IW100-压力_传感器1(INT 类型)为每个点位设置工程单位、量程转换、死区防止频繁写入等参数。3.2 实现数据采集与缓存Codex 平台通常以后台服务的方式运行采集任务。我们需要配置扫描组。创建扫描组在系统配置中创建一个名为FastScan的扫描组将4台 PLC 的所有需要快速响应的点位如状态、报警加入此组设置扫描周期为 500ms。创建另一个SlowScan组用于扫描历史数据、产量等变化不频繁的点位周期设为 5000ms。数据缓存采集到的数据会暂存在 Codex 的实时数据库RTDB中。我们需要配置一个 SQLite 数据库用于持久化存储历史数据和报警记录。在“数据库连接”中配置一个 SQLite 连接并创建一个“历史记录”任务将指定点位的值按时间间隔如1分钟记录到 SQLite 中。3.3 关键算法数据滤波处理对于电压、温度等模拟量信号采集时常常伴有噪声。在软件层面进行滤波是保证数据质量的关键。网络热词中提到的“电压采集软件滤波一般采用哪种算法”在实际项目中需要根据信号特性选择。在 Codex 的脚本中我们可以为特定点位添加“数据改变脚本”或“后处理脚本”来实现滤波。以下是几种常用算法的 Python 实现示例1. 滑动平均滤波Moving Average 简单有效适用于一般噪声。# 文件Scripts/数据过滤.py class MovingAverageFilter: def __init__(self, window_size5): self.window_size window_size self.data_window [] def filter(self, new_value): 输入新值返回滤波后的值 self.data_window.append(new_value) if len(self.data_window) self.window_size: self.data_window.pop(0) # 移除最旧的数据 return sum(self.data_window) / len(self.data_window) # 在点位‘温度_反应釜1’的后处理脚本中调用 filter_instance MovingAverageFilter(window_size10) # 全局或静态变量 current_value get_tag_value(温度_反应釜1) # 假设的API获取原始值 filtered_value filter_instance.filter(current_value) set_tag_value(温度_反应釜1_Filtered, filtered_value) # 写入滤波后的值到新点位2. 中值滤波Median Filter 对脉冲干扰有很好的抑制效果。import statistics class MedianFilter: def __init__(self, window_size5): self.window_size window_size self.data_window [] def filter(self, new_value): self.data_window.append(new_value) if len(self.data_window) self.window_size: self.data_window.pop(0) return statistics.median(self.data_window)3. 一阶滞后滤波低通滤波 适用于周期性波动计算量小。class FirstOrderLagFilter: def __init__(self, alpha0.3): # alpha越小滤波越强滞后越大 self.alpha alpha self.last_value 0 def filter(self, new_value): filtered self.alpha * new_value (1 - self.alpha) * self.last_value self.last_value filtered return filtered选择建议高频随机噪声优先使用滑动平均或中值滤波。周期性波动可尝试一阶滞后滤波。要求实时性高选择计算量小的一阶滞后滤波。允许一定延迟可使用滑动平均窗口大小根据噪声频率调整。在实际项目中我们为关键的温度和压力信号配置了滑动平均滤波并在 HMI 上同时显示原始值和滤波值供操作人员参考。3.4 多线程通信与性能优化“一台上位机控制4台PLC”是典型的多设备通信场景。Codex 的驱动管理器通常内置了多线程或异步IO机制来处理并发通信。但我们仍需在应用层注意避免阻塞主线程所有耗时的操作如复杂计算、批量数据库写入、网络上传都应放在独立的脚本任务或线程中执行。Codex 通常提供“定时任务”或“后台任务”功能。连接池与重连机制确保网络异常时驱动能自动尝试重连并记录重连日志。在 Codex 的驱动配置中一般都有“重试次数”、“重试间隔”等参数。资源管理定期检查内存和CPU占用。如果使用自定义 Python 脚本注意避免内存泄漏如全局列表无限增长。4. 上位机人机界面HMI设计4.1 主监控画面使用 Codex Studio 内置的 HMI 设计器通过拖拽控件的方式构建界面。布局采用多标签页Tab或分屏布局分别显示4条产线的状态。关键控件指示灯绑定到 PLC 的 BOOL 点显示设备运行、停止、故障状态。数值显示框绑定到滤波后的温度、压力等 REAL 或 INT 点并设置上下限颜色报警如超限变红色。趋势图添加实时趋势曲线控件将关键数据点的历史走势可视化。需要配置趋势图的数据源为之前定义的 SQLite 历史库。按钮用于下发控制命令如启动、停止。重要控制按钮必须增加权限验证和二次确认弹窗防止误操作。数据绑定这是 Codex 的优势大部分控件属性如文本、颜色、可见性都可以直接绑定到数据点Tag实现数据变化后界面自动更新。4.2 报警管理系统报警是上位机软件的核心安全功能。报警定义在 Codex 的报警管理器中为需要监控的点位定义报警条件。例如温度_反应釜1150.0- 产生“高温报警”级别为“高高报警”。电机_运行状态False且系统模式自动- 产生“异常停机报警”级别为“紧急报警”。报警显示在 HMI 上添加一个报警窗口或报警列表控件它会自动从系统的报警缓冲区中获取并显示当前活动报警和历史报警。报警通知配置报警动作如触发声音、弹出报警窗口、发送邮件或短信需要配置 SMTP 等。这部分通常需要在脚本中实现。# 文件Scripts/报警处理.py import smtplib from email.mime.text import MIMEText def on_alarm_triggered(alarm_tag_name, alarm_message, alarm_level): 报警触发时被系统调用的函数 # 1. 记录到数据库 log_to_database(alarm_tag_name, alarm_message, alarm_level) # 2. 如果是紧急报警发送邮件 if alarm_level 紧急: send_email_notification(alarm_message) def send_email_notification(message): # 这里是一个简单的SMTP示例实际使用需配置邮箱服务器信息 msg MIMEText(f监控系统报警{message}) msg[Subject] 【上位机系统】紧急报警通知 msg[From] senderexample.com msg[To] operatorexample.com try: # 注意此处仅为示例密码等敏感信息应通过配置项读取切勿硬编码 with smtplib.SMTP_SSL(smtp.example.com, 465) as server: server.login(senderexample.com, your_password) server.send_message(msg) print(报警邮件发送成功) except Exception as e: print(f发送报警邮件失败: {e}) # 此处应记录更详细的日志5. 数据持久化与远程交互5.1 本地与远程数据库配置本地 SQLite用于存储高频采集的历史数据、报警记录和操作日志。配置简单无需额外安装数据库服务可靠性高。在 Codex 中配置一个“历史存储”任务指向 SQLite 文件即可。远程 MySQL用于向中央服务器MES、ERP同步关键生产数据如班次产量、设备综合效率 OEE。我们需要在“数据库连接”中配置 MySQL 的连接信息并编写定时脚本将 SQLite 中处理好的数据批量插入到 MySQL。# 文件Scripts/数据上传.py import sqlite3 import pymysql import schedule import time def sync_data_to_central(): 定时任务将本地的聚合数据同步到中央数据库 # 1. 从本地SQLite读取过去一小时的数据 local_conn sqlite3.connect(local_data.db) local_cursor local_conn.cursor() local_cursor.execute( SELECT tag_name, AVG(value), MAX(value), MIN(value), COUNT(*) FROM history_data WHERE timestamp datetime(now, -1 hour) GROUP BY tag_name ) hourly_stats local_cursor.fetchall() local_conn.close() # 2. 连接远程MySQL并插入数据 remote_conn pymysql.connect( hostcentral-server.com, usercollector, passwordsecure_password, # 应从加密的配置文件中读取 databaseproduction_db ) remote_cursor remote_conn.cursor() for stat in hourly_stats: tag_name, avg_val, max_val, min_val, sample_count stat remote_cursor.execute( INSERT INTO hourly_metrics (tag_name, avg_value, max_value, min_value, sample_count, upload_time) VALUES (%s, %s, %s, %s, %s, NOW()) , (tag_name, avg_val, max_val, min_val, sample_count)) remote_conn.commit() remote_cursor.close() remote_conn.close() print(f数据同步完成同步了{len(hourly_stats)}个指标。) # 在Codex中配置一个每10分钟执行一次的定时任务调用 sync_data_to_central 函数 # schedule.every(10).minutes.do(sync_data_to_central) # while True: # schedule.run_pending() # time.sleep(1)5.2 对外提供数据接口可选有时其他系统如看板系统、手机APP需要实时获取数据。可以在上位机内嵌入一个轻量级的 Web 服务器如 Flask提供 RESTful API。# 文件Scripts/web_api.py from flask import Flask, jsonify import sqlite3 app Flask(__name__) app.route(/api/current_data) def get_current_data(): 获取所有点位的当前值 # 这里需要调用Codex的运行时API来获取实时数据 # 假设有一个 get_all_tag_values() 的函数 data get_all_tag_values() # 此函数需要根据Codex的脚本API实现 return jsonify(data) app.route(/api/alarms/active) def get_active_alarms(): 获取当前所有活动报警 conn sqlite3.connect(alarms.db) cursor conn.cursor() cursor.execute(SELECT * FROM alarms WHERE acknowledged 0 ORDER BY trigger_time DESC) alarms cursor.fetchall() conn.close() # 将查询结果转换为字典列表 alarm_list [...] return jsonify(alarm_list) if __name__ __main__: # 注意在生产环境中应使用生产级WSGI服务器如Waitress或Gunicorn app.run(host0.0.0.0, port5000, debugFalse)安全警告对外开发 API 必须考虑身份验证如 API Key、JWT、授权和速率限制防止未授权访问和攻击。6. 部署、交付与稳定性保障6.1 项目打包与安装程序制作Codex Studio 通常提供“发布”或“构建”功能可以将整个项目包括运行时环境打包成一个独立的安装程序。选择运行时选择与开发环境匹配的 Codex 运行时版本。包含资源确保所有驱动、脚本、画面、数据库配置文件都包含在发布包内。配置开机自启在安装程序设置中勾选“创建系统服务”或“添加到启动项”确保上位机软件在工控机开机后自动运行。生成安装包执行构建生成Setup_PLC_DataCollector.exe之类的安装文件。6.2 现场部署步骤环境检查确认目标工控机满足系统要求安装必要的运行库如 .NET, VC。网络配置正确配置工控机的 IP 地址确保其与所有 PLC 在同一网段且能互相 ping 通。务必关闭工控机的防火墙或配置放行规则。软件安装运行安装程序按照向导完成安装。建议安装到非系统盘如 D:\Programs\。参数配置首次运行可能需要根据现场 PLC 的 IP 地址微调项目内的设备连接参数。Codex 项目通常将配置存储在 XML 或 JSON 文件中可以直接修改。功能测试逐一测试与每台 PLC 的通信状态。验证数据采集是否准确对比 PLC 监控软件中的值。测试控制命令如点动按钮是否有效。模拟报警条件如短接/断开传感器检查报警产生、显示、通知是否正常。检查历史数据是否正常存储远程同步是否成功。6.3 保障长期稳定运行的工程实践完善的日志系统不仅记录错误还要记录重要的操作如手动控制、参数修改和系统状态如定时任务执行、数据库连接状态。日志应按日期滚动定期归档。看门狗机制编写一个简单的“看门狗”脚本或使用第三方工具监控上位机主进程。如果进程无响应或崩溃看门狗能自动将其重启。资源监控与告警监控工控机的 CPU、内存、磁盘空间占用。如果资源使用率持续过高应提前预警。这可以通过在 Codex 中采集系统性能计数器并设置报警来实现。定期备份定期备份项目配置文件、数据库文件。Codex 项目文件通常不大可以每天自动压缩备份到网络盘或另一台机器。版本管理对项目文件.cxp 或类似格式使用 Git 进行版本控制记录每一次的修改。交付给客户的安装包也应标注清晰的版本号。7. 常见问题与排查思路在开发和部署过程中你可能会遇到以下问题问题现象可能原因排查步骤与解决方案Codex 驱动显示“通信失败”1. 网络不通。2. PLC IP 地址或槽号配置错误。3. PLC 处于 STOP 模式。4. 防火墙/安全软件拦截。1. 在工控机上 ping PLC 的 IP检查物理网线。2. 核对驱动配置与 PLC 实际设置使用 TIA Portal 等软件查看。3. 将 PLC 切换到 RUN 模式。4. 临时关闭防火墙测试或添加出入站规则。数据采集值不正确或为01. 数据点地址错误。2. 数据类型不匹配如 WORD 读成了 INT。3. PLC 中该地址未写入有效值。4. 通信干扰或丢包。1. 使用 PLC 编程软件在线监控确认地址和值是否正确。2. 检查 Codex 中点位的“数据类型”设置。3. 在 PLC 程序中强制写入一个值测试。4. 降低采集周期检查网络质量。上位机软件运行一段时间后卡死或无响应1. 内存泄漏脚本引起。2. 数据库连接未释放堆积过多。3. 日志文件过大占满磁盘。4. 死循环或资源竞争。1. 检查任务管理器内存占用趋势。审查自定义脚本尤其是循环和全局变量。2. 确保数据库操作后关闭连接使用with语句或try-finally。3. 配置日志滚动策略定期清理旧日志。4. 检查脚本中的while True循环是否有正确的退出条件或休眠。报警不触发或误触发1. 报警条件设置错误如高低限值反了。2. 数据点的“死区”设置过大微小变化被忽略。3. 报警级别设置不合理。4. 报警缓冲区已满。1. 仔细检查报警管理器中每个报警的条件逻辑。2. 根据工艺要求调整数据点的“死区”参数。3. 合理划分报警级别警告、一般、紧急。4. 检查系统设置增大报警缓冲区容量。无法连接到远程数据库1. 网络不通。2. 数据库地址、端口、用户名、密码错误。3. 数据库用户权限不足。4. 数据库服务器防火墙未开放端口。1. 用 telnet 命令测试数据库服务器的端口是否可达。2. 使用数据库客户端工具如 Navicat使用相同参数连接测试。3. 为采集程序创建专用数据库用户并授予必要的读写权限。4. 联系服务器管理员放行对应端口如 MySQL 的 3306。8. 项目复盘与进阶思考通过这个项目的交付我深刻体会到一个稳定的上位机软件不仅仅是功能的堆砌更是对细节的掌控和工程化思维的体现。以下是一些进阶建议模块化与解耦尽量将数据采集、数据处理、业务逻辑、界面展示、数据存储等模块分离。例如使用 Codex 的“自定义模块”功能或通过清晰的脚本文件划分职责。这样有利于后期维护和功能扩展。配置外部化将所有可能变化的参数如 PLC IP、数据库连接串、邮件服务器地址、采集周期提取到外部配置文件如 JSON、XML 或 .ini 文件中。这样在客户现场调整时无需重新编译或修改项目源码降低风险。模拟与测试在开发阶段尽量使用 PLC 模拟软件如 PLCSIM Advanced或 Modbus 模拟器进行联调。可以搭建一个完整的测试环境模拟网络中断、数据异常等场景验证软件的健壮性。文档与培训交付的不只是软件还包括《用户操作手册》、《维护手册》和《二次开发指南》。对客户的操作人员进行系统培训教会他们如何查看日志、重启服务、修改简单配置能极大减少后期的维护成本。关注新技术工业互联网领域发展迅速可以关注 OPC UA over TSN、MQTT 协议、边缘计算框架等新技术思考如何将它们融入现有架构提升系统的开放性和可集成性。上位机开发是一个结合了工业知识、软件工程和现场经验的领域。从连接一台 PLC 开始到稳定管理一个车间数十台设备每一步的踏实积累都至关重要。希望这篇基于 Codex 平台的上位机开发实战总结能为你打开一扇门助你构建出更稳定、更高效的工业数据桥梁。