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;
}
}
}