Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Rich Noordam
Published © GPL3+

NodeMCU Webserver with Class-Based 60-Second Temp Average

Averaging temperatures over 60 seconds smooths some of the sensor limitations, allowing for a smoother graphic.

BeginnerProtip1 hour2,215
NodeMCU Webserver with Class-Based 60-Second Temp Average

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
SparkFun Breadboard Power Supply 5V/3.3V
SparkFun Breadboard Power Supply 5V/3.3V
×1
Resistor 10k ohm
Resistor 10k ohm
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Fritz file

replace DHT11 with DHT22

Code

NodeMCU Webserver with DHT mean based data

Arduino
Note: I'm using static IP addresses on my local network, partially to distinguish locations.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#define DHTPIN 2

#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);

// IP address
IPAddress ip (192, 168, 1, 213);
IPAddress gateway(192, 168, 1, 1);  
IPAddress subnet(255, 255, 255, 0);  
const char* ssid = "<YOURSSID>";
const char* password = "<YOURPASSKEY>";

// built in LED to show activity
#define led 13
ESP8266WebServer server(80);

class TemperatureReader
{

  // Class Member Variables
  // Array variables
  float temperatureCArray[60]; // array to generate mean C Temperature value of last 60 readings.
  float temperatureFArray[60]; // array to generate mean F Temperature value of last 60 readings.
  float humidityArray[60]; // array to generate mean Humidity value of last 60 readings.

  // public variables
  public: bool readerReady; // determine if enough readings have been taken to allow mean data return.
  public: float currTempF; // current Mean temperature.
  public: float currTempC;
  public: float currHumidity;

  // These maintain the counter state
  int counter; // array positioner.
  unsigned long previousMillis;   // determines if new Temperature Reading is necessary 


  // Constructor - creates TempeatureReader
  // and initializes the member variables and state
  public: TemperatureReader()
  {
    // initialize variables.
    counter = 0;
    previousMillis = 0;
    currTempF = 0.0;
    currTempC = 0.0;
    currHumidity = 0.0;
    readerReady=false;
    for (int i=0; i < 60; i++){
      temperatureFArray[i] = 0.0;
      temperatureCArray[i] = 0.0;
      humidityArray[i] = 0.0;
    }
  }
 
  public: void Update()
  {
    float humidity = 0.0;
    float temperatureC = 0.0;
    float temperatureF = 0.0;
    // check to see if it's time to change the state of the LED
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis >= 1000)
    {
      humidity = doSensorReading("Humidity").toFloat();
      temperatureF = doSensorReading("TemperatureF").toFloat();
      temperatureC = doSensorReading("TemperatureC").toFloat();
      humidityArray[counter] = humidity;
      temperatureFArray[counter] = temperatureF;
      temperatureCArray[counter] = temperatureC;
      if (readerReady == true){
        // set reader ready to get mean data from.
        float sumHumidity = 0.0;
        float sumTemperatureF = 0.0;
        float sumTemperatureC = 0.0;
        for (int i=0; i < 60; i++){
          sumHumidity = sumHumidity + humidityArray[i];
          sumTemperatureF = sumTemperatureF + temperatureFArray[i];
          sumTemperatureC = sumTemperatureC + temperatureCArray[i];
        }
        currHumidity = sumHumidity/60;
        currTempF = sumTemperatureF/60;
        currTempC = sumTemperatureC/60;
        //Serial.println("TemperatureF: " + String(currTempF));
      } else {
        Serial.println("Calibrating:" + String(counter));
        if (counter == 59){
          readerReady = true;
        }
      }
      previousMillis = currentMillis;  // Reset to currentmillis after temperature taken.
      counter = counter + 1;
      if (counter > 59){
        counter = 0;
      }
    }
  }

  String doSensorReading(String sType){
    String returnString = "";
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);
    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
    } else {
      char cHumidity[7];
      char cTemperatureF[8];
      char cTemperatureC[8];
      String Humidity, TemperatureF, TemperatureC;
      dtostrf(h,6,1, cHumidity);
      dtostrf(f,6,1, cTemperatureF);
      dtostrf(t,6,1, cTemperatureC);
      Humidity = String(cHumidity);
      TemperatureF = String(cTemperatureF);
      TemperatureC = String(cTemperatureC);
      if (sType == "")
        returnString = "Humidity: " + Humidity + " %\t" +"Temperature: " + TemperatureC + " *C " + TemperatureF + " *F\t";
      if (sType == "TemperatureF")
        returnString = TemperatureF;
      if (sType == "TemperatureC")
        returnString = TemperatureC;
      if (sType == "Humidity")
        returnString = Humidity;
        // test stuff   Serial.print("Humidity: ");//    Serial.print(h);//    Serial.print(" %\t");//    Serial.print("Temperature: ");//    Serial.print(t);//    Serial.print(" *C ");//    Serial.print(f);//    Serial.print(" *F\t");//    Serial.print("Heat index: ");//    Serial.print(hic);//    Serial.print(" *C ");//    Serial.print(hif);//    Serial.println(" *F");  
    }
    return returnString;
  }
};
 
TemperatureReader tempReader;

void handleNotFound(){
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

void handleHumidity(){
    digitalWrite(led, 1);
    String output = String(tempReader.currHumidity);
    //output = "<html><head>Access-Control-Allow-Origin: 192.168.1.*</head>
    server.send(200, "text/plain", output );
    Serial.println(output);
    digitalWrite(led, 0);
}

void handleTemperatureC(){
    digitalWrite(led, 1);
    String output = String(tempReader.currTempC);
    server.send(200, "text/plain", output );
    Serial.println(output);
    digitalWrite(led, 0);
}
void handleTemperatureF(){
  digitalWrite(led, 1);
  String output = String(tempReader.currTempF);
  Serial.println(output);
  server.send(200, "text/plain", output );
  Serial.println(output);
  digitalWrite(led, 0);
}

void handleRoot() {
  digitalWrite(led, 1);
  String output = "";
  server.send(200, "text/plain", output );
  Serial.println(output);
  digitalWrite(led, 0);
} 
void setup()
{
  Serial.begin(9600);
  WiFi.begin(ssid, password);
  WiFi.config(ip, gateway, subnet); 
  dht.begin();
    // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }
  server.on("/", handleRoot);
  server.on("/TemperatureF", [](){
    handleTemperatureF();
  });
  server.on("/TemperatureC", [](){
    handleTemperatureC();
  });
  server.on("/Humidity", [](){
    handleHumidity();
  });
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
}
 
void loop()
{
  tempReader.Update();
  if (tempReader.readerReady == true){
    server.handleClient();
  }
}

Credits

Rich Noordam
10 projects • 33 followers
Many interests, computing obviously being one of them. MS SQL Server Database Administration, Reporting, Data Science, and more.

Comments