Casting Variables for I2C

electron
Tags: #<Tag:0x00007f1ca317d8f8>

#21

This still doesn’t look like the two grounds are connected. Even when both share the same USB host/supply I’d not consider this common GND.

Usually that’s a sign for some deadlock situation where the device OS and the application block eachother for some reason (I2C is one of the usual suspects).

In most of your pics you have no LiPo connected. I’d suggest to always have one connected when the Electron should go online as the cellular module may require demand current in bursts that might be too much for your USB supply.

That doesn’t make any differenc - just as the number eight wouldn’t be any different whether you had 8 apples or 8 pears or 8 matchsticks - 8 == 0008 == 0x0008 == 0b1000 == (1+1+1+1+1+1+1+1)


#22

@mstanley is it possible I have a combination of issues?

This GND for the breadboard should be going to the GND of the Arduino or to the Electron?

Does my Wire.requestFrom() call look correct?


#23

Not “or”. It should go to the Arduino and the Electron to be common GND for both.


#24

Following up from the Safe Mode thread, I 've read that the i2C doesn’t transmit the data until the Wire.endTransmission is called. Is this true? I cannot get the breathing cyan with it called.

I’m implementing the GND with a jumper wire now…


#25

Implemented. Current setup is below.


I’ve been able to get my Mode issue resolved. Took out Wire.endTransmission(), and the Arduino is still getting hung up on the Master side. I think I will still need to use wire.endTransmission() but will change my mode.
Slave Code update:

void setup() {
    Serial.begin(9600);
    Wire.begin(8); // i2c bus #8
    Wire.onRequest(requestEvent);  // register event
    Serial.println("setup complete.");
}

void loop() {
    delay(500);
    requestEvent();
}

void requestEvent() {
   
  // generate some simulated data
  //float val_1 = 11.08765; //dummy values - do not change   (random(200000) - 1000) / 100000.0;
  //float val_2 =-66.01234; //dummy values - do not change   (random(200000) - 1000) / 100000.0;
  float val_1 = +42.409671;
  float val_2 = -71.097330;
  char* val_3 = NULL;

  
  // transmit the simulated data
  //Wire.write((char*)&val_1); // respond with message of 6 bytes, SENDS CRAP DATA
  //Wire.write((uint8_t*)&val_1, 9); //TESTING // WORKS TO END OF -11.087654/113 NEED 1 MORE DIGIT
  Serial.println("val_1 is: ");Serial.println(val_1,5);
  if (val_1>1) {
    //Wire.begin(8);
    Serial.println("val_1 is ok.");
  }

  String sendstring1 = String(val_1);
  Serial.println("VAR is: "+sendstring1);
  Serial.println(sizeof(sendstring1)); // sizeof(sendstring1) is 16. verified.
  //Wire.write((uint8_t*)&val_1, 5);  // currently trying to send as data. 4/28/19
//  Wire.beginTransmission(0x8);
  Wire.write(sendstring1);  //testing sending as a string 4/28/19
  //Wire.write((uint8_t*)&val_2, sizeof(val_2));// testing 4/27/19 commented to isolate
  //Wire.write((char*)&val_1, sizeof(float)); //THIS ERRORED FROM JOSH
//  Wire.endTransmission();

//*/
}

@ScruffR what would you suggest?


#26

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