У меня есть очень базовое устройство, с которым я пытаюсь взаимодействовать через последовательное соединение в Linux. Я нахожусь на крутой части кривой обучения здесь, все же, поэтому, пожалуйста, будьте нежны!
Во всяком случае, я могу управлять устройством через Hyperterminal в Windows или через cu, screen или minicom в Linux. Я подключен через встроенный последовательный порт на ПК по адресу 19200, 8N1. Интерфейс для устройства очень прост:
Там больше, но это хорошее начало. Когда я подключаюсь к устройству с помощью экрана, он отлично работает:
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", но я не хочу рисовать себя в углу, хватая определенную длину данных (в случае их изменения в будущем), а мусор в конце прочитанного не всегда кажутся одинаковой длиной или теми же данными.
Большое спасибо за то, что посмотрели,
Том
Зак и кешлам: Спасибо за помощь. Предложение Zack написать NULL до конца строки разрешило проблему, но я фактически наткнулся на более простой метод, работая с другой строкой (пытаясь захватить подстроку вывода).
Вместо того, чтобы определять строку C следующим образом:
char next_char[100];
Я сделал это так:
char next_char[100] = "";
Кажется, что присвоение значению символа перед чтением из последовательного порта должным образом завершает нуль. Теперь я могу удалить команду memset из моего кода, и теперь она отлично работает:
root@dc5000:~#./serialtest Sending Command: Result: V ADD111C
Спасибо за помощь!
memset(next_char, 0, sizeof next_char)
прямо перед вызовомmy_serial_stream.read
.