C++ 在Linux上使用libserial从串行端口读取额外字符

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”,它返回一个五行响应,

我有一个非常基本的设备,我正试图通过Linux上的串行连接与之交互。我仍然处在学习曲线的陡峭部分,所以请温柔一点

无论如何,我可以在Windows中通过超级终端控制设备,或者在Linux中通过cu、screen或minicom控制设备。我通过电脑上的内置串行端口连接到19200,8N1。设备的接口非常简单:

  • 键入“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!这就解决了问题。我无法将您的评论标记为答案,因此将更新的代码作为答案发布并标记是最佳做法吗?