EasyTransfer Arduino Library

Posted in Arduino Libraries by Bill
30 May 2011
EasyTransfer Arduino Library

The purpose of this library is to make it easy for the everyday Arduino user working on projects with multiple Arduinos communicating with each other and sharing data. I had many people ask me for the code I used in my PS2X library example that sent PS2 Controller values wirelessly to my SAGAR robot. It got to be tiresome answering the questions and I had an idea to write a library to help the inexperienced with micro controller communications. This is a easy to use and no frills way to send data between two Arduinos.

In most of my own projects I define and write my own NMEA standard communication protocols. This makes communications human readable and easy to debug, but proves wasteful with bandwidth and processing power so it’s not right for every application. Binary communications is much more efficient and versatile, but requires careful handling. This library abstracts the finer points of packetized serial communication away from the user so it easy to use and understand.

To use the library, simple define all the data types you want to share inside a data structure. This keeps all the data stored together in memory.

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to send
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int blinks;
  int pause;
};

When requested, the library will send all the binary data in the structure to another Arduino via serial with a checksum to avoid transfer errors.

void loop(){
  //this is how you access the variables. [name of the group].[variable name]
  mydata.blinks = random(5);
  mydata.pause = random(5);
  //send the data
  ET.sendData();
  delay(10000);
}

The receiving Arduino will verify the checksum, and copy the new data onto a identical structure in it’s memory.

void loop(){
  //check and see if a data packet has come in. 
  if(ET.receiveData()){
    //this is how you access the variables. [name of the group].[variable name]
    //since we have data, we will blink it out. 
    for(int i = mydata.blinks; i>0; i--){
      digitalWrite(13, HIGH);
      delay(mydata.pause * 100);
      digitalWrite(13, LOW);
      delay(mydata.pause * 100);
    }
  }

  delay(2500);
}

It’s important to make sure the structure is the same on both Arduinos for this to work. Now sharing data between Arduinos is easy without having to define and program your own communications protocol and have to worry about syncing or transmit errors. EasyTransfer will do that for you.

Using Structures to hold the data allows for versatile communications by allowing any type and number of data points to be shared, as long as the whole structure is under 255 bytes. You could define int’s, arrays, longs, etc inside the structure and share the data. It’s also possible to create two way communications by defining two sets of structs on each end and creating two objects using the library. I will have an example of that up shortly.

You can download the library and example below. The example requires two Arduino boards to be connected to each other via their Uarts. One will create two random numbers and send the data to the other that will flash out a sequence of flashes based on those numbers. The first one will also flash out the same sequence.

Now it’s easier to pick which Serial port to use; Serial, Serial1, etc. AND support for the NewSoftSerial library for creating software serial ports on any pin. EasyTransfer is for hardware serial, SoftEasyTransfer is for software; each has there own set of examples. There’s also an example for two way communications using the library.

Source Code available on GitHub project pages.

 

Or Direct Download

 

UPDATE

Thanks to Kumy, there’s now an I2C version of EasyTransfer. There’s also an experimental VirtualWire version for use with those cheap low frequency radios. All are in the single download zip file above.

 

To install the Library, open the zip file and transfer the EasyTransfer folder into your Arduino ‘libraries’ folder. Then follow the examples to add the code to your project. If you have any problems or questions, let me know in the Support Forum.

Need Help?

Please use the Support Forum to ask for help. Don’t use the comments below.

 

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Share

Trackbacks / Pingbacks

  1. Guide to Arduino and AVR Communications
  2. [Arduino] Arduino to Arduino Serial Communication | Billwaa's Blog
  3. [Arduino] Arduino to Arduino Serial Communication | Billwaa's Blog
  4. Using i2c and an ExtraCore to increase your I/O capacity | AuthenticInvention

Warning: count(): Parameter must be an array or an object that implements Countable in /homepages/46/d285670699/htdocs/bill/wp-includes/comment.php on line 879
  1. 443 Comments.

    • amr hamedNo Gravatar says:

      the servo.h & easytransfer.h can’t appear when the reply , any way see the previous code

      cheers

    • JoshNo Gravatar says:

      Would it be possible to use EasyTransfer to send data over a Ethernet link, IE two arduinos using the ethernet shield sharing data by sending the packets over ethernet instead of serial, i2C or similar?

    • Jack EdwardsNo Gravatar says:

      I am building an autopilot for a sailboat. I use a Pololu IMU-9 for heading reference and a GPS for actual course over ground. The IMU-9 runs at 50 Hz. The GPS at 1 Hz. Running the GPS on the same board as the IMU-9 slows the IMU-9 way down. I put GPS interface on a separate board (UNO) and use EasyTransfer to send the data.

      This is the data structure:
      float SD_course;
      float SD_course_to_steer;
      char SD_CTS_MorT[2];
      float SD_SOG;
      float SD_MagVar;
      float SD_XTE;
      char SD_XTE_LR[2];
      char SD_XTE_unit[2];
      char SD_Waypoint_next[9];
      boolean SD_NEMA_sentence;
      boolean SD_GPRMC_fix;
      boolean SD_GPAPB_fix;
      float SD_Bearing_origin_to_destination;
      char SD_BOD_MorT[2];
      long SD_UTC;
      Most of the time this works well then every few minutes the Receive board (MEGA 2560) crashes. If I comment out the Structure “char SD_Waypoint_next[9];” no crashes.

      Problem seems to be how to send varible length strings shorther than the declared Char Array size.

      I do the following:

      DECLARATION:
      String Waypoint_next = ” “;

      PARSING NEMA 0183 data:

      token = strtok_r(NULL,search,&brkb); //Destination Waypoint ID
      mydata[10] = token;
      Waypoint_next=mydata[10];
      if(Waypoint_next == “”)
      Waypoint_next = “NO WPT”;
      Waypoint_next.toCharArray(ETdata.SD_Waypoint_next,9);

      Any thoughts on what my problem is or ways to fix it.

      • BillNo Gravatar says:

        The simplistic beauty of my library is it doesn’t care what is inside the struct. It only grabs all the raw 1’s and 0’s in the memory where the struct is stored and sends it to another Arduino that copies the data directly to memory where an identical struct is stored.

        So commenting out char SD_Waypoint_next[9]; makes no difference to how my library works, other then it’s just sending 9 less bytes. SO I doubt the problem is related to my library or how you use it. I bet it’s with how you are accessing that 9 byte array.

        Since it’s the receiving Mega that is crashing, post the code that uses the char SD_Waypoint_next[9]; array. Also, do you have another serial port on the Mega that could be used to print debug messages, so you could see where in your code it’s crashing?

        • amr hamedNo Gravatar says:

          Hello Bill does this library works with Xbees

          cheers – amr

        • Jack EdwardsNo Gravatar says:

          I would be glad to upload the code but I don’t know how other than send an encosure or upload to Goggle docs. The code is in 17 tabs, cut and paste doesn’t seem like the way to go.

          How do you recommend transfering varible size String data. In my code I use
          Waypoint_next.toCharArray(ETdata.SD_Waypoint_next,16);

          Maybe there is a better way.

          I am packing to leave to go to the sailboat where I will install and test the autopilot. First will be to test stable steering to the Pololu MiniIMU-9 compass heading. Then I will test to see if it will steer waypoints from the GPS. The current code with the waypoint transfer commented out is stable so I will start with that. I am telling this only because if someone responds and I don’t get back to them it may be because I am travelling.

          Thanks for the help,

          Jack

          • Jerry IsdaleNo Gravatar says:

            I was working a similar GPS use of the lib. My approach is to use a fixed length string in the structure. When you fill it, first zero the array, then use strncpy() or similar to copy only the valid text up to the max-1 (to insure null terminated C string). When you empty it, use strncpy() again to insure you dont overwrite the other buffer.

            Basically you should ALWAYS check array bounds when dealing with C strings. Buffer overflow could easily be the cause of the crash you are seeing. It is also one of the primary entry points used to break into net applications.

    • Jack EdwardsNo Gravatar says:

      I believe I have the problem fixed thanks to everyone.

      The Send Data reads the GPS NEMA item and loads it to an array as follows:

      token = strtok_r(NULL, search, &brkb); //Destination Waypoint ID
      mydata[10] = token;
      Waypoint_next=mydata[10];
      if(Waypoint_next == “”)
      Waypoint_next = “NO WPT”;
      Waypoint_next = Waypoint_next + Nullstring; // pads out the length of waypoint next
      Waypoint_next = Waypoint_next.substring(0,9); //Trims waypoint next to 10 Char
      Waypoint_next.toCharArray(ETdata.SD_Waypoint_next,11); //allows null termination

      On the Receive end I had been doing this:

      Waypoint_next = String(ETdata.SD_Waypoint_next);

      This caused crashes.

      The following works:

      Waypoint_next = ETdata.SD_Waypoint_next;
      Waypoint_next.trim();
      the difference being:
      1. in the first place the conversion from char to String was explicit, and it didn’t work.

      whereas: 2. the implicit conversion worked.

      Not sure why, but thanks for the help.

      Next step is to go install the Autopilot on the boat and test it.

    • […] Arduino to Arduino data transfer – this type of communication could be really useful. One example would be to hook several cheaper data gathering circuits together and send the data back to a more expensive Ethernet capable Arduino. […]

    • AntonyNo Gravatar says:

      Hi Bill.
      I am using your Easy Transfer with no issues. 🙂
      But I have a Question… On the transciever chip there is a pull high to transmit. .. Is this not needed in you code ?? I cannot find it anyware.
      Many thanks Antony

      • JoshNo Gravatar says:

        Antony,
        Are you talking about an RS485 or similar chip? If so it is my understanding you just wire the TX Enable pin to TX and that goes high to enable transmit.

        • AntonyNo Gravatar says:

          Hi Josh
          What I have are two of http://www.olimex.cl/pdf/MINIRS422.pdf
          I will be using the RS485 as I only have 2 wires spare.Earth is already there.
          So what you are saying is wire the Dir (TX Enable) pin on the RS485 board to the TX on the Arduino ??… Are you sure ??
          BTW this is for a RoV with 100 Mtr ubblicle cable.
          I thought I would need to pull the Dir high to transmit.
          Regards Antony

    • HyderNo Gravatar says:

      Hello. Fantastic libraries. I was wondering, can I have one Arduino implementing both the Serial and i2c versions of the libraries in one sketch? So it sends out the same exact data, but through both serial and i2c?

    • MilenaNo Gravatar says:

      Hi, Bill! Your library really saved my life in a project. I’d like to know if I can use it to communicate 3 arduinos, instead of only 2. Thanks in advance!

    • blbeggsNo Gravatar says:

      Can an arduino mega using EasyTransfer transfer to an arduino Uno recieving with SoftEasyTransfer? Or do both board have to use the same version of ET?

    • Jack EdwardsNo Gravatar says:

      Very definitely. I use an UNO to read a GPS then send the parsed data to a Mega 2560 for navigation. I do this because the autopilot on the Mega uses a Pololu MinIMU9 gyro compass operating at 50Hz and the GPS operates at 1 Hz and was interfering with the IMU9 processing. Now the Mega accesses the the GPS each second using ET but only uses a few milliseconds to receive the data. I just posted a description of this project today under the title Marine Autopilot in the Arduino forum.

    • […] an easy method for transferring data from one Arduino board to another using Bill Porter’s EasyTransfer Library. Here’s a traditional method on how you hook up Arduino’s serial ports. TX to RX, RX to […]

    • SteveNo Gravatar says:

      Hey Bill! Thanks for your amazing work to date! We created the motorized hammock, and now we’ve created a new LED light show with your great code, the PS2X and This EasyTransfer library!

      The hardware is simple, RS485 MAX485 IC on one arduino MEGA 2560 master, and 8 Arduino UNOs in parallel on the RS485 network – aka they all see the same data from the master arduino.

      We managed to get some code to work, but originally I was trying to use a large array of bytes to send the LED tower RGB values for each box. Being 8 towers with 8 boxes total, this is 3×64 bytes when I use one byte for each R,G,B for each ‘pixel’ which should’ve still been under the 255 Byte limit, however I couldn’t get data on the arduino UNO slave side.

      I’d like to get this code working, because the other code I implemented is horrible in my opinion. You can see the light show we’ve created on our website: http://www.northstreetlabs.org/BackToTheHippodrome.html

      • BillNo Gravatar says:

        Have you tested the rig with a smaller data payload to see if they communicate then? That will verify it’s a size issue. Email me at the address in the footer of the page and I’ll see what I can do to help.

    • […] explore an easy method for transferring data from one Arduino board to another using Bill Porter's EasyTransfer Library. Here's a traditional method on how you hook up Arduino's serial ports. TX to RX, RX to TX, Ground […]

    • […] used the Easy Transfer library which in turn uses the built in Wire library. I ran into some problems when trying to use […]

    • DDeaNo Gravatar says:

      Hi Bill,

      have been Using your Lib for ages, especially after you tweaked it to work with Attiny Chips.

      What I am trying to do now is create a Web Relay Node, I have the sketch working fine but due to the html coding I would like to use a loop function to call up the data stored in the Data Structure without having to manually input the name.

      Can this be done?

      • BillNo Gravatar says:

        Ddea, I’m not sure what you are trying to do. Send me an email to the address at the bottom of the page with your code so far and the explanation of the function and I’ll see if I can help.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.