/// <summary> /// 串口数据接收 针对信捷PLC /// 数据没有结束符 只能通过校验来确认 /// 信捷PLC 通讯模式 发送一条带DM 区域的指令 返回所有数据 /// 数据错误需要超时机制来进行恢复 如果超时一定次数 则判断中断 机器不存在 // 数据长度达到 就进行数据处理判断 同时发送下一组读取命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void XJPLC_SerialPort_Received(object sender, SerialPortEvents e) { if (e.BufferData != null) { m_buffer.AddRange(e.BufferData); //返回命令统一都是0X01开头 如果不是则移除 if (m_buffer[0] != Constant.XJHeader) { m_buffer.RemoveAt(0); } if ((m_buffer.Count > receivedByteCount)) { m_buffer.Clear(); } //收到数据就清空错误指示器,如果长时间通讯错误 肯定会一直往上加 ErrorConnCount = 0; #region 数据长度合格了 //数据接收超长了 也清空 数据刚好相等 头几个数据相同 if (m_buffer.Count == receivedByteCount) { //符合校验规则 if (XJPLCPackCmdAndDataUnpack.IsEnd(m_buffer.ToArray())) { if ((!isDeviceReady) && (ConstantMethod.compareByteStrictly(m_buffer.ToArray(), XJPLCcmd.CmdIn))) { #region 设备未连接 //设备通了 要开始 连接了哦 准备好了 //设置标志位 打开监控定时器 设置发送和 接收命令 isDeviceReady = true; isGoToGetData = true; ErrorConnCount = 0; SetCmdOutToCmdReadDMDataOut(); m_buffer.Clear(); #endregion } else { //设备连接情况下 是写数据区域命令的反馈 还是读数据区域命令的反馈 if (isWriteCmd) { ErrorConnCount = 0; #region 设备连接了 发送设置DM区域数据 //操做XJPLCcmd.CmdOut 只能在一条主线上做 不能再好多地方不然会出错 //这样 写寄存器的数据就要先放在一个缓存寄存命令里 SetCmdOut(XJPLCcmd.CmdSetBDREGOut, XJPLCcmd.CmdSetBDREGIn.Count()); SetCmdIn(XJPLCcmd.CmdSetBDREGIn); if (ConstantMethod.compareByte(m_buffer.ToArray(), XJPLCcmd.CmdIn)) { isWriteCmd = false; SetCmdOutToCmdReadDMDataOut(); } #endregion } else { #region 数据处理 ErrorConnCount = 0; //device重新打包监控数据命令 if (IsRePackCmdReadDMDataOut) { if (IsRepackDone) { SetCmdOutToCmdReadDMDataOut(); IsRePackCmdReadDMDataOut = false; IsRePackymp = true; m_buffer.Clear(); } } else //处理函数不为空 然后 数据开头也对 那就处理数据呗 if ((EventDataProcess != null)) { if (ConstantMethod.compareByte(m_buffer.ToArray(), Constant.XJReadDataCmdCheck)) { if (IsRePackymp) { IsRePackCmdReadDMDataOut = false; } DataProcessEventArgs.Byte_buffer = m_buffer.ToArray(); EventDataProcess(this, DataProcessEventArgs); } } #endregion } } } //在读的过程当中 如果遇到要写 那就先写 有没有在优化 if (IsGoToGetData && isNoConnection == false) { m_SerialPort.Send(XJPLCcmd.CmdOut.ToArray()); } ErrorConnCount = 0; m_buffer.Clear(); #endregion 数据长度合格了 } else { //收到字节数超出预计长度了 ErrorConnCount = 0; if (m_buffer.Count > receivedByteCount) { m_buffer.Clear(); } } } ////GC.Collect(); ////GC.WaitForPendingFinalizers(); }
/// <summary> /// 串口数据接收 针对信台达PLC /// 数据没有结束符 只能通过校验来确认 /// 信捷PLC 通讯模式 发送一条带DM 区域的指令 返回所有数据 /// 数据错误需要超时机制来进行恢复 如果超时一定次数 则判断中断 机器不存在 // 数据长度达到 就进行数据处理判断 同时发送下一组读取命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void DTPLC_SerialPort_Received(object sender, SerialPortEvents e) { if (e.BufferData != null) { m_buffer.AddRange(e.BufferData); //返回命令统一都是0X3a开头 如果不是则移除 if (m_buffer[0] != Constant.DTHeader) { m_buffer.RemoveAt(0); } if ((m_buffer.Count > receivedByteCount)) { m_buffer.Clear(); } //收到数据就清空错误指示器,如果长时间通讯错误 肯定会一直往上加 ErrorConnCount = 0; #region 数据长度合格了 //数据接收超长了 也清空 数据刚好相等 头几个数据相同 if (m_buffer.Count == receivedByteCount) { //进行转换 去掉第一个0x3a m_buffer = ConstantMethod.DeltaBufferPro(m_buffer); //符合校验规则 if (DTPLCPackCmdAndDataUnpack.IsEnd(m_buffer.ToArray())) { if ((!isDeviceReady) && (ConstantMethod.compareByteStrictly(m_buffer.ToArray(), ConstantMethod.DeltaBufferPro(DTPLCcmd.CmdIn)))) { #region 设备未连接 //设备通了 要开始 连接了哦 准备好了 //设置标志位 打开监控定时器 设置发送和 接收命令 isDeviceReady = true; isGoToGetData = true; //台达这里还不能发送 因为要设置读取命令先 //SetCmdOutToCmdReadDMDataOut(); m_buffer.Clear(); #endregion } else { //设备连接情况下 是写数据区域命令的反馈 还是读数据区域命令的反馈 if (isWriteCmd) { #region 设备连接了 发送设置DM区域数据 //操做DTPLCcmd.CmdOut 只能在一条主线上做 不能再好多地方不然会出错 //这样 写寄存器的数据就要先放在一个缓存寄存命令里 SetCmdOutIn(DTPLCcmd.CmdSetBDREGOut, DTPLCcmd.CmdSetBDREGIn); if (ConstantMethod.compareByte(m_buffer.ToArray(), DTPLCcmd.CmdSetBDREGIn)) { isWriteCmd = false; //SetCmdOutToCmdReadDMDataOut(); } #endregion } else { #region 设置DM区域读取 这里不同于信捷 因为设置 命令返回还是要检查的 信捷直接就修改命令后 就返回数据了 所以多了个ympIsRePackymp if (IsSetReadDDataOut) { if (DTPLCcmd.CmdSetReadDDataOut != null) { SetCmdOutIn(DTPLCcmd.CmdSetReadDDataOut.ToArray(), DTPLCcmd.CmdSetReadDDataIn.ToArray()); if (ConstantMethod.compareByte(m_buffer.ToArray(), DTPLCcmd.CmdSetReadDDataIn)) { SetCmdDOut(DTPLCcmd.CmdReadDDataOut.ToArray()); IsSetReadDDataOut = false; IsSetReadMDataOut = true; IsReadingD = true; IsReadingM = false; } } else { IsSetReadDDataOut = false; IsSetReadMDataOut = true; } } else if (IsSetReadMDataOut) { if (DTPLCcmd.CmdSetReadMDataOut != null) { SetCmdOutIn(DTPLCcmd.CmdSetReadMDataOut.ToArray(), DTPLCcmd.CmdSetReadMDataIn.ToArray()); if (ConstantMethod.compareByte(m_buffer.ToArray(), DTPLCcmd.CmdSetReadMDataIn)) { SetCmdMOut(DTPLCcmd.CmdReadMDataOut.ToArray()); IsSetReadMDataOut = false; IsReadingM = true; IsReadingD = false; } } else { IsSetReadMDataOut = false; } } else #endregion //20180703249写到这里 #region 数据处理 //处理函数不为空 然后 数据开头也对 那就处理数据呗 if ((EventDataProcess != null)) { if (ConstantMethod.compareByte(m_buffer.ToArray(), Constant.DTReadDataCmdCheck)) { DataProcessEventArgs.Byte_buffer = m_buffer.ToArray(); EventDataProcess(this, DataProcessEventArgs); ConstantMethod.Delay(50); if ((IsReadingM) && (DTPLCcmd.CmdReadDDataOut != null)) { IsReadingD = true; IsReadingM = false; } else if ((IsReadingD) && (DTPLCcmd.CmdReadMDataOut != null)) { IsReadingM = true; IsReadingD = false; } } } #endregion } } } //在读的过程当中 如果遇到要写 那就先写 有没有在优化 if (IsGoToGetData && IsNoConnection == false) { if (!IsSetReadDDataOut && !IsSetReadMDataOut && !isWriteCmd) { if ((IsReadingM) && (DTPLCcmd.CmdReadMDataOut != null)) { SetCmdMOut(DTPLCcmd.CmdReadMDataOut); } else if ((IsReadingD) && (DTPLCcmd.CmdReadDDataOut != null)) { SetCmdDOut(DTPLCcmd.CmdReadDDataOut); } } m_SerialPortListener.Send(DTPLCcmd.CmdOut.ToArray()); } m_buffer.Clear(); #endregion 数据长度合格了 } else { //收到字节数超出预计长度了 if (m_buffer.Count > receivedByteCount) { m_buffer.Clear(); } } } ////GC.Collect(); ////GC.WaitForPendingFinalizers(); }