コード例 #1
0
ファイル: Device.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        #endregion

        // !!! Необоходимо сделать статическим методами, для того что бы уменьшить
        // размер устройтва в ОЗУ.
        #region INetworkFunctions Members
        //---------------------------------------------------------------------------
        Result INetworkFunctions.ReadCoils(Modbus.OSIModel.Message.Message request)
        {
            Message.Result result;
            Message.Message answer;
            PDU pdu;
            String message;

            if (request.Address == 0)
            {
                // Ошибка. Данная команда не может быть широковещательная
                message = "Широковещательный запрос на выполнение функции 0x01 невозможен";
                result = new Message.Result(Error.RequestError,
                    message, request, null);
            }
            else
            {
                // Проверяем длину PDU (должна равнятся 5 байтам)
                if (request.PDUFrame.ToArray().Length != 5)
                {
                    // Длина сообщения не верная
                    message = String.Format(
                        "Длина PDU-фрайма в запросе {0}. Должна быть 5 байт", request.PDUFrame.ToArray());
                    // Ответное сообщение не отсылается
                    result = new Message.Result(Error.DataFormatError, message,
                        request, null);
                }
                else
                {
                    // Разбираем сообщение
                    Byte[] array = new Byte[2];
                    // Получаем адрес первого реле
                    Array.Copy(request.PDUFrame.Data, 0, array, 0, 2);
                    UInt16 address = Modbus.Convert.ConvertToUInt16(array);
                    // Получаем количесво реле для чтения
                    Array.Copy(request.PDUFrame.Data, 2, array, 0, 2);
                    UInt16 quantity = Modbus.Convert.ConvertToUInt16(array);

                    if ((quantity == 0) || (quantity > 2000))
                    {
                        message = String.Format(
                            "Количество реле для чтения в запросе {0}, а должно быть 1...2000", quantity);
                        pdu = new Message.PDU(0x81, new Byte[] { 0x03 });
                        answer = new Modbus.OSIModel.Message.Message(_Address, pdu);
                        // Отправляем сообщение
                        SendResponse(answer);

                        result = new Message.Result(Error.IllegalDataValue,
                            message, request, answer);

                    }
                    else
                    {
                        // Выполняем запрос. Проверяем доступность в 
                        // системе реле в указанном диапазоне адресов
                        for (int i = 0; i < quantity; i++)
                        {
                            // Проверяем существует ли реле с указанным адресом.
                            // Если реле не существует в системе формируем ответ
                            // c исключение

                            if (Coils.Contains(System.Convert.ToUInt16(address + i)) == false)
                            {
                                // Формируем ответ с исключение 2
                                answer = new Modbus.OSIModel.Message.Message(Address,
                                    new PDU(0x81, new Byte[] { 0x2 }));

                                // Отправляем ответ мастеру
                                SendResponse(answer);

                                result = new Message.Result(Error.IllegalDataAddress,
                                    String.Format("Реле с адресом {0} не существует", 
                                    System.Convert.ToUInt16(address + i)),
                                    request, answer);

                                return result;
                            }
                        }

                        // Все реле найдены формируем ответное сообщение
                        int totalBytes = quantity % 8;

                        if (totalBytes == 0)
                        {
                            totalBytes = quantity / 8;
                        }
                        else
                        {
                            totalBytes = 1 + (quantity / 8);
                        }

                        Byte[] data = new Byte[totalBytes];
                        int number = 0;
                        int index = 0;

                        for (int i = 0; i < quantity; i++)
                        {
                            data[index] = (Byte)(data[index] | 
                                (Byte)(Modbus.Convert.BooleanToBit(
                                Coils[System.Convert.ToUInt16(address + i)].Value) << number));

                            if (++number > 7)
                            {
                                number = 0;
                                ++index;
                            }
                        }
                        pdu = new Message.PDU();
                        pdu.Function = 0x01;
                        pdu.AddDataByte((byte)totalBytes);  // Добавляем количество байт с состояниями реле
                        pdu.AddDataBytesRange(data);        // Добавляем байты с состояниями реле

                        answer = new Modbus.OSIModel.Message.Message(Address, pdu);
                        // Отправляем ответ мастеру
                        SendResponse(answer);
                        result = new Message.Result(Error.NoError, String.Empty, request, answer);
                    }
                }
            }
            return result;

        }
コード例 #2
0
ファイル: Device.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        Result INetworkFunctions.ReadDiscreteInputs(Message.Message request)
        {
            Message.Result result;
            Message.Message answer;
            Message.PDU pdu;
            String message;

            if (request.Address == 0)
            {
                // Ошибка. Данная команда не может быть широковещательная
                message = "Широковещательный запрос на выполнение функции 0x02 невозможен";
                result = new Message.Result(Error.RequestError,
                    message, request, null);
            }
            else
            {
                // Проверяем длину PDU (должна равнятся 5 байтам)
                if (request.PDUFrame.ToArray().Length != 5)
                {
                    // Длина сообщения не верная
                    String mes = String.Format(
                        "Длина PDU-фрайма равна в запросе 0x2 равна {0} байт. Должна быть 5 байт",
                        request.PDUFrame.ToArray().Length);

                    result = new Message.Result(Error.DataFormatError, mes, request, null);
                    Debug.WriteLine(mes);
                }
                else
                {
                    // Разбираем сообщение
                    Byte[] array = new Byte[2];
                    // Получаем адрес первого дискретного входа
                    Array.Copy(request.PDUFrame.Data, 0, array, 0, 2);
                    UInt16 address = Modbus.Convert.ConvertToUInt16(array);
                    // Получаем количесво дискретных входов для чтения
                    Array.Copy(request.PDUFrame.Data, 2, array, 0, 2);
                    UInt16 quantity = Modbus.Convert.ConvertToUInt16(array);

                    if ((quantity == 0) || (quantity > 2000))
                    {
                        message =
                            String.Format("Количество дискретных входов для чтения в запросе {0}, а должно быть 1...2000",
                            quantity);
                        pdu = new Message.PDU(0x82, new Byte[] { 0x03 });
                        answer = new Modbus.OSIModel.Message.Message(_Address, pdu);

                        // Отправляем сообщение
                        SendResponse(answer);

                        result = new Message.Result(Error.IllegalDataValue,
                            message, request, answer);
                    }
                    else
                    {
                        // Выполняем запрос. Проверяем доступность в 
                        // системе дискретных входов в указанном диапазоне адресов
                        //DiscreteInput[] inputs = new DiscreteInput[quantity];

                        for (int i = 0; i < quantity; i++)
                        {
                            //inputs[i] = _discretesInputs.Find((UInt16)(address + i));
                            if (DiscretesInputs.Contains(System.Convert.ToUInt16(address + i)) == false)
                            {
                            // Если дискретный вход не существует в системе формируем ответ
                            // c исключением 2
                                pdu = new Message.PDU(0x82, new Byte[] { 0x02 });
                                answer = new Message.Message(_Address, pdu);

                                message =
                                    String.Format("Дискретный вход с адресом {0} не существует",
                                    (address + i));
                                result = new Message.Result(Error.IllegalDataAddress,
                                    message, request, answer);

                                // Отправляем ответ мастеру
                                SendResponse(answer);

                                return result;
                            }
                        }

                        // Все дискретные входы найдены формируем ответное сообщение
                        int totalBytes = quantity % 8;

                        if (totalBytes == 0)
                        {
                            totalBytes = quantity / 8;

                            if (totalBytes == 0)
                            {
                                totalBytes++;
                            }
                        }
                        else
                        {
                            totalBytes = 1 + (quantity / 8);
                        }

                        Byte[] data = new Byte[totalBytes];
                        int number = 0;
                        int index = 0;

                        for (int i = 0; i < quantity; i++)
                        {
                            data[index] = (Byte)(data[index] |
                                (Byte)(Modbus.Convert.BooleanToBit(DiscretesInputs[address + i].Value) << number));

                            if (++number > 7)
                            {
                                number = 0;
                                ++index;
                            }
                        }
                        pdu = new Message.PDU();
                        pdu.Function = request.PDUFrame.Function;
                        pdu.AddDataByte((Byte)totalBytes);
                        pdu.AddDataBytesRange(data);
                        answer = new Message.Message(_Address, pdu);

                        result = new Message.Result(Error.NoError, String.Empty, request, answer);
                        // Отправляем ответ мастеру
                        SendResponse(answer);
                    }
                }
            }
            return result;
        }
コード例 #3
0
ファイル: Device.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        Result INetworkFunctions.FunctionNotSupported(Message.Message request)
        {
            Message.Message answer;
            Message.PDU pdu = new Message.PDU();
            pdu.Function = (Byte)(request.PDUFrame.Function | 0x80);
            pdu.AddDataByte(0x01);   //Error.IllegalFunction
            answer = new Modbus.OSIModel.Message.Message(Address, pdu);

            // Отправляем ответ
            SendResponse(answer);

            Message.Result result =
                new Message.Result(Error.IllegalFunction,
                    "Функция не поддерживается данным устройством",
                    request, answer);
            return result;
        }
コード例 #4
0
ファイル: Device.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        Result INetworkFunctions.ReadInputRegisters(Message.Message request)
        {
            Message.Result result;
            Message.Message answer;
            Message.PDU pdu;
            String message;

            if (request.Address == 0)
            {
                // Ошибка. Данная команда не может быть широковещательная
                message = "Широковещательный запрос на выполнение функции 0x04 невозможен";
                result = new Message.Result(Error.RequestError,
                    message, request, null);
            }
            else
            {
                // Проверяем длину PDU (должна равнятся  байтам)
                if (request.PDUFrame.ToArray().Length != 5)
                {
                    // Длина сообщения не верная
                    String mes = String.Format(
                        "Длина PDU-фрайма равна в запросе 0x4 равна {0} байт. Должна быть 5 байт",
                        request.PDUFrame.ToArray().Length);

                    result = new Message.Result(Error.DataFormatError, mes, request, null);
                }
                else
                {
                    // Разбираем сообщение
                    Byte[] array = new Byte[2];
                    // Получаем адрес первого регистра входа
                    Array.Copy(request.PDUFrame.Data, 0, array, 0, 2);
                    UInt16 address = Modbus.Convert.ConvertToUInt16(array);
                    // Получаем количесво регистров для чтения
                    Array.Copy(request.PDUFrame.Data, 2, array, 0, 2);
                    UInt16 quantity = Modbus.Convert.ConvertToUInt16(array);

                    if ((quantity == 0) || (quantity > 125))
                    {
                        message =
                            String.Format("Количество регистров для чтения в запросе {0}, а должно быть 1...125",
                            quantity);
                        pdu = new Message.PDU(0x84, new Byte[] { 0x03 });
                        answer = new Message.Message(_Address, pdu);

                        // Отправляем сообщение
                        SendResponse(answer);

                        result = new Message.Result(Error.IllegalDataValue,
                            message, request, answer);
                    }
                    else
                    {
                        // Выполняем запрос. Проверяем доступность в 
                        // системе регистров в указанном диапазоне адресов
                        for (int i = 0; i < quantity; i++)
                        {
                            // Если регистр не существует в системе формируем ответ
                            // c исключением 2
                            if (InputRegisters.Contains(System.Convert.ToUInt16(address + i)) == false)
                            {
                                pdu = new Message.PDU(0x84, new Byte[] { 0x02 });
                                answer = new Message.Message(Address, pdu);

                                message =
                                    String.Format("Регистр с адресом {0} не существует",
                                    (address + i));
                                result = new Message.Result(Error.IllegalDataAddress,
                                    message, request, answer);

                                // Отправляем ответ мастеру
                                SendResponse(answer);
                                return result;
                            }
                        }

                        // Все регистры найдены формируем ответное сообщение
                        Byte[] temp;
                        List<Byte> data = new List<byte>();

                        for (int i = 0; i < quantity; i++)
                        {
                            temp = Modbus.Convert.ConvertToBytes(
                                InputRegisters[System.Convert.ToUInt16(address + i)].Value);
                            data.AddRange(temp);
                        }
                        pdu = new Message.PDU();
                        pdu.Function = 0x04;
                        pdu.AddDataByte((Byte)(data.Count));
                        pdu.AddDataBytesRange(data.ToArray());
                        answer = new Message.Message(_Address, pdu);

                        result = new Result(Error.NoError, String.Empty, request, answer);
                        // Отправляем ответ мастеру
                        SendResponse(answer);
                    }
                }
            }
            return result;
        }
コード例 #5
0
ファイル: DeviceOld.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        Message.Result IModbusFunctions.ReadInputRegisters(Message.Message request)
        {
            Message.Result result;
            String message;

            if (request.Address == 0)
            {
                // Ошибка. Данная команда не может быть широковещательная
                message = "Широковещательный запрос на выполнение функции 0x04 невозможен";
                Debug.WriteLine(message);
                result = new Message.Result(Error.RequestError,
                    message, request, null);
            }
            else
            {
                // Проверяем длину PDU (должна равнятся  байтам)
                if (request.PDUFrame.ToArray().Length != 5)
                {
                    // Длина сообщения не верная
                    String mes = String.Format(
                        "Длина PDU-фрайма равна в запросе 0x4 равна {0} байт. Должна быть 5 байт",
                        request.PDUFrame.ToArray().Length);

                    result = new Message.Result(Error.DataFormatError, mes, request, null);
                    Debug.WriteLine(mes);
                }
                else
                {
                    // Разбираем сообщение
                    Byte[] array = new Byte[2];
                    // Получаем адрес первого регистра входа
                    Array.Copy(request.PDUFrame.Data, 0, array, 0, 2);
                    UInt16 address = Modbus.Convert.ConvertToUInt16(array);
                    // Получаем количесво регистров для чтения
                    Array.Copy(request.PDUFrame.Data, 2, array, 0, 2);
                    UInt16 quantity = Modbus.Convert.ConvertToUInt16(array);

                    if ((quantity == 0) || (quantity > 125))
                    {
                        message =
                            String.Format("Количество регистров для чтения в запросе {0}, а должно быть 1...125",
                            quantity);
                        Message.PDU pdu = new Message.PDU(0x84, new Byte[] { 0x03 });

                        // Отправляем сообщение
                        _connection.SendReply(pdu);

                        result = new Message.Result(Error.IllegalDataValue,
                            message, request, pdu);

                        Debug.WriteLine(message);
                    }
                    else
                    {
                        // Выполняем запрос. Проверяем доступность в 
                        // системе регистров в указанном диапазоне адресов
                        //InputRegister[] registers = new InputRegister[quantity];
                        DataRow[] rows = new DataRow[quantity];
 
                        Message.PDU pdu;

                        for (int i = 0; i < quantity; i++)
                        {
                            //registers[i] = _inputRegisters.Find((UInt16)(address + i));
                            rows[i] = _dataMap.Tables["InputRegisters"].Rows.Find(address + i);

                            // Если регистр не существует в системе формируем ответ
                            // c исключение
                            if (rows[i] == null)
                            {
                                // Формируем ответ с исключение 2
                                pdu = new Message.PDU(0x84, new Byte[] { 0x02 });

                                message =
                                    String.Format("Регистр с адресом {0} не существует",
                                    (address + i));
                                result = new Message.Result(Error.IllegalDataAddress,
                                    message, request, pdu);

                                // Отправляем ответ мастеру
                                this._connection.SendReply(pdu);

                                Debug.WriteLine(message);
                                return result;
                            }
                        }

                        // Все регистры найдены формируем ответное сообщение
                        Byte[] temp;
                        List<Byte> data = new List<byte>();

                        for (int i = 0; i < quantity; i++)
                        {
                            temp = Modbus.Convert.ConvertToBytes((UInt16)rows[i]["Value"]);
                            data.AddRange(temp);
                        }
                        pdu = new Message.PDU();
                        pdu.Function = 0x04;
                        pdu.AddDataByte((Byte)(data.Count));
                        pdu.AddDataBytesRange(data.ToArray());

                        result = new Message.Result(Error.NoError, String.Empty, request, pdu);
                        // Отправляем ответ мастеру
                        this._connection.SendReply(pdu);
                    }
                }
            }
            return result;
        }
コード例 #6
0
ファイル: DeviceOld.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------------------
        #region Члены IApi
        //---------------------------------------------------------------------------
        Message.Result IModbusFunctions.ReadCoils(Message.Message request)
        {
            Message.Result result;
            String message;

            if (request.Address == 0)
            {
                // Ошибка. Данная команда не может быть широковещательная
                message = "Широковещательный запрос на выполнение функции 0x01 невозможен";
                result = new Message.Result(Error.RequestError,
                    message, request, null);
                Debug.WriteLine(message);
            }
            else
            {
                // Проверяем длину PDU (должна равнятся 5 байтам)
                if (request.PDUFrame.ToArray().Length != 5)
                {
                    // Длина сообщения не верная
                    message = String.Format(
                        "Длина PDU-фрайма в запросе {0}. Должна быть 5 байт", request.PDUFrame.ToArray());
                    result = new Message.Result(Error.DataFormatError, message,
                        request, null);
                }
                else
                {
                    // Разбираем сообщение
                    Byte[] array = new Byte[2];
                    // Получаем адрес первого реле
                    Array.Copy(request.PDUFrame.Data, 0, array, 0, 2);
                    UInt16 address = Modbus.Convert.ConvertToUInt16(array);
                    // Получаем количесво реле для чтения
                    Array.Copy(request.PDUFrame.Data, 2, array, 0, 2);
                    UInt16 quantity = Modbus.Convert.ConvertToUInt16(array);

                    if ((quantity == 0) || (quantity > 2000))
                    {
                        message = String.Format(
                            "Количество реле для чтения в запросе {0}, а должно быть 1...2000", quantity);
                        Message.PDU pdu = new Message.PDU(0x81, new Byte[] { 0x03 });
                                                
                        // Отправляем сообщение
                        _connection.SendReply(pdu);

                        Debug.WriteLine(message);

                        result = new Message.Result(Error.IllegalDataValue,
                            message, request, pdu);

                    }
                    else
                    {
                        // Выполняем запрос. Проверяем доступность в 
                        // системе реле в указанном диапазоне адресов

                        DataRow[] row = new DataRow[quantity];


                        Message.PDU pdu;

                        for (int i = 0; i < quantity; i++)
                        {
                            row[i] = _dataMap.Tables["Coils"].Rows.Find(i + address);
                            // Если реле не существует в системе формируем ответ
                            // c исключение
                            if (row[i] == null)
                            {
                                // Формируем ответ с исключение 2
                                pdu = new Message.PDU();
                                pdu.Function = 0x01;
                                pdu.SetErrorBit();
                                pdu.AddDataByte(0x02);

                                result = new Message.Result(Error.IllegalDataAddress,
                                    String.Format("Реле с адресом {0} не существует", (address + i)),
                                    request, pdu);

                                // Отправляем ответ мастеру
                                this._connection.SendReply(pdu);

                                return result;
                            }
                        }

                        // Все реле найдены формируем ответное сообщение
                        int totalBytes = quantity % 8;

                        if (totalBytes == 0)
                        {
                            totalBytes = quantity / 8;
                        }
                        else
                        {
                            totalBytes = 1 + (quantity / 8);
                        }

                        Byte[] data = new Byte[totalBytes];
                        int number = 0;
                        int index = 0;

                        for (int i = 0; i < quantity; i++)
                        {
                            data[index] = (Byte)(data[index] | (Byte)(Modbus.Convert.BooleanToBit((Boolean)row[i]["Value"]) << number));
                            
                            if (++number > 7)
                            {
                                number = 0;
                                ++index;
                            }
                        }
                        pdu = new Message.PDU();
                        pdu.Function = 0x01;
                        pdu.AddDataByte((byte)totalBytes);  // Добавляем количество байт с состояниями реле
                        pdu.AddDataBytesRange(data);        // Добавляем байты с состояниями реле

                        result = new Message.Result(Error.NoError, String.Empty, request, pdu);
                        // Отправляем ответ мастеру
                        this._connection.SendReply(pdu);
                    }
                }
            }
            return result;
        }
コード例 #7
0
ファイル: DeviceOld.cs プロジェクト: serialbus/NGK
        //---------------------------------------------------------------------------
        Message.Result IModbusFunctions.FunctionNotSupported(Message.Message request)
        { 
            Message.PDU pdu = new Message.PDU();
            pdu.Function = (Byte)(request.PDUFrame.Function | 0x80);
            pdu.AddDataByte(0x01);   //Error.IllegalFunction

            Message.Result result =
                new Message.Result(Error.IllegalFunction,
                    "Функция не поддерживается данным устройством",
                    request, pdu);
            
            // Отправляем ответ
            this._connection.SendReply(pdu);
            
            return result;
        }