Multiple dht22 using 74HC4067 Multiplexer

Hello Everyone,

I have been struggling & bellow is my last effort. Aim is to display 8 numbers DHT22 Temp & Humidity on I2C LCD. Wokwi simulator is used to know whether my code is working correctly but all in vain as Display does not show value.

Note: in future I will use for 16 DHT, arduino will not have enough pins as 16 Pins for dht & other components like push buttons,LED hence Multiplexer is must

Could you please help me?

Thanks

Rezox

Bellow is wokwi link with code & connetion diagram

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <CD74HC4067.h>

// Pins for CD74HC4067 control
#define MUX_SIG 7
#define MUX_S0 8
#define MUX_S1 9
#define MUX_S2 10
#define MUX_S3 11

// LCD address and size
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

// DHT sensor type
#define DHT_TYPE DHT22

// Number of DHT sensors
#define NUM_SENSORS 8

// DHT sensor pins connected to the multiplexer channels
int dhtPins[NUM_SENSORS] = {A0, A1, A2, A3, A4, A5, A6, A7};

// Create an array of DHT objects
DHT dhtSensors[NUM_SENSORS] = {
  DHT(dhtPins[0], DHT_TYPE),
  DHT(dhtPins[1], DHT_TYPE),
  DHT(dhtPins[2], DHT_TYPE),
  DHT(dhtPins[3], DHT_TYPE),
  DHT(dhtPins[4], DHT_TYPE),
  DHT(dhtPins[5], DHT_TYPE),
  DHT(dhtPins[6], DHT_TYPE),
  DHT(dhtPins[7], DHT_TYPE)
};

// Create LiquidCrystal_I2C instance
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

void setup() {
  // Initialize CD74HC4067 control pins
  pinMode(MUX_SIG, OUTPUT);
  pinMode(MUX_S0, OUTPUT);
  pinMode(MUX_S1, OUTPUT);
  pinMode(MUX_S2, OUTPUT);
  pinMode(MUX_S3, OUTPUT);

  // Start I2C communication
  Wire.begin();

  // Initialize LCD
  lcd.begin(LCD_COLUMNS, LCD_ROWS);
  lcd.setBacklight(LOW); // Adjust backlight as needed

  // Initialize DHT sensors
  for (int i = 0; i < NUM_SENSORS; i++) {
    dhtSensors[i].begin();
  }
}

void loop() {
  // Loop through all sensors
  for (int i = 0; i < NUM_SENSORS; i++) {
    // Select the MUX channel
    selectMuxChannel(i);

    // Read temperature and humidity from the sensor
    float temperature = dhtSensors[i].readTemperature();
    float humidity = dhtSensors[i].readHumidity();

    // Display temperature and humidity on LCD
    displayData(i + 1, temperature, humidity);

    // Delay before moving to the next sensor
    delay(500);
  }
}

void selectMuxChannel(int channel) {
  digitalWrite(MUX_S0, channel & 0x01);
  digitalWrite(MUX_S1, (channel >> 1) & 0x01);
  digitalWrite(MUX_S2, (channel >> 2) & 0x01);
  digitalWrite(MUX_S3, (channel >> 3) & 0x01);
  digitalWrite(MUX_SIG, HIGH);
  delayMicroseconds(100);
  digitalWrite(MUX_SIG, LOW);
}

void displayData(int sensorIndex, float temperature, float humidity) {
  lcd.setCursor(0, sensorIndex - 1);
  lcd.print("Sensor ");
  lcd.print(sensorIndex);
  lcd.print(": T=");
  lcd.print(temperature);
  lcd.print("C, H=");
  lcd.print(humidity);
  lcd.print("%");
}

You may need to add pull-up resistors to the output pins of each DHT22. 4K7 or 10K should be fine.

Sir, added pullup resistors even same issue

Back to basics.

  1. Use a basic LiquidCrystal_I2C example to know if you can print to the display.
  2. In displayData(), use serial prints to know if your readings are OK.

Sir, Serial.print also used shows nanC , here is code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <CD74HC4067.h>

// Pins for CD74HC4067 control
#define MUX_SIG 7
#define MUX_S0 8
#define MUX_S1 9
#define MUX_S2 10
#define MUX_S3 11

// LCD address and size
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

// DHT sensor type
#define DHT_TYPE DHT22

// Number of DHT sensors
#define NUM_SENSORS 8

// DHT sensor pins connected to the multiplexer channels
int dhtPins[NUM_SENSORS] = {A0, A1, A2, A3, A4, A5, A6, A7};

// Create an array of DHT objects
DHT dhtSensors[NUM_SENSORS] = {
  DHT(dhtPins[0], DHT_TYPE),
  DHT(dhtPins[1], DHT_TYPE),
  DHT(dhtPins[2], DHT_TYPE),
  DHT(dhtPins[3], DHT_TYPE),
  DHT(dhtPins[4], DHT_TYPE),
  DHT(dhtPins[5], DHT_TYPE),
  DHT(dhtPins[6], DHT_TYPE),
  DHT(dhtPins[7], DHT_TYPE)
};

// Create LiquidCrystal_I2C instance
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

void setup() {

  Serial.begin(9600);
  // Initialize CD74HC4067 control pins
  pinMode(MUX_SIG, OUTPUT);
  pinMode(MUX_S0, OUTPUT);
  pinMode(MUX_S1, OUTPUT);
  pinMode(MUX_S2, OUTPUT);
  pinMode(MUX_S3, OUTPUT);

  // Start I2C communication
  Wire.begin();

  // Initialize LCD
  lcd.begin(LCD_COLUMNS, LCD_ROWS);
  lcd.setBacklight(LOW); // Adjust backlight as needed

  // Initialize DHT sensors
  for (int i = 0; i < NUM_SENSORS; i++) {
    dhtSensors[i].begin();
  }
}

void loop() {
  // Loop through all sensors
  for (int i = 0; i < NUM_SENSORS; i++) {
    // Select the MUX channel
    selectMuxChannel(i);

    // Read temperature and humidity from the sensor
    float temperature = dhtSensors[i].readTemperature();
    float humidity = dhtSensors[i].readHumidity();

    // Display temperature and humidity on LCD
    displayData(i + 1, temperature, humidity);

    // Delay before moving to the next sensor
    delay(500);
  }
}

void selectMuxChannel(int channel) {
  digitalWrite(MUX_S0, channel & 0x01);
  digitalWrite(MUX_S1, (channel >> 1) & 0x01);
  digitalWrite(MUX_S2, (channel >> 2) & 0x01);
  digitalWrite(MUX_S3, (channel >> 3) & 0x01);
  digitalWrite(MUX_SIG, HIGH);
  delayMicroseconds(100);
  digitalWrite(MUX_SIG, LOW);
}

void displayData(int sensorIndex, float temperature, float humidity) {
  lcd.setCursor(0, sensorIndex - 1);
  lcd.print("Sensor ");
  lcd.print(sensorIndex);
  lcd.print(": T=");
  lcd.print(temperature);
  lcd.print("C, H=");
  lcd.print(humidity);
  lcd.print("%");

  Serial.println(temperature);
  Serial.println(humidity);
}

I do not see them on your wokwi project.

You do not seem to have fully adapted your code to use the multiplexer. Your code is reading the sensors as if they were connected to pins A0 to A7. But Uno does not have pins A6 or A7, A4 & A5 are used for the display and A0-A3 are not connected.

Your sensors are all connected to pin 7 through the multiplexer.

I suspect you do not need an array of DHT objects. A single object will probably be ok I think.

I did not know that the display showed NanC. You said

I found Connecting multiple DHT 11 sensors - Arduino Stack Exchange; it mentions that analogue multiplexers might not be the correct choice due to (relatively high) internal resistance. I do not know if that is the cause of your problem but it might be something to keep in mind.

What I would try is to add a delay(500) between the switching and the reading; it will not address the possible resistance issue but will allow same stabilisation.

Sir,here I have used here DHT as its available in wokwi, in reality I will use thermocouple. want to be sure that code is working with multiplexer & LCD. So internal resistance is not worry to me. Just want to see temperature display on LCD

Here is simulator link with working code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <CD74HC4067.h>

// Pins for CD74HC4067 control
const byte MUX_SIG = 7;
const byte MUX_S[4] = {8, 9, 10, 11} ;
const byte lohi[2] = {LOW, HIGH};

// LCD address and size
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2

// DHT sensor type
#define DHT_TYPE DHT22

// Number of DHT sensors
#define NUM_SENSORS 8

// DHT sensor pins connected to the multiplexer channels

// Create a DHT object
DHT dhtSensor(MUX_SIG, DHT_TYPE),

// Create LiquidCrystal_I2C instance
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

void setup() {

  Serial.begin(9600);
  // Initialize CD74HC4067 control pins
  pinMode(MUX_SIG, INPUT);
  for (byte s=0; s<4; s++) pinMode(MUX_S[s], OUTPUT);

  // Start I2C communication
  Wire.begin();

  // Initialize LCD
  lcd.begin(LCD_COLUMNS, LCD_ROWS);
  lcd.setBacklight(LOW); // Adjust backlight as needed

  // Initialize DHT sensor
  dhtSensor.begin();
}

void loop() {
  // Loop through all sensors
  for (int i = 0; i < NUM_SENSORS; i++) {
    // Select the MUX channel
    selectMuxChannel(i);

    // Read temperature and humidity from the sensor
    float temperature = dhtSensor.readTemperature();
    float humidity = dhtSensor.readHumidity();

    // Display temperature and humidity on LCD
    displayData(i + 1, temperature, humidity);

    // Delay before moving to the next sensor
    delay(500);
  }
}

void selectMuxChannel(int channel) {
  for (byte s=0; s<4; s++) digitalWrite(MUX_S[s], lohi[bitRead(channel, s)]);
  delayMicroseconds(100);
}

void displayData(int sensorIndex, float temperature, float humidity) {
  lcd.setCursor(0, sensorIndex - 1);
  lcd.print("Sensor ");
  lcd.print(sensorIndex);
  lcd.print(": T=");
  lcd.print(temperature);
  lcd.print("C, H=");
  lcd.print(humidity);
  lcd.print("%");

  Serial.println(temperature);
  Serial.println(humidity);
}

// DHT sensor pins connected to the multiplexer channels

int dhtPins[NUM_SENSORS] = {A0, A1, A2, A3, A4, A5, A6, A7};

These are multiplexer Pins A0, A1, A2, A3, A4, A5, A6, A7 connected with each DHT OUTPUT

You are mistaken.

oh..... but I have doubt .... Individual Output is supposed to be connected to S0 to S7 of Multiplexer & Multiplexer Output Signal will be connected to Uno Pin.

If these are A0, A1, A2, A3, A4, A5, A6, A7 uno/mega pin ... it means we are not using Multiplexer.
Correct me plz,if am wrong

Sir, I used your code showing same issue here is the link Mux with dht22 - Wokwi ESP32, STM32, Arduino Simulator

See post #2

Sir, pulled up resistor is used for 3 DHT22 to see display....display shows nanC si I didnt use for rest of DHts......
Here is the link

The ENable pin of the multiplexer should be connected to ground.

But I already tried that on Wokwi and also tried adding pull-up resistors on the sensor data pins and Arduino pins. But none of these things worked.

I tried connecting one of the sensors directly to pin 7 and I see expected temperature and humidity values.

I don't know enough about wokwi to know if the way it models components would cause the problem. I think the circuit should work in reality.

Thank you Sir for your efforts

hi,
in my projects with A.uno and A.mega have always "debug" infos by
Serial.println(...) and lcd.print(..) seems to be useful like

messaging status like this

message = "gGbs_new_pinnums_6.ino GG29 for mega";
  //Serial.print(message);
  lcd.lineWrap();
  lcd.print(message);  
  delay(LONG_SHOW_DELAY);

and 

  message = "Setup ready";
  //Serial.println(message);
  lcd.clear();
  lcd.print(message);
  delay(LONG_SHOW_DELAY);
 

and in for loops i always insert info about loop-index and variables filled (or not ?)

further there is a gui with more information than Arduino-IDE gives

cppcheckgui.exe

the extension must be modified from .ino to .cpp
then one get warning and error messages checking code ..

thats all what i can help here at now..

i have ordered 74hc4067 because have similar project with light-barriers on model-railway
for A.mega..

is it enough or is double needed ?
you may google for cpp dataypes..