本教程基於 物聯網瀏覽器(IoTBrowser)-Web串口自定義開發 ,詳細的過程可以翻看之前的文章。
本篇以實現頂尖OS2系列電子秤協議對接,並集成到IoTBrowser平臺。由於沒有找到OS2協議的官方文檔,用串口助手抓包分析了一下,簡單封裝了一下實現代碼有點潦草。
所有的串口或者需要實時數據同步的業務都可以集成ComBase類,重量數據採集是典型的實時推送場景,由於電子秤基本只需要推送重量,需要往串口寫數據,所以不需要實現發送數據接口。
代碼如下:
using DDS.IoT.Com; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace DDS.IoT.DJ { public class Os2Driver : ComBase { public override string Type => "DJ_Os2"; public override string Name => "頂尖OS2"; /// <summary> /// 最近一次重量 /// </summary> private string _lastValue = string.Empty; private object _locker = new object(); public override bool Init(int port, int baudRate = 9600, string extendData = null) { if (SP == null) { this.Port = port; var portName = "COM" + port; SP = new SerialPort(portName); base.PortName = portName; SP.BaudRate = baudRate; SP.Parity = System.IO.Ports.Parity.None; SP.DataBits = 8; SP.StopBits = System.IO.Ports.StopBits.One; //SP.DtrEnable = true; //SP.RtsEnable = true; SP.DataReceived += SP_DataReceived; Console.WriteLine("初始化Os2驅動程序成功!"); } return true; } private void SP_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { lock (_locker) { if (false == SP.IsOpen) return; int bytesRead = SP.BytesToRead;//獲取接收緩衝區中數據的字節數 if (bytesRead < 16) { return; } byte[] bytesData = new byte[16]; //var strData = "1,2,83,45,48,48,46,48,49,56,107,103,101,3,4,0"; SP.Read(bytesData, 0, 16); if (bytesData[0] != 0x01) { SP.DiscardInBuffer(); return; } List<byte> buffer = new List<byte>(); buffer.AddRange(bytesData); SP.DiscardInBuffer(); var weight = ConvertWeight(buffer); // 驗證數據是否有效,且與上一次數據不一致 if (weight != this.Data) { if (this.OnPushData != null) { this.OnPushData(this.Id,weight);// 觸發事件 this.Data = weight; } } } } catch (Exception ex) { Console.WriteLine("串口操作失敗:" + ex.Message); } } /// <summary> /// Os2稱重數據--讀取字節爲十進制數據 0x爲十六進制 /// </summary> /// <param name="byteFrame">幀數據(兩位wn+8位數據帶小數點+kg+兩個固定字節回車換行)</param> private float ConvertWeight(List<byte> byteFrame) { float value = 0f; if (byteFrame == null || byteFrame.Count == 0) { return value; } if (true) { byte[] byteData = new byte[9]; byteFrame.CopyTo(3, byteData, 0, 9); string weightData = Encoding.ASCII.GetString(byteData).Replace("kg", "").Replace("g", ""); value = float.Parse(weightData); } return value; } public bool Opened = false; public override event PushData OnPushData; public override bool Open() { var b = false; try { if (!Opened) SP.Open(); b = true; Opened = true; } catch (Exception ex) { string msg = string.Format("Os2串口打開失敗:{0} ", ex.Message); Console.WriteLine(msg); } return b; } public override bool Close() { if (SP.IsOpen) SP.Close(); Opened = false; OnPushData = null; return true; } } }
同樣,先需要本地測試,所以需要在main方法中編寫測試代碼。
static void Main(string[] args) { var ok = false; do { Os2Driver driver = new Os2Driver(); driver.OnPushData += OnPushData; Console.Write("請輸入串口號:"); var port = Convert.ToInt32(Console.ReadLine()); ok=driver.Init(port); ok = driver.Open(); if(ok) Console.Write("打開成功,重量監聽中..."); } while (!ok); Console.ReadLine(); } private static void OnPushData(string id, dynamic weight) { Console.WriteLine(DateTime.Now.ToString()+ ":" + weight); }
本地編譯,拷貝到Plugins/Com文件夾下,在IoTBrowser中將驅動型號改爲DJ_Os2,串口號根據實際情況填寫即可。
示例代碼:
https://gitee.com/yizhuqing/IoTBrowser/tree/master/Plugins/DDS.IoT.DJ