SerialPort ReadLine () после Thread.Sleep () сходит с ума - PullRequest
1 голос
/ 27 декабря 2010

Я боролся с этим вопросом в течение дня, и я не могу найти ответ на него.Я пытаюсь прочитать данные с устройства GPS через COM-порт в Compact Framework C #.Я использую класс SerialPort (фактически мой собственный класс ComPort, упаковывающий SerialPort, но он добавляет только два поля, которые мне нужны, ничего особенного).

В любом случае, я запускаю цикл while в отдельном потоке, который читает строки из порта, анализирует данные NMEA, распечатывает их, перехватывает все исключения и затем спит (200) в потоке, потому что мне нужен ЦП для другогопотоки ... Без Sleep он работает нормально, но использует 100% CPU .. Когда я не использую Sleep через несколько минут, выход из COM-порта выглядит следующим образом:

GPGSA, A, 3, 09,12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F
GSA, A, 3,09,12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F
A, A, 3,09,12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F
, 18,12,271,24,24,05,020,24,14,04,326,25,11,03,023, * 76
A, 3,09,12,22,17,15,27 ,,,,,,, 2.6,1.6, 2,1 * 3F
3,09,12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F
09,12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F
, 12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F

как выЯ вижу, что одно и то же сообщение читается несколько раз, но cut .Интересно, что я делаю не так ... Моя конфигурация порта:

port.ReadBufferSize = 4096;  
port.BaudRate = 4800;  
port.DataBits = 8;  
port.Parity = Parity.None;  
port.StopBits = StopBits.One;  
port.NewLine = "\r\n";  
port.ReadTimeout = 1000;  
port.ReceivedBytesThreshold = 100000; 

И моя функция чтения:

private void processGps(){  
    while (!closing)   
    {  
        //reconnect if needed
        try  
        {  
            string sentence = port.ReadLine();  
            //here print the sentence  
            //analyze the sentence (this takes some time 50-100ms)  
        }  
        catch (TimeoutException)  
        {  
            Thread.Sleep(0);  
        }  
        catch (IOException ioex)  
        {  
            //handling IO exception (some info on the screen)  
        }  
    Thread.Sleep(200);  
    }  
}

В этой функции есть еще кое-что, например, переподключение, еслиустройство потеряно и т. д., но оно не вызывается при правильном подключении GPS.Я пытался

port.DiscardInBuffer();

после нескольких блоков кода (в TimeoutException, после чтения.)

У кого-нибудь была подобная проблема?Я действительно не знаю, что я делаю неправильно. Единственный способ получить это - удалить последний сон.

Ответы [ 2 ]

1 голос
/ 28 декабря 2010

Для всех тех, у кого похожие проблемы.Первая проблема была о переполнении буфера.У меня был размер буфера 4096, и данные просто проходили через него, поэтому я читал искаженные предложения.Теперь я читаю весь буфер сразу и анализирую его.Первое предложение иногда искажается, но все остальное в порядке.
Второе - проблема устройства.Tom Tom MkII иногда теряет связь с устройством.Мне пришлось перезапустить GPS и снова найти его в списке устройств Bt.Привет

0 голосов
/ 08 января 2011

В вашем сообщении нет ничего, что говорило бы о том, как вы делаете рукопожатие.

Обычно вы будете использовать программное (XON / XOFF) или аппаратное (например, RTS / CTS) установление связи, чтобы последовательный порт сообщал об остановке передачи, когда он не может получить больше данных. Конфигурация квитирования должна (конечно) соответствовать конфигурации передающего устройства.

Если вам не удастся правильно настроить рукопожатие, вам может это сойти с рук, если вы обрабатываете данные достаточно быстро, но когда вы спите, данные могут быть потеряны.

...