Чтение дополнительных символов из последовательного порта с помощью libserial в Linux

0

У меня есть очень базовое устройство, с которым я пытаюсь взаимодействовать через последовательное соединение в Linux. Я нахожусь на крутой части кривой обучения здесь, все же, поэтому, пожалуйста, будьте нежны!

Во всяком случае, я могу управлять устройством через Hyperterminal в Windows или через cu, screen или minicom в Linux. Я подключен через встроенный последовательный порт на ПК по адресу 19200, 8N1. Интерфейс для устройства очень прост:

  • Введите "H", и устройство откликнется "H".
  • Введите "V", и устройство откликнется на строку, содержащую ее версию программного обеспечения "ADD111C".
  • Введите "S", и устройство вернет "0", "1" или "?", В зависимости от состояния принтера.
  • Введите "Q", и он возвращает пятистрочный ответ с подробными сведениями о последней обработанной транзакции.
  • За каждым ответом следует новая строка, возможно, CR, также я не уверен.

Там больше, но это хорошее начало. Когда я подключаюсь к устройству с помощью экрана, он отлично работает:

root@dc5000:~# screen /dev/ttyS0 19200,cs8,-ixon,-ixoff

V
ADD111C

Когда я работал с этим вручную, я попытался написать простую программу, используя C++ и libserial для взаимодействия с устройством. Это выглядит так:

#include <SerialStream.h>
#include <string>
#include <iostream>
#include <fstream>

using namespace std;
using namespace LibSerial;

int main(){

    char next_char[100];
    int i;

    SerialStream my_serial_stream;
    my_serial_stream.Open("/dev/ttyS0") ;
    my_serial_stream.SetBaudRate( SerialStreamBuf::BAUD_19200 ) ;
    my_serial_stream.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ;
    my_serial_stream.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ;
    my_serial_stream.SetParity( SerialStreamBuf::PARITY_NONE ) ;
    my_serial_stream.SetNumOfStopBits(1) ;
    my_serial_stream.SetVTime(1);
    my_serial_stream.SetVMin(100);

    cout<<"Sending Command:\n";
    my_serial_stream << "V";

    my_serial_stream.read(next_char,100);
    cout<<"Result: "<<next_char<<"\n";

    my_serial_stream.Close();

    return 0;
}

Это успешно отправляет "V" на последовательный порт, но когда я его прочитаю, я получаю несколько непечатаемых символов после действительных данных:

root@dc5000:~# g++ -o serialtest serialtest.cpp -lserial
root@dc5000:~# ./serialtest 
Sending Command:
Result: 
V
ADD111C
��se�Xw��AN��ƿ,�
root@dc5000:~# 

Что мне не хватает, чтобы получить ответ на мой запрос? Я предполагаю, что мне нужно сбросить буфер на порт или что-то в этом роде, но я дошел до конца своих ограниченных знаний здесь.

В идеале я хотел бы просто получить "ADD111C", но я не хочу рисовать себя в углу, хватая определенную длину данных (в случае их изменения в будущем), а мусор в конце прочитанного не всегда кажутся одинаковой длиной или теми же данными.

Большое спасибо за то, что посмотрели,

Том

  • 1
    Держу пари, что эта проблема исчезнет так же таинственно, как и появилась, если вы добавите memset(next_char, 0, sizeof next_char) прямо перед вызовом my_serial_stream.read .
  • 0
    Ага. Или получите счетчик символов из операции чтения и используйте его для правильного завершения строки нулем. Отсутствующий ноль - почти наверняка проблема.
Показать ещё 1 комментарий
Теги:
serial-port
libserial

1 ответ

0
Лучший ответ

Зак и кешлам: Спасибо за помощь. Предложение Zack написать NULL до конца строки разрешило проблему, но я фактически наткнулся на более простой метод, работая с другой строкой (пытаясь захватить подстроку вывода).

Вместо того, чтобы определять строку C следующим образом:

char next_char[100];

Я сделал это так:

char next_char[100] = "";

Кажется, что присвоение значению символа перед чтением из последовательного порта должным образом завершает нуль. Теперь я могу удалить команду memset из моего кода, и теперь она отлично работает:

root@dc5000:~#./serialtest Sending Command: Result: V ADD111C

Спасибо за помощь!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню