C# ModuleBus串口通讯 问题 我写了一段串口通讯的程序,采用的是ModuleBus通讯协议。采用主从站方式进行通讯,我是主站,向从站发送读取命令的请求。程序长时间运行之后,发现收不到数据,非要拔掉电源重启后才能收到。把程序关了再启动,也没有用。也怀疑过时串口问题,但是使用USB转串口线也不行。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 关键地方写日志,这个要细心调试找问题。或是没数据时候,你暂停看看,看看监听线程的状态,看看当前的 BytesToRead属性。 把代码贴出来 /// <summary> /// 启动适配器 /// </summary> /// <returns>成功返回True,失败返回False</returns> protected override bool OnStartAdapter() { _collectThread = new Thread(new ThreadStart(CollectPro)); _collectThread.Start(); return true; } /// <summary> /// 停止适配器 /// </summary> /// <returns>成功返回True,失败返回False</returns> protected override bool OnStopAdapter() { _exitEvent.Set();#if SerialPort _serialPort.Close();#else _CommAPI.Close();#endif if (_collectThread.ThreadState == ThreadState.Suspended) { _collectThread.Resume(); } if (_collectThread.ThreadState == ThreadState.Running) { _collectThread.Join(); } return true; } protected void CollectPro() { if(Init()) _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived); SendMSG(); } /// <summary> /// CRC16校验 /// </summary> /// <param name="Buff">校验数组</param> /// <param name="Long">校验数据个数</param> /// <returns>双字节结果</returns> protected UInt16 CRC16(byte[] puchMsg, int usDataLen) { } protected void SendMSG() { UInt16 CRC; byte[] SendBuffer = new byte[8]; SendBuffer[0] = EquipMentId; //设备地址 SendBuffer[1] = Ablity; //功能码,读数据 SendBuffer[2] = 0x00; //寄存器高位 SendBuffer[3] = 0x02; //寄存器低位 SendBuffer[4] = 0x00; //寄存器数据量高位 SendBuffer[5] = 0x3b; //寄存器数据量地位 CRC = CRC16(SendBuffer, 6); SendBuffer[6] = Convert.ToByte(CRC & 0xff); //CRC校低验位 SendBuffer[7] = Convert.ToByte(CRC >> 8); //CRC校验高位 while (_collectThread.ThreadState == ThreadState.Running && !_exitEvent.WaitOne(10, false)) {#if SerialPort if (!_serialPort.IsOpen) continue; _serialPort.DiscardInBuffer(); _serialPort.Write(SendBuffer, 0, 8); OutPut("发送数据包请求," + string.Format("SendBuf:{0},WriteBuf:{1}", BitConverter.ToString(SendBuffer, 0, 8), _serialPort.ReadBufferSize.ToString())); Thread.Sleep(30000);#else if (!_CommAPI.Opened) continue; _CommAPI.Write(SendBuffer); //Thread.Sleep(4000); OutPut("发送数据包请求," + string.Format("SendBuf:{0}", BitConverter.ToString(SendBuffer, 0, 8))); if (!_CommAPI.Opened) continue; bRes = 123; _CommAPI.Read(bRes).CopyTo(ReadBuffer,0); OutPut("接受到的数据" + string.Format("ReadBuf:{0}", BitConverter.ToString(ReadBuffer, 0, bRes))); #endif } } /// <summary> /// 处理数据包 /// </summary> private void ParaPack() { } } /// <summary> /// 数据接收过程 /// </summary> private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { int DataLength = _serialPort.BytesToRead; int dwRead = 123; byte[] DataBuffer = new byte[DataLength]; if (!_exitEvent.WaitOne(10, false)) { _serialPort.Read(DataBuffer, 0, DataLength); if (DataBuffer[0] == EquipMentId || IsFrist) { IsFrist = true; try { DataBuffer.CopyTo(ReadBuffer, _constPackNum); _constPackNum += DataLength; } catch { IsFrist = false; _constPackNum = 0; } } OutPut("解析:" + BitConverter.ToString(DataBuffer, 0, DataLength) + "PackNum:" + _constPackNum.ToString() + ";" + DataLength.ToString()); if (_constPackNum >= dwRead) { IsFrist = false; ParaPack(); OutPut("成功数据包解析:" + BitConverter.ToString(ReadBuffer, 0, _constPackNum)); _constPackNum = 0; } }#if SerialPort //_serialPort.DiscardInBuffer();#else#endif } /// <summary> /// 打开串口 /// </summary> /// <returns>成功返回True</returns> protected bool Init() { OutPut("正在打开串口"); try { LogHelper.WriteLog("尝试打开串口...:", ELogLevel.Error);#if SerialPort _serialPort.PortName = _PortName; _serialPort.BaudRate = _BaudRate; _serialPort.DataBits = _DataBits; _serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _StopBits); _serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), _CheakWay); _serialPort.ReadBufferSize = 500; _serialPort.Open(); if (_serialPort.IsOpen) { LogHelper.WriteLog("成功.串口以打开", ELogLevel.Error); }#else _CommAPI.PortNum = 1; _CommAPI.BaudRate = _BaudRate; _CommAPI.ByteSize = 0x08; _CommAPI.StopBits = 0x00; _CommAPI.Parity = 0x00; _CommAPI.ReadTimeout = 10; _CommAPI.Open(); if (_CommAPI.Opened) { LogHelper.WriteLog("成功.串口以打开", ELogLevel.Error); }#endif } catch (Exception ex) { LogHelper.WriteLog("串口打开失败.原因:" + ex.Message, ELogLevel.Error); return false; } return true; } /// <summary> /// 输出程序调试日志 /// </summary> /// <param name="Msg"></param> protected void OutPut(string Msg) { if (_OutPutLog) LogHelper.WriteLog(Msg, ELogLevel.Error); } } 怀疑楼主的程序在收不到数据时已经down掉了整体做个异常记录看看本人是做电力子站的,向你学习! 如何 修改c# 应用程序exe文件的标题和ICON c# winform 如何从数据库中读取doc数据? 请问用Socket获取一个验证码输出网页,怎么把图片部分弄出来? Convert.ToInt32(com.ExecuteScalar()); 异常 谢谢 求助!From中图片透明色问题! 请教listview中的双击操作 关于一个解决方案中有多个项目的问题?(在线等…) 关于图像处理问题? 巨菜的问题 C#如何调用Com接口函数中参数含有optional 关于子类重写父类的方法 帮忙解决连发程序
/// <summary>
/// 启动适配器
/// </summary>
/// <returns>成功返回True,失败返回False</returns>
protected override bool OnStartAdapter()
{
_collectThread = new Thread(new ThreadStart(CollectPro));
_collectThread.Start();
return true;
} /// <summary>
/// 停止适配器
/// </summary>
/// <returns>成功返回True,失败返回False</returns>
protected override bool OnStopAdapter()
{
_exitEvent.Set();
#if SerialPort
_serialPort.Close();#else
_CommAPI.Close();
#endif if (_collectThread.ThreadState == ThreadState.Suspended)
{
_collectThread.Resume();
}
if (_collectThread.ThreadState == ThreadState.Running)
{
_collectThread.Join();
}
return true;
} protected void CollectPro()
{
if(Init())
_serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);
SendMSG();
}
/// <summary>
/// CRC16校验
/// </summary>
/// <param name="Buff">校验数组</param>
/// <param name="Long">校验数据个数</param>
/// <returns>双字节结果</returns>
protected UInt16 CRC16(byte[] puchMsg, int usDataLen)
{
}
protected void SendMSG()
{
UInt16 CRC;
byte[] SendBuffer = new byte[8];
SendBuffer[0] = EquipMentId; //设备地址
SendBuffer[1] = Ablity; //功能码,读数据
SendBuffer[2] = 0x00; //寄存器高位
SendBuffer[3] = 0x02; //寄存器低位
SendBuffer[4] = 0x00; //寄存器数据量高位
SendBuffer[5] = 0x3b; //寄存器数据量地位 CRC = CRC16(SendBuffer, 6);
SendBuffer[6] = Convert.ToByte(CRC & 0xff); //CRC校低验位
SendBuffer[7] = Convert.ToByte(CRC >> 8); //CRC校验高位 while (_collectThread.ThreadState == ThreadState.Running && !_exitEvent.WaitOne(10, false))
{#if SerialPort
if (!_serialPort.IsOpen)
continue;
_serialPort.DiscardInBuffer();
_serialPort.Write(SendBuffer, 0, 8);
OutPut("发送数据包请求," + string.Format("SendBuf:{0},WriteBuf:{1}", BitConverter.ToString(SendBuffer, 0, 8), _serialPort.ReadBufferSize.ToString()));
Thread.Sleep(30000);
#else
if (!_CommAPI.Opened)
continue;
_CommAPI.Write(SendBuffer);
//Thread.Sleep(4000);
OutPut("发送数据包请求," + string.Format("SendBuf:{0}", BitConverter.ToString(SendBuffer, 0, 8)));
if (!_CommAPI.Opened)
continue; bRes = 123;
_CommAPI.Read(bRes).CopyTo(ReadBuffer,0);
OutPut("接受到的数据" + string.Format("ReadBuf:{0}", BitConverter.ToString(ReadBuffer, 0, bRes)));
#endif
}
} /// <summary>
/// 处理数据包
/// </summary>
private void ParaPack()
{
} } /// <summary>
/// 数据接收过程
/// </summary>
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ int DataLength = _serialPort.BytesToRead;
int dwRead = 123; byte[] DataBuffer = new byte[DataLength];
if (!_exitEvent.WaitOne(10, false))
{
_serialPort.Read(DataBuffer, 0, DataLength);
if (DataBuffer[0] == EquipMentId || IsFrist)
{
IsFrist = true;
try
{
DataBuffer.CopyTo(ReadBuffer, _constPackNum);
_constPackNum += DataLength;
}
catch
{
IsFrist = false;
_constPackNum = 0;
}
} OutPut("解析:" + BitConverter.ToString(DataBuffer, 0, DataLength) + "PackNum:" + _constPackNum.ToString() + ";" + DataLength.ToString());
if (_constPackNum >= dwRead)
{ IsFrist = false;
ParaPack();
OutPut("成功数据包解析:" + BitConverter.ToString(ReadBuffer, 0, _constPackNum));
_constPackNum = 0;
}
}
#if SerialPort
//_serialPort.DiscardInBuffer();
#else
#endif }
/// <summary>
/// 打开串口
/// </summary>
/// <returns>成功返回True</returns>
protected bool Init()
{
OutPut("正在打开串口");
try
{
LogHelper.WriteLog("尝试打开串口...:", ELogLevel.Error);
#if SerialPort
_serialPort.PortName = _PortName;
_serialPort.BaudRate = _BaudRate;
_serialPort.DataBits = _DataBits;
_serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), _StopBits);
_serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), _CheakWay);
_serialPort.ReadBufferSize = 500;
_serialPort.Open();
if (_serialPort.IsOpen)
{
LogHelper.WriteLog("成功.串口以打开", ELogLevel.Error);
}
#else
_CommAPI.PortNum = 1;
_CommAPI.BaudRate = _BaudRate;
_CommAPI.ByteSize = 0x08;
_CommAPI.StopBits = 0x00;
_CommAPI.Parity = 0x00;
_CommAPI.ReadTimeout = 10;
_CommAPI.Open();
if (_CommAPI.Opened)
{
LogHelper.WriteLog("成功.串口以打开", ELogLevel.Error);
}
#endif
}
catch (Exception ex)
{
LogHelper.WriteLog("串口打开失败.原因:" + ex.Message, ELogLevel.Error);
return false;
}
return true;
} /// <summary>
/// 输出程序调试日志
/// </summary>
/// <param name="Msg"></param>
protected void OutPut(string Msg)
{
if (_OutPutLog)
LogHelper.WriteLog(Msg, ELogLevel.Error);
}
}
整体做个异常记录看看
本人是做电力子站的,向你学习!