示例#1
0
        /// <summary>
        /// Initializes the request ADU and calculates the response length.
        /// </summary>
        public virtual void InitReqADU(byte devAddr, TransMode transMode)
        {
            if (ReqPDU == null)
            {
                return;
            }

            int pduLen = ReqPDU.Length;

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

            case TransMode.ASCII:
                byte[] aduBuf = new byte[pduLen + 2];
                aduBuf[0] = devAddr;
                Buffer.BlockCopy(ReqPDU, 0, aduBuf, 1, ReqPDU.Length);
                aduBuf[pduLen + 1] = ModbusUtils.LRC(aduBuf, 0, pduLen + 1);

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

                ReqADU     = Encoding.ASCII.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;
                Buffer.BlockCopy(ReqPDU, 0, ReqADU, 7, ReqPDU.Length);
                RespAduLen = RespPduLen + 7;
                break;
            }
        }
示例#2
0
        /// <summary>
        /// Performs a request in the PDU mode.
        /// </summary>
        protected bool RtuRequest(DataUnit dataUnit)
        {
            bool result = false;

            // send request
            log.WriteLine(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length, ProtocolFormat.Hex, out string logText);
            log.WriteLine(logText);

            // receive response
            // partial read to calculate PDU length
            const int FirstCount = 2;
            int       readCnt    = Connection.Read(InBuf, 0, FirstCount, Timeout, ProtocolFormat.Hex, out logText);

            log.WriteLine(logText);

            if (readCnt != FirstCount)
            {
                log.WriteLine(ModbusPhrases.CommErrorWithExclamation);
            }
            else if (InBuf[0] != dataUnit.ReqADU[0]) // validate device address
            {
                log.WriteLine(ModbusPhrases.IncorrectDevAddr);
            }
            else if (!(InBuf[1] == dataUnit.FuncCode || InBuf[1] == dataUnit.ExcFuncCode)) // validate function code
            {
                log.WriteLine(ModbusPhrases.IncorrectPduFuncCode);
            }
            else
            {
                int pduLen;
                int count;

                if (InBuf[1] == dataUnit.FuncCode)
                {
                    pduLen = dataUnit.RespPduLen;
                    count  = dataUnit.RespAduLen - FirstCount;
                }
                else // exception received
                {
                    pduLen = 2;
                    count  = 3;
                }

                // read rest of response
                readCnt = Connection.Read(InBuf, FirstCount, count, Timeout, ProtocolFormat.Hex, out logText);
                log.WriteLine(logText);

                if (readCnt != count)
                {
                    log.WriteLine(ModbusPhrases.CommErrorWithExclamation);
                }
                else if (InBuf[pduLen + 1] + InBuf[pduLen + 2] * 256 != ModbusUtils.CRC16(InBuf, 0, pduLen + 1))
                {
                    log.WriteLine(ModbusPhrases.CrcError);
                }
                else if (dataUnit.DecodeRespPDU(InBuf, 1, pduLen, out string errMsg))
                {
                    log.WriteLine(ModbusPhrases.OK);
                    result = true;
                }
                else
                {
                    log.WriteLine(errMsg + "!");
                }
            }

            return(result);
        }