Interfacing Arduino with C++ and libSerial.

Standard

I know that there is a section at the Arduino Playground on interfacing the Arduino with C. However, I found it is much easier, almost trivial, to use libSerial with C++.

(libSerial works on POSIX systems. I guess Windows users could use it through Cygwin but I’m not sure)
(Update: No, they can’t)

First, you import your libraries and define the port you will be using:


#include &lt SerialStream.h &gt
#include &lt iostream &gt
#define PORT "/dev/ttyUSB0" //This is system-specific

SerialStream ardu;

using namespace std;
using namespace LibSerial;

The above code is assuming that the arduino is bound to /dev/ttyUSB0. Make sure to point the stream to the real device on you computer ;)

A new serial stream “ardu” is created.

Now let’s define a simple function to setup the Arduino for communication.

void open(){
    /*The arduino must be setup to use the same baud rate*/ 
    ardu.Open(PORT);    
    ardu.SetBaudRate(SerialStreamBuf::BAUD_9600);  
    ardu.SetCharSize(SerialStreamBuf::CHAR_SIZE_8);
    (....)

At least in my case, this simple function is enough to have a working serial communication with the microcontroller.

Now I’ll write another simple function that sends one byte through the serial port to the arduino and then reads a string, which gets interpreted as an integer..

int get(char out){    
    int res;
    char str[SOME_BIG_SIZE];
    ardu << out;
    ardu >> str;
    sscanf(str,"%d",&res);
    return res;
}


See? It’s easy! :)
If for some reason you must use standard POSIX libraries, here is a great article on POSIX serial programming.

If you have any doubts, post a comment.

About these ads

18 thoughts on “Interfacing Arduino with C++ and libSerial.

  1. Hi, i´m trying to do some functions with libserial. I tryed bufferinbg information:serial_port >> input_buffer;for (int i=0;i < BUFFER_SIZE;i++){std::cout << input_buffer[i];}But with the information i have garbage? I think that the libserial have a function to read the data inside a vector and stop when data stops. Do you know something about how to use it?information == > D V 1 6 4 0 0 5 D V 1 6 4 0 0 5 U � � ( L � � ( J � � � � � L . N = � � � "  � � @ U � � 8 � � � � � � � � � � � � � � 0 � � R � � � � � � � � X � � � � U � � � D �  � � � � � � � � � � � r � � � H � � � � � � � � � � � h � � W � r �

  2. The extra garbage data is probably memory inside the char array which hasn't been initialized. The >> operator probably worked fine.If you are always passing messages of 8 bytes, you could define BUFFER_SIZE to 8 to get rid of all those unused 0's and 1's.If you want to see if the garbage is coming from the arduino, you could try filling the char array with '0's or whatever character you want, and then check if they are replaced.You could also use the Read function of SerialPort. If you don't specify a timeout, I believe it will wait until BUFFER_SIZE bytes have been transfered.

  3. Hehe.. i´m not using a Arduino. It´s a barcode scanner. But i just found a few examples using libserial.I´m initializing the array with 0 on all positions. The garbage is from the barcode scanner because i configured a suffix(9 13 10) code that is sended after the garbage:MK9590-61A47��������(��12 9 13 10

  4. Hi! Exactly what does this script expect the arduino to send back? Because I can't get this to work. My program stops at "ardu >> input_buffer;", seemingly waiting for input.The baudrate is set to 9600 on the device and in my code, so that's not it.I have tried to do the same on Perl, and it works.This is the line sending data back to the computer:Serial.println(data, BYTE);It's in a loop, so data is sent all the time.

  5. tienes algún programa ejemplo que comunique tanto arduino con un programa en c++ con libserial, es que he estado usando tu ejemplo y no me funciona, osea, el arduino esta enviando perfectamente la información porque si hago cat /dev/ttyUSB0 me aparece la info pero al parecer libserial no la esta leyendo y no me da errores ni nada parecido :stambién viceversa, si quiero enviarle algo al arduino no está funcionando pero si uso echo algo >> /dev/ttyUSB0 funciona perfectamente.

  6. hi. ;) i trying to write a code that read arduino output in usb.I work on mac os x and i not able to install libserial on my mac. can you help me?thanks

  7. i install succesfully libserial but when i compile my progrma obtain follow errors:Undefined symbols: "LibSerial::SerialStreamBuf::underflow()", referenced from: vtable for LibSerial::SerialStreamBufin ccQlD1bA.o "LibSerial::SerialStreamBuf::overflow(int)", referenced from: vtable for LibSerial::SerialStreamBufin ccQlD1bA.o "LibSerial::SerialStream::SetCharSize(LibSerial::SerialStreamBuf::CharSizeEnum)", referenced from: _main in ccQlD1bA.o "LibSerial::SerialStream::SetBaudRate(LibSerial::SerialStreamBuf::BaudRateEnum)", referenced from: _main in ccQlD1bA.o "LibSerial::SerialStreamBuf::xsgetn(char*, int)", referenced from: vtable for LibSerial::SerialStreamBufin ccQlD1bA.o "LibSerial::SerialStreamBuf::xsputn(char const*, int)", referenced from: vtable for LibSerial::SerialStreamBufin ccQlD1bA.o "LibSerial::SerialStream::Open(std::basic_string, std::allocator >, std::_Ios_Openmode)", referenced from: _main in ccQlD1bA.o "LibSerial::SerialStreamBuf::showmanyc()", referenced from: vtable for LibSerial::SerialStreamBufin ccQlD1bA.o "LibSerial::SerialStreamBuf::pbackfail(int)", referenced from: vtable for LibSerial::SerialStreamBufin ccQlD1bA.old: symbol(s) not foundcollect2: ld returned 1 exit statusfor compile i use command : g++ file.cppfile.cpp has follow code :#include #include #define PORT "/dev/tty.usbserial-A8003LjH" //This is system-specificusing namespace std;using namespace LibSerial;int main(){ SerialStream ardu; ardu.Open(PORT); ardu.SetBaudRate(SerialStreamBuf::BAUD_9600); ardu.SetCharSize(SerialStreamBuf::CHAR_SIZE_8); int res; char str[8]; ardu >> str; sscanf(str,"%d",&res); return 0;}

  8. Hey Marco. You need to link libserial to your program. In linux I would change your compile command to g++ file.cpp -lserialMaybe that will work in MacOS. If not, you'll have to figure out how to link it.Oscar: Si quieres te mando el código por mail

  9. Hello,
    Thank you for the useful example, but my code stops right after opening the serial port, not executing anything else. The LED on the board blinks once, and nothing happens afterwards.
    Please, be forgiving and ask if any information is necessary to diagnose the problem.
    Thank you very much for help.

  10. Hi! Great article! I have an application in which I need to read Arduino from USB in a completely nonblocking manner. If the input from Arduino is a ‘?’ the program should set a few flags and reply – if not a ‘?’, do nothing. Code I use inside a while loop for testing-

    char c = ‘x';
    my_serial_stream >> c;
    std::cout << c << std::endl;
    if (c == '?') count++;

    (I've set vmin and vtime to 0 to make the read completely nonblocking)

    On the Arduino, I've burnt a program that sends a '?' every 2.5 seconds.
    My program never increments 'count' i.e. it never gets the '?'. This is curious, because if I increase vtime to 50, it starts getting the '?'s .

    Could you help me out with this?
    Samarth

    • Honestly I have forgotten the details of this article. I am aware that it is my most popular post, though =)

      From this article:

      VMIN = 0 and VTIME = 0
      This is a completely non-blocking read – the call is satisfied immediately directly from the driver’s input queue. If data are available, it’s transferred to the caller’s buffer up to nbytes and returned. Otherwise zero is immediately returned to indicate “no data”. We’ll note that this is “polling” of the serial port, and it’s almost always a bad idea. If done repeatedly, it can consume enormous amounts of processor time and is highly inefficient. Don’t use this mode unless you really, really know what you’re doing.

      My guess is that since the read is returning immediately due to vmin and vtime being 0, it is actually returning before you write to the stream. Setting vtime > 0 is letting the program wait some time for data to buffer up.
      This is just a guess, but if I am right and if you are concerned about blocking, you could fire off separate threads for each read and let each thread block for a small amount of time.

  11. Hey i found this article very interesting. Do you know how to interface with a library called Open CV with Arduino. Is so please help me out.

  12. I need to send a single byte to the board, so if I do use:

    int get(byte b){
    int res;
    ardu <> str;
    sscanf(str,”%d”,&res);
    return res;
    }

    instead you ‘ve posted, the result is the same?

  13. Thanks so much for posting this article, it helped me a lot.

    I have a question if anybody is able to answer… the serial communication between my program and the arduino only works if the arduino IDE is open and I first send something using the serial monitor of the IDE. Just one character is enough to get it started, then everything works great. But as soon as I close the IDE communication with my program will stop too, or if the IDE was not open when my program starts, nothing happens.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s