在ERP系统中,采集一线的生产数据是重要工作之一,而称重计量是企业的核心资产数据,人工计重费时费力,还容易出错,重量数据是否正确,直接影响企业的采购或销售额。基于此,由系统对接电子秤实现自动抓取数据是企业管理的第一步。
电子秤,一般由重量传感器、砝码、底座、仪表等组成。仪表与传感器相连,仪表一般具有记录皮重、归零等基本功能,大部分的仪表厂家都包含了串口数据对接的接口,满足企业的数据采集需求。
采集数据一般使用DB9 RS232串口线,连接电脑的串口,但是现代电脑基本没有保留串口头,可以购买RS232串口转USB转接线。
重点来了,上位机如何采集仪表的重量数据?
根据不同厂家的型号不同数据协议也有所不同,以耀华XK3190-A9这款为例,厂家协议的说明:
协议规定了,起止位、数据位、符号、小数点位置、校验位等参数说明,根据这个协议进行解析就可以形成上位机的重量数据。
核心代码:
/// <summary> /// 耀华A9称重数据 /// </summary> /// <param name="byteFrame">帧数据</param> private string ConvertWeight(byte[] byteFrame) { string value = string.Empty; if (byteFrame == null || byteFrame.Length == 0) { return value; } //对接收到的数据进行校验 byte byteVerif = (byte)(byteFrame[1] ^ byteFrame[2] ^ byteFrame[3] ^ byteFrame[4] ^ byteFrame[5] ^ byteFrame[6] ^ byteFrame[7] ^ byteFrame[8]); //校验高位 byte verifHigh = (byte)((byteVerif & 0xf0) >> 4); //校验低位 byte verifLow = (byte)(byteVerif & 0x0f); if (verifHigh > 9) verifHigh = (byte)(verifHigh + 0x37); else verifHigh = (byte)(verifHigh + 0x30); if (verifLow > 9) verifLow = (byte)(verifLow + 0x37); else verifLow = (byte)(verifLow + 0x30); if (byteFrame[9] == verifHigh && byteFrame[10] == verifLow) { List<byte> listDigit = new List<byte>() { (byte)0x30, (byte)0x31, (byte)0x32, (byte)0x33, (byte)0x34, (byte)0x35, (byte)0x36, (byte)0x37, (byte)0x38, (byte)0x39 }; StringBuilder sbDigit = new StringBuilder(); //获取称重数据 for (int i = 2; i < 8; i++) { if (!listDigit.Contains(byteFrame[i])) byteFrame[i] = (byte)0x30; sbDigit.Append(byteFrame[i] - 0x30); } //小数点位置 int dotPos = byteFrame[8] - 0x30; int exponent = -dotPos; double weightValue = Convert.ToInt32(sbDigit.ToString()) * Math.Pow(10, exponent); //负数处理 if (byteFrame[1] == 0x2D) weightValue = -weightValue; value = FormatWeight(weightValue); } return value; }
同一厂家不同型号的仪表,定义的协议都不一样,这点比较费事。所以在开发这类需求的时候,可以考虑统一封装一个称重基础类,定义初始化、打开串口、关闭串口、获取重量等通用接口,不同型号使用子类实现业务逻辑。这样外层的调用,不需要关心每个仪表型号。如果考虑插播服务,可以使用插件式开发,原理就是使用反射扫描读取外部dll,只要实现了基类就可以热加载称重驱动。
/// <summary> /// 查找外部电子秤驱动 /// 路径:{root}/ /// </summary> /// <param name="type">类型</param> /// <returns></returns> public static WeightBase FindExt(string type) { WeightBase WeighBase = null; string dirName = AppDomain.CurrentDomain.BaseDirectory + "plugins\\weight"; // 扫描外部电子秤驱动 if (System.IO.Directory.Exists(dirName)) { var files = System.IO.Directory.GetFiles(dirName); foreach (var file in files) { var ext = file.Substring(file.LastIndexOf('.') + 1); if (ext == "dll" || ext == "exe") { var ass = Assembly.LoadFrom(file); if (ass != null) { WeighBase = Find(ass, type); if (WeighBase != null) { break; } } } } } return WeighBase; } public static bool IsScale(Type t) { var tWeighBase = typeof(WeightBase); if (t.BaseType == null) return false; return t.BaseType == tWeighBase || t.BaseType.BaseType == tWeighBase;// 子及孙 }
本人开发的这款PC称重软件就是使用了这种方案,可以在不升级主程序的情况下,随时支持一款仪表驱动。
有兴趣的可以看下这个:基于Chromium开发的称重软件,集称重、计价、打印于一体,支持耀华、顶尖等多个厂家设备型号
标签:插件,ERP,byteFrame,串口,byte,verifHigh,verifLow,称重 From: https://www.cnblogs.com/yizhuqing/p/17027177.html