0

I am using multiple temperature sensors using I2C. Some of the sensors are connected via TCA9548 multiplexer. When I run the sketch it runs fine for a few minutes but then it suddenly stops working while printing the results. I have tried changing the baud rate, trying two different arduinos but it happens on both arduinos. So I wonder if it's some kind of buffer overflow (serial prints) or there is any collision happening on the I2C bus. Now the only other way I can think of is to run each sensor separately and see if I can find the problematic sensor. Or are there better ways to fix the issue?

/* 9 temperature & Humidity Sensors
    1 x BME280 #1 (0x77)[Ch 0]
    1 x BME280 #2 (0x77) [Ch 1]
    1 x BME280 #3 (0x76)
    1 x SHT21 (0x40) [Ch 7]
    1 x Si7021 (0x40) [Ch 5]
    1 x HTU21D (0x40) [Ch 6]
    1 x HDC1080 (0x40) [Ch 4]
    1 x AHT10 (0x38)
    1 x HDC2080 (0x41)

*/

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Sodaq_SHT2x.h>
#include "SparkFunHTU21D.h"
#include <HDC2080.h>
#include "ClosedCube_HDC1080.h"
#include <AHT10.h>
#include "Adafruit_Si7021.h"

Adafruit_BME280 bme1; // I2C
Adafruit_BME280 bme2; // I2C
Adafruit_BME280 bme3; // I2C
HTU21D HTU;
HDC2080 HDC2080(0x41);
ClosedCube_HDC1080 hdc1080;
AHT10 AHT(AHT10_ADDRESS_0X38);

Adafruit_Si7021 Si7021 = Adafruit_Si7021();
bool enableHeater = false;
uint8_t loopCnt = 0;

unsigned long delayTime;

#define MPLXADR 0x70 // Address of TCA9548A I2C Multiplexer
void multiplexer (uint8_t ch) { //ch is the channel on Multiplexer
  if (ch > 7) return;

  Wire.beginTransmission(MPLXADR);
  Wire.write(1 << ch);
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);

  while (AHT.begin() != true)
  {
    Serial.println(F("AHT10 not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free
    delay(5000);
  }
  Serial.println(F("AHT10 OK"));

  HDC2080.begin();

  // Begin with a device reset
  HDC2080.reset();

  // Set up the comfort zone
  HDC2080.setHighTemp(28);         // High temperature of 28C
  HDC2080.setLowTemp(22);          // Low temperature of 22C
  HDC2080.setHighHumidity(55);     // High humidity of 55%
  HDC2080.setLowHumidity(40);      // Low humidity of 40%

  // Configure Measurements
  HDC2080.setMeasurementMode(TEMP_AND_HUMID);  // Set measurements to temperature and humidity
  HDC2080.setRate(ONE_HZ);                     // Set measurement frequency to 1 Hz
  HDC2080.setTempRes(FOURTEEN_BIT);
  HDC2080.setHumidRes(FOURTEEN_BIT);

  //begin measuring
  HDC2080.triggerMeasurement();


  Serial.println();

  Serial.println(F("BME280 test"));

  //BME280 sensor 1
  //  multiplexer(0);
  //  if (! bme1.begin(0x77, &Wire)) {
  //    Serial.println("Could not find a valid BME280 sensor, check wiring!");
  //    while (1);
  //  }

  // weather monitoring
  //  Serial.println("-- Weather Station Scenario --");
  //  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  //  Serial.println("filter off");
  //  bme1.setSampling(Adafruit_BME280::MODE_FORCED,
  //                   Adafruit_BME280::SAMPLING_X1, // temperature
  //                   Adafruit_BME280::SAMPLING_X1, // pressure
  //                   Adafruit_BME280::SAMPLING_X1, // humidity
  //                   Adafruit_BME280::FILTER_OFF   );

  //BME280 sensor 2
  multiplexer(1);
  if (! bme2.begin(0x77, &Wire)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    //while (1);
  }

  // weather monitoring
//  Serial.println("-- Weather Station Scenario --");
//  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
//  Serial.println("filter off");
  bme2.setSampling(Adafruit_BME280::MODE_FORCED,
                   Adafruit_BME280::SAMPLING_X1, // temperature
                   Adafruit_BME280::SAMPLING_X1, // pressure
                   Adafruit_BME280::SAMPLING_X1, // humidity
                   Adafruit_BME280::FILTER_OFF   );

  //BME280 sensor 3
//  if (! bme3.begin(0x76, &Wire)) {
//    Serial.println("Could not find a valid BME280 sensor, check wiring!");
//    //while (1);
//  }

  // weather monitoring
//  Serial.println("-- Weather Station Scenario --");
//  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
//  Serial.println("filter off");
//  bme3.setSampling(Adafruit_BME280::MODE_FORCED,
//                   Adafruit_BME280::SAMPLING_X1, // temperature
//                   Adafruit_BME280::SAMPLING_X1, // pressure
//                   Adafruit_BME280::SAMPLING_X1, // humidity
//                   Adafruit_BME280::FILTER_OFF   );
//
//  // suggested rate is 1/60Hz (1m)
//  delayTime = 10000; // in milliseconds

  Serial.println("Initiating HTU21D");
  multiplexer(6);
  HTU.begin();

  Serial.println("HDC1080 Arduino Test");

  // Default settings:
  //  - Heater off
  //  - 14 bit Temperature and Humidity Measurement Resolutions
  multiplexer(4);
  hdc1080.begin(0x40);


  Serial.println("Si7021 test!");

  multiplexer(5);
  if (!Si7021.begin()) {
    Serial.println("Did not find Si7021 sensor!");
    //while (true);
  }

}

void loop() {

  unsigned long newTime = millis();
  static unsigned long oldTime = 0;

  if (newTime - oldTime >= 60000) {
    oldTime = newTime;

    printValuesHDC2080();

    multiplexer(4);
    printValuesHDC1080();

//    bme3.takeForcedMeasurement(); // has no effect in normal mode
//    printValuesBME3();

    multiplexer(1);
    bme2.takeForcedMeasurement(); // has no effect in normal mode
    printValuesBME2();

    multiplexer(6);
    printValuesHTU();

    multiplexer(5);
    printValueSi7021();

    printValuesAHT();

    //  multiplexer(0);
    //  bme1.takeForcedMeasurement(); // has no effect in normal mode
    //  printValuesBME1();

    multiplexer(7);
    printValuesSHT21();


    Serial.println();
    Serial.println();
  }
}

//void printValuesBME1() {
//
//  Serial.println();
//  Serial.print("BME1 Readings");
//  Serial.write(9); // printing a tab using ASCII code
//  Serial.print("Temperature = ");
//  Serial.print(bme1.readTemperature());
//  Serial.println(" *C");
//  Serial.write(9); // printing a tab using ASCII code
//  Serial.print("Humidity = ");
//  Serial.print(bme1.readHumidity());
//  Serial.println(" %");
//}

void printValuesBME2() {

  Serial.print("BME2: ");
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(bme2.readTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(bme2.readHumidity());
}

void printValuesBME3() {

  Serial.print("BME3: ");
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(bme3.readTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(bme3.readHumidity());
}

void printValuesSHT21() {
  Serial.print("SHT21: ");
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(SHT2x.GetTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(SHT2x.GetHumidity());
}


void printValuesHTU() {
  Serial.print("HTU: ");
  Serial.write(9); // printing a tab using ASCII code
  float humd = HTU.readHumidity();
  float temp = HTU.readTemperature();

  Serial.print("T = ");
  Serial.print(temp, 2);
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(humd, 2);
}

void printValuesHDC2080() {
  Serial.print("HDC2080:");
  //Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = "); Serial.print(HDC2080.readTemp());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = "); Serial.println(HDC2080.readHumidity());
}

void printValuesHDC1080() {
  Serial.print("HDC1080:");
  // Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(hdc1080.readTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(hdc1080.readHumidity());
}

void printValuesAHT() {
  /* DEMO - 1, every temperature or humidity call will read 6 bytes over I2C, total 12 bytes */
  Serial.print(F("AHT10: "));
  Serial.write(9); // printing a tab using ASCII code
  Serial.print(F("T = ")); Serial.print(AHT.readTemperature()); //by default "AHT10_FORCE_READ_DATA"
  Serial.write(9); // printing a tab using ASCII code
  Serial.print(F("H = ")); Serial.println(AHT.readHumidity());    //by default "AHT10_FORCE_READ_DATA"
}


void printValueSi7021() {
  Serial.print(F("Si7021: "));
  // Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(Si7021.readTemperature(), 2);
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(Si7021.readHumidity(), 2);


  //
  //  // Toggle heater enabled state every 30 seconds
  //  // An ~1.8 degC temperature increase can be noted when heater is enabled
  //  if (++loopCnt == 30) {
  //    enableHeater = !enableHeater;
  //    Si7021.heater(enableHeater);
  //    // Serial.print("Heater Enabled State: ");
  //    if (Si7021.isHeaterEnabled()) {
  //      //  Serial.println("ENABLED");
  //    } else {
  //      // Serial.println("DISABLED");
  //
  //      loopCnt = 0;
}

Code with delay:

/* 9 temperature & Humidity Sensors
    1 x BME280 #1 (0x77)[Ch 0]
    1 x BME280 #2 (0x77) [Ch 1]
    1 x BME280 #3 (0x76)
    1 x SHT21 (0x40) [Ch 7]
    1 x Si7021 (0x40) [Ch 5]
    1 x HTU21D (0x40) [Ch 6]
    1 x HDC1080 (0x40) [Ch 4]
    1 x AHT10 (0x38)
    1 x HDC2080 (0x41)

*/

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Sodaq_SHT2x.h>
#include "SparkFunHTU21D.h"
#include <HDC2080.h>
#include "ClosedCube_HDC1080.h"
#include <AHT10.h>
#include "Adafruit_Si7021.h"

Adafruit_BME280 bme1; // I2C
Adafruit_BME280 bme2; // I2C
Adafruit_BME280 bme3; // I2C
HTU21D HTU;
HDC2080 HDC2080(0x41);
ClosedCube_HDC1080 hdc1080;
AHT10 AHT(AHT10_ADDRESS_0X38);

Adafruit_Si7021 Si7021 = Adafruit_Si7021();
bool enableHeater = false;
uint8_t loopCnt = 0;

unsigned long delayTime;

#define MPLXADR 0x70 // Address of TCA9548A I2C Multiplexer
void multiplexer (uint8_t ch) { //ch is the channel on Multiplexer
  if (ch > 7) return;

  Wire.beginTransmission(MPLXADR);
  Wire.write(1 << ch);
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);

  while (AHT.begin() != true)
  {
    Serial.println(F("AHT10 not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free
    delay(5000);
  }
  Serial.println(F("AHT10 OK"));

  HDC2080.begin();

  // Begin with a device reset
  HDC2080.reset();

  // Set up the comfort zone
  HDC2080.setHighTemp(28);         // High temperature of 28C
  HDC2080.setLowTemp(22);          // Low temperature of 22C
  HDC2080.setHighHumidity(55);     // High humidity of 55%
  HDC2080.setLowHumidity(40);      // Low humidity of 40%

  // Configure Measurements
  HDC2080.setMeasurementMode(TEMP_AND_HUMID);  // Set measurements to temperature and humidity
  HDC2080.setRate(ONE_HZ);                     // Set measurement frequency to 1 Hz
  HDC2080.setTempRes(FOURTEEN_BIT);
  HDC2080.setHumidRes(FOURTEEN_BIT);

  //begin measuring
  HDC2080.triggerMeasurement();


  Serial.println();

  Serial.println(F("BME280 test"));

  //BME280 sensor 1
  //  multiplexer(0);
  //  if (! bme1.begin(0x77, &Wire)) {
  //    Serial.println("Could not find a valid BME280 sensor, check wiring!");
  //    while (1);
  //  }

  // weather monitoring
  //  Serial.println("-- Weather Station Scenario --");
  //  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  //  Serial.println("filter off");
  //  bme1.setSampling(Adafruit_BME280::MODE_FORCED,
  //                   Adafruit_BME280::SAMPLING_X1, // temperature
  //                   Adafruit_BME280::SAMPLING_X1, // pressure
  //                   Adafruit_BME280::SAMPLING_X1, // humidity
  //                   Adafruit_BME280::FILTER_OFF   );

  //BME280 sensor 2
  multiplexer(1);
  if (! bme2.begin(0x77, &Wire)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    //while (1);
  }

  // weather monitoring
  //  Serial.println("-- Weather Station Scenario --");
  //  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  //  Serial.println("filter off");
  bme2.setSampling(Adafruit_BME280::MODE_FORCED,
                   Adafruit_BME280::SAMPLING_X1, // temperature
                   Adafruit_BME280::SAMPLING_X1, // pressure
                   Adafruit_BME280::SAMPLING_X1, // humidity
                   Adafruit_BME280::FILTER_OFF   );

  //BME280 sensor 3
  //  if (! bme3.begin(0x76, &Wire)) {
  //    Serial.println("Could not find a valid BME280 sensor, check wiring!");
  //    //while (1);
  //  }

  // weather monitoring
  //  Serial.println("-- Weather Station Scenario --");
  //  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  //  Serial.println("filter off");
  //  bme3.setSampling(Adafruit_BME280::MODE_FORCED,
  //                   Adafruit_BME280::SAMPLING_X1, // temperature
  //                   Adafruit_BME280::SAMPLING_X1, // pressure
  //                   Adafruit_BME280::SAMPLING_X1, // humidity
  //                   Adafruit_BME280::FILTER_OFF   );
  //
  //  // suggested rate is 1/60Hz (1m)
  //  delayTime = 10000; // in milliseconds

  Serial.println("Initiating HTU21D");
  multiplexer(6);
  HTU.begin();

  Serial.println("HDC1080 Arduino Test");

  // Default settings:
  //  - Heater off
  //  - 14 bit Temperature and Humidity Measurement Resolutions
  multiplexer(4);
  hdc1080.begin(0x40);


  Serial.println("Si7021 test!");

  multiplexer(5);
  if (!Si7021.begin()) {
    Serial.println("Did not find Si7021 sensor!");
    //while (true);
  }

}

void loop() {

  unsigned long newTime = millis();
  static unsigned long oldTime = 0;

  if (newTime - oldTime >= 60000) {
    oldTime = newTime;

    printValuesHDC2080();
    delay(50);

    multiplexer(4);
    printValuesHDC1080();
    delay(50);

    //    bme3.takeForcedMeasurement(); // has no effect in normal mode
    //    printValuesBME3();

    multiplexer(1);
    bme2.takeForcedMeasurement(); // has no effect in normal mode
    printValuesBME2();
    delay(50);

    multiplexer(6);
    printValuesHTU();
    delay(50);

    multiplexer(5);
    printValueSi7021();
    delay(50);

    printValuesAHT();
    delay(50);

    //  multiplexer(0);
    //  bme1.takeForcedMeasurement(); // has no effect in normal mode
    //  printValuesBME1();

    multiplexer(7);
    printValuesSHT21();
    delay(50);


    Serial.println();
    Serial.println();
  }
}

//void printValuesBME1() {
//
//  Serial.println();
//  Serial.print("BME1 Readings");
//  Serial.write(9); // printing a tab using ASCII code
//  Serial.print("Temperature = ");
//  Serial.print(bme1.readTemperature());
//  Serial.println(" *C");
//  Serial.write(9); // printing a tab using ASCII code
//  Serial.print("Humidity = ");
//  Serial.print(bme1.readHumidity());
//  Serial.println(" %");
//}

void printValuesBME2() {

  Serial.print("BME2: ");
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(bme2.readTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(bme2.readHumidity());
}

void printValuesBME3() {

  Serial.print("BME3: ");
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(bme3.readTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(bme3.readHumidity());
}

void printValuesSHT21() {
  Serial.print("SHT21: ");
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(SHT2x.GetTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(SHT2x.GetHumidity());
}


void printValuesHTU() {
  Serial.print("HTU: ");
  Serial.write(9); // printing a tab using ASCII code
  float humd = HTU.readHumidity();
  float temp = HTU.readTemperature();

  Serial.print("T = ");
  Serial.print(temp, 2);
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(humd, 2);
}

void printValuesHDC2080() {
  Serial.print("HDC2080:");
  //Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = "); Serial.print(HDC2080.readTemp());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = "); Serial.println(HDC2080.readHumidity());
}

void printValuesHDC1080() {
  Serial.print("HDC1080:");
  // Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(hdc1080.readTemperature());
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(hdc1080.readHumidity());
}

void printValuesAHT() {
  /* DEMO - 1, every temperature or humidity call will read 6 bytes over I2C, total 12 bytes */
  Serial.print(F("AHT10: "));
  Serial.write(9); // printing a tab using ASCII code
  Serial.print(F("T = ")); Serial.print(AHT.readTemperature()); //by default "AHT10_FORCE_READ_DATA"
  Serial.write(9); // printing a tab using ASCII code
  Serial.print(F("H = ")); Serial.println(AHT.readHumidity());    //by default "AHT10_FORCE_READ_DATA"
}


void printValueSi7021() {
  Serial.print(F("Si7021: "));
  // Serial.write(9); // printing a tab using ASCII code
  Serial.print("T = ");
  Serial.print(Si7021.readTemperature(), 2);
  Serial.write(9); // printing a tab using ASCII code
  Serial.print("H = ");
  Serial.println(Si7021.readHumidity(), 2);


  //
  //  // Toggle heater enabled state every 30 seconds
  //  // An ~1.8 degC temperature increase can be noted when heater is enabled
  //  if (++loopCnt == 30) {
  //    enableHeater = !enableHeater;
  //    Si7021.heater(enableHeater);
  //    // Serial.print("Heater Enabled State: ");
  //    if (Si7021.isHeaterEnabled()) {
  //      //  Serial.println("ENABLED");
  //    } else {
  //      // Serial.println("DISABLED");
  //
  //      loopCnt = 0;
}
  • Can you say, where exactly it stops working? Also please check the levels on the I2C lines. If the I2C interface is stuck, at least one of the lines will be at constant LOW. – chrisl Jul 31 at 17:45
  • It's mostly random. The last two times it was after printing all the sensor values and in the middle of printing the value for HTU21D sensor. – Zaffresky Jul 31 at 17:52
  • @chrisl How can I check the levels on the I2C lines? Do you mean checking it with a voltmeter? – Zaffresky Jul 31 at 17:54
  • Yes, I mean with a voltmeter. If one of the lines is constant low (0V) the I2C bus is stuck for some reason. In that case try to introduce small delays of a few ms between the readings of different sensors. Trying to read too fast might cause the bus to get stuck – chrisl Jul 31 at 17:57
  • The CLK line was stuck at 3.4V. After resetting the sketch (working normally) the CLK line alternates between 3.4V & 2.1V – Zaffresky Jul 31 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.