using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Threading; namespace TProduct.Link { /// /// 单个Com链接的基类 /// public class SingleComBaseHelper { protected SerialPort _defaultComPort = null; public SerialPort GetComPort() { return _defaultComPort; } protected int _receiveWaitIntervalTime = 0;//发送后,COM口等待时间(180) protected int _pollIntervalTime = 0;//定时器轮询时间(300) protected System.Timers.Timer _tPollTimer; //端口总数 private int _msgTotalItemCount = 0;//所有的端口总数 private int _msgPollItemCount = 0;//参与轮询的端口总数,有的端口,只有初始化或者控制指令,没有轮询 public int TotalMsgItemCount { get => _msgTotalItemCount; } //当前端口 private int _current_poll_item_index = 0; //当前端口 private MsgItemBase _currentMsgItem = null; /// /// /// public SingleComBaseHelper() { } /// /// 收到轮询返回监控值 /// public Action, Dictionary, string, byte[]> OnReceivePollValue = null; /// /// 显示信息的委托(可用于日志,错误的返回) /// public Action OnShowMsg = null; //所有端口 protected List _allMsgItems = null; public List GetAllMsgItem() { return _allMsgItems; } protected List _allPollMsgItems = null; /// /// 初始化COM口 /// /// /// public void InitialComPort( TProduct.Model.WorkBenchBase bench, string com_name, int baud_rate = 9600, int data_bits = 8, System.IO.Ports.Parity parity = Parity.None) { var comPort = new SerialPort(); comPort.BaudRate = baud_rate; comPort.PortName = com_name; comPort.DataBits = data_bits; comPort.Parity = parity; comPort.StopBits = StopBits.One; comPort.ReceivedBytesThreshold = 1; this._defaultComPort = comPort; if (bench.LinkInfo != null) { this._receiveWaitIntervalTime = bench.LinkInfo.ReceiveWaitTime; this._pollIntervalTime = bench.LinkInfo.PollTime; } } public void SetParity(System.IO.Ports.Parity Parity) { if (this._defaultComPort != null) this._defaultComPort.Parity = Parity; } public void SetDataBits(int DataBits) { if (this._defaultComPort != null) this._defaultComPort.DataBits = DataBits; } /// /// 添加端口 /// /// public void AddMsgItem(MsgItemBase msg) { if (_allMsgItems == null) _allMsgItems = new List(); if (_allPollMsgItems == null) _allPollMsgItems = new List(); _allMsgItems.Add(msg); _msgTotalItemCount = _allMsgItems.Count(); if (msg.IsHavePollMsg) {//判断是否有轮询 _allPollMsgItems.Add(msg); _msgPollItemCount = _allPollMsgItems.Count(); } } /// /// 开始监控 /// /// /// public virtual bool Start(out string error_info) { if (_allMsgItems == null || _allMsgItems.Count == 0) { error_info = "未初始化仪器端口信息"; return false; } if (_defaultComPort == null) { error_info = "未初始化Com口信息"; return false; } try { //初始化端口 if (_defaultComPort.IsOpen) { error_info = "串口已打开,请关闭后再打开"; return false; } //使用事件接收 //defaultCom.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.OnReceiveMessage); _defaultComPort.Open();//打开串口 //连上COM口,都初始化一下,有的需要发送CT 和 PT等 foreach (var item in _allMsgItems) { // Task.Run(() => // { // msg_item.SendElectricMsg( // tesItem.ElectricInfo, (st, info) => // { // }); // }); item.InitialSerialPort(_defaultComPort); } //初始化定时器 InitialTimer(); } catch (Exception ex) { error_info = ex.Message + ",Error:225"; return false; } error_info = null; return true; } /// /// 初始化定时器 /// protected void InitialTimer() { if (_msgPollItemCount > 0) {//可能没有轮询,只有控制 if (_tPollTimer != null) { _tPollTimer.Close(); _tPollTimer.Dispose(); } //设置通讯周期 _tPollTimer = new System.Timers.Timer(); _tPollTimer.Interval = _pollIntervalTime > 50 ? _pollIntervalTime : 300;//!通讯间隔时间 _tPollTimer.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件 _tPollTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnSendPollMessage);//到达时间的时候执行事件; _tPollTimer.AutoReset = true;//设置是执行一次(false)还是一直执行(true) } } private bool _isSendCtrlMsg = false; /// /// 发送轮询消息 /// /// /// private void OnSendPollMessage(object source, System.Timers.ElapsedEventArgs e) { //如果正在发送控制指令就不要轮询 if (_isSendCtrlMsg) return; //判断是否到顶 if (_current_poll_item_index >= _msgPollItemCount) _current_poll_item_index = 0; //得到当前设备 _currentMsgItem = _allPollMsgItems[_current_poll_item_index]; try { //清除 this._defaultComPort.DiscardOutBuffer(); this._defaultComPort.DiscardInBuffer(); // byte[] send_message = _currentMsgItem.GetPollSendMessage(); if (send_message == null || send_message.Length < 1)//可能为1位 转速仪就一位 {//有时会故意返回null _current_poll_item_index++; _currentMsgItem = null;//不成功为空 return; } // _current_poll_item_index++; //发送查询 this._defaultComPort.Write(send_message, 0, send_message.Length); //显示 if (OnShowMsg != null) { OnShowMsg( new LinkMsgArgs() { MsgType = 1, PortName = this._defaultComPort.PortName, Status = 1, MsgItemName = _currentMsgItem.Name, Content = send_message }); } //直接去取数据,不用事件 ReceiveMessage(); } catch (Exception ex) { if (OnShowMsg != null) { OnShowMsg( new LinkMsgArgs() { MsgType = 1, PortName = this._defaultComPort.PortName, Status = -100, MsgItemName = _currentMsgItem.Name, Error = ex.Message }); } } } /// /// 接受消息 /// private void ReceiveMessage() { byte[] receive_message = null; try { if (_currentMsgItem == null) return; //暂停200毫秒等一条完整的命令进入缓冲区: if (_receiveWaitIntervalTime > 30) Thread.Sleep(_receiveWaitIntervalTime); else Thread.Sleep(200); //读取串口中的数据,最少也是6位 int count = this._defaultComPort.BytesToRead; if (count < 5) return; //读取信号 receive_message = new byte[count]; this._defaultComPort.Read(receive_message, 0, receive_message.Length); //得到测量值 Dictionary addition_infos = null; List monitor_results = null; string error_info = null; var ret = _currentMsgItem.AnaPollReceiveValue(receive_message, ref addition_infos, out monitor_results, out error_info); if (ret > 0) {//成功 //如果成功通知界面 if (OnReceivePollValue != null) { OnReceivePollValue(monitor_results, addition_infos, error_info, receive_message); } //显示信号 if (OnShowMsg != null) { OnShowMsg( new LinkMsgArgs() { MsgType = 2, PortName = this._defaultComPort.PortName, Status = 1, MsgItemName = _currentMsgItem.Name, Content = receive_message }); } } else {//失败 if (OnShowMsg != null) { OnShowMsg( new LinkMsgArgs() { MsgType = 2, PortName = this._defaultComPort.PortName, Status = -1,//解析失败 MsgItemName = _currentMsgItem.Name, Content = receive_message }); } } } catch (Exception ex) { if (OnShowMsg != null) { OnShowMsg( new LinkMsgArgs() { MsgType = 2, PortName = this._defaultComPort.PortName, Status = -100, MsgItemName = _currentMsgItem.Name, Content = receive_message, Error = ex.Message }); } } } /// /// 关闭COM口 /// public virtual bool Stop(out string error_info) { if (_tPollTimer != null) {//可能没有轮询,只有控制 _tPollTimer.Close(); _tPollTimer.Dispose(); Thread.Sleep(400); _tPollTimer = null; } if (_defaultComPort != null) { if (_defaultComPort.IsOpen) { _defaultComPort.Close(); } // _defaultComPort = null;//不要赋值为空, 可能重新开启 } error_info = null; return true; } /// /// /// /// /// /// /// public virtual bool SendCtrlMessage(string tag, string paras, Action cbSuccess, Action cbFail) { foreach (var item in _allMsgItems) { var ctrl_msg = item.GetCtrlMessage(tag, paras); if (ctrl_msg != null && ctrl_msg.Length > 0) { this._isSendCtrlMsg = true; //清除 if (!this._defaultComPort.IsOpen) continue; this._defaultComPort.DiscardOutBuffer(); this._defaultComPort.DiscardInBuffer(); //发送查询 this._defaultComPort.Write(ctrl_msg, 0, ctrl_msg.Length); //显示 if (OnShowMsg != null) { OnShowMsg( new LinkMsgArgs() { MsgType = 3,//3 控制请求 PortName = this._defaultComPort.PortName, Status = 1, MsgItemName = item.Name, Content = ctrl_msg }); } Thread.Sleep(250); this._isSendCtrlMsg = false; } } return false; } } }