功能要求

  1. 采集来自PLC的生产数据和报警信息
  2. 采集来自测试仪的测试数据
  3. 可以分机种保存一些参数
  4. 将采集的数据写入Excel,供MES系统查询和现场查看

项目实现

1、采集PLC数据

硬件采用RS232串口,通讯协议使用ModusbusRTU。以前跟PLC通讯,为求简单,一般直接使用无协议,使用倒没问题,但偶尔出现数据丢失也是烦人,要确保对方接收到数据还要双方写返回数据。使用modbus协议,PLC基本不用写通讯程序,而上位机可以直接自己确认对方是否收到数据,再确认是否给对方重发一次。这个项目只要求采集数据,因为读取的频率高于数据变化,所以偶尔读不到都不影响,使用modbus就更合适了。

        /// <summary>/// 通过Modbus读取PLC,获取相应数据/// </summary>private void ScanPLC(){//创建字节数组byte[] result = null;//从站号ushort DevAdd = 1;//起始地址ushort Address = 100;//长度ushort Length = 5;while (running){if (plcConnected){result = objModbus.ReadKeepReg(DevAdd, Address, Length);DataProcessing(result, Length);}else{try{objModbus.OpenMyCom(9600, comName1, 8, Parity.Odd, StopBits.One);//objModbus.ReadTimeOut = 500;plcConnected = true;textReceive.Invoke(new ExecuteWork(RecRunData), "重连PLC成功");}catch (Exception ex){textReceive.Invoke(new ExecuteWork(RecRunData), "重连PLC失败:" + ex.Message);plcConnected = false;}}Thread.Sleep(1000);}}

2、采集测试仪数据

硬件也是采用RS232串口,因为测试仪的说明书不完善,modbus协议没有测试成功,而无协议测试成功了,所以直接采用无协议接收数据。采取的采集数据模式是,测试仪有测试数据马上主动通过串口发送,而我的程序只要一直处于接收状态,有数据就记下。所以建了一个线程一直扫描串口数据。

关于串口无协议通讯,以前也有个烦恼。就是接收数据有时会把一条数据拆成两条或者两条数据合成一条接收,要进行一些处理判断很是麻烦。这次发现Serial自带的读取功能很全面(可以在Serialport这个类下找到)。于是我直接采用了下面这个函数,再也不用担心老是读错数据了~

//// 摘要://     一直读取到输入缓冲区中的指定 value 的字符串。//// 参数://   value://     指示读取操作停止位置的值。//// 返回结果://     输入缓冲区中直到指定 value 的内容。//// 异常://   T:System.ArgumentException://     长度 value 参数为 0。////   T:System.ArgumentNullException://     value 参数为 null。////   T:System.InvalidOperationException://     指定的端口未打开。////   T:System.TimeoutException://     该操作未完成之前超时期限已结束。public string ReadTo(string value);

3、分机种保存参数

这个之前有用过读写TXT文本,有读写过配置文件,也用过自带的应用程序设置。这次使用的是当前机种存在应用程序设置中,具体机种数据则存在ini文件中。应用程序设置只要配置一下读取和保存,很简单。ini文件的读写麻烦些,将机种名设为Section,将具体的参数作为key的值。

        /// <summary>/// 读取机种参数/// </summary>public void ReadFiles(){try{IniHelper iniHelp = new IniHelper(@".\config.ini", JiZhong);GongDan         = iniHelp.ReadIniData(JiZhong, "GongDan"        );LiHao           = iniHelp.ReadIniData(JiZhong, "LiHao"          );LiHaoZhouQi     = iniHelp.ReadIniData(JiZhong,"LiHaoZhouQi");DianRongGuiGe   = iniHelp.ReadIniData(JiZhong,"DianRongGuiGe");WeiZhi          = iniHelp.ReadIniData(JiZhong,"WeiZhi");PiLiang         = iniHelp.ReadIniData(JiZhong,"PiLiang");YiChangCiShu    = iniHelp.ReadIniData(JiZhong,"YiChangCiShu");ChanLiang       = iniHelp.ReadIniData(JiZhong, "ChanLiang");JiZhongs        = iniHelp.ReadIniData("JiZhongMing", "JiZhongs");}catch (Exception){MessageBox.Show("未找到配置文件,将使用默认配置");}}/// <summary>/// 写入机种参数/// </summary>public void SaveFiles(){string path = @".\config.ini";if(!File.Exists(path)){FileStream fs = new FileStream(path, FileMode.CreateNew);fs.Close();}IniHelper iniHelp = new IniHelper(path, JiZhong);iniHelp.WriteIniData("GongDan"      , GongDan);iniHelp.WriteIniData( "LiHao"        , LiHao        );iniHelp.WriteIniData("LiHaoZhouQi", LiHaoZhouQi  );iniHelp.WriteIniData("DianRongGuiGe", DianRongGuiGe);iniHelp.WriteIniData("WeiZhi", WeiZhi       );iniHelp.WriteIniData("PiLiang", PiLiang      );iniHelp.WriteIniData("YiChangCiShu", YiChangCiShu );iniHelp.WriteIniData( "ChanLiang"    , ChanLiang    );IniHelper iniHelp1 = new IniHelper(path, "JiZhongMing");iniHelp1.WriteIniData( "JiZhongs", JiZhongs      );}

4、将数据写入Excel

这涉及到Excel的读写,之前了解过,但没使用过。网上找到了好几种方案,有使用Office自带库的,有使用各种开源软件的。测试了几种开源工具,都不得其法,后来看用NPOI的很多,而且不需要安装Office,功能也很强大,遂决定采用。通过参考案例,发现还是比较容易使用的。

        /// <summary>/// 向Excel中插入行/// </summary>/// <param name="n">在第几行插入</param>/// <param name="filePath">文件路径</param>/// <param name="RecordData">插入的数据<一维数组></param>public void InsertRow(int n = 1, string filePath = "D:\\RunData\\test.xlsx", string[] RecordData =null){string fileExt = Path.GetExtension(filePath).ToLower();//获取扩展名IWorkbook workbook;using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)){if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(fs); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(fs); } else { workbook = null; }if (workbook == null) { return; }ISheet sheet = workbook.GetSheetAt(0);IRow row = sheet.GetRow(n);//获取第一行if (row != null)//檢查是否有數據,有數據就下移,沒有就直接賦值{//将表格内容整体下移sheet.ShiftRows(n, sheet.LastRowNum, 1);}var newrow = sheet.CreateRow(n);int i = 0;foreach (string v in RecordData){ICell cell = newrow.GetCell(i);if (cell == null){cell = newrow.CreateCell(i);}cell.SetCellValue(v);i++;}FileStream out2 = new FileStream(filePath, FileMode.Create);workbook.Write(out2);out2.Close();}}

当时测试其它开源工具的时候,发现往数据后面添加行很容易,但想把最新数据插入第一行却不容易,后面才转入NPOI的怀抱,因为它有下面这个函数,很合适。

        // 摘要://     Shifts rows between startRow and endRow n number of rows. If you use a negative//     number, it will shift rows up. Code ensures that rows don't wrap around. Calls//     shiftRows(startRow, endRow, n, false, false); Additionally shifts merged regions//     that are completely defined in these rows (ie. merged 2 cells on a row to be//     shifted).//// 参数://   startRow://     the row to start shifting////   endRow://     the row to end shifting////   n://     the number of rows to shiftvoid ShiftRows(int startRow, int endRow, int n);

总结

这个项目虽然不大,但相比我以前做的项目,我在尽可能将代码写得规范容易理解。

  • 将两种通讯协议和读写文件的功能都写成独立的类,使用的时候实例化对应类,再调用方法。
  • 将嵌套过多的程序再提取出独立的方法,让程序更容易理解,vs中的快速操作和重构真的好用。
  • 将运行信息和报错信息,尽可能显示在界面的信息窗口上(因为总信息量不大,所以在界面上显示,要不然就直接存为日志了),对前期查BUG和后期查问题都很有用。
  • 多次使用了开源工具,比如界面图标用了Sunny.UI,读Excel用了NPOI,读ini文件用了IniRW,让开发简单了很多。现在才发现NuGet这个神器真的不应该,对于一些常见的功能实现,使用开源工具可以大幅提高工作效率,而且好的工具也更能保证稳定性。不过对于使用的开源工具遵循怎样的开源协议,不是很明白,有些工具都没找到要遵守什么协议,网上查了也不是很明白。关于这个有解释清晰的资料的,请留言给我,不胜感激。
  • 再次熟悉了委托的使用,因为涉及到多线程的运行信息都显示到界面上,现在控件自带了Invoke方法,使用起来比以前更简单了:
        private delegate void ExecuteWork(string str);private void test(){this.textReceive.Invoke(new ExecuteWork(RecRunData), "运行异常");}private void RecRunData(string reda){if (reda != lastData&&reda.Length>0){string tim = DateTime.Now.ToLongTimeString() + "." + DateTime.Now.Millisecond.ToString() + "--";textReceive.Text = tim + reda + "\n" + textReceive.Text;lastData = reda;}}

而且还一种更简单的,甚至不用先声明委托方法,直接一行就可以搞定:

this.textYield.Invoke(new Action<string>(s => { this.textYield.Text = s; }), "运行情况");

努力方向

  1. 了解开源工具的使用规范,对工具的使用有清晰明确地把握
  2. 继续学习c#的编程知识,并将学到的东西在项目中应用起来
  3. 多阅读开源工具的源代码,提升自己的编程思维

参考文章

  • 第三章——NPOI创建/读取Excel简单案例https://blog.csdn.net/qq_39541254/article/details/107841535
  • SunnyUI的帮助文档https://gitee.com/yhuse/SunnyUI/wikis/pages
  • C# this.Invoke()的作用与用法https://www.cnblogs.com/yunmengyunxi/p/6066262.html
  • 使用NPOI实现在Excel第一行插入文字https://blog.csdn.net/yindi0712/article/details/107410929
  • ……

c#实现上位机数据采集的项目总结相关推荐

  1. ABB机器人、PLC、C#上位机全套程序 项目用的是ABB蜘蛛机器人

    ABB机器人.PLC.C#上位机全套程序 1.项目用的是ABB蜘蛛机器人,六轴用的程序开发都一样 2.上位机与机器人和PLC通讯都是通过以太网总线方式,没有使用传统的IO方式 3.自己写的程序,可提供 ...

  2. ABB机器人、PLC、C#上位机全套程序,项目用的是ABB蜘蛛机器人,六轴用的程序开发都一样

    ABB机器人.PLC.C#上位机全套程序 1.项目用的是ABB蜘蛛机器人,六轴用的程序开发都一样 2.上位机与机器人和PLC通讯都是通过以太网总线方式,没有使用传统的IO方式 3.PLC使用的是200 ...

  3. 上位机软件开发项目案例(一)_C#开发

    了解或咨询 上位机软件开发/LabVIEW软件开发/C#软件开发/QT软件开发,请访问AgainDo再度科技官网:www.againdo.com 概述 该软件为线束连接器自动化生产设备上位机软件,系统 ...

  4. 基于 QT 嵌入式ARM数据采集卡上位机(一)

    基于 QT 嵌入式ARM数据采集卡上位机(一) 下一篇<基于 QT 嵌入式ARM数据采集卡上位机(二)-- 页面布局> 由于自己最近较为闲,刚好手上有设备,所以在业余时间编写了一个上位机和 ...

  5. 基于mpu6050的角速度测量(主控stm32f103 Sram 23LC1024,c#上位机)

    大二时设计过一款角速度测量装置 ,用于测量特定物品的角速度,现整理下.实现效果是 旋转物体开始旋转到停止时,收到上位机信号,将测量数据传给上位机,上位机分析后得出一条角速度曲线. 引言 本项目是基于s ...

  6. Zigbee无线传感网 CC2530+DHT11DS18B20 温湿度采集 串口上位机显示

    文章目录 一.介绍 二.上位机数据采集 (一)采集数据 (二)拓扑结构 (三)新节点加入网络 (四)节点事件 三.实现分析 (一)配置文件 (二)发送 (三)短地址和数据获取 (四)数据包分析 (五) ...

  7. (项目实战)基于QT嵌入式ARM数据采集卡上位机(二)——页面布局

    (项目实战)基于QT嵌入式ARM数据采集卡上位机(二)--页面布局 上一篇文章<基于 QT 嵌入式ARM数据采集卡上位机(一)> 下一篇文章<(项目实战)基于QT嵌入式ARM数据采集 ...

  8. 数据采集---自制上位机界面接收单片机uart数据

    现如今大多数的设备都是通过仪器设备而不是通过人力耗时耗力地去进行监测了,自动化的普及解放了大量的劳动力.那今天就讲一下我自己制作的一个自动采集单片机发送数据给pc机的小项目吧.其中需要大家自己准备的材 ...

  9. 上位机与PLC通讯及OPC数据采集实践一

    上位机与PLC通讯及OPC数据采集实践一 背景 由于项目的需要,上位机(工控机)需要与PLC通讯(AB的PLC)通过PLC控制相关的设备:另一部分需要做一个数据采集程序从一个OPC服务器(此服务器作为 ...

最新文章

  1. 【Flutter】StatefulWidget 组件 ( 创建 StatefulWidget 组件 | MaterialApp 组件 | Scaffold 组件 )
  2. Spring Boot 2.0(三):Spring Boot 开源软件都有哪些?
  3. RecyclerView的使用和样式
  4. php文件覆盖相同文件,为什么这个PHP代码在打开时会覆盖文件内容?
  5. py2neo database
  6. PyTorch-Transformers:一款可处理最先进NLP的惊人模型库
  7. linux基础(四)——任务调度cron和anacron
  8. FineReport帆软报表的安装
  9. html仿百度贴吧,利用Canvas模仿百度贴吧客户端loading小球的方法示例
  10. H3C无线AP 瘦模式转胖模式 fit转fat
  11. .Net framework3.5装不上解决之道错误代码 0x800F0906、0x800F081F
  12. android计算器退格键,计算器有关问题,如何写退格键
  13. 科研,办公几款强大又实用的软件(含安装包)
  14. Winrar制作自解压安装程序
  15. android createbitmap设置背景色,Android createBitmap截取实现移动的游戏背景
  16. Input Leakage Current
  17. dpi和ppi换算_dpi换算(dpi换算网站)
  18. 服务器2012系统用什么更新驱动程序,服务堆栈更新程序适用于 Windows 8 和 Windows Server 2012...
  19. 【Pygame实战】风靡全球的切水果游戏升级版“水果忍者”上线啦,你敢来PK嘛?
  20. 温州中学高考2021成绩查询,2021年温州高考各高中成绩及本科升学率数据排名及分析...

热门文章

  1. CSS_渐变过渡_动画
  2. 服务器加密芯片市场空间,2020国密算法芯片行业发展趋势及市场规模分析
  3. Levinson-Durbin算法原理推导(Hermitian Toeplitz矩阵,包括实数和复数情况)
  4. 设计一个课程类,包括课程编号、课程名称、任课教师、上课地点等属性,把上课地点变量设为私有的,增加构造方法和显示课程信息的方法。
  5. 地理信息系统入门基础篇(二)---地图投影
  6. Telegram之tdesktop源码编译
  7. 论文、报告及教案公式编辑:图片公式转换Mathpix snipping Tool、快速编辑神器AxMath插件操作使用的几种用法(最详细精致)
  8. oracle常用sql语句
  9. 寒冬+裁员,互联网行业还好吗?
  10. Http非80端口的解析问题