C++ 在Linux上使用libserial从串行端口读取额外字符
我有一个非常基本的设备,我正试图通过Linux上的串行连接与之交互。我仍然处在学习曲线的陡峭部分,所以请温柔一点 无论如何,我可以在Windows中通过超级终端控制设备,或者在Linux中通过cu、screen或minicom控制设备。我通过电脑上的内置串行端口连接到19200,8N1。设备的接口非常简单:C++ 在Linux上使用libserial从串行端口读取额外字符,c++,linux,serial-port,libserial,C++,Linux,Serial Port,Libserial,我有一个非常基本的设备,我正试图通过Linux上的串行连接与之交互。我仍然处在学习曲线的陡峭部分,所以请温柔一点 无论如何,我可以在Windows中通过超级终端控制设备,或者在Linux中通过cu、screen或minicom控制设备。我通过电脑上的内置串行端口连接到19200,8N1。设备的接口非常简单: 键入“H”,设备将回显“H” 键入“V”,设备将回显包含其软件版本“ADD111C”的字符串 键入“S”,设备将根据其打印机状态返回“0”、“1”或“?” 输入“Q”,它返回一个五行响应,
- 键入“H”,设备将回显“H”李>
- 键入“V”,设备将回显包含其软件版本“ADD111C”的字符串
- 键入“S”,设备将根据其打印机状态返回“0”、“1”或“?”
- 输入“Q”,它返回一个五行响应,其中包含最后处理的事务的详细信息
- 我不确定,每一个回复后面都有一行新词,也许还有一个CR
root@dc5000:~# screen /dev/ttyS0 19200,cs8,-ixon,-ixoff
V
ADD111C
我曾经手动地使用过,我试着用C++和LIbScript编写一个简单的程序来与设备交互。看起来是这样的:
#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;
}
我错过了什么,只是为了获取对我的查询的响应?我猜我需要在端口上刷新一个缓冲区之类的东西,但是我在这里已经完成了我有限的知识
理想情况下,我只想得到“ADD111C”,但我不想通过获取特定长度的数据(以防将来数据发生变化)而把自己弄得一塌糊涂,而且读取结束时的垃圾似乎并不总是相同的长度或相同的数据
非常感谢您的关注
汤姆:谢谢你的帮助。Zack建议在字符串末尾写一个NULL,解决了这个问题,但我在处理另一个字符串(试图获取输出的子字符串)时,实际上偶然发现了一个更简单的方法 而不是像这样定义C字符串:
#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;
}
charnext_char[100]代码>
我是这样做的:
#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;
}
char next_char[100]=“”代码>
似乎在从串行端口读取之前为char赋值会正确地终止它。我现在可以从代码中删除memset命令,它现在可以正常工作了:
root@dc5000:~# screen /dev/ttyS0 19200,cs8,-ixon,-ixoff
V
ADD111C
root@dc5000:~#/连续测试
发送命令:
结果:
v
ADD111C
谢谢你的帮助 我敢打赌,如果您将memset(next\u char,0,sizeof next\u char)
添加到my\u serial\u流之前,这个问题会像它出现时一样神秘地消失。请阅读call.Yep。或者从读取操作中获取字符计数,并使用该计数正确地为null终止字符串。缺少空值几乎肯定是问题所在。谢谢,Zack和keshlam!这就解决了问题。我无法将您的评论标记为答案,因此将更新的代码作为答案发布并标记是最佳做法吗?