Изменить тип вывода события system.io.port для данных

Я строю библиотеку классов для Modbus и последовательных соединений, мне нужно вернуть массив байтов обратно, но при использовании события DataReceived из System.IO.Ports я не могу вернуть ни одного, так как его тип void. Также я замечаю, что DataReceived не стреляет. Вот мой код:

        public void ConnectSerialModBus_Loopback(string COM, int baud, int meter_address, int function, int Code_HighByte, int Code_LowByte, int data_high_byte, int data_low_byte)
    {
        SerialPort port = new SerialPort(COM, baud);
        try
        {

            if (!(port.IsOpen))
            {
                byte[] sendPacket = BuildPacket(meter_address, function, Code_HighByte, Code_LowByte, data_high_byte, data_low_byte);
                double dataBytes = 2.0;

                port.Open();
                port.RtsEnable = false;//rts = high
                port.Handshake = Handshake.None;
                //SEND PACKET TO DEVICE
                port.Write(sendPacket, 0, sendPacket.Length);

                #region RECEIVE DATA FROM SERIAL
                //MAKE DELAY TO SEND
                Thread.Sleep(10);

                port.RtsEnable = true;
                //MAKE DELAY TO RECEIVE
                port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                //Thread.Sleep(CalculateDelay(dataBytes)+90);

                port.Close();
                port.Dispose();
                #endregion

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (port != null)
            {
                if (port.IsOpen)
                {
                    port.Close();
                }
                port.Dispose();
            }
        }
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort port = (SerialPort)sender;
        byte[] readingbyte = new byte[port.BytesToRead];
        if (port.BytesToRead > 0)
        {
            port.Read(readingbyte, 0, readingbyte.Length);   
        }
    }

каким-то образом я хочу вернуть байты, полученные от port_DataReceived или из ConnectSerialModBus_Loopback также DataReceived не стреляет. Пожалуйста, помогите это очень срочно

2 ответа

Полученные данные не стреляют

DataReceived не стреляет, потому что вы звоните port.Close() сразу после присоединения обработчика и до того, как поток приема SerialPort сможет запустить.

Вернуть массив байтов назад - Простой ответ

В приведенном вами простом примере кода вы можете создать Byte[] член и назначить readingbyte возражать против этого изнутри вашего port_DataReceived обработчик события.

Вернуть массив байтов назад - Ответ подсказки

Однако в более жестком приложении вам следует рассмотреть возможность создания класса Transaction, который инкапсулирует части протокола Modbus ADU, обрабатывая как передачу запроса клиента, так и обработку (уровень 2) ответа сервера.

В дополнение к уровню ADU вы должны разделить уровень PDU на абстрактный базовый класс ModbusFunction, который предоставляет интерфейс для класса ADU для получения байтов запроса и возврата байтов ответа. Тогда каждая функция Modbus, которую вы хотите, чтобы ваш клиент использовал, будет реализована в своем собственном классе, производном от базового класса PDU.

Таким образом, когда вам нужно взаимодействовать с сервером, вы создаете экземпляр класса функций PDU с соответствующими параметрами для формирования правильного пакета данных PDU и передаете его объекту Transaction, который обрабатывает логику запроса / повтора / ответа, и передает возвращенные данные обратно в объект PDU для надлежащего анализа.

Добавление события к базовому классу PDU позволит другим частям вашего кода присоединяться к событию класса PDU и получать уведомление после успешного завершения функции.

С сервером, имеющим несколько адресуемых свойств, реализованных посредством функций Modbus, вы должны создать экземпляр соответствующего класса функций Modbus для каждого свойства (или установить его, например, для смежных регистров) и присоединить к событию, обновляя вашу модель. и / или пользовательский интерфейс всякий раз, когда объект вызывает событие обновления. Подключите команды пользовательского интерфейса для передачи объектов "Свойства функции Modbus" в объект "Транзакция", если вы хотите выполнить запрос к серверу вручную, или реализуйте поток таймера, который делает это по расписанию, если вы хотите, чтобы свойства опрашивались на регулярной основе.

Не спите воспринятое событие.

Когда происходит событие, поместите байты в очередь. Вам понадобятся методы, которые пользовательский интерфейс может использовать для объединения кусков байтов обратно.

Смотрите SerialPort101 для более подробной информации об этом.

Другие вопросы по тегам