简体   繁体   English

Linux中的C ++串行通信

[英]C++ serial communication in Linux

I am trying to send data from my BeagleBone black board to Arduino Uno. 我试图将数据从BeagleBone黑板发送到Arduino Uno。 The baud rate I have selected is 300. I am using the serialib library which is located here: http://serialib.free.fr/html/classserialib.html#ac8988727fef8e5d86c9eced17876f609 you can scroll all the way to the bottom to view the two files (serialib.h and serialib.cpp), however I have posted the main snippets here too. 我选择的波特率为300。我使用的是位于此处的serialib库: http ://serialib.free.fr/html/classserialib.html#ac8988727fef8e5d86c9eced17876f609您可以一直滚动到底部以查看这两个文件(serialib.h和serialib.cpp),但是我也在此处发布了主要代码片段。 I read some reviews saying that this library is not reliable however I would first want to check my code before really suspecting anything else. 我读过一些评论说该库不可靠,但是在真正怀疑任何其他内容之前,我首先要检查我的代码。

This is the program I have written in C++ on my BeagleBone: 这是我用C ++在BeagleBone上编写的程序:

#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 port\n";
      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 write\n";}
      else{cout<<"done writing\n";}
  }
  LS.Close();
  cout<<"Transmission complete\n";
}

My code on the Arduino Uno is as follows: 我在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++ - I am first opening up my UART port on the BeagleBone and sending the string "650X450Y" character by character which is repeated 500 times to see if my communication system is robust or not. C ++-我首先在BeagleBone上打开UART端口,然后逐个字符发送字符串“ 650X450Y”,该字符串重复500次以查看我的通信系统是否可靠。 As you can see that within the 'for' loop I am closing and opening this port after sending every character because without this, it sends quite a lot of wrong data and if this 'for' loop is very big then the writing process even stops (not sure why it behaves like that) thus after closing and opening this port every time, I have managed to reduce the errors significantly but there are still a few errors: 如您所见,在“ for”循环中,我在发送每个字符后关闭并打开该端口,因为如果没有此操作,它将发送很多错误数据,如果此“ for”循环很大,则写入过程甚至会停止(不确定为什么会这样),因此每次关闭和打开该端口后,我都设法显着减少了错误,但仍然存在一些错误:

  • I sent this string 500 times but one sample I received on the Uno was "660X450Y", wrong value. 我将该字符串发送了500次,但在Uno上收到的一个样本为“ 660X450Y”,值错误。
  • About 2-3 times out of 500, I am receiving "650X450Y650X450Y650X450Y" ie repetitions, this is definitely not the string length then how come it can send this data?. 在500中大约有2-3次,我收到“ 650X450Y650X450Y650X450Y”(即重复),这绝对不是字符串长度,那么它将如何发送此数据?

The rest of the strings I received on the Uno are perfect. 我在Uno上收到的其余字符串都很完美。

On the Uno as you can see that I am reading in character by character and appending it to my string named data and printing out this data as soon as the byte 'Y' is detected which denotes the end of the string. 在Uno上,您可以看到我正在逐字符读取字符,并将其附加到名为data字符串中,并在检测到表示字符串末尾的字节“ Y”后立即打印出该数据。 I previously used the WriteString() function in my C++ code however that gave a number of errors, The code I have provided is the closest I have come so far in the last few days to make this system 100% reliable and robust after lots of debugging, however I'm really not sure why the system is still not 100%. 我以前在我的C ++代码中使用WriteString()函数,但是却给出了许多错误。我提供的代码是最近几天来我得到的最接近的代码,以使该系统在经过很多次尝试后100%可靠且健壮调试,但是我真的不确定为什么系统仍然不是100%。

I saw the source code of both the files in the library and observed the WriteChar(char Byte) function which is defined at line 210 in serialib.cpp (link already provided above) and I see that this is the function transmitting the characters: 我看到了库中两个文件的源代码,并观察了在serialib.cpp的第210行定义的WriteChar(char Byte)函数(上面已经提供了链接),并且我看到这是传递字符的函数:

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

I don't see anything wrong with this function then why can't I receive the data with 100% accuracy, Is there anything wrong in both my source codes or either one?, should I opt for a different serial library?, in case I opt for other libraries and I still don't get my results then I think I may have to transmit this info in a wireless manner for eg using bluetooth modules. 我没有看到此功能有什么问题,那么为什么我不能以100%的准确度接收数据,我的源代码或任何一个源代码有问题?我应该选择其他串行库吗?我选择其他库,但仍然无法获得结果,因此我可能不得不以无线方式传输此信息,例如使用蓝牙模块。 If anyone has any suggestions/improvements regarding this problem then do let me know :), till then I'll try other methods to achieve a 100% accuracy. 如果有人对这个问题有任何建议/改进,请告诉我:),在此之前,我将尝试其他方法以达到100%的准确性。

The easiest just to check if quickly can be done in the linux terminal and no library is used for that. 最简单的方法是检查是否可以在linux终端中快速完成,并且不使用任何库。

  1. Set the baudrate to 300 for the UART1 (stty -F /dev/ttyO1 raw & stty -F /dev/ttyO1 300) 将UART1的波特率设置为300(stty -F / dev / ttyO1 raw&stty -F / dev / ttyO1 300)

  2. You can sent data to the UART1 simply by writing(or reading) to the device file for the UART1 which is in your case /dev/ttyO1 您只需将UART1的设备文件(在您的情况下为/ dev / ttyO1)写入(或读取)即可将数据发送到UART1

Writing: echo "650X450Y" > /dev/ttyO1 编写:回声“ 650X450Y”> / dev / ttyO1

Reading: cat /dev/ttyO1 阅读:cat / dev / ttyO1

If you want to do this in C Code you can use the open/read/write/close syscall functions. 如果要在C代码中执行此操作,则可以使用open / read / write / close syscall函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM