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. TIMO TOOTS | Elektron
  2. Adding a lot of twinkle to this rebar sculpture - Hack a Day

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.

    • Jeremy StewartNo Gravatar says:

      Will SoftEasyTransfer work with EasyTransfer? ie: (One arduino I need to use softwareSerial.. and the other I’m using the hardware serial pins.

      (Doesn’t seem to be working for me at the moment.

      • BillNo Gravatar says:

        It should. Are you trying it with the example sketches from each library?

        • No, I was giving it a try with my own code, but it’s very difficult to debug since I am using the hardware serial pins. Now at least I know that it’s supposed to work, so I’ll play with it until I can figure out what’s going on.

          I’m using multiple calls of the library.. for example:

          This is some snippets of code.. I’m using four.. so I can have four different structures. Not sure if this is the best method, but I can’t see why it wouldn’t work.

          I tried to show all relevant lines.. the receiving side looks similar, except I used Easy Transfer instead of softeasytransfer.
          I called my NewSoftSerial pins commSerial.
          Hopefully this isn’t too confusing.

          #include

          EasyTransfer arduinoPID;
          EasyTransfer arduinomPID;
          EasyTransfer arduinopPID;
          EasyTransfer arduinoBAL;

          struct RECEIVE_DATA_STRUCTURE_PID{
          float Pin,Iin,Din;
          };

          struct RECEIVE_DATA_STRUCTURE_mPID{
          float mPin,mIin,mDin;
          };

          struct RECEIVE_DATA_STRUCTURE_pPID{
          float pPin, pIin, pDin;
          };

          struct RECEIVE_DATA_STRUCTURE_BAL{
          float Bin;
          };

          RECEIVE_DATA_STRUCTURE_mPID inPacketmPID;
          RECEIVE_DATA_STRUCTURE_pPID inPacketpPID;
          RECEIVE_DATA_STRUCTURE_PID inPacketPID;
          RECEIVE_DATA_STRUCTURE_BAL inPacketBAL;

          void setup()
          {
          arduinomPID.begin(details(outPacketmPID), &commSerial);
          arduinopPID.begin(details(outPacketpPID), &commSerial);
          arduinoPID.begin(details(outPacketPID), &commSerial);
          arduinoBAL.begin(details(outPacketBAL), &commSerial);
          }

          void loop()
          {

          if(digitalRead(butPin1) == HIGH)
          {
          outPacketBAL.Bin = Bin_new;
          lcdSerial.print(0xFF,BYTE); delay(5); arduinoBAL.sendData(); lcdSerial.print(0x0D,BYTE);delay(1000);
          }
          }
          }

        • Here are relevant snippets from my code:

          **** START OF SENDING ARDUINO CODE *******
          #include
          #include

          #define BAUD 57600

          //SERIAL PINS
          const int commTxPin = 3;
          const int commRxPin = 2;

          NewSoftSerial commSerial = NewSoftSerial(commRxPin, commTxPin);

          SoftEasyTransfer arduinoPID;
          SoftEasyTransfer arduinomPID;
          SoftEasyTransfer arduinopPID;
          SoftEasyTransfer arduinoBAL;

          struct SEND_DATA_STRUCTURE_PID{
          float Pin,Iin,Din;
          };

          struct SEND_DATA_STRUCTURE_mPID{
          float mPin,mIin,mDin;
          };

          struct SEND_DATA_STRUCTURE_pPID{
          float pPin,pIin,pDin;
          };

          struct SEND_DATA_STRUCTURE_BAL{
          float Bin;
          };

          SEND_DATA_STRUCTURE_mPID outPacketmPID;
          SEND_DATA_STRUCTURE_pPID outPacketpPID;
          SEND_DATA_STRUCTURE_PID outPacketPID;
          SEND_DATA_STRUCTURE_BAL outPacketBAL;

          void setup()
          {
          commSerial.begin(BAUD); // Set Baud for Arduino Communication

          arduinomPID.begin(details(outPacketmPID), &commSerial);
          arduinopPID.begin(details(outPacketpPID), &commSerial);
          arduinoPID.begin(details(outPacketPID), &commSerial);
          arduinoBAL.begin(details(outPacketBAL), &commSerial);

          }

          void loop()
          {
          if(digitalRead(butPin1) == HIGH)
          {
          outPacketBAL.Bin = Bin_new;
          lcdSerial.print(0xFF,BYTE); delay(5); arduinoBAL.sendData(); lcdSerial.print(0x0D,BYTE);delay(1000);
          }
          }

          ********** END *******

          ****** START OF RECEIVING ARDUINO *******

          #include

          #define BAUD 57600

          EasyTransfer arduinoPID;
          EasyTransfer arduinomPID;
          EasyTransfer arduinopPID;
          EasyTransfer arduinoBAL;

          struct RECEIVE_DATA_STRUCTURE_PID{
          float Pin,Iin,Din;
          };

          struct RECEIVE_DATA_STRUCTURE_mPID{
          float mPin,mIin,mDin;
          };

          struct RECEIVE_DATA_STRUCTURE_pPID{
          float pPin, pIin, pDin;
          };

          struct RECEIVE_DATA_STRUCTURE_BAL{
          float Bin;
          };

          RECEIVE_DATA_STRUCTURE_mPID inPacketmPID;
          RECEIVE_DATA_STRUCTURE_pPID inPacketpPID;
          RECEIVE_DATA_STRUCTURE_PID inPacketPID;
          RECEIVE_DATA_STRUCTURE_BAL inPacketBAL;

          void setup()
          {

          Serial.begin(BAUD);
          arduinomPID.begin(details(inPacketmPID), &Serial);
          arduinopPID.begin(details(inPacketpPID), &Serial);
          arduinoPID.begin(details(inPacketPID), &Serial);
          arduinoBAL.begin(details(inPacketBAL), &Serial);
          }

          Void loop(){
          if(arduinoBAL.receiveData())
          {
          Setpoint = (double)inPacketBAL.Bin;
          }
          }

          **** END *****

          At the moment, I’ve debugged it to the point that I’m not getting inside of the if statement.. so the line arduinoBAL.receiveData() is never equal to true.. even though I am getting to the send commend on send side.

          • Alright,

            So now I’ve figured out that if I comment the three other Easy Transfer calls out of my code.. the one works alone.. so there’s a problem with how I am trying to use four different structures. Is there a way to do this? I’m trying to update specific variables on command..

            So by the push of a button.. update these variables… by a push of another button.. only update these other variables.. I could send a byte to signify which variables I want to update.. but If I’m going to do this.. I figure I might as well write my own protocal? I’d rather limit the amount of work my receiving end has to do as my loop time is important.

            Thanks,
            Jeremy

            • Jerry IsdaleNo Gravatar says:

              EasyTransfer only supports one struct per serial line. You need to merge your packets. Here are two crude examples showing the approach – either a packet that carries one at a time with ‘type’ element to identify which one it is, or a combined struct that holds all values and flags to id which are valid…

              #define Type_PID
              #define Type_mPID
              #define Type_pPID
              #define Type_BAL
              struct OneAtATime {
              int type;// value defines if data below is Type_xxxx
              float pid;
              float lin;
              float din;
              float bin;
              };
              Then your code loads up the appropriate values/type and sends
              on the receive side you test type and set locals appropriately.
              Alternatively, you could have all values in one struct and flags to say if they are valid…

              struct SupportsAllFour {
              boolean PValid, mValid, pValid, BValid;
              float Pin,Iin,Din;
              float mPin,mIin,mDin;
              float pPin, pIin, pDin;
              float Bin;
              };

              clear as mud?

            • BillNo Gravatar says:

              And actually, to clarify, it does support multiple structs per a single serial line but not multiple structs per library object. You created four different library objects all pointing to the same serial port but with different structs. However both the sending and receiving Arduino need to be synced to which struct is being sent.

              In your code you are only sending and receiving from the arduinoBAL object, so really it should have worked. As soon as you tried sending or receiving from another object then things would have gotten squirrely.

              i’ll have to take a better look at your code when I get off work. Maybe I’m missing something.

    • JJ KoolwaterNo Gravatar says:

      Hi BIll.
      I’m relatively new to programming so I don’t truly understand your examples. Could you write an example to turn on an LED with a push button. Like the LED is connected to one arduino and the push button is connected to the other. Thanks

    • PeterNo Gravatar says:

      Hi Bill

      We can move the VirtualWire code from Beta. I have done a days worth of testing on the http://www.seeedstudio.com/depot/315mhz-rf-link-kit-p-76.html 315MHZ Link kit I got from Netram.co.za (In South Africa)
      The code works a charm! This model of radio is non-inverted, so I just commented those lines out in the examples.

      One question though? How much data should I be able to send? Right now I have two analog joysticks (i.e. 4 analog values) and 10 buttons states that I want to put in a structure. Have not tested yet, but wanted an idea of how much data I should be able to fit in. Would it be best to use short name for the variables (eg A1, A2, D1, D2 instead of Direction=(analogRead, 0); Speed=(analogRead, 1);
      And also convert the 0-1024 to 0-255 in code before sending to save a byte each = total of 4 bytes?

      Regards

      Peter
      Itux.co.za

    • Very Clear.

      Thank you.

      I just started trying the exact same thing.. I’m using modes and switch statements anyway.. so it was very easy to implement. Didn’t work on my first attempt, but I’m sure I’ve just got a small mistake somewhere..

      Thank you!

      Jeremy

      • This worked beautifully.. Thank you so much for your help.

        Jeremy

      • BillNo Gravatar says:

        Thanks for helping him out Jerry.

        Yep, that was you problem. If the size of the received struct doesn’t match the one initialized by the library, the function will never return true.

        I’ve daydreamed about adding support for addressed structs so the library would handle multiple types of data just like Jerry is suggesting. I may add it one day, though didn’t think many would find that useful.

        • I actually like this method better. Cleaned up my code a lot for someone else reading it.

          This is a really neat library. I’m going to use it after I’m done this project to try and figure out how to write my own protocols. I had to write one to communicate with a toshiba controller controlling an lcd screen, without checksums. So I get corrupted packets and errors a lot, hopefully I’ll be able to use this library to improve my communications coding in the future. Thank you so much for writing it.

          Jeremy

        • Bill or Jerry,

          Ok. So now I’m a bit baffled. Does it can I use two structures on the same serial port?

          Isn’t that what the send and receive examples do?
          I got send working from one, and receive on the other,
          but I can’t get send and receive from both working now.

          I used two different library calls and initialized them seperatly,
          for example

          EasyTransfer ETin; ETout;

          • Here are some snippets of code from one of my arduinos.

            EasyTransfer ET, ETcurr;

            struct SEND_DATA_STRUCTURE{
            float Bcurr, Pcurr, Icurr, Dcurr;
            int modecurr;
            };

            struct RECEIVE_DATA_STRUCTURE{
            float Bin, Pin, Iin, Din;
            int modein; // Update Mode
            };

            RECEIVE_DATA_STRUCTURE inPacket;
            SEND_DATA_STRUCTURE outPacket;

            void setup(){
            ET.begin(details(inPacket), &Serial);
            ETcurr.begin(details(outPacket), &Serial);

            outPacket.Bcurr = Setpoint;
            outPacket.Pcurr = Po;
            outPacket.Icurr = Io;
            outPacket.Dcurr = Do;
            outPacket.modecurr = BALANGLE;
            ETcurr.sendData();
            outPacket.modecurr = ANGLEPID;
            ETcurr.sendData();
            outPacket.Pcurr = Pp;
            outPacket.Icurr = Ip;
            outPacket.Dcurr = Dp;
            outPacket.modecurr = POSPID;
            ETcurr.sendData();
            outPacket.Pcurr = Pm;
            outPacket.Icurr = Im;
            outPacket.Dcurr = Dm;
            outPacket.modecurr = MOTPID;
            ETcurr.sendData();

            }

            void loop(){
            if(ET.receiveData())
            {

            switch(inPacket.modein)
            {
            case BALANGLE:
            Setpoint = (double)inPacket.Bin;
            break;
            case ANGLEPID:
            myPID.SetTunings(inPacket.Pin, inPacket.Iin, inPacket.Din);
            break;
            case MOTPID:
            motorPID.SetTunings(inPacket.Pin, inPacket.Iin, inPacket.Din);
            break;
            case POSPID:
            positionPID.SetTunings(inPacket.Pin, inPacket.Iin, inPacket.Din);
            break;
            }
            }

            • BillNo Gravatar says:

              Ok, so you are just trying to do 2way comms with 1 struct per direction, yes?

              Send me all your code to the email address at the bottom of the page and I’ll see if I can spot your problem. There is a 2way example in the examples folder. Did you look through that?

          • BillNo Gravatar says:

            Ok, lets make things a bit clearer.

            Can ET do 2-way comms with one struct per direction? Yes, see the 2way example.

            Can ET do 1-way comms with multiple structs in one direction? Sort of. ET itself does not, but the nature of C++ Object Oriented Programing allows you to create multiple ET objects with different structs but the same serial port. If you don’t understand what that means, just stick with once instance of the ET library and put all your data in one struct.

    • “However both the sending and receiving Arduino need to be synced to which struct is being sent.”

      I’m guessing this is the problem I am having now.. Not sure how to sync.. Maybe the problem is that both of my structures are the same size… 3 floats and an int? Maybe I need to make sure they are different sizes so the library can distiguish them?

      • DdeaNo Gravatar says:

        Just my little input:

        How about using Serial.write(0xff) or something else and use that to identify the correct struct.

        That’s what I would try!

        Ddea

        • Just write it inside the structure?..
          Wouldn’t I need to create a variable inside the structure equal to 255? or 0xFF or whatever?

          • BillNo Gravatar says:

            If you were trying to do 1-way comms with multiple structs, Ddea’s idea is one good way to go about it. Doing it inside the struct would not work because the ET library would drop mis-matched structs before the end user could do anything with it.

            But I think you are having trouble with 2-way comms, so this is not related. Sorry for the confusion.

      • BillNo Gravatar says:

        If you are still just trying 2way comms with one struct per direction, no that’s not your problem. My comment refers to what you would have to do to make multiple structs work in one direction.

        • I’m just trying to make either two structures work in two directions (one in each direction).. or one structure two directions… either one. I looked at the two way example, and I thought I mimicked it correctly. The example uses two structure, one for each direction. Which is what I thought I had done?

          One structure, in one direction works fine. Now i just need to get the other direction working.. I tried using two library objects and a second structure.. as I showed in my code above and I can’t get ETcurr.readData() on the other end to come true. I feel like this is exactly what the examples do?

    • Sorry, I mean if(ETcurr.receiveData())

      • Jerry IsdaleNo Gravatar says:

        Your snippet sends all the data in setup() and then hangs out in loop() waiting for data from other side. Thus the data only gets sent once – at startup. If the other side is not up and running it might miss the data.

        Is other side code similar? If so and you reset them both at the same time, they would both send a whole bunch (perhaps colliding on serial wire) and then sit waiting forever.

        Bill’s 2 way code does all the send/receive in loop() : send(), rcv(), rcv() rcv() rcv() rcv() delay(). With lots more receive than send (5:1).

        Your code might have a mod 4 counter in loop and send 1 of 4 each time…

        int sendType = 0
        loop()
        {

        sendData(sendType);
        sendType++;
        if (sendType%4==0) sendType = 0;

        for (int i=0;i<5;i++)
        receiveData();
        }

        sendData(int type)
        {
        switch (type)
        {
        case A: loadAData; break;
        case B: loadBData; break;

        }
        ETsender.sendData();
        }

        recieveData()
        {
        if (ETrcv.receiveData())
        { switch to unload}
        }

        • BillNo Gravatar says:

          He also is using ET on a newSoftSerial port alongside 1 and 2 other newSoftSerial ports (depending on which Arduino) all running at 57,600 baud. I think this is dangerous alone yet worse, one of the Arduinos has both external interrupts enabled for encoder counts. I think he’s running into a interrupt resource conflict.

          If a encoder moves right when a bit needs to be read off the softserial port, the bit on the serial port may be lost and the whole packet corrupted. The Arduino with 3 softSerial ports has just 17 microseconds to read all three bits or risk loosing one.

          • Jerry IsdaleNo Gravatar says:

            wow that is pushing it. Thats where I’d drop in a teensy, ProMini or similar simple micro to handle some of the interrupt intense devices, and send data out as EasyTransfer packets at a reasonable rate (50-200Hz should be adequate for most UI apps)

            EasyTransfer makes such data acquisition schemes pretty easy. An I2C or SPI approach could work for multiple sensors on single line with significant extra work, if you are serial port limited.

          • One of my arduinos (newsoftserial) is sitting in a while loop waiting to receive.. so that arduino is doing nothing but looking for a packet to be received.

            The other arduino is using hardware serial, and sent out in the setup phase, which I could make send before the interrupts kick in. (going to try right now). So far I’ve had no luck.

            Sending in the other direction works perfectly, from newsoft to hardware. During the main loop (ie: While my interrupts and everything else is happening).

            • BillNo Gravatar says:

              Just because your main code is sitting in a while loop doesn’t free up any resource time from your interrupts. While you sit in that loop, all the newSoftSerial ports are firing interrupts at 57,600 rate. Not to mention any other interrupts that fire from the Arduino API. Time keeping, hardware serial, etc.

              “from newsoft to hardware” is actually the easy way and less prone to resource conflicts. A hardware serial port only fires an interrupt when a whole byte (8 bits) has come in. newSoftSerial fires an interrupt when every bit should be read. IE, needs a lot more time to process.

            • Jerry IsdaleNo Gravatar says:

              As I understand your comment –

              The conversation that fails is the one whose sender operates on hardware serial and sends only in setup(), and listener is on softSerial and constantly listening.

              Question1: it only sends during setup()? No sends in loop()?
              Question2: the receiver is fully operational (i.e. in loop() ) before sender is started (i.e. enters setup() )?

    • Question 1: Only sends during setup.. I send it four times (changing the variables around, with delays during the sends.

      Question 2: The receiver is waiting in a while loop.. I’m not exactly sure on the timing… but I know that the receiver is waiting to receive before the sender sends.. and is still waiting… well.. it waits forever, because it never receives anything.

      Two Arduinos

      arduino A:

      HARDWARE Serial
      Uses intterupts
      Sends in setup only

      Arduino B:
      NewSoftSerail (yes three of them)
      Receives in a while loop (inside of setup) until it has recieved.

      This me attempting a second ET library object for the second direction. The first direction Arduino B to Arduino A works fine on it’s own. I’ve been trying to implement the other direction, and I have no luck.

      I just tried taking the interrupts and the other NewSoftSerial ports out of the picture, it still doesn’t work. Next I’m going to try lowering the baud rate and checking for bad checksums.

      • BillNo Gravatar says:

        Has A to B ever worked without the B to A ET added?

      • BillNo Gravatar says:

        BTW, did you look at the recent changes to NewSoftSerial?

        From the example:

        // Start each soft serial port
        ss.begin(4800);
        ss2.begin(4800);

        // By default, the most recently “begun” port is listening.
        // We want to listen on ss, so let’s explicitly select it.
        ss.listen();

        // Simply wait for a ? character to come down the pipe
        Serial.println(“Data from the first port: “);
        char c = 0;
        do
        if (ss.available())
        {
        c = (char)ss.read();
        Serial.print(c);
        }
        while (c != ‘?’);

        // Now listen on the second port
        ss2.listen();

        I don’t recall seeing the listen functions in your code.

    • I’m starting to think this is not the major problem.. I tried lowering my baud rate.. interrupts and other NewSoftSerial objects are out of the picture.. so my code is something like.

      Arduino A:

      EasyTransfer ET;
      EasyTransfer ETcurr;

      struct SEND_DATA_STRUCTURE{
      float Bcurr, Pcurr, Icurr, Dcurr;
      int modecurr;
      int o;
      };

      struct RECEIVE_DATA_STRUCTURE{
      float Bin, Pin, Iin, Din;
      int modein;
      };

      RECEIVE_DATA_STRUCTURE inPacket;
      SEND_DATA_STRUCTURE outPacket;

      void setup()
      {

      Serial.begin(9600); // Set Serial BaudRate for Rx/Tx Pins and for serial monitor

      ET.begin(details(inPacket), &Serial);
      ETcurr.begin(details(outPacket), &Serial);

      sendGains();

      …. *** It continues ****}

      void sendGains(){
      delay(2000);
      outPacket.Bcurr = Setpoint;
      outPacket.Pcurr = Po;
      outPacket.Icurr = Io;
      outPacket.Dcurr = Do;
      outPacket.modecurr = BALANGLE;
      ETcurr.sendData();
      delay(500);
      outPacket.modecurr = ANGLEPID;
      ETcurr.sendData();
      delay(500);
      outPacket.Pcurr = Pp;
      outPacket.Icurr = Ip;
      outPacket.Dcurr = Dp;
      outPacket.modecurr = POSPID;
      ETcurr.sendData();
      delay(500);
      outPacket.Pcurr = Pm;
      outPacket.Icurr = Im;
      outPacket.Dcurr = Dm;
      outPacket.modecurr = MOTPID;
      ETcurr.sendData();
      delay(500);
      }

      END

      ARDUINO B:

      NewSoftSerial commSerial = NewSoftSerial(commRxPin, commTxPin);
      SoftEasyTransfer ET;
      SoftEasyTransfer ETcurr;

      struct RECEIVE_DATA_STRUCTURE{
      float Bcurr, Pcurr, Icurr, Dcurr;
      int modecurr;
      int o;
      };

      struct SEND_DATA_STRUCTURE{
      float Bin,Pin,Iin,Din;
      int modein;
      };

      SEND_DATA_STRUCTURE outPacket;
      RECEIVE_DATA_STRUCTURE inPacket;

      void setup()
      {
      Serial.begin(BAUD); // Set Baud for Bluetooth Communication
      commSerial.begin(9600); // Set Baud for Arduino Communication

      ET.begin(details(outPacket), &commSerial);
      ETcurr.begin(details(inPacket), &commSerial);

      getGains();

      *** it continues…***}

      void getGains(){

      void getGains()
      {

      int w = 0;
      int x = 0;
      int y = 0;
      int z = 0;

      while(w + x + y + z != 4)
      {
      if(ETcurr.receiveData())
      {
      setupMode();

      if (inPacket.modecurr == BALANGLE)
      {
      Bbcurr = inPacket.Bcurr;
      w = 1;
      }
      if (inPacket.modecurr == ANGLEPID)
      {
      Ppcurr = inPacket.Pcurr;
      Iicurr = inPacket.Icurr;
      Ddcurr = inPacket.Dcurr;
      x = 1;
      }
      if (inPacket.modecurr == POSPID)
      {
      pPcurr = inPacket.Pcurr;
      pIcurr = inPacket.Icurr;
      pDcurr = inPacket.Dcurr;
      y = 1;
      }
      if (inPacket.modecurr == MOTPID)
      {
      mPcurr = inPacket.Pcurr;
      mIcurr = inPacket.Icurr;
      mDcurr = inPacket.Dcurr;
      z = 1;
      }
      }
      }

      }

    • Jerry IsdaleNo Gravatar says:

      Bill sent me your full code to examine (more eyes idea). The issue is the sendGains()/getGains() communication, correct?
      (alternative is this works but the loop() send/receive is failing.)

      Assuming its the setup Gain area….
      Have you tried JUST this (i.e. nothing in loop(), no other setup actions )?
      Does anything come thru?

      This may not be an issue yet, but the current send/getGain() is not error tolerant. If you miss one, you wont get all gains and there is no going back. An alternative would be to add some handshake comms:

      sendBangle
      wait for Bangle ACK, if doesnt come in N sec, resend
      send AnglePID
      wait for AnglePID ACK …

      or
      send all… wait for ACK all
      retry after N sec

      only after ArduinoB has acknowledged receipt of gains do both go forward to setup other interrupts, enter loop(), etc.

    • Jerry,

      yes. I am able to communicate across the serial lines without the use of the library. I just tested it out. I’m trying to figure out how to add print lines into the library so I can test where the the fault is.

      Jeremy

      • Jerry IsdaleNo Gravatar says:

        To edit the library, you need to edit the EasyTransfer.cpp file in your Arduino/libraries area (its where you installed it). You could also copy the .cpp and .h files to your project folder, close and reopen the folder – then it will (should) use the local version of library.

        note that you will now be using C++ and may not have Serial.println().

        • BillNo Gravatar says:

          All Arduino libraries have to include either WProgram.h or Arduino.h that bring in all the Arduino API functions to be used in the library. So Serial.println() will work fine.

    • deancornellNo Gravatar says:

      Howdy bill,
      Great work putting this library together. I am new to Arduino, and programming in general, and I am trying to apply what little new-tech knowledge I have to building a robot. I have a Arduino Fio acting as a remote controller and a Arduino Mega acting as the brains of the robot. at present I have working code that reads 3 potentiometers attached to the Fio, stores the values to variables in the send struct, and in the Mega I have code that reads and maps those values and drives three hobby servos. The one problem I am having right now is that between a position change on the controller and movement on the servo, there is about a half second of delay (not delayed by a delay statement in the code). In the near future I will have the two communicating via a pair of Xbee radios, but for now I am bench testing on a breadboard, hard-wired at 9600 baud. It works so far, in no small part because of EasyTransfer, but I would like the finished robot to have no latency.

      • BillNo Gravatar says:

        There should not be a delay like that. Make sure the receiving Arduino is checking for new messages much faster then the transmitting Arduino is sending them. Look at the example sketches for comparison. I think the receiving Arduino checks 4 times as often as the transmitting one sends.

        • deancornellNo Gravatar says:

          All I had to do was take out an extra serial.flush on the receiving end (I didn’t know the library did that already), and adjust the delay time on the transmitting end (it was at 10 and 20 during initial tests). I adjusted to a delay of 40ms and it now reacts instantly. I also tested all of this today at 19200 instead of 9600, so I think I’ll go back and check out what delay time it takes to react instantly at 9600.
          You rock Bill!

          • deancornellNo Gravatar says:

            And the good news is; it reacts the same at 9600 and at 19200. Thanks again Bill for writing this wonderful library. And now, off to the shop to do the other half of the build!

          • BillNo Gravatar says:

            Be careful with serial.flush() They completely changed what it means in 1.0. It now pertains to the transmitting buffer and not the receiving buffer.

            Increasing the transmitting delay is probably what fixed it. If the transmitting arduino is sending messages too fast, messages will get buffered by the receiving arduino and add perceived delay.

            • deancornellNo Gravatar says:

              I figured that’s what did it too, I messed around with the timing on the transmitter and it varied a bit. I’ve stuck with version Arduino IDE 0022 for now, since I heard of a few bothersome bugs from early adopters.

    • […] SOFTWARE custom scripts, ShiftPWM library, EasyTransfer library […]

    • PhDNo Gravatar says:

      Hi, I will test the lib between 2 arduino’s (328p & 1280), using an RS485 driver and line. I tested TX to RX (TX is hardware serial, RX is software serial), and this works fine. Now I’ll try master to slave then slave reply to master…:) will let you know.

      • PhDNo Gravatar says:

        I did test the lib, using finally two MEGA1280 arduino’s, and RS485 (with LTC485 chip), in send and receive mode. It works fine and rather fast. One problem though to take into account: if a system sends a message, it loops back in its own input, so one should consider a protocol that delays messages, that makes sure the master is driving the flows, and that some input buffer clean up is made right after sending a message.

        • BillNo Gravatar says:

          I can’t make the library automatically dump the input buffer after transmitting because it would interfere with multiple instances of the library running in opposite directions. Your application is unique because you are using a 485 conversion chip which creates the loopback problem. I’m going to leave it up to you to clean out the RX buffer after you transmit.

          • PhDNo Gravatar says:

            Thanks for your feedback. You are right, the problem is related to the way the 485 works. No big problem, as I make sure the master always administrates the slaves, so I can decide when and what to purge. All the rest works pretty well though, so one more thanks for the good job.
            Ph

    • […] in the control box, and five Teensy boards to address the LED strips. They grabbed [Bill Porter's] Easy Transfer library to facilitate communication between the microcontrollers (his libraries are becoming popular, we […]

    • DanNo Gravatar says:

      Hello
      In the code there is this line:
      //you should make this delay shorter then your transmit delay or else messages could be lost
      Since this lib is based on softserial on 1.0 why this could happen?
      softserial should use interrupt (based on NewSoftSerial) to avoid missing messages…
      Can you explain my why this could happen?
      Thankyou

      • BillNo Gravatar says:

        If you have equal delays in both Arduinos, one will be slightly faster then the other due to difference in the clock crystal. If the transmitting arduino is faster, then it will send more messages then the receiving arduino is expecting, and messages will start to build up in the buffer unprocessed. Once the buffer hits it’s limit, messages will start to get lost.

        It has nothing to do with the serial library or Arduino version.

        • DanNo Gravatar says:

          I understand 🙂
          This means that if the arduinos send messages every n loops ( scheduling the datasending with counters and millis() ) no data will be lost!

          Thankyou!

Leave a Reply

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