• 物联网浏览器(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";
    
            /// 
            /// 最近一次重量
            /// 
            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);
                }
            }
    
            /// 
            /// Os2称重数据--读取字节为十进制数据 0x为十六进制
            /// 
            /// 帧数据(两位wn+8位数据带小数点+kg+两个固定字节回车换行)
            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

  • 相关阅读:
    Coursera: An Introduction to American Law 学习笔记 Week 02: Contract Law
    最高提升10倍性能!揭秘火山引擎ByteHouse查询优化器实现方案
    网络安全深入学习第四课——热门框架漏洞(RCE— Log4j2远程代码执行)
    CSS 变量的优势
    Allure精通指南(01)介绍与基本使用
    TVS管和ESD管的技术指标和选型指南-嘉立创推荐
    SpringBoot 源码学习——SpringBoot 自动装配源码解析 +Spring 如何处理配置类的
    LeetCode_279_完全平方数
    FlinkSQL 窗口聚合
    python基于GDAL的多线程高速批量重采样、对齐栅格、对齐行列数,并无损压缩
  • 原文地址:https://www.cnblogs.com/yizhuqing/p/17988086