Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Читаю бинарную дату
 private void ReadComPort()
        {
            char chr;
            string str = "";

            while (serial_port.BytesToRead > 0)
            {
                chr = (char)serial_port.ReadChar();
                str += chr;
            }

            richTextBoxLog.AppendText(str );
        }

Но так как дата бинарная вижу в текст боксе краказябы. А как мне увидеть реальные данные?
11 июл 18, 12:49    [21562014]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Dima T
Member

Откуда:
Сообщений: 13841
char это юникод. Читай в массив byte[], в конце конвертируй в строку Encoding.ASCII.GetString()
11 июл 18, 12:54    [21562030]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Dima T
char это юникод. Читай в массив byte[], в конце конвертируй в строку Encoding.ASCII.GetString()

спасибо. так работает
int rx_byte;
while (serial_port.BytesToRead > 0)
{
     rx_byte = serial_port.ReadByte();

      str += (byte)rx_byte;

}
11 июл 18, 13:24    [21562202]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
а вот еще такая проблема
условие while (serial_port.BytesToRead > 0) не всегда адекватное. уж не знаю какой там механизм но байт в приемном буфере может приходить с задержкой.
чтоб вычитать все данные приходиться применять такой механизм
while (serial_port.BytesToRead > 0)
{
    rx_byte = serial_port.ReadByte();

    str += (byte)rx_byte;

    if (serial_port.BytesToRead == 0)
    {
         ticks = 0;
         while (serial_port.BytesToRead == 0)
          {
                Thread.Sleep(1);
                 ticks++;
                 if (ticks > timeout)
                    break;
          }
   }
}

а что то красивее можно придумать?
11 июл 18, 15:08    [21562842]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Pallaris
Member

Откуда: Украина, Донецк
Сообщений: 1600
jenya7,

можно подписаться на события получения данных, тогда циклов не нужно будет - что пришло, то сразу и получил
12 июл 18, 06:44    [21564687]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Pallaris
jenya7,

можно подписаться на события получения данных, тогда циклов не нужно будет - что пришло, то сразу и получил

делал и так
serial_port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

 private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            string serial_data = "";

            if (richTextBoxLog.InvokeRequired)
            {
                richTextBoxLog.Invoke(new SerialDataReceivedEventHandler(DataReceivedHandler), sender, e);
            }
            else
            {
                //get data from comport
                SerialPort sp = (SerialPort)sender;

                serial_data = sp.ReadExisting();

                //append text
                richTextBoxLog.AppendText(serial_data);

            }
        }

все равно криво работает
12 июл 18, 09:20    [21564840]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Pallaris
Member

Откуда: Украина, Донецк
Сообщений: 1600
jenya7,

а в чем кривость-то заключается?
12 июл 18, 11:18    [21565353]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Pallaris
Member

Откуда: Украина, Донецк
Сообщений: 1600
Кстати, реализацию DataReceivedHandler я бы сделал не так: сначала бы все считал из порта, потом бы проверял inokeRequired и просто бы добавлял к тексту полученные символы.
12 июл 18, 11:21    [21565374]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Pallaris
Кстати, реализацию DataReceivedHandler я бы сделал не так: сначала бы все считал из порта, потом бы проверял inokeRequired и просто бы добавлял к тексту полученные символы.

так?
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
     string serial_data = "";

     SerialPort sp = (SerialPort)sender;

     serial_data = sp.ReadExisting();

     if (richTextBoxLog.InvokeRequired)
     {
          richTextBoxLog.AppendText(serial_data);
     }
}
12 июл 18, 12:17    [21565645]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
fortibransa
Member

Откуда: СПб
Сообщений: 22917
А на основании чего Вы начинаете читать?
Наверное есть команда Write, Вы просите сначала некое устройство "отдать" вам дату?

Формат ответа какой ASCII или byte[].

Если ASCII, то что у вас является началом и концом передачи.
Если byte[], то какова длина ответа и откуда Вы это знаете?
12 июл 18, 13:43    [21565959]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
fortibransa
А на основании чего Вы начинаете читать?
Наверное есть команда Write, Вы просите сначала некое устройство "отдать" вам дату?

Формат ответа какой ASCII или byte[].

Если ASCII, то что у вас является началом и концом передачи.
Если byte[], то какова длина ответа и откуда Вы это знаете?

я передаю команду - выдай мне столько то байт. но я хочу читать из порта пока идет передача данных. не привязываясь к длине.
12 июл 18, 13:57    [21565988]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3408
jenya7,

протокол передачи данных существует или только на уровне, есть поток и из него мы что-то читаем?
нельзя просто взять и читать данные от балды =)
более того, с комп порта можно получить поврежденные данные.
12 июл 18, 15:29    [21566288]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Roman Mejtes
jenya7,

протокол передачи данных существует или только на уровне, есть поток и из него мы что-то читаем?
нельзя просто взять и читать данные от балды =)
более того, с комп порта можно получить поврежденные данные.

нельзя? нужно! нужно вычитать сырые бинарные данные от балды. а верхний леер сделает парсинг данных. там есть и заголовок и CRC. но сначала данные нужно загрузить на комп.
12 июл 18, 16:20    [21566481]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Konst_One
Member

Откуда:
Сообщений: 11417
COM-порт так не работает
12 июл 18, 17:31    [21566788]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Konst_One
COM-порт так не работает

раскажите мне как работает COM-порт. а то я за 10 лет так и не разобрался.
12 июл 18, 17:33    [21566793]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Konst_One
Member

Откуда:
Сообщений: 11417
откройте наконец для себя hyperterminal (в винде 10 нет уже) и посмотрите, как работает
12 июл 18, 18:00    [21566875]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Splash
Member

Откуда:
Сообщений: 10
автор
Но так как дата бинарная вижу в текст боксе краказябы. А как мне увидеть реальные данные?

А что такое реальные данные? Каждый байт можно представить в HEX формате, будет красивее, но, возможно, ни разу не понятнее. Может быть там идут числа с плавающей точкой, числа в big-endian или little-endian, строки в UTF или DOS-кодировке... да мало ли что, даже бессмысленный паддинг может быть. Это как раз ваша задача: зная формат, вывести данные в красивом виде.

PS: Вот тут пример читалки RFID-меток, которая из одного порта читает, переделывает немного данные и в другой порт отправляет.
12 июл 18, 18:15    [21566923]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
Pallaris
Member

Откуда: Украина, Донецк
Сообщений: 1600
jenya7
Pallaris
Кстати, реализацию DataReceivedHandler я бы сделал не так: сначала бы все считал из порта, потом бы проверял inokeRequired и просто бы добавлял к тексту полученные символы.

так?
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
     string serial_data = "";

     SerialPort sp = (SerialPort)sender;

     serial_data = sp.ReadExisting();

     if (richTextBoxLog.InvokeRequired)
     {
          richTextBoxLog.AppendText(serial_data);
     }
}


не, вот так:

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
     string serial_data = "";

     SerialPort sp = (SerialPort)sender;

     serial_data = sp.ReadExisting();

     if (richTextBoxLog.InvokeRequired)
     {
           richTextBoxLog.Invoke(/*.... тут инвокаем делегат с кодом richTextBoxLog.AppendText(serial_data)...*/ );
     }
     else
     {
          richTextBoxLog.AppendText(serial_data);
     }
}


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


Если в протоколе обмена нет четкого задекларированного сообщения, что в ответе будет N байт (что не очень хорошо, но бывает), то можно поступить, например, так. Подписавшись на событие и получив в нем данные, перезапускать некий таймер, скажем на 500мс, по истечении которого принимать решение, что все, больше ничего не дождемся в данном сеансе обмена.
13 июл 18, 05:47    [21567658]     Ответить | Цитировать Сообщить модератору
 Re: Чтение из сериального порта.  [new]
jenya7
Member

Откуда:
Сообщений: 1159
Pallaris

не, вот так:

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
     string serial_data = "";

     SerialPort sp = (SerialPort)sender;

     serial_data = sp.ReadExisting();

     if (richTextBoxLog.InvokeRequired)
     {
           richTextBoxLog.Invoke(/*.... тут инвокаем делегат с кодом richTextBoxLog.AppendText(serial_data)...*/ );
     }
     else
     {
          richTextBoxLog.AppendText(serial_data);
     }
}



Если в протоколе обмена нет четкого задекларированного сообщения, что в ответе будет N байт (что не очень хорошо, но бывает), то можно поступить, например, так. Подписавшись на событие и получив в нем данные, перезапускать некий таймер, скажем на 500мс, по истечении которого принимать решение, что все, больше ничего не дождемся в данном сеансе обмена.


спасибо.
13 июл 18, 11:43    [21568258]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить