Exemple #1
0
        /// <summary>
        /// Инициализировать ADU запроса и рассчитать длину ответа
        /// </summary>
        public virtual void InitReqADU(byte devAddr, TransModes transMode)
        {
            if (ReqPDU != null)
            {
                int pduLen = ReqPDU.Length;

                switch (transMode)
                {
                case TransModes.RTU:
                    ReqADU    = new byte[pduLen + 3];
                    ReqADU[0] = devAddr;
                    ReqPDU.CopyTo(ReqADU, 1);
                    ushort crc = ModbusUtils.CalcCRC16(ReqADU, 0, pduLen + 1);
                    ReqADU[pduLen + 1] = (byte)(crc % 256);
                    ReqADU[pduLen + 2] = (byte)(crc / 256);
                    RespAduLen         = RespPduLen + 3;
                    break;

                case TransModes.ASCII:
                    byte[] aduBuf = new byte[pduLen + 2];
                    aduBuf[0] = devAddr;
                    ReqPDU.CopyTo(aduBuf, 1);
                    aduBuf[pduLen + 1] = ModbusUtils.CalcLRC(aduBuf, 0, pduLen + 1);

                    StringBuilder sbADU = new StringBuilder();
                    foreach (byte b in aduBuf)
                    {
                        sbADU.Append(b.ToString("X2"));
                    }

                    ReqADU     = Encoding.Default.GetBytes(sbADU.ToString());
                    ReqStr     = ModbusUtils.Colon + sbADU;
                    RespAduLen = RespPduLen + 2;
                    break;

                default:     // TransModes.TCP
                    ReqADU    = new byte[pduLen + 7];
                    ReqADU[0] = 0;
                    ReqADU[1] = 0;
                    ReqADU[2] = 0;
                    ReqADU[3] = 0;
                    ReqADU[4] = (byte)((pduLen + 1) / 256);
                    ReqADU[5] = (byte)((pduLen + 1) % 256);
                    ReqADU[6] = devAddr;
                    ReqPDU.CopyTo(ReqADU, 7);
                    RespAduLen = RespPduLen + 7;
                    break;
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Выполнить запрос в режиме RTU
        /// </summary>
        public bool RtuRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            bool result = false;

            // отправка запроса
            ExecWriteToLog(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length,
                             CommUtils.ProtocolLogFormats.Hex, out string logText);
            ExecWriteToLog(logText);

            // приём ответа
            // считывание начала ответа для определения длины PDU
            int readCnt = Connection.Read(InBuf, 0, 5, Timeout, CommUtils.ProtocolLogFormats.Hex, out logText);

            ExecWriteToLog(logText);

            if (readCnt == 5)
            {
                int pduLen;
                int count;

                if (InBuf[0] != dataUnit.ReqADU[0]) // проверка адреса устройства в ответе
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectDevAddr);
                }
                else if (!(InBuf[1] == dataUnit.FuncCode || InBuf[1] == dataUnit.ExcFuncCode))
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectPduFuncCode);
                }
                else
                {
                    if (InBuf[1] == dataUnit.FuncCode)
                    {
                        // считывание окончания ответа
                        pduLen = dataUnit.RespPduLen;
                        count  = dataUnit.RespAduLen - 5;

                        readCnt = Connection.Read(InBuf, 5, count, Timeout,
                                                  CommUtils.ProtocolLogFormats.Hex, out logText);
                        ExecWriteToLog(logText);
                    }
                    else // устройство вернуло исключение
                    {
                        pduLen  = 2;
                        count   = 0;
                        readCnt = 0;
                    }

                    if (readCnt == count)
                    {
                        if (InBuf[pduLen + 1] + InBuf[pduLen + 2] * 256 == ModbusUtils.CalcCRC16(InBuf, 0, pduLen + 1))
                        {
                            // расшифровка ответа
                            string errMsg;

                            if (dataUnit.DecodeRespPDU(InBuf, 1, pduLen, out errMsg))
                            {
                                ExecWriteToLog(ModbusPhrases.OK);
                                result = true;
                            }
                            else
                            {
                                ExecWriteToLog(errMsg + "!");
                            }
                        }
                        else
                        {
                            ExecWriteToLog(ModbusPhrases.CrcError);
                        }
                    }
                    else
                    {
                        ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
                    }
                }
            }
            else
            {
                ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }
Exemple #3
0
        /// <summary>
        /// Run RTU query
        /// </summary>
        public bool RtuRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            var result = false;

            // sending request
            ExecWriteToLog(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length,
                             CommUtils.ProtocolLogFormats.Hex, out string logText);
            ExecWriteToLog(logText);

            // reception of the answer
            // reading the start of the response to determine the length of the PDU
            int readCnt = Connection.Read(InBuf, 0, 5, Timeout, CommUtils.ProtocolLogFormats.Hex, out logText);

            ExecWriteToLog(logText);

            if (readCnt == 5)
            {
                int pduLen;
                int count;

                if (InBuf[0] != dataUnit.ReqADU[0]) // checking device address in response
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectDevAddr);
                }
                else if (!(InBuf[1] == dataUnit.FuncCode || InBuf[1] == dataUnit.ExcFuncCode))
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectPduFuncCode);
                }
                else
                {
                    if (InBuf[1] == dataUnit.FuncCode)
                    {
                        // read end of response
                        pduLen = dataUnit.RespPduLen;
                        count  = dataUnit.RespAduLen - 5;

                        readCnt = Connection.Read(InBuf, 5, count, Timeout,
                                                  CommUtils.ProtocolLogFormats.Hex, out logText);
                        ExecWriteToLog(logText);
                    }
                    else   // device returned exception
                    {
                        pduLen  = 2;
                        count   = 0;
                        readCnt = 0;
                    }

                    if (readCnt == count)
                    {
                        if (InBuf[pduLen + 1] + InBuf[pduLen + 2] * 256 ==
                            ModbusUtils.CalcCRC16(InBuf, 0, pduLen + 1))
                        {
                            // answer decryption
                            string errMsg;

                            if (dataUnit.DecodeRespPDU(InBuf, 1, pduLen, out errMsg))
                            {
                                ExecWriteToLog(ModbusPhrases.OK);
                                result = true;
                            }
                            else
                            {
                                ExecWriteToLog(errMsg + "!");
                            }
                        }
                        else
                        {
                            ExecWriteToLog(ModbusPhrases.CrcError);
                        }
                    }
                    else
                    {
                        ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
                    }
                }
            }
            else
            {
                ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }