c++ - 在 Linux 上使用 libserial 将 ASCII 控制字符发送到串行设备

标签 c++ linux serial-port

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

其中一个功能涉及将数据发送到连接的打印机。您向设备发送命令,然后设备将您输入的数据中继到连接到设备的打印机。命令看起来像这样:

  • 发送“EXEX*”。设备回显“EXEX”('*'还没有回显)
  • 发送一个字节,指示您将发送的数据的长度,包括末尾的 LF。
  • 发送数据(设备现在将回显 *)。
  • 发送“#”。该设备现在将准备好接受另一个命令。

我有一个与设备通信的小 C++ 程序,我可以成功发送单个字符等,但是当我尝试发送此命令时,我没有得到预期的结果。

在 Windows 中使用 super 终端,使用 alt 组合键发送 ASCII 控制代码特别容易。只需连接并:

  • 输入“EXEX*”
  • 键入 Alt+010 发送一个 LF 字符,表示您要向打印机发送 10 个字节(九个字符和一个 LF)。
  • 键入您要发送的数据:“123456789”(长度为 9 个字节)。
  • 再次键入 Alt+010 以将最后一个 LF 字符发送到打印机。
  • 输入“#”完成。

这是我在 C++ 中拼凑的尝试:

#include <SerialStream.h>
#include <string>
#include <iostream>
#include <fstream>

using namespace std;
using namespace LibSerial;

int main(){
char buffer [50];
int n;

n=sprintf (buffer, "EXEX*%c123456789%c#",10,10);
printf("Variable buffer was set to a %d character string: %s\n",n,buffer);

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 << buffer;
//my_serial_stream << printf("%s",buffer);
//my_serial_stream << "EXEX*\n123456789\n#";
my_serial_stream.read(next_char,100);
cout<<"Result: "<<next_char<<"\n";
my_serial_stream.Close();

return 0;
}

我还尝试了两条注释掉的行,但都没有用。设备在另一端没有收到正确的字符。”

我确定这是非常基本的,也许有什么东西在捕获中间的控制字符?如果有人对更好的方法有任何想法,我将不胜感激。具体来说,我可能需要发送一个值介于 1 和 40 之间的字节,具体取决于我希望发送到打印机的数据长度。

很抱歉我不清楚,如果我需要进一步分解,请告诉我。

非常感谢,

汤姆

最佳答案

您发送的行不包含您在字符序列中提到的#。

您是否使用 gtkterm/cutecom 等检查串行通信在/dev/ttyS0 上的工作情况?

要测试您的接口(interface),您可以读回串行端口。如果您有第二个端口或计算机,您可以通过零调制解调器连接到另一个端口来实现。否则,您可以将串行端口的引脚 2 和引脚 3 短接,并检查您是否收到了您发送的字符。

您可能需要检查对串行库的调用的返回值,以查看是否返回了任何错误。

可能对打印机有时间要求,发送一些字符之间可能需要等待。

我编译了代码并使用 gtkterm 检查了另一个串行端口上的输出,它确实收到了您期望的字符串:

45 58 45 58 2A 0A 31 32 - 33 34 35 36 37 38 39 0A EXEX*.12 3456789。

它不会影响代码的发送部分,但接收看起来很可疑。如果 read() 成员函数类似于系统调用,并且如果 next_char 是字符数组,那么它不会以 null 终止字符串。相反,您必须查看返回值以获得大小,然后如果您要将它用作以空值终止的 C 字符串,则以空值终止。

关于c++ - 在 Linux 上使用 libserial 将 ASCII 控制字符发送到串行设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21924798/

相关文章:

c++ - Xcode 4.2 无法识别 C++ 原始字符串文字?

c++ - 信号处理

c - 如何检查附加到可执行文件的静态库?

c - C LINUX中串口读取不一致

java - 如何查看电脑可用端口?

c++ - 得到一个类的两个实例?

c++ - QMutex 是否需要是静态的,以便此类实例的其他线程调用知道暂停它们的操作?

linux - 如何从docker swarm中的管理器中删除服务

node.js - 在 ubuntu 18.04 上安装 node-sass 返回错误

java - 如何在JAVA中读取USB串口?