Add second DHT11 sensor to EPS32 arduino code

I am new to Arduino and wondering what the best way forward is to add an extra DHT11 to the same ESP32. I have one DHT11 sensor working correctly. When i add a second DHT11 sensor to the same EPS32 (WROOM-32) i get only the Humidity output of sensor 2 and Temperature output of sensor 1 outputted:

12:54:00.763 -> humi sensor 1: 28.00
12:54:08.107 -> temp sensor 2: 24.10
12:54:10.856 -> humi sensor 1: 28.00
12:54:17.919 -> temp sensor 2: 24.10
12:54:20.722 -> humi sensor 1: 28.00
12:54:28.139 -> temp sensor 2: 24.10
12:54:30.895 -> humi sensor 1: 28.00

I just went and duplicated the code (not the best way to do things but it "should" be able to work) as follows:

// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include <Adafruit_Sensor.h>
#include <DHT.h>

// Replace with your network credentials
const char* ssid = "welcomeneighbor";
const char* password = "1234";

const int tempfix = 2;  // 2 verminderen
const int humifix = 10; // 10 toevoegen

#define DHTPIN 4     // Digital pin connected to the DHT sensor
#define DHTPIN2 5     // Digital pin connected to the DHT sensor

// Uncomment the type of sensor in use:
#define DHTTYPE    DHT11     // DHT 11
// #define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
///////////////////////////////////////////////////////////////////////////////
// sensor 1
String readDHTTemperature() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature() - tempfix;
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float t = dht.readTemperature(true);
  // Check if any reads failed and exit early (to try again).
  if (isnan(t)) {    
    Serial.println("Failed to read from DHT temp sensor 1!");
    return "--";
  }
  else {
    Serial.print("temp sensor 1: ");
    Serial.println(t);
    return String(t);
  }
}

String readDHTHumidity() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity() + humifix;
  if (isnan(h)) {
    Serial.println("Failed to read from DHT humi sensor 1!");
    return "--";
  }
  else {
    Serial.print("humi sensor 1: ");
    Serial.println(h);
    return String(h);
  }
}
///////////////////////////////////////////////////////////////////////////////
// sensor 2
String readDHTTemperature2() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  // Read temperature as Celsius (the default)
  float t2 = dht2.readTemperature() - tempfix;
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float t = dht.readTemperature(true);
  // Check if any reads failed and exit early (to try again).
  if (isnan(t2)) {    
    Serial.println("Failed to read from DHT temp sensor 2!");
    return "--";
  }
  else {
    Serial.print("temp sensor 2: ");
    Serial.println(t2);
    return String(t2);
  }
}

String readDHTHumidity2() {
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h2 = dht2.readHumidity() + humifix;
  if (isnan(h2)) {
    Serial.println("Failed to read from DHT humi sensor 2!");
    return "--";
  }
  else {
    Serial.print("humi sensor 2: ");
    Serial.println(h2);
    return String(h2);
  }
}
///////////////////////////////////////////////////////////////////////////////
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .dht-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
    }
  </style>
</head>
<body>
  <h2>DHT Server</h2>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="dht-labels">Temperature</span> 
    <span id="temperature">%TEMPERATURE%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-tint" style="color:#00add6;"></i> 
    <span class="dht-labels">Humidity</span>
    <span id="humidity">%HUMIDITY%</span>
    <sup class="units">&percnt;</sup>
  </p>
  <hr>
  <p>
    <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> 
    <span class="dht-labels">Temperature2</span> 
    <span id="temperature2">%TEMPERATURE2%</span>
    <sup class="units">&deg;C</sup>
  </p>
  <p>
    <i class="fas fa-tint" style="color:#00add6;"></i> 
    <span class="dht-labels">Humidity2</span>
    <span id="humidity2">%HUMIDITY2%</span>
    <sup class="units">&percnt;</sup>
  </p>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 10000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("humidity").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/humidity", true);
  xhttp.send();
}, 10000 ) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperature2").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperature2", true);
  xhttp.send();
}, 10000 ) ;

setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("humidity2").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/humidity2", true);
  xhttp.send();
}, 10000 ) ;
</script>
</html>)rawliteral";

// Replaces placeholder with DHT values
String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return readDHTTemperature();
  }
  else if(var == "HUMIDITY"){
    return readDHTHumidity();
  }
  else if(var == "TEMPERATURE2"){
    return readDHTTemperature2();
  }
  else if(var == "HUMIDITY2"){
    return readDHTHumidity2();
  }
  return String();
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  dht.begin();
  dht2.begin();
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTTemperature().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTHumidity().c_str());
  });


  server.on("/temperature2", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTTemperature2().c_str());
  });
  server.on("/humidity2", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTHumidity2().c_str());
  });

  // Start server
  server.begin();
}
 
void loop(){
  
}

Start by making it easier to help you by writing a small but complete sketch that does nothing but read the 2 sensors and print the 4 results to the Serial monitor with text labels indicating what is being printed. Print the actual values returned without converting them to Strings

Sure, like so:

#include "DHT.h"
DHT sensor1(4, DHT11);
DHT sensor2(5, DHT11); 
float sensor1_temp,
      sensor2_temp;

float sensor1_humi,
      sensor2_humi;

void setup(void) {
  Serial.begin(9600);
  sensor1.begin();
  sensor2.begin();
}

void loop() {
  sensor1_temp = sensor1.readTemperature();
  sensor1_humi = sensor1.readHumidity();
  sensor2_temp = sensor2.readTemperature();
  sensor2_humi = sensor2.readHumidity();
  
  Serial.print("Sensor-1 Readings:  ");
  Serial.print(sensor1_temp,1); Serial.print(String(char(176))+"C  ");
  Serial.print(sensor1_humi,1); Serial.println("%RH");
  Serial.println();

  Serial.print("Sensor-2 Readings:  ");
  Serial.print(sensor2_temp,1); Serial.print(String(char(176))+"C  ");
  Serial.print(sensor2_humi,1); Serial.println("%RH");
  Serial.println();

  delay(3000);
}

But do i get the results in the webserver?

If that code gets the 4 expected values in 4 separate variables then the problem is in including it in the webserver page

Your code seems to make a mixture of Strings and strings in what is sent to the webserver

What is this section of code meant to do ?

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
  {
    request->send_P(200, "text/html", index_html, processor);
  });

The processor() function takes a parameter and returns a String, the but the code above seems not to call the function anyway and certainly does not provide a parameter

Next you do

  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest * request)
  {
    request->send_P(200, "text/plain", readDHTTemperature().c_str());
  });

and so on, which sends a C string

I have very little experience of webservers on the ESP32, and none with an asynchronous webserver, but in my experiments I used C strings throughout and the sprintf() function to build the string to be sent

Would it be possible to return some text with the string like forexample so?

return String("some text" + t1);

What i got thus far is an actual webserver output. But it would be nice if it will be outputted with some additional text, like:
sensor 1 temp: XX, humidity: XX
sensor 2 temp: XX, humidity: XX

what i am using now:

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){

  sensor1_temp = sensor1.readTemperature();
  sensor1_humi = sensor1.readHumidity();
  sensor2_temp = sensor2.readTemperature();
  sensor2_humi = sensor2.readHumidity();

  Serial.print("Sensor 1 temp: ");
  Serial.println(sensor1_temp);

//    request->send_P(200, "text/plain", "Sensor 1: ");
    request->send_P(200, "text/plain", sensorReadings().c_str());
  });

  server.begin();
}

It looks like the sensorReadings() function is something that you wrote and it looks like it returns a String and that you convert it to a C string

Please post the complete sketch that you are using, including the sensorReadings() function

Hi,
Sorry that code doesn't even compile.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
https://forum.arduino.cc/index.php?topic=712198.0
Then look down to "code problems" about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

Thanks for posting the code but please do us all a favour and Auto format your code in the IDE, use Copy for forum in the IDE and paste it here so that it is code tags to make it easier to read and copy for examination

I will look at it when you have done that

oeps...

obvious!

#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "DHT.h"
DHT sensor1(4, DHT11);
DHT sensor2(5, DHT11); 

const char* ssid = "welcome";
const char* password = "1234";

float sensor1_temp,
      sensor2_temp;

float sensor1_humi,
      sensor2_humi;

AsyncWebServer server(80);

// sensor 2
String sensorReadings() {
  float t1 = sensor1.readTemperature();
  float h1 = sensor1.readHumidity();
  // temperature 1
  if (isnan(t1)) {    
    Serial.println("Failed to read from DHT temp sensor 1!");
    return "--";
  }
  else {
    Serial.print("temp sensor 1: ");
    Serial.println(t1);
    return String(t1);
  }
  // humidity 1
  if (isnan(h1)) {    
    Serial.println("Failed to read from DHT humi sensor 1!");
    return "--";
  }
  else {
    Serial.print("humi sensor 1: ");
    Serial.println(h1);
    return String(h1);
  }
}

void setup(){
  Serial.begin(9600);
  sensor1.begin();
  sensor2.begin();

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){


  sensor1_temp = sensor1.readTemperature();
  sensor1_humi = sensor1.readHumidity();
  sensor2_temp = sensor2.readTemperature();
  sensor2_humi = sensor2.readHumidity();

  request->send_P(200, "text/plain", "Sensor 1: ");             // will be returned
  request->send_P(200, "text/plain", sensorReadings().c_str()); // will not be returned
  });

  server.begin();
}

void loop(){}

The first thing I see is that the sensorReadings() function only returns the first reading it makes that is a number. So, if t1 is a number then that is all you will get back and it never even tries to read sensor2

Presumably you want all 4 readings and you seem determined to use Strings, so you could read all 4 of them into separate Strings in a function, substituting say "#" for invalid values, then format a String to return containing text and variables and return that

Which Arduino are you using ?

ESP32 WROOM 30 pins

you got a sample?

Try a function like this

String getValues()
{
  sensor1_temp = sensor1.readTemperature();
  sensor1_humi = sensor1.readHumidity();
  sensor2_temp = sensor2.readTemperature();
  sensor2_humi = sensor2.readHumidity();
  String output = "  Sensor 1 : temp: " + String(sensor1_temp) + " hum: " + String(sensor1_humi);
  output += "\n\  //insert a carriage return
  ";
  output += "Sensor 2 : temp: " + String(sensor2_temp) + " hum: " + String(sensor2_humi);
  return output;
}

and call it and use what it returns like this

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
  {
    String output = getValues();
    request->send_P(200, "text/plain", output.c_str());             // will be returned
  });

Of course, once you have got the 4 values in the function you can lay them and associated text out how you like, including HTML commands if you want

the good old += operator

in PHP I use to use .=

thanks!

It is just a quicker way of typing aString = aString + "something else"

Personally I probably would not use Strings, particularly as the resulting String is going to be converted to a C string anyway. I would probably use sprintf() to build the required C string and use it directly, but Strings are used extensively with ESP8266 and ESP32 based systems because they have much more memory than the AVR based where they can cause problems

Little strange, some sketch uploads result in 99% sensor 1 and 2 value returns and most others i get 30-40% sensor 2 returns, the other 70-60% for sensor 2 i get for temperature and humidity NAN (none available).

The code and connections are the same...

Sorry but I cannot explain that. I tested what I posted on an ESP32 with a DHT11 and a DHT22 and got solid results from both

Hi,
Can you post a copy of your circuit diagram please?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

Sure!

(i replace the parts that weren't available and changed them with similar/close-to-next optional)

the corrected version: