C # .Net Serial DataReceived Реакция на событие слишком медленная для высокоскоростных данных - PullRequest
6 голосов
/ 01 июня 2010

Я установил SerialDataReceivedEventHandler с программой на основе форм в экспрессе VS2008. Мой последовательный порт настроен следующим образом:

115200, 8N1

Dtr и Rts включены

ReceivedBytesThreshold = 1

У меня есть устройство, с которым я взаимодействую через Bluetooth, Serial. Гипертерминал получает данные просто отлично с любой скоростью передачи данных. Данные отправляются регулярно в виде пакетов длиной 22 байта. Это устройство имеет регулируемую скорость передачи данных. При низких скоростях передачи данных, 10-20 Гц, приведенный ниже код работает отлично, никаких проблем. Тем не менее, когда я увеличиваю скорость передачи данных за 25 Гц, там начинает принимать несколько пакетов за один вызов. Под этим я подразумеваю, что для каждого входящего пакета должен быть триггер события. При более высоких скоростях вывода я сразу же протестировал размер буфера (команда BytesToRead), когда вызывается событие, и тогда в буфере есть несколько пакетов. Я думаю, что событие происходит медленно, и к тому времени, когда оно достигает кода, больше пакетов попало в буфер. Один тест, который я делаю, это посмотреть, сколько раз событие срабатывает в секунду. На 10 Гц я получаю 10 триггеров событий, потрясающе. На частоте 100 Гц я получаю около 40 триггеров событий, не очень хорошо. Моя цель для скорости передачи данных - 100 Гц, приемлемо, 200 Гц предпочтительно и 300 Гц оптимально. Это должно работать, потому что даже на частоте 300 Гц, то есть всего 52800 бит / с, это меньше половины установленной скорости 115200 бод. Что-нибудь, что я просматриваю?

    public Form1()
    {
        InitializeComponent();
        serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);            
    }


    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        this.Invoke(new EventHandler(Display_Results));
    }


    private void Display_Results(object s, EventArgs e)
    {
        serialPort1.Read(IMU, 0, serial_Port1.BytesToRead);
    }

Ответы [ 4 ]

5 голосов
/ 27 июня 2011

Вы пытались отрегулировать задержку времени на последовательном USB-конвертере? У меня была такая же проблема с конвертером FTDI USB в последовательный порт. Я использую осциллограф, чтобы увидеть мои входные и выходные данные, поступающие с устройства, и я мог видеть, что компьютер всегда медленно реагировал. По умолчанию время задержки на устройстве установлено на 16 мс. Я изменил его на 2 мс, и это имеет большое значение. Перейдите к вашему последовательному USB-конвертеру в диспетчере устройств и в дополнительных настройках измените время задержки на 2 мс. Это должно работать. Попробуй.

3 голосов
/ 01 июня 2010

Почему вы вызываете () вызов DisplayResults?

Это переместит его в MessageLoop, ненужная задержка.

Было бы лучше, если бы DataReceived () помещал данные в (поточно-ориентированную) очередь для развязанной обработки.

Я также думаю, что у вас могут возникнуть проблемы с разделенными пакетами.

2 голосов
/ 20 июля 2017

Проблема заключается в обработчике полученных данных.

Я запустил отдельный поток с циклом while(true) и serial.ReadLine(), все работает отлично.

using System.Threading;

Thread readThread = new Thread(Read);
readThread.Start();

Надеюсь, кому-то еще не нужно тратить 3 часа, чтобы это исправить.

1 голос
/ 20 ноября 2010

Вы можете попробовать установить ReceivedBytesThreshold = 22 * ​​1004 *, что приведет к возникновению события, когда будет прочитано не менее 22 байтов. Обратите внимание, что это будет по крайней мере 22. Может быть больше.

Я не думаю, что лично сделал бы это, потому что, что произойдет, если размер вашего пакета изменится в будущем, например, до 12 байт? В результате вы получите 12 байт в буфере, но не запустите событие вообще.

Гораздо лучше оставить его равным 1, что вызовет событие, когда будет доступен по крайней мере 1 байт. Затем поместите все полученные байты в список или очередь, как уже написал Хенк.

Обратите внимание, что DataReceivedEvent не знает, что вы, конечно, считаете пакетом данных. Он просто срабатывает, когда есть доступные байты. Разработчик должен собрать эти байты в значимое сообщение или пакет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...