Swaraj Dubey
Swaraj Dubey

Reputation: 48

C++ serial communication in Linux

I am trying to send data from my BeagleBone black board to 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. 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:

#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:

#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. 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:

The rest of the strings I received on the Uno are perfect.

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. 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%.

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:

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 e.g using bluetooth modules. 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.

Upvotes: 0

Views: 7984

Answers (1)

Patrick Schmelzer
Patrick Schmelzer

Reputation: 66

The easiest just to check if quickly can be done in the linux terminal and no library is used for that.

  1. Set the baudrate to 300 for the UART1 (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

Writing: echo "650X450Y" > /dev/ttyO1

Reading: cat /dev/ttyO1

If you want to do this in C Code you can use the open/read/write/close syscall functions.

Upvotes: 1

Related Questions