SIEMENS西门子福建省福州市(授权)电机一级代理商——西门子华南总代理

供应商
广东湘恒智能科技有限公司
认证
西门子总代理
PLC
西门子一级代
驱动
西门子代理商
伺服电机
联系电话
15915421161
手机号
15903418770
联系人
张经理
所在地
惠州大亚湾澳头石化大道中480号太东天地花园2栋二单元9层01号房
更新时间
2024-05-02 07:00

详细介绍

对于上位机而言,快速的高质量交付依然极为重要。在上位机项目中,通信毫无疑问是极为重要的一个模块。不同的项目需要的变量不一样,连接的设备类型和数量也不一样。那么对于上位机的通信这块,我们如何才能快速的高质量完成和设备的数据交互?


图1 c#上位机项目实例网络图

有的项目只需要对接一台plc,有的项目可能需要对接多台。有的plc可能只需要访问几个变量,而有的plc可能需要访问几百、数千甚至上万变量。那种用modbusrtu或者一个串口自定义协议连接一个小i/o模块的demo在现实中几乎没有,毫无实际意义。既然要学上位机,那么肯定奔着高水准去。有能力挑战大项目才算真正掌握了c#上位机。

说了这么多,那么如何合理地规划数据交互模块?我觉得重要的一点就是实现变量与驱动的解耦。多设备、多变量的项目,如果不能做到变量和驱动的解耦,那么编程与调试工作量将非常大。

关于变量与驱动的解耦我们有两种方案,方案一用于我们重构的c#上位机项目实例中。方案二技术难度更大一点,用于我们的c#上位机框架hwlib.advscada中。今天我们要介绍的是方案一。在方案一中,每种驱动拥有一个独立的线程。它根据我们传递进来的报文要求发送数据读取指令到设备。然后再将读取到的报文返回。在返回报文时通过事件通知的方式调用解析方法,将报文解析到对应的变量。在ui层中或者其它模块中,我们只需要关联这些变量名即可。这样我们可以将工作重心放在业务逻辑上,不再需要关注驱动。

在我们的c#上位机项目实例中的早期版本其实变量和驱动也并没有实现解耦。在这次版本大升级过程中。我们重构了驱动模块。下面以这次重构来简单介绍了我们的方案一。这次重构,我们的c#上位机实例集成了两种通信协议,分别是s7和modbus。以modbus为例,我们首先基于easymodbus做了二次封装。对外提供了读取与写入两个公开方法,另外增加了两个事件,分别是连接状态改变事件和数据更新事件。










//需要读取的报文信息,包含了寄存器区域、起始地址和长度等信息public list<readmsg> readmsglist = newlist<readmsg>();//需要写入数据的变量信息public dictionary<string, tagmodel> writetagslist = new dictionary<string, tagmodel>();//返回的报文数据public dictionary<string, int[]> rstdata = new dictionary<string, int[]>();public bool isconnected { get; set; }public event eventhandler statuschanged;public event eventhandler dataupdate;

驱动类封装后放在dal层。无论我们后续其它项目中有多少设备或者仪表,我们都不再需要修改这个类。而只需要在bll层中实例化这个类并传递变量信息即可。meter是我们在bll中创建的一个类,用于根据仪表数量实例化驱动并管理变量。在其它ui或者模块中,我们只需要关联这里的变量就行了。












meter2 = new modbustcp("192.168.1.12");//订阅事件//ui界面上显示通信状态meter2.statuschanged += meter2_statuschanged;//数据更新时间,用于解析报文meter2.dataupdate += meter2_dataupdate;//读写变量信息bytelist2(meter2);meter2.writetagslist = tagsmeter2;//通信启动meter2.start();

其中订阅状态改变事件是为了在标题栏显示连接状态。


图2 设备状态显示

在方法bytelist中,我们会传递请求的报文信息到驱动。驱动类根据我们传递的报文到plc中请求数据。











private static void bytelist2(modbustcp mdb) { modbustcp.readmsg msg = new modbustcp.readmsg(); msg.id = "1"; msg.rgstarea = 3; msg.startaddress = 1; msg.count = 10;
mdb.readmsglist.add(msg); }

报文解析方法会在驱动类modbustcp的数据更新时触发。它会对驱动类modbustcp返回的byte[]类型报文解析并关联到变量。这样我们在ui层或者其它模块就可以直接使用变量名称来获取数据了。至于ui层,我们可以用定时器,也可以用订阅事件的方法来刷新数据。

由于刷新数据并不占用多少资源,所以我们在ui界面采用了定时器更新。





private void timer1_tick(object sender, eventargs e){ labpower.text = meter.tagsmeter1["power"].value.tostring();}

该方案实现了变量和驱动的解耦。对于不同项目的设备和变量的不同,我们只需要在bll层根据工艺要求调整变量即可,而不用再修改驱动层。这种方式极大地提高了工程效率。


PLC,变频器,代理商,一级代理,伺服电机

展开全文

我们其他产品
我们的新闻
咨询 在线询价 拨打电话