Linux下的C++串行通信

C++ serial communication in Linux

本文关键字:通信 C++ 下的 Linux      更新时间:2023-10-16

我正试图将数据从BeagleBone黑板发送到Arduino Uno。我选择的波特率是300。我正在使用serializb库,该库位于以下位置:http://serialib.free.fr/html/classserialib.html#ac8988727fef8e5d86c9eced17876f609您可以一直滚动到底部查看这两个文件(serializb.h和serializb.cpp),不过我也在这里发布了主要的片段。我读到一些评论说这个库不可靠,但在真正怀疑其他任何事情之前,我首先想检查一下我的代码。

这是我在BeagleBone:上用C++编写的程序

#include <iostream>
#include "serialib.h"
#ifdef __linux__
#define     DEVICE_PORT    "/dev/ttyO1"
#endif
using namespace std;
int main()
{
serialib LS; //the main class to access
int Ret;
Ret= LS.Open(DEVICE_PORT,300);
if (Ret!=1)
{
cout<<"cant open portn";
return 0;
}
else{cout<<"port now open n";}
string xval="650X450Y";
for(int i=0;i<500;i++)//send xval 500 times 
{
for(int j=0;j<xval.length();j++)//send each character separately 
{
Ret=LS.WriteChar(xval[j]);
LS.Close();
LS.Open(DEVICE_PORT,300);
}
if (Ret!=1){cout<<"cannot writen";}
else{cout<<"done writingn";}
}
LS.Close();
cout<<"Transmission completen";
}

我在Arduino Uno上的代码如下:

#include <SoftwareSerial.h>
SoftwareSerial uart(10,11);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); //baud rate for Serial communication
uart.begin(300);
}
char x;
String data="";
void loop()
{
if(uart.available()>0)//check if data is coming in
{
while(uart.available())
{
x=uart.read();//read the incoming byte
data+=x;//append the string with incoming bytes
}
if(x=='Y')//received all the bits
{
Serial.println(data); //display received information
}
}
}

C++-我首先在BeagleBone上打开我的UART端口,逐字符发送字符串"650X450Y",重复500次,看看我的通信系统是否稳健。正如你所看到的,在"for"循环中,我在发送每个字符后都会关闭和打开这个端口,因为如果没有这个,它会发送很多错误的数据,如果这个"for"环路很大,那么写入过程甚至会停止(不确定它为什么会这样),因此在每次关闭和打开该端口后,我已经设法大大减少了错误,但仍然有一些错误:

  • 我发送了500次这个字符串,但我在Uno上收到的一个样本是"660X450Y",值错误
  • 在500次中,大约有2-3次,我收到了"650X450Y650X450Y",即重复,这肯定不是字符串长度,那么它怎么会发送这个数据呢

我在Uno上收到的其余字符串都是完美的。

在Uno上,正如你所看到的,我正在逐个字符地读取,并将其附加到名为data的字符串中,一旦检测到表示字符串末尾的字节"Y",就会打印出这些数据。我以前在C++代码中使用过WriteString()函数,但它给出了一些错误。我提供的代码是我在过去几天里经过大量调试后最接近于使这个系统100%可靠和健壮的代码,但我真的不确定为什么这个系统仍然不是100%。

我看到了库中两个文件的源代码,并观察到了在serializb.cpp(上面已经提供的链接)中第210行定义的WriteChar(char-Byte)函数,我发现这是传输字符的函数:

if (write(fd,&Byte,1)!=1)     // Write the char
return -1;      // Error while writting
return 1; // Write operation successfull

我看不出这个函数有什么问题,那么为什么我不能100%准确地接收数据,我的两个源代码或其中任何一个都有问题吗?,我应该选择不同的串行库吗?,如果我选择了其他库,但仍然没有得到结果,那么我想我可能必须以无线方式传输这些信息,例如使用蓝牙模块。如果有人对这个问题有任何建议/改进,请告诉我:),在那之前,我会尝试其他方法来实现100%的准确性。

检查是否可以在linux终端中快速完成,并且不使用库。

  1. 将UART1的波特率设置为300(stty-F/dev/tyO1 raw和stty-F/dev/ttyO1 300)

  2. 您可以简单地通过写入(或读取)UART1的设备文件将数据发送到UART1,在您的情况下是/dev/ttyO1

写入:echo"650X450Y">/dev/ttyO1

正在读取:cat/dev/ttyO1

如果要在C代码中执行此操作,可以使用open/read/write/close系统调用函数。