Sending a data string between Mega's doesn't work

I am sending a request for data from a Master to a Slave, the slave sends a string of data back that contains alpha numeric data as well as , . and *. I started modifying the Master and Slave examples (they worked OK) on the Arduino web site to suit this need. I found it remarkably difficult to come up with a working solution. The text of my Master and Slave sketches are:

/*
 Arduino Mega 2560.
 Read and file measurements from another Arduino slave devices using  I2C/TWI procedures.
 We do not know the length of the data string we want to read before hand.
*/

#include <Wire.h> // for I2C communication.
#include "Arduino.h" // for file manipulation.

String logd(128);

void setup() { // the setup routine runs at startup and once when you press reset:
   Serial.begin(9600);//initialize serial communication. The highest rate that works on the HP Presario 2800T is 57600.
   Wire.begin(20);  // join i2c bus as Master. Start the I2C service.
 }

 void loop() { 
  // START LOGGING DATA FROM CARD 21 
    Wire.requestFrom(21, 12);    // request for data from slave device #21, 128 bytes
    int j=0;
    logd="";
    Serial.println();    
      
      while (Wire.available()>0) 
      {
        char x= Wire.read();// Read one single character at a time.
         Serial.println();Serial.print(j);Serial.print(" - ");Serial.print(x);
         logd += x; Serial.print(" - ");Serial.print(logd);
         j +=1;
      }

      delay(1000);// Time between reading the data. 
}

/* Errors found: 
1) Too many lines per cycle (12 instead of the available 10);
2) characters not recognized, it seems that only the last one is printed (J):

Print out for one cycle:

0 - J - J
1 - ÿ - Jÿ
2 - ÿ - Jÿÿ
3 - ÿ - Jÿÿÿ
4 - ÿ - Jÿÿÿÿ
5 - ÿ - Jÿÿÿÿÿ
6 - ÿ - Jÿÿÿÿÿÿ
7 - ÿ - Jÿÿÿÿÿÿÿ
8 - ÿ - Jÿÿÿÿÿÿÿÿ
9 - ÿ - Jÿÿÿÿÿÿÿÿÿ
10 - ÿ - Jÿÿÿÿÿÿÿÿÿÿ
11 - ÿ - Jÿÿÿÿÿÿÿÿÿÿÿ

*/

I have listed a summary of the errors I saw at the bottom of the program above. Only the last character of the input string from the slave is reproduced in the wrong place.

The slave program is listed below:

// Arduino Mega 2560

#include <Wire.h>
#include "Arduino.h"

/*
  Sends data as an I2C/TWI slave device
*/

// the setup routine runs once at startup or when you press reset:
void setup() {
  Wire.begin(21);// join the I2C bus, address for this slave unit is #21 (#20 is used as master)  
  Wire.onRequest(requestedEvent); // register event
  Serial.begin(9600);//Initialize serial communication to the PC: The higher the faster you can sample. Try the highest that works.
}

int i ; // counter
String logd(15);// what gets filed. 
// The Send buffer in the Wire library was modified to handle an 128 byte buffer.
// http://arduino.cc/forum/index.php?topic=54439.0


// the loop routine runs over and over again forever:
void loop() {
  delay(1);
}

void requestedEvent() //Requested event was called.
{  
      logd="123,.FGHIJ";
      for(i=0;i< logd.length();i++)Wire.write(logd[i]); 
        //Confirm what was transmitted:
      for(i=0;i< logd.length();i++)Serial.print(logd[i]);        

      Serial.println();
}

Any suggestions?
Thanks.

void requestedEvent() //Requested event was called.
{  
      logd="123,.FGHIJ";
      for(i=0;i< logd.length();i++)Wire.write(logd[i]); 
        //Confirm what was transmitted:
      for(i=0;i< logd.length();i++)Serial.print(logd[i]);        

      Serial.println();
}

Do not do serial prints inside an ISR.

http://www.gammon.com.au/interrupts


      for(i=0;i< logd.length();i++)Wire.write(logd[i]);

Inside a Wire “request” handler you must do only one write.

http://www.gammon.com.au/i2c

You can set up a buffer and write the whole buffer, but you must only do one write.


    Wire.requestFrom(21, 12);    // request for data from slave device #21, 128 bytes

Either make the comments correct, or omit them.


   Wire.begin(20);  // join i2c bus as Master. Start the I2C service.

Typically the master omits the address.


String logd(128);

Please note that, at present, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here: Fixing String Crashes

Nick,

Thanks for your expert comments. Obviously I got my home work cut out for me!

Kindest Regards, MJ.

Please note that, at present, the String library has bugs as discussed here and here.

The malloc issue has been fixed in 1.0.4, according to the release notes, and that version is now available for download. Perhaps the time has come to edit this standard (though good) response.

I'll amend it, although who knows what people are using what version? Often they don't tell us.

How does this look?


Please note that in versions of the IDE up to and including 1.0.3, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here: Fixing String Crashes

Preferably upgrade your IDE to version 1.0.4 or above at: http://arduino.cc/en/Main/Software

How does this look?

Much better.