У меня есть очень простое устройство, с которым я пытаюсь взаимодействовать через последовательное соединение в 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
Спасибо за помощь!
Других решений пока нет …