i2c between arduino boards not reading sensor

hello everyone, i having problem with i2c communucation.

my setup is 2 arduino. one is mega the master and the second is an uno the slave.

the master requestfrom the slave.

basically the slave has 3 sensor attach to it(temperature, voltage,lightsensor).

the wiring is good but the problem is that i want to pass an array which contain all the 3 sensor value like float tomaster[2]={ 23.3,12.2,300}.

the array will be pass onrequest from master.

i dont know how to pass it so that the requesting master can decode it. i tried and i got unknown reading. any help will be most welcome.

Please post the full Master and full Slave sketch.

The onRequest handler should have just one Wire.write() call to write all the data.

An array of three float numbers ?

volatile float myNumbers[3];
...
  
  Wire.write( (char *) myNumbers, sizeof(myNumbers));

It should be volatile, because onRequest is an interrupt handler.

here my master:

#include <Wire.h>
char fromslave[3];
void setup() {
  Serial.begin(9600);
  Wire.begin();        // Activate I2C link
}

void loop() {
   Wire.requestFrom(5, 5);
   if(Wire.available()) {  // if data size is avaliable from nodes
    fromslave[2] = Wire.read(); // get nodes data
       Serial.println(fromslave[2]);   // print nodes data   
      
      }
      delay(100);
}

my slave code:

//i2c slave uno
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>


#define ONE_WIRE_BUS A2
OneWire ourWire(ONE_WIRE_BUS);
DallasTemperature sensorstemp(&ourWire);



// array to send to master
volatile float tomaster[3];
//----//

//variable used by temperature sensor
float temperature=0.00;
//------//




//variable used by voltage sensor
int val11;
float val2;
float voltage=0.00;
//-------//

//variable used by light sensor
int sensorPin = 0;//lightsensor on A0 on uno
int lightsensor;
//

void setup() {
Serial.begin(9600);
Wire.begin(5);//Address of slave uno
Wire.onRequest(requestEvent);
/*-( Start up the DallasTemperature library )-*/
sensorstemp.begin();
}




void loop() {
  
// reading the temperature sensor in celsius
sensorstemp.requestTemperatures(); // Send the command to get temperatures
temperature=sensorstemp.getTempCByIndex(0);
delay(10);
//-------//



//reading the voltage sensor from 0.00 to 25v
float volt;
val11=analogRead(A1);
volt=val11/4.092;
val2=(volt/10);
voltage=val2;
delay(10);
//-------//


//reading light sensor data from 0 - 960
int sensorValue = analogRead(sensorPin);
lightsensor=(sensorValue);
delay(10);
//---------------//


//storing in array
tomaster[0] = lightsensor; // storing the lightsensor to array nodepayload
tomaster[1] = voltage;     // storing the voltage to array nodepayload
tomaster[2] = temperature; // storing the temperature to array nodepayload
//--------//


//for debuging purpose
Serial.println(lightsensor);
Serial.println(tomaster[0]);
Serial.println(voltage);
Serial.println(tomaster[1]);
Serial.println(temperature);
Serial.println(tomaster[2]);
//------//

}
//end of loop//


//onrequest function
void requestEvent(){
//tomaster is my array
Wire.write((char*)tomaster, sizeof(tomaster)); 
  }

i cannot decode the array from the master

The Slave seems okay. A 'float' is 4 bytes. The slave writes three float, that is 12 bytes.

However, you only request 5 bytes in the Master, and the "fromslave" is not float, and only one of them is printed.
Could you change the Master into this and try again:

#include <Wire.h>

float fromslave[3];

void setup() {
  Serial.begin(9600);
  Wire.begin();        // Activate I2C link
}

void loop() {
   Wire.requestFrom(5, sizeof(fromslave));    // request 12 bytes from address 5
   int n = Wire.available();             // check the number of received bytes.
   if( n == sizeof(fromslave)) {        // are 12 bytes received ?
     Wire.readBytes( (char *) fromslave, sizeof(fromslave));    // read 12 bytes into the array.

     for( int i=0; i<3; i++) {
       Serial.println(fromslave[i]);
     }
     Serial.println("-----");
   }

   delay(1000);     // slow down sketch, run loop once a second.
}

If that is working, the Slave sketch has to be improved.
Is the OneWire disabling interrupts for a long time ? That could have influence on the I2C bus.
Filling the "tomaster" with data has to be done when the interrupts are disabled. I prefer this:

// storing in volatile array.
// The interrupts are disabled, to prevent that the requestEvent has half-a-written value.
noInterrupts();          // disable interrupts.
tomaster[0] = lightsensor; // storing the lightsensor to array nodepayload
tomaster[1] = voltage;     // storing the voltage to array nodepayload
tomaster[2] = temperature; // storing the temperature to array nodepayload
interrupts();              // enable interrupts
//--------//

nice man its working fine now i add the interrupt in the slave. can the slave code be improve? what about the master? Thanks man regards. :slight_smile: