How to use the Wire library

Hi,
I’d like to send a datetime string from a Yun board to a Mega board.

I use the library wire to accomplish that but I cannot get it going, no errors are produced just I get no data.

I’d appreciate some help, here’s the code:

/* Master board Yun */

#include <Wire.h>
#include <Process.h>

String timeDate;

void setup() {
  Wire.begin(); // join i2c bus as Master
}

void loop() {
  timeDate = getTimeStamp(); // store date & time
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write(timeDate.c_str()); // sends data out
  Wire.endTransmission(); // stop transmitting
  delay(1000);
}

String getTimeStamp() {
  String result;
  Process time;
  time.begin("date");
  time.addParameter("+%D-%T");
  time.run();

  while (time.available() > 0) {
    char c = time.read();
    if (c != '\n')
      result += c;
  }
  return result;
}

/* Mega as slave */

#include <Wire.h>

String timeDate;

void setup() {
  Wire.begin(8);        // join i2c bus set device #8
  Serial.begin(9600);  // start serial for output
}

void loop() {
  while (Wire.available()) { // 
    timeDate = ""; // clear string
    timeDate = (char)Wire.read(); // receive a string
    Serial.println(timeDate); // print data
  }
  delay(500);
}

I'd like to send a datetime string

Then create a string, not a stupid String.

  Wire.write(timeDate.c_str()); // sends data out

Well, one byte of it, anyway. That is NOT how to send an array.

Can you please enlighten me...

ebolisa:
Can you please enlighten me...

About what? The evils of Strings? Do some research. Read the source code.

About how to send an array? I could say the same thing. But, the write() method is overloaded to send arrays. The overload takes two arguments - where the data starts and the amount of data to send.

Read the reference...string and String Object.

Hi,

I reworked the code to pass time from a Yun to a Mega but I still don't get an output on the Mega and I cannot find the problem.

Any help is appreciated.

Yun SCL -> SCL Mega
Yun SDA -> SDA Mega
No pull-up resistors are used

/* Master board Yun */

#include <Wire.h>
#include <Process.h>

String dateTime;
int strlength;
char b;

void setup() {
  Serial.begin(9600);
  Wire.begin(); // join i2c bus as Master
}

void loop() {
  Bridge.begin();
  dateTime = getTimeStamp(); // store date & time
  Wire.beginTransmission(8); // transmit to device #8
  strlength = dateTime.length();
  for (int i = 0; i >= strlength; i++)
  {
    b = dateTime.charAt(i);
    Wire.write(b);
  }
  Wire.endTransmission(); // stop transmitting
  delay(1000);

}

String getTimeStamp() {
  String result;
  Process time;
  time.begin("date");
  //time.addParameter("+%D-%T");
  time.addParameter("+%T"); // shows time
  time.run();

  while (time.available() > 0) {
    char c = time.read();
    if (c != '\n')
      result += c;
  }
  return result;
}
/* Mega as slave */

#include <Wire.h>

String dateTime;
char v;

void setup() {
  Wire.begin(8); // join i2c bus set device #8
  Serial.begin(9600); // start serial for output
}

void loop() {
  while (Wire.available()) { //
    dateTime = ""; // clear string
    v = Wire.read();
    dateTime += v;
  }
  delay(500);
  Serial.println(dateTime); // window is scrolling but no data is printed
}
  while (Wire.available()) { //
    dateTime = ""; // clear string
    v = Wire.read();
    dateTime += v;
  }

I think that if you describe what this code does, in English, there will come a palm-to-forehead moment. If not, post the text here, and I'll supply the palm-to-forehead moment.

I’m so burned out on this that I cannot see the tree in the forest. I moved the lines around with no avail. It’s very basic loop!

#include <Wire.h>

String dateTime;

void setup() {
  Wire.begin(8); // join i2c bus set device #8
  Serial.begin(9600); // start serial for output
}

void loop() {
  dateTime = ""; // clear string
  while (Wire.available()) {
   char v = Wire.read();
    dateTime += v; // add chars to compose a string
  }
  Serial.println(dateTime); // print data
  delay(500);
}

Perhaps you should simply print each character received. If you don't print anything, it's because you don't receive anything, and that is a hardware problem not a software problem.

By the way, receiving data from Wire is generally done by registering an onReceive handler and writing the handler.

Done that in the past with no avail. I know I'm trasmitting because I see voltage changes on the pins.

here's the code using the handler

void loop() {
  dateTime = ""; // clear string
  Wire.onReceive(receiveEvent);
  Serial.println(dateTime); // print data
  delay(500);
}

void receiveEvent(int howMany) {
  while (Wire.available()) {
    v = Wire.read();
    dateTime = dateTime + v; // add chars to compose a string
  }
}

The onReceive handler should be registered in setup(), not loop().

  for (int i = 0; i >= strlength; i++)
  {
    b = dateTime.charAt(i);
    Wire.write(b);
  }

Starting with i equal 0, while i is greater than strlength, do something, and then increment i.

I seriously doubt that you ARE transmitting...

This example works between my 2 boards confirming that my HW is ok.

This example works between my 2 boards confirming that my HW is ok.

OK.

But, put a Serial.print() in your for loop on the sender. Tell me EXACTLY what is being sent.

Using this code, I get transmission but no visual characters.

#include <Wire.h>
#include <Process.h>

String timeDate;
int strlength;
char b;

void setup() {
  Bridge.begin();
  Serial.begin(9600);
  Wire.begin(); // join i2c bus as Master
}

void loop() {
  timeDate = getTimeStamp(); // store date & time
  Wire.beginTransmission(8); // transmit to device #8
  strlength = timeDate.length();
  int i = 0;
  while (1 < strlength) {
    b = timeDate.charAt(i);
    Wire.write(b);
    Serial.print(b);
    i++;
  }
  Wire.endTransmission(); // stop transmitting
  delay(1000);
}

Using this code, I get transmission but no visual characters.

Then, perhaps getTimeStamp() is not doing what you think it does.

  while (1 < strlength) {
    b = timeDate.charAt(i);
    Wire.write(b);
    Serial.print(b);
    i++;
  }

Since strlength never changes, if it is 2 or more, you have an infinite loop.

Is it so hard to use a for loop properly?

for(byte i=0; i<strlength; i++)
{
    b = timeDate.charAt(i);
    Wire.write(b);
    Serial.print(b);
    i++;
}

Thank you Paul, I finally got it to work.

/* Master - Yun */

#include <Wire.h>
#include <Process.h>

String timeDate;
int strlength;
char b;

void setup() {
  Bridge.begin();
  Wire.begin(); // join i2c bus as Master
  //Serial.begin(9600);
 }

void loop() {
  timeDate = getTimeStamp(); // store date & time
  Wire.beginTransmission(8); // transmit to device #8
  strlength = timeDate.length();
  for (int i = 0; i < strlength; i++)
  {
    b = timeDate.charAt(i);
    //Serial.print(b);
    Wire.write(b);
  }
  Wire.endTransmission(); // stop transmitting
  delay(1000);
}

/* Slave - Mega*/

#include <Wire.h>

String dateTime;
char v;

void setup() {
  Wire.begin(8); // join i2c bus set device #8
  Wire.onReceive(receiveEvent);
  Serial.begin(9600); // start serial for output
}

void loop() {
  delay(500);
}

void receiveEvent(int howMany) {
  dateTime = "";
  while ( Wire.available()) {
    v = Wire.read();
    dateTime += v; // add chars to compose a string
  }
  Serial.println(dateTime);
}