如何处理串口通讯数据重合与分批到达的问题
2006-09-29 09:25
525 查看
重合:
指示设备工作时,设备返回ok;而此时设备主动上报数据,这两个数据可能发生重合;因此串口同时可能有多个消息到达
分批到达:
一个回复由于干扰信号的关系,分两次到达,第一次到达了11个字节的前5个字节,第二次到达了11个字节的后6个字节。
在接收事件中(On_Comm)需要对数据进行整理,将这两种问题解决后(借助于数据包头,数据包尾),还有校验码的问题
下面是我的解决方案,由于是第一编写这样的程序,没什么经验,所以希望大家能提出意见.
private static Logger logger = LogManager.GetCurrentClassLogger(); //
MSCommLib.MSCommClass mc = new MSCommLib.MSCommClass(); //实例化MSCOMM
System.Timers.Timer timer = null; //定时器
ArrayList m_bytelist = new ArrayList(); //全局变量来存放接收到的数据
byte[] m_data = new byte[11]; //一个完整的消息指令数组长度为11
private int m_second = 0; //超时时间
private void InitCommonPort()
{
try
{
mc.CommPort = 3;
mc.Settings = "38400,n,8,1";
mc.RThreshold = 1; //每接收一个字符则激发OnComm()事件
mc.DTREnable = true;
mc.Handshaking = MSCommLib.HandshakeConstants.comNone;
mc.InputMode = MSCommLib.InputModeConstants.comInputModeBinary; //二进制
mc.InBufferSize = 1024;
mc.InputLen = 0; //决定每次Input读入的字符个数,缺省为0,表示读取接收缓冲区的全部内容
//mc.InputLen = 1; //一次读取一个
mc.NullDiscard = false;
mc.PortOpen = true; //打开串口
mc.OnComm +=new MSCommLib.DMSCommEvents_OnCommEventHandler(mc_OnComm);
Console.WriteLine("串口已打开!");
logger.Debug("串口已打开!");
}
catch
{
logger.Debug("串口打开失败!");
}
}
/// <summary>
/// 初始化定时器
/// </summary>
private void InitTimer()
{
timer = new System.Timers.Timer(1000);
timer.AutoReset = true;
timer.Enabled = true;
timer.Elapsed +=new ElapsedEventHandler(timer_Elapsed);
}
/// <summary>
/// 处理接收的数据
/// </summary>
private void checkByteList()
{
byte[] t_byte = new byte[11];
int j = 0;
if(m_bytelist.Count == 0)
{
return;
}
else
{
for(int i=0;i<m_bytelist.Count;i++)
{
t_byte[j] = (byte)m_bytelist[i];
if(t_byte[0] == 0x82)
{
if(j==10)
{
if(t_byte[10] == 0x83)
{
sendMail(t_byte);
j = 0;
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,11);
}
else //如果包尾不是以83开头,数据不合法,丢弃
{
j=0;
logger.Debug("/n错误的指令 : [" + Utilities.ByteArrayToHexString(t_byte) + "] 已被丢弃! ");
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,11);
}
}
else
{
j++;
this.InitTimer(); //初始化定时器
if(m_second == 5) //5秒后停止
{
logger.Debug("不完整的指令 : ["+Utilities.ByteArrayToHexString(t_byte) + "]");
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,j);
j=0;
}
}
}
else //如果包头不是以82开头,数据不合法,丢弃
{
j=0;
logger.Debug("/n错误的指令 : [" + Utilities.ByteArrayToHexString(t_byte) + "] 已被丢弃! ");
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,1);
}
}
}
}
/// <summary>
/// clear array
/// </summary>
/// <param name="o_data"></param>
private void clearArray(ref byte[]o_data)
{
for(int i=0;i<o_data.Length;i++)
{
o_data[i] =0;
}
}
/// <summary>
/// 将消息发给上层
/// </summary>
/// <param name="inData"></param>
private void sendMail(byte[] inData)
{
}
/// <summary>
/// 从串口接收数据
/// </summary>
private void mc_OnComm()
{
byte [] t_byte = (byte[])mc.Input; //receive data and clear buffer
for(int i = 0;i<t_byte.Length;i++)
{
m_bytelist.Add(t_byte[i]);
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
m_second = now.Second;
}
/// <summary>
/// 接收MCU主动发送的消息、解析、封装成对象消息发送给Session层
/// </summary>
protected override void process()
{
checkByteList();
}
主要的代码就这么多了,没有整理比较乱,有空的时候再整理一下了.
指示设备工作时,设备返回ok;而此时设备主动上报数据,这两个数据可能发生重合;因此串口同时可能有多个消息到达
分批到达:
一个回复由于干扰信号的关系,分两次到达,第一次到达了11个字节的前5个字节,第二次到达了11个字节的后6个字节。
在接收事件中(On_Comm)需要对数据进行整理,将这两种问题解决后(借助于数据包头,数据包尾),还有校验码的问题
下面是我的解决方案,由于是第一编写这样的程序,没什么经验,所以希望大家能提出意见.
private static Logger logger = LogManager.GetCurrentClassLogger(); //
MSCommLib.MSCommClass mc = new MSCommLib.MSCommClass(); //实例化MSCOMM
System.Timers.Timer timer = null; //定时器
ArrayList m_bytelist = new ArrayList(); //全局变量来存放接收到的数据
byte[] m_data = new byte[11]; //一个完整的消息指令数组长度为11
private int m_second = 0; //超时时间
private void InitCommonPort()
{
try
{
mc.CommPort = 3;
mc.Settings = "38400,n,8,1";
mc.RThreshold = 1; //每接收一个字符则激发OnComm()事件
mc.DTREnable = true;
mc.Handshaking = MSCommLib.HandshakeConstants.comNone;
mc.InputMode = MSCommLib.InputModeConstants.comInputModeBinary; //二进制
mc.InBufferSize = 1024;
mc.InputLen = 0; //决定每次Input读入的字符个数,缺省为0,表示读取接收缓冲区的全部内容
//mc.InputLen = 1; //一次读取一个
mc.NullDiscard = false;
mc.PortOpen = true; //打开串口
mc.OnComm +=new MSCommLib.DMSCommEvents_OnCommEventHandler(mc_OnComm);
Console.WriteLine("串口已打开!");
logger.Debug("串口已打开!");
}
catch
{
logger.Debug("串口打开失败!");
}
}
/// <summary>
/// 初始化定时器
/// </summary>
private void InitTimer()
{
timer = new System.Timers.Timer(1000);
timer.AutoReset = true;
timer.Enabled = true;
timer.Elapsed +=new ElapsedEventHandler(timer_Elapsed);
}
/// <summary>
/// 处理接收的数据
/// </summary>
private void checkByteList()
{
byte[] t_byte = new byte[11];
int j = 0;
if(m_bytelist.Count == 0)
{
return;
}
else
{
for(int i=0;i<m_bytelist.Count;i++)
{
t_byte[j] = (byte)m_bytelist[i];
if(t_byte[0] == 0x82)
{
if(j==10)
{
if(t_byte[10] == 0x83)
{
sendMail(t_byte);
j = 0;
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,11);
}
else //如果包尾不是以83开头,数据不合法,丢弃
{
j=0;
logger.Debug("/n错误的指令 : [" + Utilities.ByteArrayToHexString(t_byte) + "] 已被丢弃! ");
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,11);
}
}
else
{
j++;
this.InitTimer(); //初始化定时器
if(m_second == 5) //5秒后停止
{
logger.Debug("不完整的指令 : ["+Utilities.ByteArrayToHexString(t_byte) + "]");
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,j);
j=0;
}
}
}
else //如果包头不是以82开头,数据不合法,丢弃
{
j=0;
logger.Debug("/n错误的指令 : [" + Utilities.ByteArrayToHexString(t_byte) + "] 已被丢弃! ");
this.clearArray(ref t_byte);
m_bytelist.RemoveRange(0,1);
}
}
}
}
/// <summary>
/// clear array
/// </summary>
/// <param name="o_data"></param>
private void clearArray(ref byte[]o_data)
{
for(int i=0;i<o_data.Length;i++)
{
o_data[i] =0;
}
}
/// <summary>
/// 将消息发给上层
/// </summary>
/// <param name="inData"></param>
private void sendMail(byte[] inData)
{
}
/// <summary>
/// 从串口接收数据
/// </summary>
private void mc_OnComm()
{
byte [] t_byte = (byte[])mc.Input; //receive data and clear buffer
for(int i = 0;i<t_byte.Length;i++)
{
m_bytelist.Add(t_byte[i]);
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
m_second = now.Second;
}
/// <summary>
/// 接收MCU主动发送的消息、解析、封装成对象消息发送给Session层
/// </summary>
protected override void process()
{
checkByteList();
}
主要的代码就这么多了,没有整理比较乱,有空的时候再整理一下了.
相关文章推荐
- 如何处理串口通讯数据重合与分批到达的问题 2
- 串口如何接收数据,接收到又如何处理
- 如何在串口通讯程序中处理数据包
- Qt串口处理数据丢包问题
- 解决在epoll中accept接收端口会漏处理的问题. 直到新的socket消息到达,epoll_wait才响应去接收socket端口数据的问题
- 能源物联网中如何处理上报的大量数据问题的思路分析(题目有点长,但是我不介意它更长)--后续会继续补充
- 从重采样到数据合成:如何处理机器学习中的不平衡分类问题? 转载 2017年08月01日 17:09:03 标签: 机器学习 / 数据 719 转自:http://www.sohu.com/a/12
- 能源物联网中如何处理上报的大量数据问题的思路分析(题目有点长,但是我不介意它更长)--后续会继续补充
- Java如何处理多线程的数据同步问题
- 如何处理Oledb中EXCEL驱动读取EXCEL文件中字段长度大于255字符时出现的"数据截断"问题.
- 从重采样到数据合成:如何处理机器学习中的不平衡分类问题?
- 游戏开发中AS3和服务端通过socket通讯,如何处理粘包的问题
- 3n+1问题大数据如何处理?
- 如何及时处理文件数据丢失的问题呢
- 如何处理ODBC中EXCEL驱动读取EXCEL文件中字段长度大于255字符时出现的"数据截断"问题.
- C#中请问如何在串口通讯中接收输出HEX格式数据
- 如何处理javascript中var类型有效数据极限值问题(超大数据)
- 如何处理集群、分布架构的数据同步问题
- 串口通讯中垃圾数据的处理
- 遇到的问题(一):智能家居中WIFI模块设备在接收底层家具设备串口数据时由于断帧而出现的指令丢失的情况处理