Page 1 of 1

Add functionality for LEDs, Buzzer with exiting Web Server functionality

Posted: Sun Oct 22, 2023 3:44 pm
by KO4OEH
Good day all! I'm fairly new to working with development boards in general and hopeful that someone might be able to help me out with a code issue I'm running into.

I've already got working the following code for an ESP32 Environmental Web Server that outputs the values associated with sensors BME280, MQ2, MQ4, and MQ135 to a simple Web server (again this is working code):

Code: Select all

#include <MQUnifiedsensor.h>
#include <Wire.h>
#include <NTPClient.h>
#include <Time.h>
#include <WiFi.h>
#include <WebServer.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1014.5)
#define board "ESP32"
#define Voltage_Resolution 3.3
#define pin 34 //Analog input 0 of your ESP32
#define pin2 35 //Analog input 1 of your ESP32
#define pin3 32 //Analog input 2 of ESP32
#define type "MQ-135" //MQ135
#define type2 "MQ-2" //MQ2
#define type3 "MQ-4" //MQ4
#define ADC_Bit_Resolution 12 // For ESP32
#define RatioMQ135CleanAir (3.6) //RS / R0 = 3.6 ppm
#define RatioMQ2CleanAir (9.83) //RS / R0 = 9.83 ppm 
#define RatioMQ4CleanAir (4.4) //RS / R0 = 60 ppm   

MQUnifiedsensor MQ135(board, Voltage_Resolution, ADC_Bit_Resolution, pin, type);
MQUnifiedsensor MQ2(board, Voltage_Resolution, ADC_Bit_Resolution, pin2, type2);
MQUnifiedsensor MQ4(board, Voltage_Resolution, ADC_Bit_Resolution, pin3, type3);

Adafruit_BME280 bme;

float temperature, fahrenheit, humidity, pressure, altitude, altfeet, CO2, H2, Smoke;
String formattedTime;
String Date;
int Day;
int Month;
int Year;

/*Put your SSID & Password*/
const char* ssid = "BellDOTnet";  // Enter SSID here
const char* password = "D3lt@H3x01";  //Enter Password here

WebServer server(80);    

WiFiUDP ntpUDP;

//NTP Client
NTPClient timeClient(ntpUDP, "us.pool.ntp.org", -18000, 18000);
unsigned long epochTime = timeClient.getEpochTime();
struct tm *ptm = gmtime ((time_t *)&epochTime);
 
void setup() {
  Serial.begin(115200);
  delay(100);
  
  bme.begin(0x76);   // 0x76 is the default address of the I2C chip

  Serial.println("Connecting to ");
  Serial.println(ssid);

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");

  timeClient.begin();

  MQ135.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ135.setA(110.47); MQ135.setB(-2.862); // Configure the equation to to calculate CO2 concentration

  MQ135.init();  

  Serial.print("Calibrating please wait.");
  float calcR0 = 0;
  for(int i = 1; i<=10; i ++)
  {
    MQ135.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ135.calibrate(RatioMQ135CleanAir);
    Serial.print(".");
  }
  MQ135.setR0(calcR0/10);
  Serial.println("  done!.");

  MQ2.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ2.setA(987.99); MQ2.setB(-2.162); // Configure the equation to to calculate LPG concentration

  MQ2.init(); 

  Serial.print("Calibrating please wait.");
  for(int i = 1; i<=10; i ++)
  {
    MQ2.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ2.calibrate(RatioMQ2CleanAir);
    Serial.print(".");
  }
  MQ2.setR0(calcR0/10);
  Serial.println("  done!.");

  MQ4.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ4.setA(30000000); MQ4.setB(-8.308);

  MQ4.init();

  Serial.print("Calibrating please wait.");
  for(int i = 1; i<=10; i ++)
  {
    MQ4.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ4.calibrate(RatioMQ4CleanAir);
    Serial.print(".");
  }
  MQ4.setR0(calcR0/10);
  Serial.println("  done!.");
}

void loop() {

  server.handleClient();

}

void handle_OnConnect() {

  timeClient.update();

   unsigned long epochTime = timeClient.getEpochTime();
   String formattedTime = timeClient.getFormattedTime();

  struct tm *ptm = gmtime ((time_t *)&epochTime);

  int monthDay= ptm->tm_mday;
  int currentMonth = ptm->tm_mon+1;
  int currentYear = ptm->tm_year+1900;
 
  formattedTime = timeClient.getFormattedTime(); 
  Date = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);

  temperature = bme.readTemperature();
  fahrenheit = (temperature * 9/5) + 32;
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
  altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
  altfeet = (altitude * 3.281);

  MQ135.setA(110.47); MQ135.setB(-2.862); // Configure the equation to calculate CO2 concentration value
  float CO2 = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ2.setA(987.99); MQ2.setB(-2.162); //Configure the equation to calculate Smoke concentration value
  float H2 = MQ2.readSensor(); // Sensor will read the PPM concentration using the model, a and b values set previously or from the setup

  MQ4.setA(30000000); MQ4.setB(-8.308); // Configure the equation to to calculate CH4 concentration
  float Smoke = MQ4.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.update();
  MQ2.update();
  MQ4.update();

  server.send(200, "text/html", SendHTML(temperature,fahrenheit,humidity,pressure,altitude,altfeet,CO2,H2,Smoke,formattedTime,Date)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(float temperature, float fahrenheit, float humidity, float pressure, float altitude, float altfeet, float CO2, float H2, float Smoke, String TimeWeb, String DateWeb){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>Garage Environmental Monitoring</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
  ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<div id=\"webpage\">\n";
  ptr +="<h1>Garage Environmental Monitoring</h1>\n";
  ptr +="<p>Temperature: ";
  ptr +=temperature;
  ptr +="&deg;C</p>";
  ptr +="<p>Temperature: ";
  ptr +=fahrenheit;
  ptr +="&deg;F</p>";
  ptr +="<p>Humidity: ";
  ptr +=humidity;
  ptr +="%</p>";
  ptr +="<p>Pressure: ";
  ptr +=pressure;
  ptr +="hPa</p>";
  ptr +="<p>Altitude: ";
  ptr +=altitude;
  ptr +="m</p>";
  ptr +="<p>Altitude: ";
  ptr +=altfeet;
  ptr +="ft</p>";
  ptr +="<p>CO2 Level: ";
  ptr +=CO2 + 416;
  ptr +="ppm</p>";
  ptr +="<p>H2 Level: ";
  ptr +=H2;
  ptr +="ppm</p>";
  ptr +="<p>Smoke Level: ";
  ptr +=Smoke;
  ptr +="ppm</p>";
  ptr +="<p>Time: ";
  ptr +=(String)TimeWeb;
  ptr +="</p>";
  ptr +="<p>Date: ";
  ptr +=(String)DateWeb;
  ptr +="</p>";
  ptr +="</div>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}
What I'd like to be able to do is also add the following pieces to this code to allow certain LEDs and a buzzer to work along with the existing code once certain thresholds are reached by the MQ sensors. However, when I add it as I have below, I keep running into the following error: 'error: 'handle_NotFound' was not declared in this scope server.onNotFound(handle_NotFound);

Here is the code with the functionality I'd like added that is returning the above error:

Code: Select all

#include <MQUnifiedsensor.h>
#include <Wire.h>
#include <NTPClient.h>
#include <Time.h>
#include <WiFi.h>
#include <WebServer.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1014.5)
#define placa "ESP32"
#define Voltage_Resolution 3.3
#define pin 34 //Analog input 0 of ESP32
#define pin2 35 //Analog input 1 of ESP32
#define pin3 32 //Analog input 2 of ESP32
#define type "MQ-135" //MQ135
#define type2 "MQ-2" //MQ2
#define type3 "MQ-4" //MQ4
#define ADC_Bit_Resolution 12 // For ESP32
#define RatioMQ135CleanAir 3.6//RS / R0 = 3.6 ppm
#define RatioMQ2CleanAir (9.83) //RS / R0 = 9.83 ppm 
#define buzzer 13
#define redLED 12
#define greenLED 14
#define blueLED 27
#define yellowLED 26  

MQUnifiedsensor MQ135(placa, Voltage_Resolution, ADC_Bit_Resolution, pin, type);
MQUnifiedsensor MQ2(placa, Voltage_Resolution, ADC_Bit_Resolution, pin2, type2);
MQUnifiedsensor MQ4(placa, Voltage_Resolution, ADC_Bit_Resolution, pin3, type3);

Adafruit_BME280 bme;

float temperature, fahrenheit, humidity, pressure, altitude, altfeet, CO2, H2, Smoke;
String formattedTime;
String Date;
int Day;
int Month;
int Year;

int sensorThres = 420;

/*Put your SSID & Password*/
const char* ssid = "BellDOTnet";  // Enter SSID here
const char* password = "D3lt@H3x01";  //Enter Password here

WebServer server(80);    

WiFiUDP ntpUDP;

//NTP Client
NTPClient timeClient(ntpUDP, "us.pool.ntp.org", -18000, 18000);
unsigned long epochTime = timeClient.getEpochTime();
struct tm *ptm = gmtime ((time_t *)&epochTime);
 
void setup() {
  Serial.begin(115200);
  delay(100);
  
  bme.begin(0x76);   // 0x76 is the default address of the I2C chip

  Serial.println("Connecting to ");
  Serial.println(ssid);

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");

  timeClient.begin();

  MQ135.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ135.setA(110.47); MQ135.setB(-2.862); // Configure the equation to to calculate CO2 concentration

  MQ135.init();

  Serial.print("Calibrating please wait.");
  float calcR0 = 0;
  for(int i = 1; i<=10; i ++)
  {
    MQ135.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ135.calibrate(RatioMQ135CleanAir);
    Serial.print(".");
  }
  MQ135.setR0(calcR0/10);
  Serial.println("  done!.");

  MQ2.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ2.setA(987.99); MQ2.setB(-2.162); // Configure the equation to to calculate LPG concentration

  MQ2.init(); 

  Serial.print("Calibrating please wait.");
 
  for(int i = 1; i<=10; i ++)
  {
    MQ2.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ2.calibrate(RatioMQ2CleanAir);
    Serial.print(".");
  }
  MQ2.setR0(calcR0/10);
  Serial.println("  done!.");

  //Set math model to calculate the PPM concentration and the value of constants
  MQ4.setRegressionMethod(1); //_PPM =  a*ratio^b
  MQ4.setA(30000000); MQ4.setB(-8.308);

  MQ4.init(); 

  Serial.print("Calibrating please wait.");

  for(int i = 1; i<=10; i ++)
  {
    MQ4.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ4.calibrate(RatioMQ4CleanAir);
    Serial.print(".");
  }
  MQ4.setR0(calcR0/10);
  Serial.println("  done!.");

  pinMode(buzzer, OUTPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(redLED, OUTPUT);
  pinMode(blueLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);

}

void loop() {

  server.handleClient();

void handle_OnConnect() {

  timeClient.update();

  unsigned long epochTime = timeClient.getEpochTime();
  String formattedTime = timeClient.getFormattedTime();

  struct tm *ptm = gmtime ((time_t *)&epochTime);

  int monthDay= ptm->tm_mday;
  int currentMonth = ptm->tm_mon+1;
  int currentYear = ptm->tm_year+1900;
 
  formattedTime = timeClient.getFormattedTime(); 
  Date = String(currentYear) + "-" + String(currentMonth) + "-" + String(monthDay);

  temperature = bme.readTemperature();
  fahrenheit = (temperature * 9/5) + 32;
  humidity = bme.readHumidity();
  pressure = bme.readPressure() / 100.0F;
  altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
  altfeet = (altitude * 3.281);

  MQ135.setA(110.47); MQ135.setB(-2.862); // Configure the equation to calculate CO2 concentration value
  float CO2 = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ2.setA(987.99); MQ2.setB(-2.162); //Configure the equation to calculate Smoke concentration value
  float H2 = MQ2.readSensor(); // Sensor will read the PPM concentration using the model, a and b values set previously or from the setup

  MQ4.setA(30000000); MQ4.setB(-8.308); // Configure the equation to to calculate CH4 concentration
  float Smoke = MQ4.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.update();
  MQ2.update();
  MQ4.update();

    if (CO2 >= sensorThres) && (H2 < sensorThres) && (Smoke < sensorThres){           // CO2 Alarm
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, LOW);
    digitalWrite(yellowLED, LOW);
    tone(buzzer, 1000, 1000);
  }

    else if (CO2 < sensorThres) && (H2 >= sensorThres) && (Smoke < sensorThres){    // H2 Alarm
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, HIGH);
    digitalWrite(yellowLED, LOW);
    tone(buzzer, 2000, 2000);
  }

  else if (CO2 < sensorThres) && (H2 < sensorThres) && (Smoke >= sensorThres){    // Smoke Alarm
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, LOW);
    digitalWrite(yellowLED, HIGH);
    tone(buzzer, 4000, 4000);
  }

  else if (CO2 >= sensorThres) && (H2 >= sensorThres) && (Smoke < sensorThres){    // CO2 & H2 Alarm
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, HIGH);
    digitalWrite(yellowLED, LOW);
    tone(buzzer, 1000, 1000);
    tone(buzzer, 2000, 2000);
  }

  else if (CO2 >= sensorThres) && (H2 < sensorThres) && (Smoke >= sensorThres){  // CO2 & Smoke Alarm
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, LOW); 
    digitalWrite(yellowLED, HIGH);
    tone(buzzer, 1000, 1000);
    tone(buzzer, 4000, 4000);
  }

  else if (CO2 < sensorThres) && (H2 >= sensorThres) && (Smoke >= sensorThres){   // H2, Smoke Alarm
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, HIGH);
    digitalWrite(yellowLED, HIGH);
    tone(buzzer, 2000, 2000);
    tone(buzzer, 4000, 4000);
  }

  else if (CO2 >= sensorThres) && (H2 >= sensorThres) && (Smoke >= sensorThres){   // CO2, H2, Smoke Alarm
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, LOW);
    digitalWrite(blueLED, HIGH);
    digitalWrite(yellowLED, HIGH);
    tone(buzzer, 1000, 1000);
    tone(buzzer, 2000, 2000);
    tone(buzzer, 4000, 4000);
  }

  else if (CO2 < sensorThres) && (H2 < sensorThres) && (Smoke < sensorThres){     // NO ALARM/STABLE STATE
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, HIGH);
    digitalWrite(blueLED, LOW);
    digitalWrite(yellowLED, LOW);
    noTone(buzzer);
  }

}

}

  server.send(200, "text/html", SendHTML(temperature,fahrenheit,humidity,pressure,altitude,altfeet,CO2,H2,Smoke,formattedTime,Date)); 
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(float temperature, float fahrenheit, float humidity, float pressure, float altitude, float altfeet, float CO2, float H2, float Smoke, String TimeWeb, String DateWeb){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>Garage Environmental Monitoring</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
  ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<div id=\"webpage\">\n";
  ptr +="<h1>Garage Environmental Monitoring</h1>\n";
  ptr +="<p>Temperature: ";
  ptr +=temperature;
  ptr +="&deg;C</p>";
  ptr +="<p>Temperature: ";
  ptr +=fahrenheit;
  ptr +="&deg;F</p>";
  ptr +="<p>Humidity: ";
  ptr +=humidity;
  ptr +="%</p>";
  ptr +="<p>Pressure: ";
  ptr +=pressure;
  ptr +="hPa</p>";
  ptr +="<p>Altitude: ";
  ptr +=altitude;
  ptr +="m</p>";
  ptr +="<p>Altitude: ";
  ptr +=altfeet;
  ptr +="ft</p>";
  ptr +="<p>CO2 Level: ";
  ptr +=CO2 + 416;
  ptr +="ppm</p>";
  ptr +="<p>H2 Level: ";
  ptr +=H2;
  ptr +="ppm</p>";
  ptr +="<p>Smoke Level: ";
  ptr +=Smoke;
  ptr +="ppm</p>";
  ptr +="<p>Time: ";
  ptr +=(String)TimeWeb;
  ptr +="</p>";
  ptr +="<p>Date: ";
  ptr +=(String)DateWeb;
  ptr +="</p>";
  ptr +="</div>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}