物联网浏览器(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

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