Пример #1
0
        /// <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();
        }
Пример #2
0
        /// <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();
        }