I2C Crash/Reboot with multiple Slaves

I have been setting up a weather monitor, and am splitting up the various sensors onto different boards. They all send their information to a central UNO board via I2C bus. Right now I have two slaves - an Uno board and a Sparkfun HTU21D breakout board. Each of them can be run without the other and no hitches are to be found. However, when they are both run, the program restarts to the void setup() after one specific slave is called.

Could there be an issue with RAM or in my code? The script only occupies about 25% of the available memory when uploaded, so idk what else it could be.

void setup()
{
  Serial.begin(9600);
  Serial.println("MASTER READER NODE");
  Serial.print("Maximum Slave Nodes: ");
  Serial.println(NODE_MAX);
  Serial.print("Payload size: ");
  Serial.println(PAYLOAD_SIZE);

  Wire.begin();        // Activate I2C link
}

void loop()
{
   
     //<<<-------------------------------------------->>>
  //Humidity Board - HTU21D
  Slave3();
  delay(100); 
  
  //<<<-------------------------------------------->>>
  //CO2 and Particle
  Slave2();
  delay(3000);
}

//<<=========================================================================>>
void Slave2()
{
  Wire.requestFrom(2, PAYLOAD_SIZE); //Wire.requestFrom(Node Address, Bytes Expected)
  nodePayload[1] = Wire.read();
  //Serial.println(nodePayload[1]);    //Low
  nodePayload[2] = Wire.read();
  //Serial.println(nodePayload[2]);    //High

  unsigned long valCO2 = nodePayload[2] * 256 + nodePayload[1]; //Combine high byte and low byte with this formula to get value
  Serial.print("Co2 [ppm] = ");
  Serial.println(valCO2);
}

Above is the code from the setup to the slave that breaks/resets the program. I appreciate any help!

This code doesn't even compile

#include <Wire.h>

//<---------------------------------------------------------------------->
//Slave 2
#define PAYLOAD_SIZE 2 // how many bytes to expect from each I2C slave node
#define NODE_MAX 2 // maximum number of slave nodes (I2C addresses) to probe
#define START_NODE 2 // The starting I2C address of slave nodes
#define NODE_READ_DELAY 3000 // Some delay between I2C node reads

int nodePayload[PAYLOAD_SIZE];


//<---------------------------------------------------------------------->
//Humidity Slave
#define HTDU21D_ADDRESS 0x40  //Unshifted 7-bit I2C address for the sensor
#define TRIGGER_TEMP_MEASURE_HOLD  0xE3
#define TRIGGER_HUMD_MEASURE_HOLD  0xE5
#define TRIGGER_TEMP_MEASURE_NOHOLD  0xF3
#define TRIGGER_HUMD_MEASURE_NOHOLD  0xF5
#define WRITE_USER_REG  0xE6
#define READ_USER_REG  0xE7
#define SOFT_RESET  0xFE






void setup()
{
  Serial.begin(9600);
  Serial.println("MASTER READER NODE");
  Serial.print("Maximum Slave Nodes: ");
  Serial.println(NODE_MAX);
  Serial.print("Payload size: ");
  Serial.println(PAYLOAD_SIZE);

  Wire.begin();        // Activate I2C link
}

void loop()
{
   
     //<<<-------------------------------------------->>>
  //Humidity Board - HTU21D
  Slave3();
  delay(100); 
  
  //<<<-------------------------------------------->>>
  //CO2 and Particle
  Slave2();
  delay(3000);
}

//<<=========================================================================>>
void Slave2()
{
  Wire.requestFrom(2, PAYLOAD_SIZE); //Wire.requestFrom(Node Address, Bytes Expected)
  nodePayload[1] = Wire.read();
  //Serial.println(nodePayload[1]);    //Low
  nodePayload[2] = Wire.read();
  //Serial.println(nodePayload[2]);    //High

  unsigned long valCO2 = nodePayload[2] * 256 + nodePayload[1]; //Combine high byte and low byte with this formula to get value
  Serial.print("Co2 [ppm] = ");
  Serial.println(valCO2);
}



//<<=========================================================================>>
void Slave3()
{
  float humd = readHumidity1();
  float temp = readTemperature();

  Serial.print("Temperature [C] = ");
  Serial.println(temp, 1);
  Serial.print("Humidity [%] = ");
  Serial.println(humd, 1);
}

float readHumidity1(void)
{
  //Request a humidity reading
  Wire.beginTransmission(HTDU21D_ADDRESS);
  Wire.write(TRIGGER_HUMD_MEASURE_NOHOLD); //Measure humidity with no bus holding
  Wire.endTransmission();

  //Hang out while measurement is taken. 50mS max, page 4 of datasheet.
  delay(55);

  //Comes back in three bytes, data(MSB) / data(LSB) / Checksum
  Wire.requestFrom(HTDU21D_ADDRESS, 3);

  //Wait for data to become available
  int counter = 0;
  while (Wire.available() < 3)
  {
    counter++;
    delay(1);
    if (counter > 100) return 998; //Error out
  }

  byte msb, lsb, checksum;
  msb = Wire.read();
  lsb = Wire.read();
  checksum = Wire.read();

  /* //Used for testing
  byte msb, lsb, checksum;
  msb = 0x4E;
  lsb = 0x85;
  checksum = 0x6B;*/

  unsigned int rawHumidity = ((unsigned int) msb << 8) | (unsigned int) lsb;


  //sensorStatus = rawHumidity & 0x0003; //Grab only the right two bits
  rawHumidity &= 0xFFFC; //Zero out the status bits but keep them in place

  //Given the raw humidity data, calculate the actual relative humidity
  float tempRH = rawHumidity / (float)65536; //2^16 = 65536
  float rh = -6 + (125 * tempRH); //From page 14

  return (rh);
}

//Read the temperature
/*******************************************************************************************/
//Calc temperature and return it to the user
//Returns 998 if I2C timed out
//Returns 999 if CRC is wrong
float readTemperature(void)
{
  //Request the temperature
  Wire.beginTransmission(HTDU21D_ADDRESS);
  Wire.write(TRIGGER_TEMP_MEASURE_HOLD);
  Wire.endTransmission();

  //Hang out while measurement is taken. 50mS max, page 4 of datasheet.
  delay(55);

  //Comes back in three bytes, data(MSB) / data(LSB) / Checksum
  Wire.requestFrom(HTDU21D_ADDRESS, 3);

  //Wait for data to become available
  int counter = 0;
  while (Wire.available() < 3)
  {
    counter++;
    delay(1);
    if (counter > 100) return 998; //Error out
  }

  unsigned char msb, lsb, checksum;
  msb = Wire.read();
  lsb = Wire.read();
  checksum = Wire.read();

  /* //Used for testing
  byte msb, lsb, checksum;
  msb = 0x68;
  lsb = 0x3A;
  checksum = 0x7C; */

  unsigned int rawTemperature = ((unsigned int) msb << 8) | (unsigned int) lsb;

  //sensorStatus = rawTemperature & 0x0003; //Grab only the right two bits
  rawTemperature &= 0xFFFC; //Zero out the status bits but keep them in place

  //Given the raw temperature data, calculate the actual temperature
  float tempTemperature = rawTemperature / (float)65536; //2^16 = 65536
  float realTemperature = -46.85 + (175.72 * tempTemperature); //From page 14

  return (realTemperature);
}

Here is the full code. Sorry, that was just a sample of part.

I see one obvious mistake. When you declare an array of size N, the available indexes are 0 to N-1, not 1 to N. When you try to store a value to an index that is out of the array bounds, you are creating a buffer overflow error, and that may be the cause of your problem.

I have pulled a lot of this code from elsewhere because it was deemed necessary to operate the functions. Where would I change this? I don't want to be screwing the code up any further than it already is. Thanks for the assistance, guix

Here:

#define PAYLOAD_SIZE 2 // how many bytes to expect from each I2C slave node
...
int nodePayload[PAYLOAD_SIZE];

...
  nodePayload[1] = Wire.read();
  //Serial.println(nodePayload[1]);    //Low
  nodePayload[2] = Wire.read();

That worked perfectly. I went back to the code I had over simplified and replaced it. Thanks again to you both.

{
  for (int nodeAddress = START_NODE; nodeAddress <= NODE_MAX; nodeAddress++) { // we are starting from Node address 2
    Wire.requestFrom(nodeAddress, PAYLOAD_SIZE);    // request data from node#
    if(Wire.available() == PAYLOAD_SIZE) {  // if data size is avaliable from nodes
      for (int i = 0; i < PAYLOAD_SIZE; i++) nodePayload[i] = Wire.read();  // get nodes data
      for (int j = 0; j < PAYLOAD_SIZE; j++) Serial.println(nodePayload[j]);   // print nodes data   
      Serial.println("*************************");      
      }
    }
    delay(NODE_READ_DELAY);
}