i2c between uno and nodemcu.. using I2C_Anything.h

Hello,

I’d like to send two (or more) floats from an uno to a NodeMCU. However the float values on the master (NodeMCU) appears as ‘nan’ on the serial port.

Btw, for some reason, NodeMCU can only be a master. The examples of the I2C_Anthing library (GitHub - nickgammon/I2C_Anything: Arduino library to simplify reading/writing to I2C) only seem to work when the uno is a slave.

Uno

#include <Wire.h> 
#include <ArduinoJson.h>
//#include <LiquidCrystal_I2C.h>
#include <I2C_Anything.h>

int bigNTCsensor = A0; // thermistor is actually at A0
int reed_sensor = A2;

volatile float temperature;
volatile float Val_reed;

void setup() {
  Serial.begin (115200);
  Wire.begin(8);                /* join i2c bus with address 8 */
  Wire.onRequest(requestEvent); // function to run when asked for data
  
}

void loop() {

delay(100);

Serial.println();
  
  int temperature=analogRead(bigNTCsensor);
  Serial.print("Temperature big sensor is = ");
  Serial.print(temperature);
  Serial.println(" Celsius, ");
  
int Val_reed=analogRead(reed_sensor);
  Serial.print("Reed sesnor value is = ");
  Serial.print(Val_reed);
  
  delay(1000);
}


/* // function: what to do when asked for data
void requestEvent(int howMany)
 {
 if (howMany >= (sizeof temperature) + (sizeof Val_reed))
   {
   I2C_writeAnything (temperature);
   I2C_writeAnything (Val_reed);
   }
 } */


void requestEvent () {
  
   struct 
    {
    float temperature;
    float Val_reed;
    } response;
    
  response.temperature = temperature;
  response.Val_reed = Val_reed;
  
  Wire.write ((byte *) &response, sizeof response);
  
} // request event

NodeMCU

#include <ESP8266WiFi.h>
#include <Wire.h>
#include <I2C_Anything.h>



volatile float temperature;
volatile float Val_reed;


void setup() {
  // put your setup code here, to run once:

Serial.begin(115200);
Wire.begin(D1, D2); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() 
{

    // It is best to make a copy of the data while interrupts are disabled, but for now they are used directly.
    Wire.requestFrom(8,6); // reqeust 6 bytes from salve Uno #8

//Wire.beginTransmission (8);
    I2C_readAnything (temperature);
    I2C_readAnything (Val_reed);
    //Wire.endTransmission ();

Serial.println();
  

  Serial.print("Temperature big sensor is = ");
  Serial.print(temperature);
  Serial.println(" Celsius, ");
  
  Serial.print("Reed sesnor value is = ");
  Serial.print(Val_reed);
 delay(200); 
  
}
Temperature big sensor is = nan Celsius,
Reed sesnor value is = nan

You have two float type variables at the Slave side. Each float type variable occupies 4-byte space in the memory, and now you have 8-byte data to transfer from Slave to Master. Therefore, this instruction at the Master side: Wire.requestFrom(8, 6); should be changed to Wire.requestFrom(8, 8 );.

Also, I have done some moderation on your Master and Slave Codes to make them working in my ESP + UNO Setup (the sensor values were simulated using 3.3V supply).

Master Codes:

//#include <ESP8266WiFi.h>
#include <Wire.h>
#include <I2C_Anything.h>

volatile float temperature;
volatile float Val_reed;
//byte x;


void setup()
{
  // put your setup code here, to run once:

  Serial.begin(115200);
  Wire.begin(D1, D2); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop()
{
  // It is best to make a copy of the data while interrupts are disabled, but for now they are used directly.
  Wire.requestFrom(8, 8); // reqeust 6 bytes from salve Uno #8
   //Wire.beginTransmission (8);
  I2C_readAnything (temperature);
  I2C_readAnything (Val_reed);
  //Wire.endTransmission ();

  Serial.print("Temperature big sensor is = ");
  Serial.print(temperature, 2);
  Serial.println(" Celsius, ");

  Serial.print("Reed sesnor value is = ");
  Serial.println(Val_reed, 2);
  Serial.println("==============================");
  delay(1000);
}

Slave Codes:

#include <Wire.h>
//#include <ArduinoJson.h>
//#include <LiquidCrystal_I2C.h>
#include <I2C_Anything.h>

struct
{
  float temperature;
  float Val_reed;
} response;

int bigNTCsensor = A0; // thermistor is actually at A0
int reed_sensor = A2;

//volatile float temperature;
//volatile float Val_reed;

void setup()
{
  Serial.begin (115200);
  Wire.begin(8);                /* join i2c bus with address 8 */
  Wire.onRequest(requestEvent); // function to run when asked for data

}

void loop()
{

  //  delay(100);

  Serial.println();

  response.temperature = (float)analogRead(bigNTCsensor);
  Serial.print("Temperature big sensor is = ");
  Serial.print(response.temperature, 2);
  Serial.println(" Celsius, ");

  response.Val_reed = (float)analogRead(reed_sensor);
  Serial.print("Reed sesnor value is = ");
  Serial.println(response.Val_reed, 2);
  Serial.println("===================================");

  delay(1000);
}


/* // function: what to do when asked for data
  void requestEvent(int howMany)
  {
  if (howMany >= (sizeof temperature) + (sizeof Val_reed))
   {
   I2C_writeAnything (temperature);
   I2C_writeAnything (Val_reed);
   }
  } */


void requestEvent ()//(int howMany)Edit
{
  //response.temperature = temperature;
 // response.Val_reed = Val_reed;
  I2C_writeAnything(response);
 // Wire.write ((byte *) &response, sizeof response); this works
} // request event

changes suggested by @GolamMostafa works perfectly.