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

У меня есть очень простое устройство, с которым я пытаюсь взаимодействовать через последовательное соединение в 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», но я не хочу рисовать себя в углу, захватывая определенную длину данных (на случай, если она изменится в будущем), и мусор в конце чтения не всегда кажется, что они имеют одинаковую длину или одинаковые данные.

Большое спасибо за взгляд,

Том

0

Решение

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

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

char next_char[100];

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

char next_char[100] = "";

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

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

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

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]