示例#1
0
        // TODO: too many arguments
        // Build common part of modbus request, decorate it with transport layer specific header, send request and get response PDU back
        public byte[] SendModbusRequest(byte id, ModbusFunctionCodes functionCode, ushort readAddress, ushort readCount, ushort writeAddress, ushort writeCount, byte[] writeData)
        {
            // Build common part of modbus request
            byte[] requestPdu = BuildRequestPdu(id, functionCode, readAddress, readCount, writeAddress, writeCount, writeData);

            // Decorate common part of modbus request with transport layer specific header
            byte[] requestAdu = BuildRequestAdu(requestPdu);

            // Send modbus request and return response
            return(Query(requestAdu)); // response PDU
        }
        public static ModbusTCPMessage ParseBytes(IEnumerable <byte> message)
        {
            var og = new ModbusTCPMessage(message);
            ModbusFunctionCodes func = og.PDU.FunctionCode;

            switch (func)
            {
            case ModbusFunctionCodes.ReadHoldingRegisters:
                return(new ReadRegistersMessage(message));

            case ModbusFunctionCodes.PresetMultipleRegisters:
                return(new WriteHoldingRegistersMessage(message));

            default:
                return(new ModbusTCPMessage(message));
            }
        }
示例#3
0
        // TODO: Refactor this. Too many lines and arguments; ugly switch statement. Hard to follow. Break out a new class.
        // Build common part of modbus request
        private byte[] BuildRequestPdu(byte id, ModbusFunctionCodes functionCode, ushort readAddress, ushort readCount, ushort writeAddress, ushort writeCount, byte[] writeData)
        {
            byte[] help; // Used to convert ushort into bytes
            byte[] requestPdu = null;

            switch (functionCode)
            {
            case ModbusFunctionCodes.ReadCoils:
            case ModbusFunctionCodes.ReadDiscreteInputs:
            case ModbusFunctionCodes.ReadHoldingRegisters:
            case ModbusFunctionCodes.ReadInputRegisters:
                requestPdu = new byte[6];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = (byte)functionCode;
                help          = BitConverter.GetBytes(readAddress);
                requestPdu[2] = help[1];     // Start read address -Hi
                requestPdu[3] = help[0];     // Start read address -Lo
                help          = BitConverter.GetBytes(readCount);
                requestPdu[4] = help[1];     // Number of coils or register to read -Hi
                requestPdu[5] = help[0];     // Number of coils or register to read -Lo
                break;

            case ModbusFunctionCodes.WriteSingleCoil:
                requestPdu = new byte[6];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = 0x05;
                help          = BitConverter.GetBytes(writeAddress);
                requestPdu[2] = help[1];      // Address of coil to force -Hi
                requestPdu[3] = help[0];      // Address of coil to force -Lo
                // Copy data
                requestPdu[4] = writeData[0]; // Output value -Hi  ( 0xFF or 0x00 )
                requestPdu[5] = 0x00;         // Output value -Lo  ( const: 0x00  )
                break;

            case ModbusFunctionCodes.WriteSingleRegister:
                requestPdu = new byte[6];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = 0x06;
                help          = BitConverter.GetBytes(writeAddress);
                requestPdu[2] = help[1];      // Address of register to force -Hi
                requestPdu[3] = help[0];      // Address of register to force -Lo
                requestPdu[4] = writeData[1]; // Output value -Hi
                requestPdu[5] = writeData[0]; // Output value -Lo
                break;

            case ModbusFunctionCodes.GetCommEventCounter:
                requestPdu = new byte[2];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = 0x0B;
                break;

            case ModbusFunctionCodes.WriteMultipleCoils:
                byte byteCount = (byte)(writeCount / 8);
                if ((writeCount % 8) > 0)
                {
                    byteCount += 1;
                }
                requestPdu = new byte[7 + byteCount];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = 0x0F;
                help          = BitConverter.GetBytes(writeAddress);
                requestPdu[2] = help[1];     // Start address of coils to force -Hi
                requestPdu[3] = help[0];     // Start address of coils to force -Lo
                help          = BitConverter.GetBytes(writeCount);
                requestPdu[4] = help[1];     // Number of coils to write -Hi
                requestPdu[5] = help[0];     // Number of coils to write -Lo
                requestPdu[6] = byteCount;
                // Copy data
                for (int i = 0; i < byteCount; ++i)
                {
                    requestPdu[7 + i] = writeData[i];
                }
                break;

            case ModbusFunctionCodes.WriteMultipleRegisters:
                requestPdu = new byte[7 + (writeCount * 2)];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = 0x10;
                help          = BitConverter.GetBytes(writeAddress);
                requestPdu[2] = help[1];                // Start address of coils to force -Hi
                requestPdu[3] = help[0];                // Start address of coils to force -Lo
                help          = BitConverter.GetBytes(writeCount);
                requestPdu[4] = help[1];                // Number of register to write -Hi
                requestPdu[5] = help[0];                // Number of register to write -Lo
                requestPdu[6] = (byte)(writeCount * 2); // Number of bytes to write
                // Copy data
                for (int i = 0; i < (writeCount * 2); i++)
                {
                    requestPdu[7 + i] = writeData[i];
                }
                break;

            case ModbusFunctionCodes.MaskWriteRegister:
                requestPdu = new byte[8];
                // Build request header
                requestPdu[0] = id;
                requestPdu[1] = 0x16;
                help          = BitConverter.GetBytes(writeAddress);
                requestPdu[2] = help[1];      // Address of register to force -Hi
                requestPdu[3] = help[0];      // Address of register to force -Lo
                requestPdu[4] = writeData[1]; // And_Mask -Hi
                requestPdu[5] = writeData[0]; // And_Mask -Lo
                requestPdu[6] = writeData[3]; // Or_Mask -Hi
                requestPdu[7] = writeData[2]; // Or_Mask -Lo
                break;

            case ModbusFunctionCodes.ReadWriteMultipleRegisters:
                requestPdu = new byte[11 + (writeCount * 2)];
                // Build request header
                requestPdu[0]  = id;
                requestPdu[1]  = 0x17;
                help           = BitConverter.GetBytes(readAddress);
                requestPdu[2]  = help[1];                // Start read address -Hi
                requestPdu[3]  = help[0];                // Start read address -Lo
                help           = BitConverter.GetBytes(readCount);
                requestPdu[4]  = help[1];                // Number of register to read -Hi
                requestPdu[5]  = help[0];                // Number of register to read -Lo
                help           = BitConverter.GetBytes(writeAddress);
                requestPdu[6]  = help[1];                // Start write address -Hi
                requestPdu[7]  = help[0];                // Start write address -Lo
                help           = BitConverter.GetBytes(writeCount);
                requestPdu[8]  = help[1];                // Number of register to write -Hi
                requestPdu[9]  = help[0];                // Number of register to write -Lo
                requestPdu[10] = (byte)(writeCount * 2); // Number of bytes to write
                // Copy data
                for (int i = 0; i < (writeCount * 2); ++i)
                {
                    requestPdu[11 + i] = writeData[i];
                }
                break;
            } // switch

            return(requestPdu);
        }
示例#4
0
 public ProtocolDataUnit(ModbusFunctionCodes functionCode, IEnumerable <byte> data)
 {
     FunctionCode = functionCode;
     Data         = data;
 }