Two ENS160+AHT21 with a multiplexer

Hi, I have this circuit,


and this code:


#include <Wire.h>
#include "DFRobot_ENS160.h"
#include "Adafruit_AHTX0.h"
// Create ENS160 and AHT21 instances for two channels
DFRobot_ENS160_I2C ens160_1(&Wire, 0x53);
DFRobot_ENS160_I2C ens160_2(&Wire, 0x53);
Adafruit_AHTX0 aht_1;
Adafruit_AHTX0 aht_2;
// Multiplexer address
#define TCA_ADDR 0x70
// Function to select a multiplexer channel (0–7)
void tcaSelect(uint8_t channel) {
  if (channel > 7) return;
  Wire.beginTransmission(TCA_ADDR);
  Wire.write(1 << channel);
  Wire.endTransmission();
}
void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing sensors via TCA9548A...");
  // --- Channel 0: Sensor Module 1 ---
  tcaSelect(0);
  if (!aht_1.begin()) {
    Serial.println("AHT21 #1 not found! Check wiring on channel 0.");
    while (1) delay(10);
  }
  while (ens160_1.begin() != NO_ERR) {
    Serial.println("Waiting for ENS160 #1...");
    delay(3000);
  }
  ens160_1.setPWRMode(ENS160_STANDARD_MODE);
  // --- Channel 1: Sensor Module 2 ---
  tcaSelect(1);
  if (!aht_2.begin()) {
    Serial.println("AHT21 #2 not found! Check wiring on channel 1.");
    while (1) delay(10);
  }
  while (ens160_2.begin() != NO_ERR) {
    Serial.println("Waiting for ENS160 #2...");
    delay(3000);
  }
  ens160_2.setPWRMode(ENS160_STANDARD_MODE);
  Serial.println("Both sensor sets ready. Warming up...");
  delay(60000);  // 60-second warm-up
}
void loop() {
  sensors_event_t humidity1, temp1, humidity2, temp2;
  // --- Channel 0: Module 1 ---
  tcaSelect(0);
  aht_1.getEvent(&humidity1, &temp1);
  ens160_1.setTempAndHum(temp1.temperature, humidity1.relative_humidity);
  Serial.println("=== Sensor Module 1 (TCA Ch. 0) ===");
  printSensorData(ens160_1, temp1.temperature, humidity1.relative_humidity);
  // --- Channel 1: Module 2 ---
  tcaSelect(1);
  aht_2.getEvent(&humidity2, &temp2);
  ens160_2.setTempAndHum(temp2.temperature, humidity2.relative_humidity);
  Serial.println("=== Sensor Module 2 (TCA Ch. 1) ===");
  printSensorData(ens160_2, temp2.temperature, humidity2.relative_humidity);
  Serial.println("==================================");
  delay(5000);
}
// Helper function to print one module's data
void printSensorData(DFRobot_ENS160_I2C &ens, float temp, float hum) {
  uint8_t status = ens.getENS160Status();
  if (status == 0 || status == 1 || status == 2) {
    Serial.print("eCO2: "); Serial.print(ens.getECO2()); Serial.println(" ppm");
    Serial.print("TVOC: "); Serial.print(ens.getTVOC()); Serial.println(" ppb");
    Serial.print("AQI:  "); Serial.println(ens.getAQI());
  }
  Serial.print("Temp: "); Serial.print(temp); Serial.println(" °C");
  Serial.print("Hum:  "); Serial.print(hum); Serial.println(" %");
  Serial.println("---");
}
/*
Connection	Description
Uno/Nano SDA (A4) → TCA9548A SDA	Shared data line
Uno/Nano SCL (A5) → TCA9548A SCL	Shared clock line
TCA9548A VCC → 5V (or 3.3V), GND → GND	Power
Channel 0 (SDA0/SCL0) → ENS160 #1 + AHT21 #1	First module
Channel 1 (SDA1/SCL1) → ENS160 #2 + AHT21 #2	Second module
Both ENS160 and AHT21 on each channel use the same addresses (0x53 and 0x38), but the TCA9548A isolates them.
*/

Unfortunately, the serial output is just:
-> Initializing sensors via TCA9548A...
-> AHT21 #1 not found! Check wiring on channel 0.

I have checked and checked...Any suggestions are very welcome,

Try this special version of the i2c scanner sketch for use with multiplexer:

Can it detect ENS160 and AHT21 on channels 0 & 1?

No (there's no "Found I2C 0x" message)...

Ok, comment or delete this line out to check if it can detect the multiplexer:

if (addr == TCAADDR) continue;

Hm, same output:
TCA9548A Scanner ready!

TCA Port #0

TCA Port #1

TCA Port #2

TCA Port #5

TCA Port #6

TCA Port #7

Scan completed.

So it can't even detect the multiplexer...

Can you post a photo of your circuit. Please make sure it's bright and sharp, taken from directly above, and all the wires can be seen and traced.

If you are using Dupont wires, check each one with a multimeter.

Also check that there isn't a break half way along the 5V or GND bus on your breadboard. Some breadboard designs have this break.

You could also try powering the sensor modules with 5V to their Vin pins. The 3.3V pin on a Nano is very weak and can only supply a small current. It could be that these modules need a larger current. But continue to power the multiplexer with 3.3V from the Nano.

Did any of your modules arrive with the PCB header pins not soldered on? If so, did you solder them, and make a neat job? Simply pushing the PCB header pins through the module's holes is very unlikely to work, and dry solder joints, shorts etc could be another reason.

Probably my inept soldering then... I have tried 5V, still no luck

Yeah, it's not good :blush:

Thank you so much; you've given me a lot to work on. I get a new multiplex and work on my soldering technique, i rrally do looks horrible

It's probably ok, you just need to re-solder it. You will need a solder-sucker or de-soldering braid to remove the old solder.

You can try using the SoftI2C library. It will enable you to create several I2C ports so you don't need the multiplexer at all.

Thank you! I am trying to merge the coding. When using the SoftI2C, I suppose I will have to change the declarations:

DFRobot_ENS160_I2C airQualitySensor(&Wire, 0x53); // ENS160 I2C-adress
Adafruit_AHTX0 aht; // AHT21 temperature- og humiditysensor 

I would be grateful for a little help with that

Working on it

I made changes to your original code. I put a row of '*' before the changes I made. I did not remove the code for the multiplexer but you should do that.

One sensor is on the hardware I2C pins and the other is on digital pins 5 and 6.

I don't have the sensors so I can't test the code.

#include <Wire.h>
#include "DFRobot_ENS160.h"
#include "Adafruit_AHTX0.h"
//************************************************
SoftI2C SoftWire = SoftI2C(5, 6); //SDA, SCL

// Create ENS160 and AHT21 instances for two channels
DFRobot_ENS160_I2C ens160_1(&Wire, 0x53);

//************************************************
DFRobot_ENS160_I2C ens160_2(&SoftWire, 0x53); 

Adafruit_AHTX0 aht_1;
Adafruit_AHTX0 aht_2;


// Multiplexer address
#define TCA_ADDR 0x70
// Function to select a multiplexer channel (0–7)
void tcaSelect(uint8_t channel) {
  if (channel > 7) return;
  Wire.beginTransmission(TCA_ADDR);
  Wire.write(1 << channel);
  Wire.endTransmission();
}
void setup() {
  Serial.begin(115200);
  Wire.begin();
  Serial.println("Initializing sensors via TCA9548A...");
  // --- Channel 0: Sensor Module 1 ---
  tcaSelect(0);
  if (!aht_1.begin()) {
    Serial.println("AHT21 #1 not found! Check wiring on channel 0.");
    while (1) delay(10);
  }
  while (ens160_1.begin() != NO_ERR) {
    Serial.println("Waiting for ENS160 #1...");
    delay(3000);
  }
  ens160_1.setPWRMode(ENS160_STANDARD_MODE);
  // --- Channel 1: Sensor Module 2 ---
  tcaSelect(1);

  //************************************************
  if (!aht_2.begin(&SoftWire, 1, 0x38)) {
    Serial.println("AHT21 #2 not found! Check wiring on channel 1.");
    while (1) delay(10);
  }
  while (ens160_2.begin() != NO_ERR) {
    Serial.println("Waiting for ENS160 #2...");
    delay(3000);
  }
  ens160_2.setPWRMode(ENS160_STANDARD_MODE);
  Serial.println("Both sensor sets ready. Warming up...");
  delay(60000);  // 60-second warm-up
}
void loop() {
  sensors_event_t humidity1, temp1, humidity2, temp2;
  // --- Channel 0: Module 1 ---
  tcaSelect(0);
  aht_1.getEvent(&humidity1, &temp1);
  ens160_1.setTempAndHum(temp1.temperature, humidity1.relative_humidity);
  Serial.println("=== Sensor Module 1 (TCA Ch. 0) ===");
  printSensorData(ens160_1, temp1.temperature, humidity1.relative_humidity);
  // --- Channel 1: Module 2 ---
  tcaSelect(1);
  aht_2.getEvent(&humidity2, &temp2);
  ens160_2.setTempAndHum(temp2.temperature, humidity2.relative_humidity);
  Serial.println("=== Sensor Module 2 (TCA Ch. 1) ===");
  printSensorData(ens160_2, temp2.temperature, humidity2.relative_humidity);
  Serial.println("==================================");
  delay(5000);
}
// Helper function to print one module's data
void printSensorData(DFRobot_ENS160_I2C &ens, float temp, float hum) {
  uint8_t status = ens.getENS160Status();
  if (status == 0 || status == 1 || status == 2) {
    Serial.print("eCO2: "); Serial.print(ens.getECO2()); Serial.println(" ppm");
    Serial.print("TVOC: "); Serial.print(ens.getTVOC()); Serial.println(" ppb");
    Serial.print("AQI:  "); Serial.println(ens.getAQI());
  }
  Serial.print("Temp: "); Serial.print(temp); Serial.println(" °C");
  Serial.print("Hum:  "); Serial.print(hum); Serial.println(" %");
  Serial.println("---");
}
/*
Connection	Description
Uno/Nano SDA (A4) → TCA9548A SDA	Shared data line
Uno/Nano SCL (A5) → TCA9548A SCL	Shared clock line
TCA9548A VCC → 5V (or 3.3V), GND → GND	Power
Channel 0 (SDA0/SCL0) → ENS160 #1 + AHT21 #1	First module
Channel 1 (SDA1/SCL1) → ENS160 #2 + AHT21 #2	Second module
Both ENS160 and AHT21 on each channel use the same addresses (0x53 and 0x38), but the TCA9548A isolates them.
*/

I forgot

#include <SoftI2C.h>

put it at the beginning.

Thank you very much. When trying to verify, it says: no matching function for call to 'DFRobot_ENS160_I2C::DFRobot_ENS160_I2C(SoftI2C*, int)

Did you see post #18

I know softI2c works but I have not tried to use it with a library. Apparently the DFRobot library will only work with hardware I2C.