《物联网框架ServerSuperIO教程》-4.如开辟一套设备

作者:编程技术

4.3.4    创设筑组织商驱动对象... 6

4.4    创设宿主程序

     贰个简练的设施驱动就已经支付好了,光有驱动还极度,那么大家依据SSIO框架再写几行代码,完毕一个宿主程序,把设备驱动实例化,放SSIO的劳动实例中运作,完结串口和网络二种格局的报导交互,代码也很轻便。代码如下:

class Program
{
        static void Main(string[] args)
        {
            DeviceDriver dev1 = new DeviceDriver();
            dev1.DeviceParameter.DeviceName = "串口设备1";
            dev1.DeviceParameter.DeviceAddr = 0;
            dev1.DeviceParameter.DeviceID = "0";
            dev1.DeviceDynamic.DeviceID = "0";
            dev1.DeviceParameter.COM.Port = 1;
            dev1.DeviceParameter.COM.Baud = 9600;
            dev1.CommunicateType = CommunicateType.COM;
            dev1.Initialize("0");

            DeviceDriver dev4 = new DeviceDriver();
            dev4.DeviceParameter.DeviceName = "网络设备2";
            dev4.DeviceParameter.DeviceAddr = 0;
            dev4.DeviceParameter.DeviceID = "3";
            dev4.DeviceDynamic.DeviceID = "3";
            dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1";
            dev4.DeviceParameter.NET.RemotePort = 9600;
            dev4.CommunicateType = CommunicateType.NET;
            dev4.Initialize("3");

            IServer server = new ServerFactory().CreateServer(new ServerConfig()
            {
                ServerName = "服务实例1",
                SocketMode = SocketMode.Tcp,
                ControlMode = ControlMode.Loop,
                CheckSameSocketSession = false,
                StartCheckPackageLength = false,
            });

            server.AddDeviceCompleted  = server_AddDeviceCompleted;
            server.DeleteDeviceCompleted  = server_DeleteDeviceCompleted;
            server.SocketConnected =server_SocketConnected;
            server.SocketClosed =server_SocketClosed;
            server.Start();

            server.AddDevice(dev1);
            server.AddDevice(dev4);

            while ("exit"==Console.ReadLine())
            {
                 server.Stop();
            }
        }

        private static void server_SocketClosed(string ip, int port)
        {
            Console.WriteLine(String.Format("断开:{0}-{1} 成功", ip, port));
        }

        private static void server_SocketConnected(string ip, int port)
        {
            Console.WriteLine(String.Format("连接:{0}-{1} 成功",ip, port));
        }

        private static void server_AddDeviceCompleted(string devid, string devName, bool isSuccess)

        {
            Console.WriteLine(devName ",增加:" isSuccess.ToString());
        }

        private static void server_DeleteDeviceCompleted(string devid, string devName, bool isSuccess)
        {
            Console.WriteLine(devName   ",删除:"   isSuccess.ToString());
        }
    }
}

     这么些代码大家都能看理解,具体的操纵格局大家接下去会相继介绍。在营造宿主程序的时候,切忌对服务实例那样引用:server.ChannelManager、server.ControllerManager、server.DeviceManager。尽管提供了这么的接口,重即使为了SSIO框架之中使用的,无需大家单独去操作这么些接口。有的网上亲密的朋友是那般的写的,那么就成为了二个纯的通讯IO框架,那么就错过了SSIO框架本人的价值。作为二回开采者,只必要设置设备驱动的参数,以至向服务实例中追加或删除设备就行了,别的具备的运维总体交由SSIO框架来实现。

1.C#跨平台物联网通信框架ServerSuperIO(SSIO)介绍

4.3.4    创设筑组织商驱动对象

    有了公约命令之后,大家要求营造筑组织商驱动对象,SSIO框架支持自定义谐和也在于此,而且与设施驱动的接口相关联,在SSIO框架的高等应用中也进展了引用,创设那引对象十分重大。代码如下:

internal class DeviceProtocol:ProtocolDriver
{
        public override bool CheckData(byte[] data)
        {
            if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public override byte[] GetCommand(byte[] data)
        {
            return new byte[] { data[3] };
        }

        public override int GetAddress(byte[] data)
        {
            return data[2];
        }

        public override byte[] GetHead(byte[] data)
        {
            return new byte[] { data[0], data[1] };
        }

        public override byte[] GetEnd(byte[] data)
        {
            return new byte[] { data[data.Length - 1] };
        }

        public override byte[] GetCheckData(byte[] data)
        {
            byte checkSum = 0;
            for (int i = 2; i < data.Length - 2; i  )
            {
                checkSum  = data[i];
            }
            return new byte[] { checkSum };
        }

        public override string GetCode(byte[] data)
        {
            throw new NotImplementedException();
        }

        public override int GetPackageLength(byte[] data, IChannel channel, ref int readTimeout)
        {
           throw new NotImplementedException();
        }
}

     DeviceProtocol 合同驱动承袭自ProtocolDriver ,叁个设备驱动只存在二个合同驱动,二个左券驱动能够存在八个公约命令(如61指令)。该类中的CheckData函数很重点,SSIO框架中的设备驱动基类引用了,首如果落成校验接收数据的完事性,是或不是相符合同,进而决定了电视发表状态:通信不奇怪、通信中断、通信苦恼、以至通信未知,分裂的简报状态也决定了调用设备驱动中的哪个函数接口:Communicate、CommunicateInterrupt、CommunicateError和CommunicateNone。

4.5           运转效果... 15

4.如开拓一套装置驱动,同分外间援助串口和互联网通信

 

4.3.1    创设实时数据持久对象(不是必得)

1.透过重回数据的报纸发表公约,有流量和实信号多少个动态变量,大家须求创立二个动态目的实体类,首要用于公约驱动与设备驱动之间的数码交互。代码如下:

public class Dyn
{
        private float _Flow = 0.0f;
        /// <summary>
        /// 流量
        /// </summary>
        public float Flow
        {
            get { return _Flow; }
            set { _Flow = value; }
        }
        private float _Signal = 0.0f;
        /// <summary>
        /// 信号
        /// </summary>
        public float Signal
        {
            get { return _Signal; }
            set { _Signal = value; }
        }
}

  2.我们主要的办事是要开创一个实时数据长久对象类,实时缓存数据音讯,也足以把该实时数据音讯保存到数据库中或其余存款和储蓄媒质。实时多少长久对象类的代码如下:

public class DeviceDyn:DeviceDynamic
{
        public DeviceDyn() : base()
        {
            Dyn=new Dyn();
        }
        public override string GetAlertState()
        {
            throw new NotImplementedException("无报警信息");
        }
        public override object Repair()
        {
            return new DeviceDyn();
        }
        public Dyn Dyn { get; set; }
}

     DeviceDyn 类传承自DeviceDynamic,因为种种硬件设施的告急音信有望不均等,所以GetAlertState函数能够实该功用,不过SSIO框架并不曾直接援引;那一个类精神上是多少个得以系列化,在不加互斥的情景下只怕导致文件损坏,所以Repair能够做到修复效果与利益,在DeviceDynamic基类里达成了该成效;其他,达成DeviceDynamic基类自带八个函数,Save函数用于持久化(种类化)此类的音讯,Load用于获取(反种类化)此类的新闻,在器械驱动中得以使用。

4.2    通信合同规定

    在成就叁个配备驱动的付出从前,首先要驾驭它的通信公约,好比五人调换的语言同样。针对广播发表协议,大家自定义三个粗略交互格局,只是发送命令,提取数额信息。

4.5    运行作效果果

 分分快三计划 1

 

1.[连载]《C#通信(串口和互联网)框架的设计与达成》

2.[开源]C#跨平台物联网通信框架ServerSuperIO(SSIO)介绍

2.利用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)构建系统的总体方案

3.C#工业物联网和集成系统应用方案的技巧路径(数据源、数据搜罗、数据上传与摄取、ActiveMQ、Mongodb、WebApi、手提式有线电话机App)

5.ServerSuperIO开源地址:

物联网&集成技能(.NET) QQ群54256083

10 IOT,win10iot 1.C#跨平台物联网通讯框...

《连载 | 物联网框架ServerSuperIO教程》- 3.设施驱动介绍

《物联网框架ServerSuperIO教程》-4.如开拓一套设备驱动,同期扶助串口和网络通讯。附:以后支撑Windows 10 IOT,win10iot

1.C#跨平台物联网通信框架ServerSuperIO(SSIO)介绍

《连载 | 物联网框架ServerSuperIO教程》1.4种简报格局机制。

《连载 | 物联网框架ServerSuperIO教程》2.服务实例的布署参数表明

《连载 | 物联网框架ServerSuperIO教程》- 3.道具驱动介绍

 

注:ServerSuperIO有非常的大可能率被移植到Windows 10 IOT上,那么以后有极大可能付出一套设备驱动,可以分段在服务端、嵌入式设备中,将形成完整的解决方案。

      现在一度调节和测量试验通过有个别代码,还得须要一段时间,经常都以夜间干,时间也有数。如下图:

分分快三计划 2

 

目       录

4.如开荒一套装置驱动,同一时间帮助串口和互联网通信... 2

4.1           概述... 2

4.2           通信协议显明... 2

4.2.1    发送读实时数据命令公约... 2

4.2.2    深入分析实时数据合同... 3

4.2.3    发送和接收数据事例... 3

4.3           开拓设备驱动... 3

4.3.1    营造实时数据悠久对象(不是必需)... 3

4.3.2    营造参数数据漫长对象... 5

4.3.3    营造发送和分析合同命令对象... 5

4.3.4    塑造筑组织商驱动对象... 6

4.3.5    塑造设备驱动对象... 8

4.4           创设宿主程序... 12

4.5           运营作效果果... 15

 

 

4.2.2    分析实时数据左券... 3

4.3    开拓设备驱动

 

4.3.3    创设发送和深入分析合同命令对象

    与器材进行交互会涉及到不菲交互式的下令或指令代码,而这一个命令在SSIO框架内是以商业事务命令对象的样式存在,概况包涵多个部:推行命令接口、打包发送数据接口、剖析接收数据接口等。

    针对地点的通信左券,有八个61限令,那么大家就能够依照61下令为命名创设三个磋商命令对象,包罗发送数据和深入分析数据部分。假设有此外命令代码,问牛知马。代码如下:

internal class DeviceCommand:ProtocolCommand
{
        public override string Name
        {
            get { return "61"; }
        }

        public override void ExcuteCommand<T>(T t)
        {
            throw new NotImplementedException();
        }

        public override byte[] Package<T> (string code, T1 t1,T2 t2)
        {
            //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
            byte[] data = new byte[6];
            data[0] = 0x55;
            data[1] = 0xaa;
            data[2] = byte.Parse(code);
            data[3] = 0x61;
            data[4] = this.ProtocolDriver.GetCheckData(data)[0];
            data[5] = 0x0d;
            return data;
        }

        public override dynamic Analysis<T>(byte[] data, T t)
        {
            Dyn dyn = new Dyn()
            //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
            byte[] flow = BinaryUtil.SubBytes(data, 4, 4, true);
            dyn.Flow = BitConverter.ToSingle(flow, 0);
            byte[] signal = BinaryUtil.SubBytes(data, 8, 4, true);
            dyn.Signal = BitConverter.ToSingle(signal, 0);
            return dyn;
        }

}

     营造筑组织议命令须求方方面面接续自ProtocolCommand,依照报纸发表左券规定,Name属性再次回到61,作为重大字;Package是包装要送的数目音信;Analysis对应着接收数据之后进展分析操作。如同此四个差不离的左券命令驱动就塑造完毕了。

目       录

4.2.1    发送读实时数据命令公约

     Computer发送0x61命令为读实时数据命令,共发送6个字节,校验和为从“从机地址”初叶的拉长和,不满含“数据报头”、“校验和”和“左券甘休”。

     发送指令数据帧如下:

帧结构

数量报头

从机地址

指令代码

校验和

磋商甘休

0x55

0xAA

 

0x61

 

0x0D

字节数

1

1

1

1

1

1

  

4.3.1    营造实时数据长久对象(不是必需)

1.由此再次来到数据的报导公约,有流量和时限信号七个动态变量,大家须求制造一个动态目的实体类,首要用以公约驱动与设备驱动之间的数据交互。代码如下:

public class Dyn
{
        private float _Flow = 0.0f;
        /// <summary>
        /// 流量
        /// </summary>
        public float Flow
        {
            get { return _Flow; }
            set { _Flow = value; }
        }
        private float _Signal = 0.0f;
        /// <summary>
        /// 信号
        /// </summary>
        public float Signal
        {
            get { return _Signal; }
            set { _Signal = value; }
        }
}

  2.我们器重的干活是要开创一个实时数据漫长对象类,实时缓存数据消息,也得以把该实时数据信息保存到数据库中或任何存款和储蓄媒质。实时数据长久对象类的代码如下:

public class DeviceDyn:DeviceDynamic
{
        public DeviceDyn() : base()
        {
            Dyn=new Dyn();
        }
        public override string GetAlertState()
        {
            throw new NotImplementedException("无报警信息");
        }
        public override object Repair()
        {
            return new DeviceDyn();
        }
        public Dyn Dyn { get; set; }
}

     DeviceDyn 类承接自DeviceDynamic,因为各样硬件设备的报告急察方音讯有十分大希望不相同样,所以GetAlertState函数能够实该作用,但是SSIO框架并不曾一贯引用;这么些类精神上是一个足以类别化,在不加互斥的景色下也许导致文件损坏,所以Repair能够完结修复功效,在DeviceDynamic基类里福寿绵绵了该意义;别的,完结DeviceDynamic基类自带三个函数,Save函数用于持久化(类别化)此类的音讯,Load用于获取(反系列化)此类的音讯,在设施驱动中得以应用。

4.2.3    发送和接收数据事例

出殡(十六进制):0x55 0xaa 0x00 0x61 0x61 0x0d

摄取(十六进制):0x55 0xaa 0x00 0x61 0x43 0x7a 0x00 0x00 0x43 0xb4 0x15 0x0d

流量数据为:250.00

连续信号数据为:360.00

4.2           通讯左券明显... 2

4.1    概述

     作为物联网通信框架,明确要扶助五种通信链路,在四种简报链路的基础上成功多样简报公约的相互,举个例子:Modbus、自定义协商等等。不过,有二个难点:针对同一台硬件设备或传感器,达成串口和网络三种简报形式的数目采撷和调整,是或不是要分别写代码?一经从现实角度分析,同一硬件,它要形成的职业逻辑断定是均等的,所以ServerSuperIO物联网框架,允许开辟一套设备驱动,同一时候帮衬串口和网络二种简报情势的相互。

     通信很轻巧、交互很简短、业务很简短……借使把广大简短的难题合在一齐,那么就变得不轻松了,所以要有三个框架性的东西,重新把数不尽标题变得简单。

4.3.5    构建设备驱动对象

     下边包车型地铁底蕴专业都做完之后,现在就构建设备驱动的中坚部分,也正是SSIO框架与设施驱动对接、和睦、调度的举世无双接口,写完那一个接口,设备驱动就可以在SSIO上一贯运转了,何况与硬件配备开展互相。间接上代码:

public class DeviceDriver:RunDevice
{
        private DeviceDyn _deviceDyn;
        private DevicePara _devicePara;
        private DeviceProtocol _protocol;
        public DeviceDriver() : base()
        {
            _devicePara = new DevicePara();
            _deviceDyn = new DeviceDyn();
            _protocol = new DeviceProtocol();
        }

        public override void Initialize(string devid)
        {
            this.Protocol.InitDriver(this.GetType(),null);
            //初始化设备参数信息
            _devicePara.DeviceID = devid;//设备的ID必须先赋值,因为要查找对应的参数文件。
            if (System.IO.File.Exists(_devicePara.SavePath))
            {
                //如果参数文件存在,则获得参数实例
                _devicePara = _devicePara.Load<DevicePara>();
            }
            else
            {
                //如果参数文件不存在,则序列化一个文件
                _devicePara.Save<DevicePara>(_devicePara);
            }

            //初始化设备实时数据信息
            _deviceDyn.DeviceID = devid;//设备的ID必须先赋值,因为要查找对应的实时数据文件。
            if (System.IO.File.Exists(_deviceDyn.SavePath))
            {
                //参数文件存在,则获得参数实例
                _deviceDyn = _deviceDyn.Load<DeviceDyn>();
            }
            else
            {
                //如果参数文件不存在,则序列化一个文件
                _deviceDyn.Save<DeviceDyn>(_deviceDyn);
            }
        }

        public override byte[] GetConstantCommand()
        {
            return this.Protocol.DriverPackage<String>("0", "61", null);
        }

        public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
        {
            Dyn dyn = this.Protocol.DriverAnalysis<String>("61", info.Data, null);
            if (dyn != null)
            {
                _deviceDyn.Dyn = dyn;
            }
            OnDeviceRuningLog("通讯正常");
        }

        public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
        {
            OnDeviceRuningLog("通讯中断");
        }

        public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
        {
            OnDeviceRuningLog("通讯干扰");
        }

        public override void CommunicateNone()
        {
            OnDeviceRuningLog("通讯未知");
        }

        public override void Alert()
        {
            return;
        }

        public override void Save()
        {
            try
            {
                _deviceDyn.Save<DeviceDyn>(_deviceDyn);
            }
            catch (Exception ex)
            {
                OnDeviceRuningLog(ex.Message);
            }
        }

        public override void Show()
        {
            List<string> list=new List<string>();
            list.Add(_devicePara.DeviceName);
            list.Add(_deviceDyn.Dyn.Flow.ToString());
            list.Add(_deviceDyn.Dyn.Signal.ToString());
            OnDeviceObjectChanged(list.ToArray());
        }

        public override void UnknownIO()
        {
            OnDeviceRuningLog("未知通讯接口");
        }

        public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)
        {
            OnDeviceRuningLog("通讯状态改变");
        }

        public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
        {
            OnDeviceRuningLog("通道状态改变");
        }

        public override void Exit()
        {
            OnDeviceRuningLog("退出设备");
        }

        public override void Delete()
        {
            OnDeviceRuningLog("删除设备");
        }

        public override object GetObject()
        {
            throw new NotImplementedException();
        }

        public override void ShowContextMenu()
        {
            throw new NotImplementedException();
        }

        public override IDeviceDynamic DeviceDynamic
        {
            get { return _deviceDyn; }
        }

        public override IDeviceParameter DeviceParameter
        {
            get { return _devicePara; }
        }

        public override IProtocolDriver Protocol
       {
            get { return _protocol;}
        }

        public override DeviceType DeviceType
        {
            get { return DeviceType.Common; }
        }

        public override string ModelNumber
        {
            get { return "serversuperio"; }
        }

        public override System.Windows.Forms.Control DeviceGraphics
        {
            get { throw new NotImplementedException(); }
        }
}

    实时动态数据对象_deviceDyn、参数数据对象_devicePara、左券驱动对象_protocol分别提供给接口:DeviceDynamic、DeviceParameter和Protocol,为SSIO提供可援引的根底属性参数。

     Initialize是设备驱动最初化的函数接口,在这里个接口达成八个关键工作:初阶化合同驱动和参数性的新闻。通过this.Protocol.InitDriver(this.GetType(),null);代码能够加载全体公约命令到协商驱动的缓存中,以便实时调用。当然这里边也得以打开别的方面包车型的士干活,可是注意对那多少个的管理。

     DeviceType那么些是设备的连串,日常钦命为Common就好了。别的函数接口效用已经在《物联网框架ServerSuperIO教程-3.设备驱动介绍》中详细介绍了,请参照他事他说加以考察。

4.3.2    创设参数数据悠久对象

    日常的话硬件配备会有读参数的下令,那么重返来的参数也须要实行长久化存储,并且每台设备的参数都或者不均等,在那提供二个可增添的接口。在这里个电视发表左券中并不曾关系到器械参数相关的商量表达,可是大家也急需创制四个参数数据漫长对象类,能够不写任何扩充的参数属性,在SSIO框架对参数的接口进行了援引,那是必需开展了专门的学问。代码如下:

public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
        public override object Repair()
        {
            return new DevicePara();
        }
}

     DevicePara承袭自DeviceParameter类,情状与实时数据长久对象类似,能够参数。

4.1    概述

     作为物联网通信框架,确定要协助多种通信链路,在多种简报链路的基础上做到多样广播发表左券的相互,譬如:Modbus、自定义商量等等。但是,有一个难题:针对同一台硬件设备或传感器,达成串口和互联网两种简报格局的数目搜集和调控,是或不是要分头写代码?要是从切实角度解析,同一硬件,它要成功的专业逻辑肯定是一模一样的,所以ServerSuperIO物联网框架,允许开辟一套装置驱动,同临时候扶植串口和互连网二种简报格局的相互。

     通信很简单、交互很简短、业务很简短……假如把不计其数大约的难题合在一同,那么就变得不轻松了,所以要有叁个框架性的事物,重新把广大题目变得简单。

4.3.5    营造设备驱动对象

     上边的底蕴职业都做完以往,现在就营造设备驱动的主导部分,也正是SSIO框架与设施驱动对接、和谐、调整的独一接口,写完那几个接口,设备驱动就足以在SSIO上向来运营了,并且与硬件配备进行互动。直接上代码:

public class DeviceDriver:RunDevice
{
        private DeviceDyn _deviceDyn;
        private DevicePara _devicePara;
        private DeviceProtocol _protocol;
        public DeviceDriver() : base()
        {
            _devicePara = new DevicePara();
            _deviceDyn = new DeviceDyn();
            _protocol = new DeviceProtocol();
        }

        public override void Initialize(string devid)
        {
            this.Protocol.InitDriver(this.GetType(),null);
            //初始化设备参数信息
            _devicePara.DeviceID = devid;//设备的ID必须先赋值,因为要查找对应的参数文件。
            if (System.IO.File.Exists(_devicePara.SavePath))
            {
                //如果参数文件存在,则获得参数实例
                _devicePara = _devicePara.Load<DevicePara>();
            }
            else
            {
                //如果参数文件不存在,则序列化一个文件
                _devicePara.Save<DevicePara>(_devicePara);
            }

            //初始化设备实时数据信息
            _deviceDyn.DeviceID = devid;//设备的ID必须先赋值,因为要查找对应的实时数据文件。
            if (System.IO.File.Exists(_deviceDyn.SavePath))
            {
                //参数文件存在,则获得参数实例
                _deviceDyn = _deviceDyn.Load<DeviceDyn>();
            }
            else
            {
                //如果参数文件不存在,则序列化一个文件
                _deviceDyn.Save<DeviceDyn>(_deviceDyn);
            }
        }

        public override byte[] GetConstantCommand()
        {
            return this.Protocol.DriverPackage<String>("0", "61", null);
        }

        public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
        {
            Dyn dyn = this.Protocol.DriverAnalysis<String>("61", info.Data, null);
            if (dyn != null)
            {
                _deviceDyn.Dyn = dyn;
            }
            OnDeviceRuningLog("通讯正常");
        }

        public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
        {
            OnDeviceRuningLog("通讯中断");
        }

        public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
        {
            OnDeviceRuningLog("通讯干扰");
        }

        public override void CommunicateNone()
        {
            OnDeviceRuningLog("通讯未知");
        }

        public override void Alert()
        {
            return;
        }

        public override void Save()
        {
            try
            {
                _deviceDyn.Save<DeviceDyn>(_deviceDyn);
            }
            catch (Exception ex)
            {
                OnDeviceRuningLog(ex.Message);
            }
        }

        public override void Show()
        {
            List<string> list=new List<string>();
            list.Add(_devicePara.DeviceName);
            list.Add(_deviceDyn.Dyn.Flow.ToString());
            list.Add(_deviceDyn.Dyn.Signal.ToString());
            OnDeviceObjectChanged(list.ToArray());
        }

        public override void UnknownIO()
        {
            OnDeviceRuningLog("未知通讯接口");
        }

        public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)
        {
            OnDeviceRuningLog("通讯状态改变");
        }

        public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
        {
            OnDeviceRuningLog("通道状态改变");
        }

        public override void Exit()
        {
            OnDeviceRuningLog("退出设备");
        }

        public override void Delete()
        {
            OnDeviceRuningLog("删除设备");
        }

        public override object GetObject()
        {
            throw new NotImplementedException();
        }

        public override void ShowContextMenu()
        {
            throw new NotImplementedException();
        }

        public override IDeviceDynamic DeviceDynamic
        {
            get { return _deviceDyn; }
        }

        public override IDeviceParameter DeviceParameter
        {
            get { return _devicePara; }
        }

        public override IProtocolDriver Protocol
       {
            get { return _protocol;}
        }

        public override DeviceType DeviceType
        {
            get { return DeviceType.Common; }
        }

        public override string ModelNumber
        {
            get { return "serversuperio"; }
        }

        public override System.Windows.Forms.Control DeviceGraphics
        {
            get { throw new NotImplementedException(); }
        }
}

    实时动态数据对象_deviceDyn、参数数据对象_devicePara、合同驱动对象_protocol分别提要求接口:DeviceDynamic、DeviceParameter和Protocol,为SSIO提供可引用的根基属性参数。

     Initialize是道具驱动初叶化的函数接口,在这里个接口实现多个主要工作:伊始化左券驱动和参数性的音讯。通过this.Protocol.InitDriver(this.GetType(),null);代码可以加载全部左券命令到协和驱动的缓存中,以便实时调用。当然这里边也能够扩充此外地方的做事,可是注意对至极的拍卖。

     DeviceType那几个是装备的花色,常常钦定为Common就好了。别的函数接口成效已经在《物联网框架ServerSuperIO教程-3.设备驱动介绍》中详细介绍了,请参见。

4.2.1    发送读实时数据命令合同

     Computer发送0x61命令为读实时数据命令,共发送6个字节,校验和为从“从机地址”开端的丰富和,不包蕴“数据报头”、“校验和”和“合同甘休”。

     发送指令数据帧如下:

帧结构

数据报头

从机地址

指令代码

校验和

研究甘休

0x55

0xAA

 

0x61

 

0x0D

字节数

1

1

1

1

1

1

  

4.2.2    剖判实时数据协议

    下位机接收到读实时数据命令后,并校验成功,重返实时数据,校验和为从“从机地址”起初的丰硕和,不包涵“数据报头”、“校验和”和“协议甘休”。

    接收数据帧如下:

帧结构

多少报头

从机地址

一声令下代码

流量

信号

校验和

磋商截止

0x55

0xAA

 

0x61

浮点型

浮点型

 

0x0D

字节数

1

1

1

1

4

 

4

1

1

4.3    开辟设备驱动

4.2    通信公约分明

    在成功多少个装置驱动的开销从前,首先要理解它的广播发表左券,好比四人沟通的言语同样。针对电视发表公约,大家自定义贰个粗略交互格局,只是发送命令,提取数额音讯。

分分快三计划 3

注:ServerSuperIO有十分的大希望被移植到Windows 10 IOT上,那么以往有极大可能率开采一套设备驱动,能够分段在服务端、嵌入式设备中,将产生总体的施工方案。

 

4.3.2    创设参数数据长久对象

    日常的话硬件器械会有读参数的下令,那么再次来到来的参数也急需展开悠久化存款和储蓄,並且每台道具的参数都大概不相同样,在那提供叁个可扩展的接口。在这里个广播发表公约中并未提到到器械参数相关的公约表明,可是大家也须求创制三个参数数据悠久对象类,能够不写任何增添的参数属性,在SSIO框架对参数的接口实行了援用,那是必得开展了办事。代码如下:

public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
        public override object Repair()
        {
            return new DevicePara();
        }
}

     DevicePara承接自DeviceParameter类,情状与实时数据漫长对象类似,能够参数。

《连载 | 物联网框架ServerSuperIO教程》2.劳务实例的配置参数表达

4.3           开辟设备驱动... 3

      以往一度调节和测量检验通过一些代码,还得需求一段时间,经常都以晚间干,时间也简单。如下图:

《连载 | 物联网框架ServerSuperIO教程》1.4种简报情势机制。

4.2.2    解析实时数据公约

    下位机接收到读实时数据命令后,并校验成功,再次来到实时数据,校验和为从“从机地址”开头的增进和,不富含“数据报头”、“校验和”和“契约停止”。

    接收数据帧如下:

帧结构

数量报头

从机地址

命令代码

流量

信号

校验和

共谋结束

0x55

0xAA

 

0x61

浮点型

浮点型

 

0x0D

字节数

1

1

1

1

4

 

4

1

1

4.3.3    营造发送和分析公约命令对象

    与设施开展交互会涉及到好些个交互式的一声令下或指令代码,而这一个命令在SSIO框架内是以公约命令对象的款式存在,大意包括四个部:推行命令接口、打包发送数据接口、分析接收数据接口等。

    针对地点的简报公约,有一个61命令,那么大家就足以依赖61发令为命名塑造一个探究命令对象,富含发送数据和分析数据部分。假如有其他命令代码,一举三反。代码如下:

internal class DeviceCommand:ProtocolCommand
{
        public override string Name
        {
            get { return "61"; }
        }

        public override void ExcuteCommand<T>(T t)
        {
            throw new NotImplementedException();
        }

        public override byte[] Package<T> (string code, T1 t1,T2 t2)
        {
            //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
            byte[] data = new byte[6];
            data[0] = 0x55;
            data[1] = 0xaa;
            data[2] = byte.Parse(code);
            data[3] = 0x61;
            data[4] = this.ProtocolDriver.GetCheckData(data)[0];
            data[5] = 0x0d;
            return data;
        }

        public override dynamic Analysis<T>(byte[] data, T t)
        {
            Dyn dyn = new Dyn()
            //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
            byte[] flow = BinaryUtil.SubBytes(data, 4, 4, true);
            dyn.Flow = BitConverter.ToSingle(flow, 0);
            byte[] signal = BinaryUtil.SubBytes(data, 8, 4, true);
            dyn.Signal = BitConverter.ToSingle(signal, 0);
            return dyn;
        }

}

     创设筑组织议命令需求全方位卫冕自ProtocolCommand,依照报纸发表公约分明,Name属性再次回到61,作为关键字;Package是包裹要送的数量消息;Analysis对应着接收数据之后展开解析操作。就那样二个轻易的合计命令驱动就构建产生了。

4.2.1    发送读实时数据命令左券... 2

4.2.3    发送和接收数据事例... 3

4.3.3    营造发送和深入分析左券命令对象... 5

4.4           营造宿主程序... 12

4.如开辟一套装置驱动,同期帮助串口和网络通信... 2

4.3.1    营造实时数据长久对象(不是必须)... 3

4.2.3    发送和接收数据事例

发送(十六进制):0x55 0xaa 0x00 0x61 0x61 0x0d

收下(十六进制):0x55 0xaa 0x00 0x61 0x43 0x7a 0x00 0x00 0x43 0xb4 0x15 0x0d

流量数据为:250.00

非信号数据为:360.00

4.1           概述... 2

4.如开垦一套设备驱动,同有时候协助串口和网络通信

4.4    创设宿主程序

     叁个简短的配备驱动就已经支付好了,光有驱动还十一分,那么大家根据SSIO框架再写几行代码,达成一个宿主程序,把器具驱动实例化,放SSIO的劳动实例中运营,完毕串口和互连网两种格局的广播发表交互,代码也非常轻易。代码如下:

class Program
{
        static void Main(string[] args)
        {
            DeviceDriver dev1 = new DeviceDriver();
            dev1.DeviceParameter.DeviceName = "串口设备1";
            dev1.DeviceParameter.DeviceAddr = 0;
            dev1.DeviceParameter.DeviceID = "0";
            dev1.DeviceDynamic.DeviceID = "0";
            dev1.DeviceParameter.COM.Port = 1;
            dev1.DeviceParameter.COM.Baud = 9600;
            dev1.CommunicateType = CommunicateType.COM;
            dev1.Initialize("0");

            DeviceDriver dev4 = new DeviceDriver();
            dev4.DeviceParameter.DeviceName = "网络设备2";
            dev4.DeviceParameter.DeviceAddr = 0;
            dev4.DeviceParameter.DeviceID = "3";
            dev4.DeviceDynamic.DeviceID = "3";
            dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1";
            dev4.DeviceParameter.NET.RemotePort = 9600;
            dev4.CommunicateType = CommunicateType.NET;
            dev4.Initialize("3");

            IServer server = new ServerFactory().CreateServer(new ServerConfig()
            {
                ServerName = "服务实例1",
                SocketMode = SocketMode.Tcp,
                ControlMode = ControlMode.Loop,
                CheckSameSocketSession = false,
                StartCheckPackageLength = false,
            });

            server.AddDeviceCompleted  = server_AddDeviceCompleted;
            server.DeleteDeviceCompleted  = server_DeleteDeviceCompleted;
            server.SocketConnected =server_SocketConnected;
            server.SocketClosed =server_SocketClosed;
            server.Start();

            server.AddDevice(dev1);
            server.AddDevice(dev4);

            while ("exit"==Console.ReadLine())
            {
                 server.Stop();
            }
        }

        private static void server_SocketClosed(string ip, int port)
        {
            Console.WriteLine(String.Format("断开:{0}-{1} 成功", ip, port));
        }

        private static void server_SocketConnected(string ip, int port)
        {
            Console.WriteLine(String.Format("连接:{0}-{1} 成功",ip, port));
        }

        private static void server_AddDeviceCompleted(string devid, string devName, bool isSuccess)

        {
            Console.WriteLine(devName ",增加:" isSuccess.ToString());
        }

        private static void server_DeleteDeviceCompleted(string devid, string devName, bool isSuccess)
        {
            Console.WriteLine(devName   ",删除:"   isSuccess.ToString());
        }
    }
}

     这几个代码咱们都能看通晓,具体的主宰方式我们接下去会挨个介绍。在创设宿主程序的时候,切忌对劳务实例那样援用:server.ChannelManager、server.ControllerManager、server.DeviceManager。就算提供了那样的接口,主如若为着SSIO框架之中接纳的,没有供给大家单独去操作这么些接口。有的网上朋友是如此的写的,那么就改为了叁个纯的通信IO框架,那么就失去了SSIO框架本身的股票总值。作为一回开荒者,只需求安装设备驱动的参数,以至向劳动实例中追加或删除设备就行了,其余兼具的运维总体提交SSIO框架来造成。

 

4.3.4    营造筑组织商驱动对象

    有了会谈命令之后,大家须要创设协商驱动对象,SSIO框架帮忙自定义和睦也在于此,并且与设施驱动的接口相关联,在SSIO框架的高等应用中也进展了引用,构建那引对象十分重大。代码如下:

internal class DeviceProtocol:ProtocolDriver
{
        public override bool CheckData(byte[] data)
        {
            if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public override byte[] GetCommand(byte[] data)
        {
            return new byte[] { data[3] };
        }

        public override int GetAddress(byte[] data)
        {
            return data[2];
        }

        public override byte[] GetHead(byte[] data)
        {
            return new byte[] { data[0], data[1] };
        }

        public override byte[] GetEnd(byte[] data)
        {
            return new byte[] { data[data.Length - 1] };
        }

        public override byte[] GetCheckData(byte[] data)
        {
            byte checkSum = 0;
            for (int i = 2; i < data.Length - 2; i  )
            {
                checkSum  = data[i];
            }
            return new byte[] { checkSum };
        }

        public override string GetCode(byte[] data)
        {
            throw new NotImplementedException();
        }

        public override int GetPackageLength(byte[] data, IChannel channel, ref int readTimeout)
        {
           throw new NotImplementedException();
        }
}

     DeviceProtocol 左券驱动承袭自ProtocolDriver ,二个设备驱动只设有贰个共谋驱动,二个共谋驱动能够存在四个左券命令(如61发令)。该类中的CheckData函数很关键,SSIO框架中的设备驱动基类援用了,主若是成就校验接收数据的完事性,是还是不是切合左券,从而调节了通信状态:通信不荒谬、通信中断、通信干扰、以致通信未知,差别的电视发表状态也调整了调用设备驱动中的哪个函数接口:Communicate、CommunicateInterrupt、CommunicateError和CommunicateNone。

4.5    运维效果

 分分快三计划 4

 

1.[连载]《C#报道(串口和网络)框架的宏图与完成》

2.[开源]C#跨平台物联网通信框架ServerSuperIO(SSIO)介绍

2.应用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)创设系统的欧洲经济共同体方案

3.C#工业物联网和集成系统施工方案的技术路径(数据源、数据搜求、数据上传与接收、ActiveMQ、Mongodb、WebApi、手提式有线电话机App)

5.ServerSuperIO开源地址:

物联网&集成工夫(.NET) QQ群54256083

4.3.5    营造设备驱动对象... 8

4.3.2    打造参数数据长久对象... 5

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划