изменить тип вывода события system.io.port для данных - PullRequest
2 голосов
/ 14 октября 2010

Я создаю библиотеку классов для 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 ]

22 голосов
/ 14 июля 2014

Полученные данные не запускаются

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

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

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

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

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

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

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

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

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

0 голосов
/ 17 октября 2010

Не спите полученное событие.

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

Подробнее об этом см. SerialPort101 .

...