物聯網瀏覽器(IoTBrowser)-頂尖OS2電子秤協議實現

本教程基於  物聯網瀏覽器(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章