コード例 #1
0
        //TODO: Evaluate ReadHoldingRegisters return type.  Should this be words? Bytes? something else?
        //      At the core of the protocol, this is really returning words.  The words can be interpreted
        //      as floating point, integers, unsigned, etc.
        public IEnumerable <Int16> ReadHoldingRegisters(Int16 startRegister, Int16 count)
        {
            List <byte> mbPacket = new List <byte>();

            mbPacket.Add(0x03);
            mbPacket.AddRange(startRegister.GetBytes());
            mbPacket.AddRange(count.GetBytes());

            MBAP mbap = MBAP.Create((Int16)(mbPacket.Count + 1), 0);

            mbPacket.InsertRange(0, mbap.GetBytes());

            tcpClient.GetStream().Write(mbPacket.ToArray(), 0, mbPacket.Count);

            byte[] readBuffer = new byte[500];

            tcpClient.GetStream().Read(readBuffer, 0, 500);

            int returnCount = (int)readBuffer[8];

            List <Int16> returnList = new List <short>();

            for (int i = 9; i < 9 + returnCount; i += 2)
            {
                returnList.Add(Int16Extensions.FromBytes(readBuffer[i], readBuffer[i + 1]));
            }

            return(returnList);
        }
コード例 #2
0
        public void WriteMultipleRegisters(Int16 startRegister, IEnumerable <Int16> values)
        {
            List <byte> mbPacket = new List <byte>();

            mbPacket.Add(0x10);
            mbPacket.AddRange(startRegister.GetBytes());
            mbPacket.AddRange(((Int16)(values.Count())).GetBytes());

            var data = values.SelectMany(v => new List <byte>()
            {
                v.HighByte(), v.LowByte()
            });

            mbPacket.Add(((Int16)data.Count()).LowByte());
            mbPacket.AddRange(data.ToArray());

            MBAP mbap = MBAP.Create((Int16)(mbPacket.Count + 1), 0);

            mbPacket.InsertRange(0, mbap.GetBytes());

            tcpClient.GetStream().Write(mbPacket.ToArray(), 0, mbPacket.Count);

            byte[] buffer = new byte[500];

            //technically, the operation should be confirmed by examining the response
            tcpClient.GetStream().Read(buffer, 0, buffer.Length);

            //error function codes will be: (original function code) | (0x80)
            if ((buffer[7] & 0x80) > 0)
            {
                throw new Exception();
            }
        }
コード例 #3
0
        public override ModbusTCPMessage Process(IMemoryModel memory)
        {
            int address = Int16Extensions.FromBytes(PDU.Data.First(), PDU.Data.Skip(1).First());
            int length  = Int16Extensions.FromBytes(PDU.Data.Skip(2).First(), PDU.Data.Skip(3).First());

            try
            {
                var values           = memory.Read4x(address, length);
                ProtocolDataUnit pdu = PDU.ValidResponse(
                    new byte[]
                    { (byte)(values.Count() * 2) }
                    .Concat(values.SelectMany(v => v.GetBytes())));
                ModbusTCPMessage reply = Create(
                    MBAP.Create((byte)(pdu.GetBytes().Count() + 1), ApplicationHeader.UnitID),
                    pdu);
                return(reply);
            }
            catch
            {
                ProtocolDataUnit pdu   = PDU.ErrorResponse(new byte[] { 0x01 });
                ModbusTCPMessage reply = Create(
                    MBAP.Create((byte)(pdu.GetBytes().Count() + 1), ApplicationHeader.UnitID),
                    pdu);
                return(reply);
            }
        }
コード例 #4
0
        public static ModbusTCPMessage Create(MBAP appHeader, ProtocolDataUnit pdu)
        {
            switch (pdu.FunctionCode)
            {
            case ModbusFunctionCodes.ReadHoldingRegisters:
                return(new ReadRegistersMessage(appHeader, pdu));

            case ModbusFunctionCodes.PresetMultipleRegisters:
                return(new WriteHoldingRegistersMessage(appHeader, pdu));

            default:
                return(new ModbusTCPMessage(appHeader, pdu));
            }
        }
コード例 #5
0
        public override ModbusTCPMessage Process(IMemoryModel memory)
        {
            try
            {
                int address = StartAddress();
                var values  = ParseValues();

                memory.Write4x(address, values);

                var pdu   = PDU.ValidResponse(((Int16)values.Count()).GetBytes());
                var reply = Create(
                    MBAP.Create((byte)(pdu.GetBytes().Count() + 1), ApplicationHeader.UnitID),
                    pdu);
                return(reply);
            }
            catch
            {
                var pdu = PDU.ErrorResponse(new byte[] { 0x01 });
                ModbusTCPMessage reply = Create(
                    MBAP.Create((byte)(pdu.GetBytes().Count() + 1), ApplicationHeader.UnitID),
                    pdu);
                return(reply);
            }
        }
コード例 #6
0
 public ReadRegistersMessage(MBAP appHeader, ProtocolDataUnit pdu)
     : base(appHeader, pdu)
 {
 }
コード例 #7
0
 protected ModbusTCPMessage(IEnumerable <byte> messageBuffer)
 {
     ApplicationHeader = MBAP.ParseFromMessage(messageBuffer);
     PDU = new ProtocolDataUnit(messageBuffer);
 }
コード例 #8
0
 protected ModbusTCPMessage(MBAP appHeader, ProtocolDataUnit pdu)
 {
     ApplicationHeader = appHeader;
     PDU = pdu;
 }
コード例 #9
0
 public WriteHoldingRegistersMessage(MBAP appHeader, ProtocolDataUnit pdu)
     : base(appHeader, pdu)
 {
 }