Saturday, May 11, 2013

Arduino: Serial Communication Between Two Arduinos

I wanted to know more about inter-Arduino communication, so I did this project. I want to explore the different ways to communicate with and between Arduinos.

First up is serial communication. This is pretty simple. I expected there to be more hitches, but it turned out to be pretty straight forward. Well let's get to it.

First things first, HERE is the Arduino playground page for serial communication. You might want to read up on the different commands you have there.

Ok, first program. One Arduino transmits one integer every second counting from 1 to 10. The receiving Arduino then prints that number to the COM port where I can see it.  I only have one Arduino with a working USB to serial interface, so I used it as the Rx.

The code is simple enough. You can get mine HERE, but I would encourage anyone to try to write it yourself. It helps, and this is short enough. The only unexpected detail is the parseInt(). I first tried a simple read(). Well that doesn't work because that displays the ASCII character and not the integer value. I had forgotten that.

To wire it up, simply connect Tx (probably pin 1) of the Tx board to the Rx (probably pin 0) of the Rx board. Then connect a common ground between the two. Note that you may need to connect these pins after you load the program on the Arduino (since you are using that pin to communicate with the computer via the USB to serial chip). Leaving them connected caused an error for me. This might be avoided if you put a resistor in between the 2 boards, but I have not tried. By the way, if you're wondering where I got that super cool Tx Arduino, check out THIS post. It was really cheap fun!

Left: Rx                         Right: Tx
Well that was cool. Now I want to go the other way. The next program blinks the LED on the Rx board a specific number of times entered through the Serial Monitor connected to the Tx board.

The code again is not that difficult. HERE is mine. Again, use parseInt() and you're golden.

The wiring is equally simple. It's the same as you just did except in reverse the two boards. In fact, if you had two "real" Arduinos with an FTDI or similar, you wouldn't even need to do that. Just make sure you wire in the common ground as always.

Left: Tx                       Right: Rx

Well that's great and all, but I want to communicate both ways. Next program. This one takes an integer value from a user input through the Serial Monitor and then sends it to the Rx Arduino. The Rx then adds 5 to the integer an sends it back to the Tx. Note that the Tx and Rx labels are a bit arbitrary in this one. It's more of a master-slave relationship.


HERE is my code if you want it.


Wiring is similar to above. However, I used Serial1 on the Tx to communicate with the Rx board. This just kept the USB communication from interfering. This functionality is only available on the Arduino Mega as far as I know (besides 3rd party boards). See the Arduino Documentation linked at the beginning of this post for more details. It's also interesting to note that I noticed I didn't need to power the Rx board for it to work. It would draw power from the Tx pin. That was interesting. I powered it anyway.


Ok.  Last program. This one only uses one Arduino. It allows you to input a word , and it mirrors it back to you. Now this is not all that impressive in itself, but it is still very useful.

There are only a few major changes to the code we have been using. We need to make the variables we use char variables. Also we need to change the parseInt() to a plain read(). Another note, remember that serial is one bit at a time. So if you want to do a line return, you need to handle that yourself. I made it do one every time it saw a period. \n would be more traditional, but that was more work.

HERE is my program. It is pretty simple, but I am not a programmer. If your program is doing anything else you will probably want to use a char string. THIS looks like a good example of this.

Wiring nonexistent. Just connect your Arduino via USB.

That's all I have for now. Hope this was useful! If you want the full package of programs you can get them in zip HERE. Also, if you want to learn about serial communication with an ATtiny (a $2 microcontroller) check that out HERE. If you are looking for something else, try my communication label. There may be something in there that will interest you.

-Matthew

18 comments:

  1. Hi and THANK YOU! This solved a huge problem for my little project. I am however getting something strange with your first setup here. My TX board sends a value of 85 every second which my RX board receives just fine. However my RX board also prints a 0 every half second (in between the 85s) This is the serial output from my RX board to my console:

    0
    85
    0
    85
    0
    85
    0
    85
    0

    Any idea where that 0 comes from?

    ReplyDelete
  2. Actually....small update...
    Seems my TX sends 85 every 2 seconds. If i reduce that time to 1 second i dont get that extra 0. For some reason....

    ReplyDelete
  3. I went back and looked at the code and didn't see any reason for the extra 0. Without seeing your Tx code it is hard to say though. It seems especially odd that changing the delay effects it.

    Perhaps the problem is the Serial.print. That sends 2 bytes. Maybe that is causing some problems. Since writing this post I have wizened up a bit.

    Try this, change the Tx print to a serial.write. This will only send 1 byte without doing an ASCII conversion. Then you can just do a serial.read on the Rx side. This will of course only give you a value of 0-256, but if you need a larger one you can concatenate them manually (see http://projectsfromtech.blogspot.com/2013/09/combine-2-bytes-into-int-on-arduino.html).

    Maybe that will solve it.

    ReplyDelete
  4. i tried with the placed code for serial communication between 2 arduino controllers.
    All the times i am able to send ,but not even once i am able to successfully reecieve
    exchanged the TX and RX controllers also .still same problem exists.
    some one help me my am i not able to receive it.

    LED 13 is blinking for TX controller when data is getting transmitted

    ReplyDelete
  5. Could you provide some more details? What boards are running the Tx and Rx sketches? What pins are connected? Are you powering them via usb or external power?


    Note that the Tx code has 2 serial ports open. One communicates with your computer and one communicates with the other board. The LED blinks every time the Tx board sends data through the USB to your computer (through pin 1 on most Arduinos). However, if it is wired the way I did it the number being sent to the other Arduino is getting sent via Serial1 which is a different pin and not connected to the LED.

    ReplyDelete
  6. can you teach me how to send data (sensor value) from arduino 1 to arduino 2? using serial? iam confused . thx :D

    ReplyDelete
  7. Check out the Serial label. It has some other posts that might be useful to you if this one isn't cutting it. http://projectsfromtech.blogspot.com/search/label/Serial


    If something is unclear let me know, and I will try to explain it further.
    -Matthew

    ReplyDelete
  8. i mean, i like your code "adds five" but, iam still confusing,
    how if what value i send is from analogpin? (data beetween 0-1024 like from potentiometer) and i then send it to another arduino to move the servo? thank you bro :) , perhaps you can help me , iam newbie huhu >.<

    ReplyDelete
  9. Well you could do something like Serial.print(YourSensorData);


    Then on the receiver side,
    ReceivedSensorData = Serial.parseInt();


    print and parseInt should take care of the fact that you will have to send 2 bytes to represent 1024. This is probably not the most efficient approach, but it works. Alternatively you could map the value down to 0- 256 and use serial.write and read instead. Or take care of the combining the 2 bytes yourself.


    The adding five was just to make sure the Receiving Arduino was actually getting the value. I wanted the value returned to be distinct from the input.

    ReplyDelete
  10. please give me some example please..... :(

    ReplyDelete
  11. Tx Arduino:
    Serial1.print(analogRead(analogInPin));

    Rx Arduino:
    int Value = Serial1.parseInt();



    You might have better luck posting on the Arduino forum. There you can give details about your project and people can suggest solutions. All I can do is tell you one way to send data over serial. Reasons why it might not be working are infinite and dependent on your setup of which I have no knowledge.

    ReplyDelete
  12. thanks dude, i success to send data from arduino 1 to arduino 2, (only data from 1 sensor)
    how if i wanna send data from 2 sensor, ? how to separate it?

    ReplyDelete
  13. Well I'm not a software programmer, so I don't know the "correct" way of doing it. Google may provide better answers, but I can tell you how I've done it.


    I've done stuff like sending an identifier before each value. For instance, I map the sensors to a value from 0-100 then I'll send this.


    105 [sensor 1 value] 106 [sensor 2 value] etc.


    Then I know if I read a byte and its 105, the next byte I read will be sensor 1. You get the idea.


    Another way, I have done the same thing except with just an identifier to mark the first sensor (in this case 128). e.g.


    128 [sensor 1 value] [sensor 2 value] ... [sensor last value]


    This has worked well for me in the past. Just make sure that whatever your identifier is, it will never be included in the data packets.


    If you want examples of where I have done this, I know one of these methods is used in the serial HC-SRO4 controller post. Again, check out the Serial or communication label.


    Like I said, both of these methods are approaches that I just came up with. They aren't rooted in textbooks or efficiency. For stuff like that, you'll have to ask someone more knowledgeable than I.

    ReplyDelete
  14. i am using two arduino mega and two nrf24l01 wireless transceivers. i want to communicate from one arduino to another using nrf24l01 transceivers but it does not work, actually i want that when i send any data or code from first arduino's serial monitor, it should receive by second arduino serial monitor. help me. what should i do?

    ReplyDelete
  15. Thanks a lot! With the examples that was really easy. Cheers !

    ReplyDelete
  16. How would i go about being able to send words over the serial communication, assuming I had two computers open with the serial monitor? I have tried the code from this one instructable, but it doesnt seem to work.

    ReplyDelete
  17. i am facing the problem with the codes. both Tx and Rx are working individually separately when i changed the code... but they are not to communicate with each other...i am working with 2 Intel galileo boards here.

    ReplyDelete
  18. suvimali hettiarachchiJune 29, 2015 at 3:45 AM

    i need to transfer data string between two arduinos.one arduino connect with sensor and another arduino connect with lcd display. I suppose to read sensor reading from lcd by using RX and TX pinsin mega could you please help me to find some code for that.Thank you

    ReplyDelete