Communicating with Arduino using C/C++

Hello Everyone

This post is on “How to communicate with Arduino using C/C++”.

I basically have an array of integers from my C/C++ code which i need to send to an Arduino. I need to communicate between C/C++ and Arduino

Before we actually see how this is done, we should know a little about how are actually devices handled in Linux.
Under Linux and UNIX each and every hardware device is treated as a file. They are special files located in the /dev folder in your system which allow us to access the hardware directly.

Like any other normal file in our computer we can read/write to these device files(which means reading or writing to the device itself). That is pretty much how the OS also does it on a primitive level. It opens the file associated with the device it has to use and then reads or writes to it accordingly.

Arduino boards are also handled in the same way. We will read/write to the device file of our Arduino.

First, we need to identify the device file for our arduino.

  • Go to the tools menu and look for Serial Port submenu.
  • There it will show you the list of device files(Serial Ports). For Arduino Duemilanove it is /dev/ttyUSB0(file name can change if it is already in use), for Arduino UNO it will be /dev/ttyACM0. Select a file from this menu which will be used for communication.

Now, there are 2 parts to this problem, the C code and the Arduino code.

  • C code will send data
  • Arduino code will receive data.

C code

int main()
{
    int data[] = {10,5,13};  //Random data we want to send
    FILE *file;
    file = fopen("/dev/ttyUSB0","w");  //Opening device file
    int i = 0;
    for(i = 0 ; i < 3 ; i++)
    {
        fprintf(file,"%d",data[i]); //Writing to the file
        fprintf(file,"%c",','); //To separate digits
        sleep(1);
    }
    fclose(file);
}

Explanation.

  • We have an array of integers and we want to send this array to our arduino. First we open our arduino device file which is /dev/ttyUSB0.
    int data[] = {10,5,13};  //Random data we want to send
    FILE *file;
    file = fopen("/dev/ttyUSB0","w");  //Opening device file
  • Next we write each element of the array to the file using a simple for loop, after writing each element we add a comma(‘,‘) to separate elements in our file.
    int i = 0;
    for(i = 0 ; i < 3 ; i++)
    {
        fprintf(file,"%d",data[i]); //Writing to the file
        fprintf(file,"%c",','); //To separate digits
        sleep(1);
    }
    fclose(file);

Next thing is to read this data through an arduino.

Arduino Code

void setup()
{
    Serial.begin(9600);
}

int calc()
{
    int num=0,x=0;

    for(x;x<=j;x++)
          num=num+(buff[x]-48)*pow(10,j-x);

    return num;
}

int input,num;
int buff[5];
int j=-1;

void loop()
{
    if(Serial.available()>0)
    {
        input=Serial.read();

        if(input==',')
        {
            num=calc();
            j=-1;
            Serial.println(num);
        }
        else
        {
            j++;
            buff[j]=input;
        }
    }
}

Explanation

  • First we setup the Serial port in void setup()(line 3).
  • After setting it up, we have to start reading, now in our C code we wrote integer values to our file
    fprintf(file,"%d",data[i]);
    

    But our arduino will read them as characters, so we need to read characters and convert them back to our original number.

  • So in void loop() we keep on reading data(which is nothing but our integers converted to characters) and store them in an array(buff) until we read a comma (‘,‘) . comma was used to separate digits(line 10 of our C code).
    input=Serial.read();
    
    if(input==',')
    {
        num=calc();
        j=-1;
        Serial.println(num);
    }
    else
    {
        j++;
        buff[j]=input;
    }
    

    As soon as we read a comma we call calc() where we convert the read characters back to the integer.

  • In calc() we subtract 48 from the ascii value of the character, multiply it with its place value raised to 10 and return the final integer num.
    for(x;x<=j;x++)
        num=num+(buff[x]-48)*pow(10,j-x);
    
  • Repeat the process until all the data has been read.

Finally, we were able to send an array from C/C++ to our arduino.

This was a very basic way of communicating, many better techniques can also be used.

Advertisements

54 thoughts on “Communicating with Arduino using C/C++

  1. Hi,
    I am trying to implement your code in windows machine but its not working. The PC cannot write to arduino. In serial monitor of arduino I couldn’t see any output.

    I have changed your code in one line only
    file = fopen(“COM10″,”w”);
    As arduino in Com10 so I have done that. If you have any suggestions and help or any code please help and suggest.

    1. Hi
      The post was written keeping in mind a Linux Platform. So i guess the code will not be directly usable on a windows machine as windows treats devices differently.

      I can help you using python.
      You can do something like this

      import serial

      s = serial.Serial(“COM10”,9600)
      s.write(‘hello’)

      I think this should work.

      Salil

  2. Thanks for your prompt reply. I will use python and lets see what will happen. I will give you update.

  3. I just have small query to you. Simultaneously PC and arduino can not access the same port at the same time. At the same time PC or arduino can get access the port. So when you are writing to the port how can you see the output in the serial monitor [arduino].

    1. Hi

      To answer your question, it appears that the operations are taking place simultaneously but actually they are consecutive operations. The PC first writes to the port and then the arduino reads the data.

      Both arduino and PC try to gain access to the port. So lets say if the PC is granted access to the port, the PC puts a write lock on the port. This prevents the arduino from reading the data while the PC is trying to write data. Once the writing operation is complete the PC releases the write lock and then the arduino puts a read lock so that the PC cannot write again to the port while the arduino is trying to read data. It all happens one by one.

      I hope this answers your query.

      Salil

  4. Thanks. I understood your reply. However I am wondering after PC writing data to the port will arduino get data to read from port ?

    If you please give your step to watch the output. I am doing the following step.
    1. Running the program in EDITOR to write data to port.
    2. Closing the program
    3. Watch the Serial monitor of Arduino [Porgram already uploaded to arduino board].

    If you have any suggestion regarding the step please suggest.

    1. I guess you are trying to catch what you have send using your python/C code on the serial monitor.

      1) So first run your C/python code and send some data.
      2) Then in your arduino code read the serial data and print it on the monitor using println() and open the serial monitor.

      This should work.

  5. Very simple and clear. It worked at first, but I added the arduino the first line: # include ,
      with arduino uno and linux raspberian.
    Many thanks and good job.

  6. hi there,
    thanks for this post. I was wonering how i could read information being sent from the arduino to the pc in C/C++.
    cheers,

    1. Hi
      Sorry for the late reply.

      So for sending information back to your computer, you first send the data from your arduino to the serial port and then in your C/C+ code you can read that data from the device file(Serial Port)

      So to send data to the serial port from the arduino you can use Serial.write().
      and then in your C/C++ code open the device file( i.e /dev/ttyUSB0) and read data from this file.
      (Synchronizing read and write can be a bit tedious here)

      Essentially all the information exchange happens using the device files.

      I hope this helps.

      Salil

  7. Firstly, Thank you very much for this tutorial. It is very helpful, I was able to implement it in my project. However, it seems like there is a ten second delay between when I write the value and when the arduino reacts to it. Do you have any ideas what would cause this kind of lag?

  8. Hello,

    thank you for this post but how can i knew that arduino receive data.

    How can i read data sending by arduino ?

    Thanks

  9. Hi

    Thanks you for this code
    I have some question

    I coding in Xcode(Mac os)
    this code be ocurred error in ‘sleep’
    error Content is “Use of undeclared identifier ‘sleep’ “

  10. hey!
    Please can you help me out to write a c++ code of the given arduino code
    please reply me on my given e-mail and i will send you the required condition with the arduino file included.

    1. Hi,

      I am assuming you are looking for the C++ version of the C code mentioned in the blog post. You can use the given C code directly in your C++ file. Just copy the code in any .cpp file and compile it using g++ and it should work.

      I hope I have answered your query. Tell me if you were looking for something else.

      Salil

  11. no sir, the arduino code is different and i am asking for the c++ code of the arduino that i m having which is different from the code that you have provided above.

    i understood your’s arduino’s code but i’m stucked in a different one

    so please can you help me out ?

  12. Good day,
    I have been dabbling with the Arduino, but not having a good grasp of C++, it is an uphill battle.
    I’m trying to read value from an MS excel spreadsheet, to the Arduino, and compare it with values read into an analogue port of the Arduino. If higher, I want to light a LED – if lower, a second LED and if equal, a third LED.
    These inputs read at the analog ports, must also be written into the same excel spreadsheet (different column) so that a graph can be generated by live if necessary on excel.
    It is purely for experimental purposes.
    So, basically, I want to read and write to and from excel – draw a graph and light three LED’s dependent on the comparative values.
    Any great ideas??
    Regards
    Z

    1. Hi Zahir,

      All you need is a library that can help you interface with Excel. Now there are many libraries available for Java and Python. I am not sure how easy it is do use C/C++ for such a task. I would suggest you to use Python because it will make it easier for you on both fronts Excel interfacing as well as communicating with the Arduino. You can use http://www.python-excel.org/ for the excel part and for the arduino all you have to do is again open the device file and read/write values to/from it. It is exactly how I have done using C/C++.

      I hope this helps! Leave a comment otherwise.

      1. Thanks… back to the drawing board for me. My son has been urging me to use Python as well.
        The reason for me going to C++, was mainly because I thought it was a good way to ease writing commands to PIC devices – I have in the past used assembler to program these and I have recently bought a book that starts with the words “A good understanding of C++ is required”.
        At my age, a few years from 60, I still pride myself knowing valve theory!!
        I have downloaded PLX over the weekend, this enabled me to write to an excel file – storing analog values read from the Arduino to excel drawing a graph live. Great to use as a logging device, but, this does half the job reading from Arduino – as stated, I need a two way comms live.
        Maybe I must overcome my fear of snakes and tackle the PYTHON!
        Cheers
        Z

  13. Hi Zahir,

    After looking up over the internet, I found this library “libxl” http://www.libxl.com/
    This might be the thing for you. The library has support for both C/C++ just in case you want to shift to C. I guess this can help in all your tasks. PIC, Excel, Arduino.

    PS:- This PYTHON isn’t that deadly, give it a try 😉
    PPS:- It is inspiring, how you are still so enthusiastic 🙂

    Cheers
    Salil

  14. Hello , Do you have any idea on how we can simultaneously send data from Arduino to serial port and make the C++ program read in the values? Like the arduino is going to print out some readings continuously and the C++ program will act on those values read in in real time.

  15. Hi salilkapur,
    Your code was really helpful thank you.
    For the arduino code I am getting the errors that j and buff is not declared in the scope. If I declare them before the calc() the error goes away but I am not sure if this will spoil the work of this code.
    Also the command Serial.println(num), should print the num value on the serial monitor? but its not
    I want to send an integer (int i = 10) from Xcode to arduino and in my arduino code I am checking if the input == 10 then blink my LED. I guess the sending part must be much similar to the code you shared here except that I will just send an integer rather than an array. The part that i dont know is how you converted your ascii value to integer. Can you show a code as to how I can get this working? Your help is much appreciated.
    Thanks once again.

    1. Hi Adil,

      The code works fine for me. But declaring them before calc() will not make any difference to its functioning. You can go ahead and do that.

      Yes, the logic will not change when you use xcode. Only the way device files are accessed may change. You can take a look at this https://developer.apple.com/library/mac/Documentation/DeviceDrivers/Conceptual/WorkingWSerial/WWSerial_SerialDevs/SerialDevices.html

      ASCII to Integer conversion is very simple. So using my C\C++ code I am sending an integer value to arduino. While sending, the integer is treated as a stream of characters. So if I am trying to send an integer 123, it is transferred as separate characters 1 2 3. While receiving the integer(you actually receive the ASCII values of the characters 1 2 3) in my arduino I store the stream of characters in a temporary buffer (buff in the code). Then I iterate over the buffer and convert each character to its corresponding integer by subtracting 48. So, consider the character 1, the buffer will have its ASCII value which will be ’49’. After subtracting 48 from it I will get the original number back i.e 1. Once I have restored the original set of integers I will combine them to form the original number 123 by multiplying each number with its corresponding place value. Example (1 * 100) + (2 * 10) + (3 * 1) = 123.

      I hope this answers your question. Drop in a comment in case this does not help.

      Salil

  16. Hi Salil,
    I tried your code on Mac OS X 10.9 with a Arduion 1.5 environment but I’m getting an error that ‘fopen’ is not declared in this scope. Can you share what #include you are using. I have actually already tried including stdio.h, cstdio, iostream and its still not working. If I try: ‘using namespace std;’ I get an error that ‘fopen’ is not a member of std.

    Appreciate your help,
    Thanks you in advance,
    hg

  17. Hi, my board is Arduino Uno and I have changed the code to ttyACM0. I have done in the way you did. But it seems there’s no data pass to Arduino from my C file. I did this on Ubuntu platform. Any idea why it didn’t work?

    1. Hi Harris,

      Check the Tx/Rx/ leds on your arduino board. If they are blinking while you are trying to transfer the data, it means that there is some problem in your arduino code otherwise check your C/C++ code.

      It is really difficult to exactly pin point the problem without having looked at the code. If you can share your code, it will be easier to debug.

      Salil

  18. I have a C code running in linux
    and Ardiuno sending output to serial.

    In order to read data in PC do I need to send something first to arduino?

    Currently I am getting 00 as output in c program.However once I run the serial monitor in ardiuno ide and then run the C program I get the correct output.

  19. You set the baud rate in your sketch, but in your C code you didn’t initialize the serial port at all. How do you know the state of the serial port is correct? What if you wanted to use a different baud rate?

    1. Hi John,

      Yes, ideally you should set baud rate in your C code as well. But the reason this code worked for me was because I was dealing with small amounts of data. The device file acts as a buffer and the data sent by the arduino keeps getting appended at the end of the file. But if the amount of data you are transferring is more than the buffer size, it will be troublesome.

      You can change your baud rate, provided the amount of data that you are dealing with is limited.

      Salil

      1. Where in a C++ program would you specify baud rate? Basically, I need to send a string of char’s (all commands) to the Arduino. I have already read the commands from a file in the C++ program, but for some reason, I am getting nothing from my Arduino code. I think that the baud rate might be the problem, but I am not positive. I will give you my code for specific help:

        C++:
        #include
        #include //For sleep()
        #include //For FILE
        #include //For ifstream
        #include //For assert()
        #include //For string
        using namespace std;

        int main()
        {
        //Setting up the output to the Arduino
        FILE *arduino;
        arduino = fopen(“/dev/tty.usbmodem1411″,”w”);
        if (arduino == NULL) perror (“Error opening file”);

        //Setting up the file input stream
        ifstream inFile (“input.txt”);
        assert(inFile.is_open());

        char input = ”; //Starts out as NULL

        while (input!= EOF) {
        fprintf(arduino,”%c “, input); //Writing to the file
        inFile >> input; //Getting the file input to make sure it isn’t the EOF
        sleep(1);
        }
        fclose(arduino);
        }

        Arduino Code:
        void setup()
        {
        Serial.begin(9600);
        }

        void loop()
        {
        char input;
        if(Serial.available())
        {
        input=Serial.read();

        Serial.println(input);
        }
        }

        Sample input from input.txt:

        w a d s w d a a s d w

        That string of characters will provide a direction (up, down, left, right) as per WASD.
        Thanks in advance for your time and I hope you can help :D.

  20. Hi,
    Can data(integer value) from a sensor connected to arduino be written to the file dev\ACM0/1 using Serial.write() and then be read and used by a code in C++ by opening the file in read mode? if yes what should be the variable type that can be used in fscanf command?

    1. Hi Rahul,

      Yes, you can send data back to your computer using Serial.write() function. The safest thing to do here would be to treat data as characters and then convert them to whatever type you want in your C code.

      Salil

  21. Hey,
    Excellent programming, I unfortunatly too have hit some problems. I am trying to write my program in Xcode as a few above, and it gives me an error of bad acces. I think the fopen statement doesn’t work properly, because of a wrong path. I have changed the path to what is written in the bottom right corner of the IDE, but I am not sure, that’s right. And I am not sure what the “w” is for. Any help explaining the “w” or helping me to make sure I have the correct path is greatly appreciated.

    I have read all the corners but couldn’t make any of the other problems and solutions help.

    1. Hi Mathias,

      Like you many others have also pointed out issues with xcode. Unfortunately I haven’t got the opportunity to test this out on xcode, so I will be of very little help to you. Looks like device files are handled a bit differently there (not sure on this).

      A very primitive way to get the correct file path could be to open the /dev/ folder without plugging in your arduino and making a note of all the files in that folder. Then plugin your arduino and again make a note of all the files. The new file that you see in that folder should correspond to your arduino.

      I am assuming the ‘w’ you are taking about is the second parameter that goes into fopen. It is used for specifying the mode in which you want to open the file i.e. read or write.
      w -> Opening the file in write mode
      r -> Opening the file in read mode

      You can check the official documentation for more details on these modes.

      I hope this helps.

      Salil

      1. Hi
        I want to send/receive data into Excel2000 and Arduino Nano. Very little at a time, say 5-10 single characters from consecutive cells in single column.2sets per minute. Is there a VBA version (the very basics only, simple) Iam new to this communication thing.
        So code to open/close USB port, send d then g,then j etc. And later receive e then r.
        Thanks
        CharlesHarris

  22. Hi Charlie,

    I am sorry but I haven’t tried implementing this is VBA. I am sure you will be able to find resources on the internet. Do share with us if you find anything useful. Thanks

    As an alternative, you can use python for doing this. Python has support for both Excel and Arduino. There are libraries that can help you play around with excel sheets.

    Salil

  23. here is a method to let the arduino communicate with the C++ via serial link, what if i want ti integrate the c++ code in a SDcard on arduino how can i link the C++ code and arduino sketches and let them communicate without serial link?

  24. Hi,
    How can communicate with arduino with out using arduino software.
    Here you are using arduino software to make arduino read the data written to the arduino file. What should I do eliminate this part and write the whole commands in C/C++(may be using some .dll file) ?
    Thank you.

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