Casting Variables for I2C

I fear I have to rebuild your setup to see what’s happening first hand :blush:

BTW, why are you calling requestEvent() form loop().
This function is supposed to be triggered by the master. The slave has no business just chatting away without being asked.


I’ve tested communication between two Photons with this code and it works both directions

//#define MASTER
#define SLAVE

const byte addr = 4;
SerialLogHandler Logger(LOG_LEVEL_ALL);
char msg[32] = "dummy";

#ifdef MASTER
void setup() {
  Wire.begin();                     // join i2c bus as master
  Particle.function("send", fnSend);
  Particle.function("recv", fnRecv);
}

int fnSend(const char *arg) {
  strcpy(msg, arg);
  
  Wire.beginTransmission(addr);         // transmit to slave
  Wire.print(msg);                      // buffer data
  Wire.endTransmission();               // stop transmitting (=initiate transfer)

  return strlen(msg);
}

int fnRecv(const char *arg) {
  Wire.requestFrom(addr, strlen(msg));  // request as many bytes as we had sent before
  Wire.readBytes(msg, strlen(msg));
  Serial.print(msg);                    // print the character

  return strlen(msg);
}
#endif

// ----------------------------------------------------------------------------------------------


#ifdef SLAVE
void setup() {
  Wire.begin(addr);                     // join i2c bus with address #4
  Wire.onReceive(receiveEvent);         // register event
  Wire.onRequest(requestEvent);         // register event
  Serial.begin(115200);                 // start serial for output
}

void receiveEvent(int howMany) {
  int i = 0;
  
  Serial.printf("%d: ", howMany);       // we are expecting x bytes
  Wire.readBytes(msg, howMany);         // read them
  msg[howMany] = '\0';                  // terminate the string
  Serial.println(msg);                  // print the string
}

void requestEvent() {
  Wire.print(msg);                      // respond with message we got sent last
}
#endif

I have yet to dig up an Arduino UNO and try with an Electron.


Update:
I’ve now tested that code with Electron and Arduino UNO and it works too
This is the Arduino Master code

#include <Wire.h>

const int addr = 0x04;
char      msg[32] = "test\r\n";

void setup() {
  Wire.begin();                         // join i2c bus (address optional for master)
  Serial.begin(115200);                 // start serial for output
  
  // by this time the Electron should already be breathing cyan to receive the data
  Wire.beginTransmission(addr);         // start transmission to intended slave
  Wire.print(msg);                      // send to slave what we want to be sent back later
  Wire.endTransmission();               // finish transmission (=initiate transfer)
}

void loop() {
  int count = strlen(msg);
  memset(msg, 0x00, sizeof(msg));       // clear buffer to be sure we actually receive data
  Wire.requestFrom(addr, count);        // request back as many bytes we prevsiously sent to slave
  Wire.readBytes(msg, count);           // read all the requested bytes into buffer again
  Serial.println(msg);
  delay(500);
}

As it turns out, pull-up resistors are not needed. The Arduino’s own on-board pull-ups suffice.

Wiring:

UNO    -  Electron
 5V    -   Vin
GND    -   GND
A4/SDA - D0/SDA
A5/SCL - D1/SCL