Exemplo n.º 1
0
        private void ReadObjects(ModbusReadRequest request)
        {
            try
            {
                switch (request.ObjectType)
                {
                case ObjectType.Coil:
                    ReadCoils(request);
                    break;

                case ObjectType.DiscreteInput:
                    ReadDiscreteInputs(request);
                    break;

                case ObjectType.InputRegister:
                    ReadInputRegisters(request);
                    break;

                case ObjectType.HoldingRegister:
                    ReadHoldingRegisters(request);
                    break;

                default:
                    throw new ArgumentException("request");
                }
            }
            catch (Exception e)
            {
                PublishException(e);
            }
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            var logger = new ConsoleModbusLogger();

            var modbusMaster = new ModbusMaster
            {
                Channel = new TcpClientModbusChannel("127.0.0.1", 502, 1000)
                          //Channel = new UdpClientModbusChannel("127.0.0.1", 502)
                {
                    Logger = logger
                },
                //Serializer = new ModbusRtuSerializer(),
                Serializer = new ModbusTcpSerializer(),
                //Serializer = new ModbusAsciiSerializer(),
                Logger = logger,
            };

            while (true)
            {
                Thread.Sleep(1000);

                try
                {
                    var request  = new ModbusReadRequest(1, ModbusObjectType.InputRegister, 100, 2);
                    var resposne = modbusMaster.Request(request, 1000);

                    Console.WriteLine((resposne as ModbusReadRegisterResponse).GetSingle(100));
                }
                catch
                {
                }
            }
        }
Exemplo n.º 3
0
 private ModbusReadResponse CreateResponse(ModbusReadRequest request, dynamic data)
 {
     return(new ModbusReadResponse()
     {
         ObjectType = request.ObjectType,
         MasterId = request.MasterId,
         SlaveId = request.SlaveId,
         StartAddress = request.StartAddress,
         Data = data
     });
 }
Exemplo n.º 4
0
        /// <summary>
        /// Reading request to Modbus target device
        /// </summary>
        public override Task <ModbusReadResponse> ReadModbus(ModbusReadRequest request, ServerCallContext context)
        {
            // Get required device
            var address = Convert.ToString(request.Ip);
            var port    = Convert.ToUInt16(request.Port);
            var device  = new Tuple <string, ushort>(address, port);

            DeviceContextsPool = ModbusContextMultiton.GetInstance(device);

            var registerType = request.RegisterType;
            var startAddress = Convert.ToUInt16(request.StartAddress);
            var readCnt      = Convert.ToUInt16(request.ReadCnt);

            // Request Modbus slave
            // TODO: Fix type conversions in library
            // TODO: Think more about logic to call required function
            byte[] seq = null;
            switch (registerType)
            {
            case ModbusRegisters.Coil:
                var resultCoil = DeviceContextsPool.ModbusContext.ReadCoils(startAddress, readCnt);
                seq = Array.ConvertAll(resultCoil, b => b ? (byte)1 : (byte)0);
                break;

            case ModbusRegisters.DiscreteInput:
                var resultInput = DeviceContextsPool.ModbusContext.ReadDiscreteInputs(startAddress, readCnt);
                seq = Array.ConvertAll(resultInput, b => b ? (byte)1 : (byte)0);
                break;

            case ModbusRegisters.Holding:
//                    var result_holding = device_context.ReadHolding(startAddress, readCnt);
//                    seq = Array.ConvertAll(result_holding, b => b ? (byte) 1 : (byte) 0);
                break;

            case ModbusRegisters.Input:
//                    var result_input_registers = device_context.ReadInputRegisters(startAddress, readCnt);
//                    seq = Array.ConvertAll(result_input_registers, b => b ? (byte) 1 : (byte) 0);
                break;
            }

            Console.WriteLine(ByteString.CopyFrom(seq));
            return(Task.FromResult(new ModbusReadResponse
            {
                Seq = ByteString.CopyFrom(seq)
            }));
        }
Exemplo n.º 5
0
 internal abstract ModbusResponse DeserializeReadRegisterResponse(ResponseBuffer buffer, ModbusReadRequest request, int timeout);
Exemplo n.º 6
0
        internal override ModbusRequest DeserializeRequest(RequestBuffer buffer)
        {
            ModbusRequest result = null;

            while (!buffer.Channel.IsDisposed)
            {
                if (errorBuffer.Count >= 256)
                {
                    RaiseUnrecognized(buffer.Channel, errorBuffer.ToArray());
                    errorBuffer.Clear();
                }

                while (buffer.Count < 8 && !buffer.Channel.IsDisposed)
                {
                    buffer.Read();
                }

                if (buffer.Channel.IsDisposed)
                {
                    break;
                }

                var slaveAddress  = buffer[0];
                int messageLength = 0;

                if (buffer.ModbusSlave.IsValidSlaveAddress(slaveAddress, buffer.Channel) &&
                    Enum.IsDefined(typeof(ModbusFunction), buffer[1]))
                {
                    ModbusFunction function      = (ModbusFunction)buffer[1];
                    var            address       = ToUInt16(buffer, 2);
                    var            valueOrLength = ToUInt16(buffer, 4);

                    switch (function)
                    {
                    case ModbusFunction.ReadCoils:
                    case ModbusFunction.ReadDiscreteInputs:
                    case ModbusFunction.ReadHoldingRegisters:
                    case ModbusFunction.ReadInputRegisters:
                    case ModbusFunction.WriteSingleCoil:
                    case ModbusFunction.WriteSingleHoldingRegister:
                        if (CalculateCrc(buffer.Take(6)).SequenceEqual(buffer.Skip(6).Take(2)))
                        {
                            messageLength = 8;
                            switch (function)
                            {
                            case ModbusFunction.ReadCoils:
                            case ModbusFunction.ReadDiscreteInputs:
                            case ModbusFunction.ReadHoldingRegisters:
                            case ModbusFunction.ReadInputRegisters:
                                result = new ModbusReadRequest(slaveAddress, (ModbusObjectType)(byte)function, address, valueOrLength);
                                break;

                            case ModbusFunction.WriteSingleCoil:
                                if (valueOrLength != 0xff00 && valueOrLength != 0)
                                {
                                    result = new ModbusWriteCoilRequest(slaveAddress, address);
                                }
                                else
                                {
                                    result = new ModbusWriteCoilRequest(slaveAddress, address, valueOrLength == 0xff00);
                                }
                                break;

                            case ModbusFunction.WriteSingleHoldingRegister:
                                result = new ModbusWriteHoldingRegisterRequest(slaveAddress, address, valueOrLength);
                                break;
                            }
                        }
                        break;

                    case ModbusFunction.WriteMultipleCoils:
                    case ModbusFunction.WriteMultipleHoldingRegisters:
                        if (buffer.Count < 7 && !buffer.Channel.IsDisposed)
                        {
                            buffer.Read();
                        }

                        if (buffer.Channel.IsDisposed)
                        {
                            break;
                        }

                        var byteLength = buffer[6];
                        messageLength = byteLength + 9;

                        if (function == ModbusFunction.WriteMultipleCoils && byteLength == Math.Ceiling(valueOrLength / 8d) ||
                            function == ModbusFunction.WriteMultipleHoldingRegisters && byteLength == valueOrLength * 2)
                        {
                            while (buffer.Count < messageLength && !buffer.Channel.IsDisposed)
                            {
                                buffer.Read();
                            }

                            if (buffer.Channel.IsDisposed)
                            {
                                break;
                            }

                            if (CalculateCrc(buffer.Take(byteLength + 7)).SequenceEqual(buffer.Skip(byteLength + 7).Take(2)))
                            {
                                switch (function)
                                {
                                case ModbusFunction.WriteMultipleCoils:
                                    result = new ModbusWriteCoilRequest(slaveAddress, address, buffer.Skip(7).Take(byteLength).SelectMany(b => ByteToBooleanArray(b)).Take(valueOrLength).ToArray());
                                    break;

                                case ModbusFunction.WriteMultipleHoldingRegisters:
                                    result = new ModbusWriteHoldingRegisterRequest(slaveAddress, address, buffer.Skip(7).Take(byteLength).ToArray());
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }

                if (result != null)
                {
                    if (errorBuffer.Count > 0)
                    {
                        RaiseUnrecognized(buffer.Channel, errorBuffer.ToArray());
                        errorBuffer.Clear();
                    }
                    return(result);
                }
                else
                {
                    errorBuffer.Add(buffer[0]);
                    buffer.RemoveAt(0);
                    continue;
                }
            }
            return(null);
        }
Exemplo n.º 7
0
        internal override ModbusResponse DeserializeReadRegisterResponse(ResponseBuffer buffer, ModbusReadRequest request, int timeout)
        {
            if (IsException(buffer, request, timeout, out var responseMessage))
            {
                return(responseMessage);
            }

            byte byteLength = Read(buffer, 2, timeout);

            if (IsErrorCRC(buffer, 3 + byteLength, request, timeout))
            {
                throw new ModbusCommException(ModbusCommErrorCode.ErrorCRC, buffer, request);
            }

            if (Read(buffer, 0, timeout) != request.SlaveAddress)
            {
                throw new ModbusCommException(ModbusCommErrorCode.ResponseSlaveAddressDoNotMatch, buffer, request);
            }
            if ((Read(buffer, 1, timeout) & 0x7f) != (byte)request.Function)
            {
                throw new ModbusCommException(ModbusCommErrorCode.ResponseFunctionDoNotMatch, buffer, request);
            }
            if (byteLength != (byte)(request.Length * 2))
            {
                throw new ModbusCommException(ModbusCommErrorCode.ResponseLengthDoNotMatch, buffer, request);
            }

            return(new ModbusReadRegisterResponse(Read(buffer, 3, byteLength, timeout).ToArray(), request));
        }
Exemplo n.º 8
0
 private void ReadHoldingRegisters(ModbusReadRequest request)
 {
     UInt16[] result = _masters[request.MasterId].ReadHoldingRegisters(
         request.SlaveId, request.StartAddress, request.NumberOfPoints);
     PublishResponse(CreateResponse(request, result));
 }
Exemplo n.º 9
0
 private void ReadCoils(ModbusReadRequest request)
 {
     bool[] result = _masters[request.MasterId].ReadCoils(
         request.SlaveId, request.StartAddress, request.NumberOfPoints);
     PublishResponse(CreateResponse(request, result));
 }
Exemplo n.º 10
0
        internal override ModbusResponse DeserializeReadBooleanResponse(ResponseBuffer buffer, ModbusReadRequest request, int timeout)
        {
            if (IsException(buffer, request, timeout, out var responseMessage))
            {
                return(responseMessage);
            }

            byte byteLength = Read(buffer, 8, timeout);

            if (Read(buffer, 6, timeout) != request.SlaveAddress)
            {
                return(new ModbusCommErrorResponse(ModbusCommErrorCode.ResponseSlaveAddressDoNotMatch, buffer, request));
            }
            if ((Read(buffer, 7, timeout) & 0x7f) != (byte)request.Function)
            {
                return(new ModbusCommErrorResponse(ModbusCommErrorCode.ResponseFunctionDoNotMatch, buffer, request));
            }
            if (byteLength != (byte)Math.Ceiling(request.Length / 8d))
            {
                return(new ModbusCommErrorResponse(ModbusCommErrorCode.ResponseLengthDoNotMatch, buffer, request));
            }

            return(new ModbusReadBooleanResponse(Read(buffer, 9, byteLength, timeout).SelectMany(b => ByteToBooleanArray(b)).Take(request.Length).ToArray(), request));
        }
Exemplo n.º 11
0
        internal override ModbusRequest DeserializeRequest(RequestBuffer rawBuffer)
        {
            ModbusRequest result = null;

            while (!rawBuffer.Channel.IsDisposed)
            {
                if (errorBuffer.Count >= 256)
                {
                    RaiseUnrecognized(rawBuffer.Channel, errorBuffer.ToArray());
                    errorBuffer.Clear();
                }

                while (rawBuffer.Count < 17 && !rawBuffer.Channel.IsDisposed)
                {
                    rawBuffer.Read();
                }

                if (rawBuffer.Channel.IsDisposed)
                {
                    break;
                }

                int messageLength = 0;

                if (rawBuffer[0] == 0x3a)
                {
                    List <byte> buffer = new List <byte>();

                    for (int i = 0; i < 7; i++)
                    {
                        if (TryParseFromHex(rawBuffer, i * 2 + 1, out var byteValue))
                        {
                            buffer.Add(byteValue);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (buffer.Count < 7)
                    {
                        errorBuffer.AddRange(rawBuffer.Take((buffer.Count + 1) * 2 + 1));
                        rawBuffer.RemoveRange(0, (buffer.Count + 1) * 2 + 1);
                        continue;
                    }

                    var slaveAddress = buffer[0];

                    if (rawBuffer.ModbusSlave.IsValidSlaveAddress(slaveAddress, rawBuffer.Channel) &&
                        Enum.IsDefined(typeof(ModbusFunction), buffer[1]))
                    {
                        ModbusFunction function      = (ModbusFunction)buffer[1];
                        var            address       = ToUInt16(buffer, 2);
                        var            valueOrLength = ToUInt16(buffer, 4);

                        switch (function)
                        {
                        case ModbusFunction.ReadCoils:
                        case ModbusFunction.ReadDiscreteInputs:
                        case ModbusFunction.ReadHoldingRegisters:
                        case ModbusFunction.ReadInputRegisters:
                        case ModbusFunction.WriteSingleCoil:
                        case ModbusFunction.WriteSingleHoldingRegister:
                            if ((-buffer.Take(6).Sum(b => b) & 0xff) == buffer[6] &&
                                rawBuffer[15] == '\r' && rawBuffer[16] == '\n')
                            {
                                messageLength = 17;
                                switch (function)
                                {
                                case ModbusFunction.ReadCoils:
                                case ModbusFunction.ReadDiscreteInputs:
                                case ModbusFunction.ReadHoldingRegisters:
                                case ModbusFunction.ReadInputRegisters:
                                    result = new ModbusReadRequest(slaveAddress, (ModbusObjectType)(byte)function, address, valueOrLength);
                                    break;

                                case ModbusFunction.WriteSingleCoil:
                                    if (valueOrLength != 0xff00 && valueOrLength != 0)
                                    {
                                        result = new ModbusWriteCoilRequest(slaveAddress, address);
                                    }
                                    else
                                    {
                                        result = new ModbusWriteCoilRequest(slaveAddress, address, valueOrLength == 0xff00);
                                    }
                                    break;

                                case ModbusFunction.WriteSingleHoldingRegister:
                                    result = new ModbusWriteHoldingRegisterRequest(slaveAddress, address, valueOrLength);
                                    break;
                                }
                            }
                            break;

                        case ModbusFunction.WriteMultipleCoils:
                        case ModbusFunction.WriteMultipleHoldingRegisters:
                            var byteLength = buffer[6];
                            messageLength = byteLength * 2 + 19;

                            if (function == ModbusFunction.WriteMultipleCoils && byteLength == Math.Ceiling(valueOrLength / 8d) ||
                                function == ModbusFunction.WriteMultipleHoldingRegisters && byteLength == valueOrLength * 2)
                            {
                                while (rawBuffer.Count < messageLength && !rawBuffer.Channel.IsDisposed)
                                {
                                    rawBuffer.Read();
                                }

                                if (rawBuffer.Channel.IsDisposed)
                                {
                                    break;
                                }

                                for (int i = 0; i < byteLength + 1; i++)
                                {
                                    if (TryParseFromHex(rawBuffer, i * 2 + 15, out var byteValue))
                                    {
                                        buffer.Add(byteValue);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (buffer.Count < 8 + byteLength)
                                {
                                    errorBuffer.AddRange(rawBuffer.Take((buffer.Count + 1) * 2 + 1));
                                    rawBuffer.RemoveRange(0, (buffer.Count + 1) * 2 + 1);
                                    continue;
                                }


                                if ((-buffer.Take(7 + byteLength).Sum(b => b) & 0xff) == buffer[6] &&
                                    rawBuffer[15] == '\r' && rawBuffer[16] == '\n')
                                {
                                    switch (function)
                                    {
                                    case ModbusFunction.WriteMultipleCoils:
                                        result = new ModbusWriteCoilRequest(slaveAddress, address, buffer.Skip(7).Take(byteLength).SelectMany(b => ByteToBooleanArray(b)).Take(valueOrLength).ToArray());
                                        break;

                                    case ModbusFunction.WriteMultipleHoldingRegisters:
                                        result = new ModbusWriteHoldingRegisterRequest(slaveAddress, address, buffer.Skip(7).Take(byteLength).ToArray());
                                        break;
                                    }
                                }
                            }
                            break;
                        }
                    }
                }

                if (result != null)
                {
                    if (errorBuffer.Count > 0)
                    {
                        RaiseUnrecognized(rawBuffer.Channel, errorBuffer.ToArray());
                        errorBuffer.Clear();
                    }
                    return(result);
                }
                else
                {
                    errorBuffer.Add(rawBuffer[0]);
                    rawBuffer.RemoveAt(0);
                    continue;
                }
            }
            return(null);
        }