ESP32 Email Alert Based on Temperature Threshold (change values on web server)

Learn how to send an email alert with the ESP32 based on a temperature threshold. The ESP32 also hosts a Web Server that shows the latest sensor readings and input fields to change the threshold value, email’s recipient, and the option to arm or disarm the system.

ESP32 Email Alert Based on Temperature Threshold change values on web server

We’ll read the temperature using a DS18B20 sensor and send emails using an SMTP Server. The ESP32 will be programmed using Arduino IDE.

To better understand how this project works, we recommend taking a look at the following tutorials:

Watch the Video Demonstration

To see how the project works, you can watch the following video demonstration:

Project Overview

The following image shows a high-level overview of the project we’ll build.

Project Overview ESP32 Send Email with SMTP Server based on temperature threshold
  • The ESP32 hosts a web server that shows the latest temperature readings from a DS18B20 temperature sensor.
  • There’s an input field to set up a threshold. When the temperature goes above or below the threshold value, you’ll receive an email.
  • You can also set up the recipient’s email address on the web page.
  • The system can be activated or deactivated through the web server. If you choose to deactivate the system, you won’t receive email notifications when the temperature crosses the threshold value.

The following image shows an overview of the web server page.

ESP32 Temperature Threshold Email Notification Web Server

Prerequisites

Make sure you check each of the following prerequisites before proceeding with this project.

1. ESP32 add-on Arduino IDE

We’ll program the ESP32 using Arduino IDE. So, you need to have the ESP32 add-on installed in your Arduino IDE. Follow the next tutorial, if you haven’t already.

2. ESP32 Mail Client Library

To send emails with the ESP32, we’ll use the ESP32 Mail Client library (how to use the library to send emails). Follow the next steps to install the library.

In your Arduino IDE go to Sketch > Include Library > Manage Libraries…

The Library Manager should open. Search for ESP32 Mail Client by Mobizt and install the library as shown below.

Install library ESP32 Send Email SMTP Server Arduino IDE

3. Create a Sender Email (New Account)

We recommend creating a new email account to send the emails to your main personal email address. Do not use your main personal email to send emails via ESP32. If something goes wrong in your code or if by mistake you make too many requests, you can be banned or have your account temporary disabled.

We’ll use a newly created Gmail.com account to send the emails, but you can use any other email provider. The receiver email can be your personal email without any problem.

Create a new email account for sending emails with the ESP32. If you want to use a Gmail account, go to this link to create a new one.

Gmail Create a new account

Create an App Password

You need to create an app password so that the ESP32 is able to send emails using your Gmail account. An App Password is a 16-digit passcode that gives a less secure app or device permission to access your Google Account. Learn more about sign-in with app passwords here.

An app password can only be used with accounts that have 2-step verification turned on.

  1. Open your Google Account.
  2. In the navigation panel, select Security.
  3. Under “Signing in to Google,” select 2-Step Verification > Get started.
  4. Follow the on-screen steps.

After enabling 2-step verification, you can create an app password.

  1. Open your Google Account.
  2. In the navigation panel, select Security.
  3. Under “Signing in to Google,” select App Passwords.
Create app password gmail
  1. In the Select app field, choose mail. For the device, select Other and give it a name, for example ESP32. Then, click on Generate. It will pop-up a window with a password that you’ll use with the ESP32 or ESP8266 to send emails. Save that password (even though it says you won’t need to remmeber it) because you’ll need it later.
Generated App password gmail

Now, you should have an app password that you’ll use on the ESP32 code to send the emails.

Gmail app password created for ESP32 send emails

If you’re using another email provider, check how to create an app password. You should be able to find the instructions with a quick google search “your_email_provider + create app password”.

4. SMTP Server Settings

Before proceeding you need to know the SMTP server settings of the sender email.

Gmail SMTP Server Settings

If you’re using a Gmail account, these are the SMTP Server details:

  • SMTP Server: smtp.gmail.com
  • SMTP username: Complete Gmail address
  • SMTP password: Your Gmail password
  • SMTP port (TLS): 587
  • SMTP port (SSL): 465
  • SMTP TLS/SSL required: yes

Outlook SMTP Server Settings

For Outlook accounts, these are the SMTP Server settings:

  • SMTP Server: smtp.office365.com
  • SMTP Username: Complete Outlook email address
  • SMTP Password: Your Outlook password
  • SMTP Port: 587
  • SMTP TLS/SSL Required: Yes

Live or Hotmail SMTP Server Settings

For Live or Hotmail accounts, these are the SMTP Server settings:

  • SMTP Server: smtp.live.com
  • SMTP Username: Complete Live/Hotmail email address
  • SMTP Password: Your Windows Live Hotmail password
  • SMTP Port: 587
  • SMTP TLS/SSL Required: Yes

If you’re using another email provider, you need to search for its SMTP Server settings.

5. Async Web Server and DS18B20 Libraries

In this project, we’ll build an asynchronous web server using the next libraries:

These two libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation folder. Alternatively, in your Arduino IDE, you can go to Sketch Include Library > Add .zip Library and select the libraries you’ve just downloaded.

Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open and you can install these libraries:

6. Parts Required

ESP32 with DS18B20 temperature sensor read

To follow this tutorial you need the following parts:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic Diagram

Wire the DS18B20 temperature sensor to the ESP32 as shown in the following schematic diagram, with the data pin connected to GPIO 4

Wiring Schematic diagram with DS18B20 temperature sensor to ESP32 board

ESP32 Code – Email Web Server

Copy the following code to your Arduino IDE, but don’t upload it yet. You need to make some changes to make it work for you. You need to insert the sender’s email address, the recipient’s email address, your default threshold input and your network credentials.

If you’re using a ESP32 Arduino Core V3, you need to downgrade your ESP32 boards’ add-on to version 2.0.17. At the moment, the ESP32_MailClient library is not compatible with version 3.X.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-email-alert-temperature-threshold/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "ESP32_MailClient.h"

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// To send Emails using Gmail on port 465 (SSL), you need to create an app password: https://support.google.com/accounts/answer/185833
#define emailSenderAccount    "[email protected]"
#define emailSenderPassword   "email_sender_password"
#define smtpServer            "smtp.gmail.com"
#define smtpServerPort        465
#define emailSubject          "[ALERT] ESP32 Temperature"

// Default Recipient Email Address
String inputMessage = "[email protected]";
String enableEmailChecked = "checked";
String inputMessage2 = "true";
// Default Threshold Temperature Value
String inputMessage3 = "25.0";
String lastTemperature;

// HTML web page to handle 3 input fields (email_input, enable_email_input, threshold_input)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>Email Notification with Temperature</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <h2>DS18B20 Temperature</h2> 
  <h3>%TEMPERATURE% &deg;C</h3>
  <h2>ESP Email Notification</h2>
  <form action="/get">
    Email Address <input type="email" name="email_input" value="%EMAIL_INPUT%" required><br>
    Enable Email Notification <input type="checkbox" name="enable_email_input" value="true" %ENABLE_EMAIL%><br>
    Temperature Threshold <input type="number" step="0.1" name="threshold_input" value="%THRESHOLD%" required><br>
    <input type="submit" value="Submit">
  </form>
</body></html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

AsyncWebServer server(80);

// Replaces placeholder with DS18B20 values
String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return lastTemperature;
  }
  else if(var == "EMAIL_INPUT"){
    return inputMessage;
  }
  else if(var == "ENABLE_EMAIL"){
    return enableEmailChecked;
  }
  else if(var == "THRESHOLD"){
    return inputMessage3;
  }
  return String();
}

// Flag variable to keep track if email notification was sent or not
bool emailSent = false;

const char* PARAM_INPUT_1 = "email_input";
const char* PARAM_INPUT_2 = "enable_email_input";
const char* PARAM_INPUT_3 = "threshold_input";

// Interval between sensor readings. Learn more about timers: https://RandomNerdTutorials.com/esp32-pir-motion-sensor-interrupts-timers/
unsigned long previousMillis = 0;     
const long interval = 5000;    

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;     
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

// The Email Sending data object contains config and data to send
SMTPData smtpData;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("ESP IP Address: http://");
  Serial.println(WiFi.localIP());
  
  // Start the DS18B20 sensor
  sensors.begin();

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

  // Receive an HTTP GET request at <ESP_IP>/get?email_input=<inputMessage>&enable_email_input=<inputMessage2>&threshold_input=<inputMessage3>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    // GET email_input value on <ESP_IP>/get?email_input=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      // GET enable_email_input value on <ESP_IP>/get?enable_email_input=<inputMessage2>
      if (request->hasParam(PARAM_INPUT_2)) {
        inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
        enableEmailChecked = "checked";
      }
      else {
        inputMessage2 = "false";
        enableEmailChecked = "";
      }
      // GET threshold_input value on <ESP_IP>/get?threshold_input=<inputMessage3>
      if (request->hasParam(PARAM_INPUT_3)) {
        inputMessage3 = request->getParam(PARAM_INPUT_3)->value();
      }
    }
    else {
      inputMessage = "No message sent";
    }
    Serial.println(inputMessage);
    Serial.println(inputMessage2);
    Serial.println(inputMessage3);
    request->send(200, "text/html", "HTTP GET request sent to your ESP.<br><a href=\"/\">Return to Home Page</a>");
  });
  server.onNotFound(notFound);
  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    sensors.requestTemperatures();
    // Temperature in Celsius degrees 
    float temperature = sensors.getTempCByIndex(0);
    Serial.print(temperature);
    Serial.println(" *C");
    
    // Temperature in Fahrenheit degrees
    /*float temperature = sensors.getTempFByIndex(0);
    SerialMon.print(temperature);
    SerialMon.println(" *F");*/
    
    lastTemperature = String(temperature);
    
    // Check if temperature is above threshold and if it needs to send the Email alert
    if(temperature > inputMessage3.toFloat() && inputMessage2 == "true" && !emailSent){
      String emailMessage = String("Temperature above threshold. Current temperature: ") + 
                            String(temperature) + String("C");
      if(sendEmailNotification(emailMessage)) {
        Serial.println(emailMessage);
        emailSent = true;
      }
      else {
        Serial.println("Email failed to send");
      }    
    }
    // Check if temperature is below threshold and if it needs to send the Email alert
    else if((temperature < inputMessage3.toFloat()) && inputMessage2 == "true" && emailSent) {
      String emailMessage = String("Temperature below threshold. Current temperature: ") + 
                            String(temperature) + String(" C");
      if(sendEmailNotification(emailMessage)) {
        Serial.println(emailMessage);
        emailSent = false;
      }
      else {
        Serial.println("Email failed to send");
      }
    }
  }
}

bool sendEmailNotification(String emailMessage){
  // Set the SMTP Server Email host, port, account and password
  smtpData.setLogin(smtpServer, smtpServerPort, emailSenderAccount, emailSenderPassword);

  // For library version 1.2.0 and later which STARTTLS protocol was supported,the STARTTLS will be 
  // enabled automatically when port 587 was used, or enable it manually using setSTARTTLS function.
  //smtpData.setSTARTTLS(true);

  // Set the sender name and Email
  smtpData.setSender("ESP32", emailSenderAccount);

  // Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest)
  smtpData.setPriority("High");

  // Set the subject
  smtpData.setSubject(emailSubject);

  // Set the message with HTML format
  smtpData.setMessage(emailMessage, true);

  // Add recipients
  smtpData.addRecipient(inputMessage);

  smtpData.setSendCallback(sendCallback);

  // Start sending Email, can be set callback function to track the status
  if (!MailClient.sendMail(smtpData)) {
    Serial.println("Error sending Email, " + MailClient.smtpErrorReason());
    return false;
  }
  // Clear all data from Email object to free memory
  smtpData.empty();
  return true;
}

// Callback function to get the Email sending status
void sendCallback(SendStatus msg) {
  // Print the current status
  Serial.println(msg.info());

  // Do something when complete
  if (msg.success()) {
    Serial.println("----------------");
  }
}

View raw code

How the Code Works

Continue reading to learn how the code works, or skip to the demonstration section.

Libraries

Start by importing the required libraries. The WiFi, AsyncTCP and ESPAsyncWebServer are required to build the web server. The OneWire and DallasTemperature are required to interface with the DS18B20 and the ESP32_MailClient is required to send emails with the ESP32 via SMTP server.

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "ESP32_MailClient.h"

Network Credentials

Insert your network credentials in the following lines:

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Email Settings

Insert the sender email – this is the email that will be used to send emails by the ESP32.

#define emailSenderAccount "[email protected]"

Type the email sender password:

#define emailSenderPassword "email_sender_password"

In the next lines, insert the email sender SMTP server settings. We’re using a Gmail account. If you’re using another email provider you need to insert the right server settings.

#define smtpServer      "smtp.gmail.com"
#define smtpServerPort  465

Insert the email subject on the following line:

#define emailSubject "[ALERT] ESP32 Temperature"

Auxiliar Variables

Next, we have some auxiliar variables to save the values submitted through the form. The inputMessage variable holds the recipient’s email. You can insert the default’s recipient’s email. You can change the recipient’s email later on the form.

String inputMessage = "[email protected]";

The enableEmailChecked variable will tell us whether the checkbox to send an email is checked or not.

String enableEmailChecked = "checked";

In case it’s checked, the value saved on the inputMessage2 should be set to true.

String inputMessage2 = "true";

The inputMessage3 holds the temperature threshold value. By default is set to 25.0ÂşC, but you can set it to any other default value that makes more sense to you. You can also change it later in the HTML form.

String inputMessage3 = "25.0";

The lastTemperature variable saves the last temperature value to compare with the current value.

String lastTemperature;

HTML Text

Then, we have some basic HTML text to build a page with three input fields: the recipient’s email, a checkbox to enable or disable email notifications and the temperature threshold input field. The web page also displays the latest temperature reading from the DS18B20 temperature sensor.

The following lines display the temperature:

<h2>DS18B20 Temperature</h2> 
<h3>%TEMPERATURE% &deg;C</h3>

The %TEMPERATURE% is placeholder that will be replaced by the actual temperature value when the ESP32 serves the page.

Then, we have a form with three input fields and a “Submit” button. When the user types some data and clicks the “Submit” button, those values are sent to the ESP32 to update the variables.

<form action="/get">
  Email Address <input type="email" name="email_input" value="%EMAIL_INPUT%" required><br>
  Enable Email Notification <input type="checkbox" name="enable_email_input" value="true" %ENABLE_EMAIL%><br>
  Temperature Threshold <input type="number" step="0.1" name="threshold_input" value="%THRESHOLD%" required><br>
  <input type="submit" value="Submit">
</form>

The first input field is of type email, the second input field is a checkbox and the last input field is of type number. To learn more about input fields, we recommend taking a look at following resources of the w3schools website:

The action attribute of the form specifies where to send the data inserted on the form after pressing submit. In this case, it makes an HTTP GET request to:

/get?email_input=value&enable_email_input=value&threshold_input=value

The value refers to the text you enter in each of the input fields. To learn more about handling input fields with the ESP32, read: Input Data on HTML Form ESP32 Web Server using Arduino IDE.

processor()

The processor() function replaces all placeholders in the HTML text with the actual values.

  • %TEMPERATURE% » lastTemperature
  • %EMAIL_INPUT% » inputMessage
  • %ENABLE_EMAIL% » enableEmailChecked
  • %THRESHOLD% » inputMessage3
String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return lastTemperature;
  }
  else if(var == "EMAIL_INPUT"){
    return inputMessage;
  }
  else if(var == "ENABLE_EMAIL"){
    return enableEmailChecked;
  }
  else if(var == "THRESHOLD"){
    return inputMessage3;
  }
  return String();
}

Input Field Parameters

The following variables will be used to check whether we’ve received an HTTP GET request from those input fields and save the values into variables accordingly.

const char* PARAM_INPUT_1 = "email_input";
const char* PARAM_INPUT_2 = "enable_email_input";
const char* PARAM_INPUT_3 = "threshold_input";

DS18B20 Temperature Sensor Init

Initialize the DS18B20 temperature sensor.

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

To learn more about interfacing the DS18B20 temperature sensor with the ESP32, read: ESP32 DS18B20 Temperature Sensor with Arduino IDE.

SMTPData Object

The smtpData object contains configurations and data to be sent via email. These configurations are set later on the sendEmailNotification() function.

SMTPData smtpData;

setup()

In the setup(), connect to Wi-Fi in station mode and print the ESP32 IP address:

Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
  Serial.println("WiFi Failed!");
  return;
}
Serial.println();
Serial.print("ESP IP Address: http://");
Serial.println(WiFi.localIP());

Initialize the DS18B20 temperature sensor:

sensors.begin();

Handle Web Server

Then, define what happens when the ESP32 receives HTTP requests. When we get a request on the root / url, send the HTML text with the processor (so that the placeholders are replaced with the latest values).

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

When a form is submitted, the ESP32 receives a request on the following URL:

<ESP_IP>/get?email_input=<inputMessage>&enable_email_input=<inputMessage2>&threshold_input=<inputMessage3>

So, we check whether the request contains input parameters, and save those parameters into variables:

server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
  // GET email_input value on <ESP_IP>/get?email_input=<inputMessage>
  if (request->hasParam(PARAM_INPUT_1)) {
    inputMessage = request->getParam(PARAM_INPUT_1)->value();
    // GET enable_email_input value on <ESP_IP>/get?enable_email_input=<inputMessage2>
    if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      enableEmailChecked = "checked";
    }
    else {
      inputMessage2 = "false";
      enableEmailChecked = "";
    }
    // GET threshold_input value on <ESP_IP>/get?threshold_input=<inputMessage3>
    if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage3 = request->getParam(PARAM_INPUT_3)->value();
    }
  }
  else {
    inputMessage = "No message sent";
  }

This is the part of the code where the variables will be replaced with the values submitted on the form. The inputMessage variable saves the recipient’s email address, the inputMessage2 saves whether the email notification system is enabled or not and the inputMessage3 saves the temperature threshold.

After submitting the values on the form, it displays a new page saying the request was successfully sent to the ESP32 with a link to return to the homepage.

request->send(200, "text/html", "HTTP GET request sent to your ESP.<br><a href=\"/\">Return to Home Page</a>");
});

Finally, start the server:

server.begin();

loop()

In the loop(), we use timers to get new temperature readings every 5 seconds.

unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
  sensors.requestTemperatures();
  // Temperature in Celsius degrees 
  float temperature = sensors.getTempCByIndex(0);
  Serial.print(temperature);
  Serial.println(" *C");
    
  // Temperature in Fahrenheit degrees
  /*float temperature = sensors.getTempFByIndex(0);
  SerialMon.print(temperature);
  SerialMon.println(" *F");*/
    
  lastTemperature = String(temperature);

After getting a new temperature reading, we check whether it is above or below the threshold and send an email if necessary.

You’ll send an email alert, if all these conditions are met:

  • The current temperature is above the threshold;
  • Email notifications are enabled (the checkbox is ticked on the web page);
  • If an email hasn’t been sent yet.
if(temperature > inputMessage3.toFloat() && inputMessage2 == "true" && !emailSent){
  String emailMessage = String("Temperature above threshold. Current temperature: ") + 
                        String(temperature) + String("C");
  if(sendEmailNotification(emailMessage)) {
    Serial.println(emailMessage);
    emailSent = true;
  }
  else {
    Serial.println("Email failed to send");
  }    
}

The email contains a message saying the temperature is above the threshold and the current temperature.

Then, if the temperature goes below the threshold, send another email.

else if((temperature < inputMessage3.toFloat()) && inputMessage2 == "true" && emailSent) {
  String emailMessage = String("Temperature below threshold. Current temperature: ") 
                        + String(temperature) + String(" C");
  if(sendEmailNotification(emailMessage)) {
    Serial.println(emailMessage);
    emailSent = false;
  }
  else {
    Serial.println("Email failed to send");
  }
}

To send emails, we’ve created the sendEmailNotification function that contains all the details to send the email. This function returns true if the email was successfully sent, or false if it failed. To learn more about sending emails via SMTP Server with the ESP32, read: ESP32 Send Emails using an SMTP Server.

Demonstration

Upload the code to your ESP32 board (with the DS18B20 wired to your ESP32 board).

ESP32 Web Server Temperature Threshold Triggered Received Email Alert

Open the Serial Monitor at a baud rate of 115200 and press the on-board RST button. The ESP32 will print its IP address and it will start displaying new temperature values every 5 seconds.

ESP32 Email Web Server Arduino IDE Serial Monitor Temperature

Open a browser and type the ESP32 IP address. A similar web page should load with the default values (defined in your code):

ESP32 Email Notification Web Server Values temperature, email recipient, threshold

If the email notifications are enabled (checkbox checked) and if the temperature goes above the threshold, you’ll receive an email notification.

After that, when the temperature goes below the threshold, you’ll receive another email.

ESP32 Email Alert Notification Temperature Reached above below threshold

You can use the web page input fields to set up a different recipient’s email address, to enable or disable email notifications, and to change the threshold value. For any change to take effect, you just need to press the “Submit” button.

At the same time, you should get the new input fields in the Serial Monitor.

ESP32 Web Server Arduino IDE Serial Monitor change values temperature email

Wrapping Up

In this project you’ve learn how to set a threshold value and send an email notification when the temperature crosses that value. We hope you’ve found this project interesting. Now, feel free to modify the project to meet your own needs. For, example, when the temperature crosses the threshold, you may also want to trigger an output to control a relay.

In this project, we’ve used raw HTML text, to make the project easier to follow. We suggest adding some CSS to style your web page to make it look nicer.

Instead of using a DS18B20, you might consider using a different temperature sensor: DHT vs LM35 vs DS18B20 vs BME280 vs BMP180.

If you want to learn more about the ESP32, try our projects and resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

57 thoughts on “ESP32 Email Alert Based on Temperature Threshold (change values on web server)”

  1. That’s amazing project. I subscribed to your website because I’m doing my final project with esp32 and also, your projects are really helpful.
    I working doing a fall detection system using esp32 and MPU6050 GY-521 sensor. Can you tell me how to see my sensor values in my database while also allow a user to receive an email and/or sms when the sensor exceeds a certain threshold to indicate as a fall?

    Reply
  2. Hi

    Some thoughts.
    I have little greenhouse.
    When temperature goes over 45Celsius .it is orange alert.
    I go and open greenhouse’s Door and Window.

    When Temperature is 10- 40 Celsius, everything is ok.

    When Temperature goes below 5 Celsius,it is red alert,
    because heater for some reason doesn’t work.

    That’s all folk.
    Best regards.
    Ahti

    Reply
  3. hey Rui can you help me
    i have some troubleshooting on my wiring cable, when iam took a jumper on there. then when iam get compile
    “A fatal error occurred: “Failed to connect to ESP32: Timed out… Connecting…”

    i would ask to take on sample picture on sd card – button “capture”
    then analyze the picture
    iam just thinking how to make it – “algorithm”

    can you help me how to fix that

    Reply
  4. Hi @Ahti,

    The temperature threshold can be set by the user on the web interface, in the field. The value of this field is set by default within the code with the inputMessage3 variable, but the user can change it by entering another value in the web form.

    If you want to define 2 thresholds (a min value and a max value), you would have to add another input field in the form for this 2nd threshold, as well as a default value (for example, as an inputMessage4 variable)… but you will also have to slightly modify the code to take it into account.

    Finally, I suppose that this code also works with ESP8266 (I don’t have one to test). But if this was not the case, the modifications would be minor.

    Reply
    • Rhaaaaa… damn comment editor…

      Too bad you can’t re-edit it if you make a typing error, or when its content is altered by the process that saves it!
      I’m redoing a test concerning my first sentence:
      The temperature threshold can be set by the user on the web interface, in the <input name=”threshold_input” … /> field.

      Sorry for that!

      Reply
    • Hi StĂ©phane.
      Thanks for helping out.
      Just a minor correction: this code is not compatible with the ESP8266.
      Regards,
      Sara

      Reply
      • Hi Sara,

        Yeah, sorry… I didn’t really look into the ESP8266 case because I don’t have one on hand to test or write suitable code that works for sure.

        Nevertheless, I guess it is still possible to reimplement an SMTP client quite easily with the ESPAsyncTCP library:

        Now, for more simplicity (@Athi) maybe you can take a look at the following tutorial:

        ESP32/ESP8266 Send Email Notification using PHP Script

        It allows you to more easily deport the mail sending procedure to a PHP server, and simplify the code running on the ESP8266 at the same time.

        Reply
  5. Hi
    Thank You for help.
    I have NodeMcu32S chip. I don’t know what it is exactly.
    I managed to load program to chip.
    I have ordered this sensor DS18B20 .I don’t have it.

    Best regards
    Ahti.N

    Reply
  6. Hello, this is a very clear writedown of a usefull project!
    I was wondering: if there is a power interruption, the ESP32 will use the threshold values declared in the code and not the ones who were given by the user through the webpage?

    Is there a way to store the values given by the user on the webpage, so that in case of a power outage, the system keeps working, but with the values that were given by the user?

    Kind regards,
    Christophe

    Reply
    • Hi.
      Yes. You can save the values on the flash memory. The values saved on the flash memory don’t change even if the ESP32 resets or power is removed.
      Take a look at this tutorial to see how it works:
      https://randomnerdtutorials.com/esp32-flash-memory/
      At the beginning of you sketch you need to add some lines to read the value currently saved on the flash memory.
      Then, every time you change the values, you should save them on the flash memory (EEPROM)
      Regards,
      Sara

      Reply
      • Hi Sara,

        Great tutorials. I love your work. Can you help me write the code for storing email address of recipient in EEPROM.
        Tnx,

        Best regards

        Reply
        • Hi Robert.
          I’m sorry, but due to time constraints we don’t build custom projects for our readers.

          However, I recommend you read the following tutorial: https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/

          This shows how to save values permanently on the ESP32 flash memory using the Preferences library. Take a look at the example that shows how to save and read network credentials—then, adapt to save the recipient email.
          I hope this helps.
          Regards,
          Sara

          Reply
  7. Hello please need help

    I have tried this code but doesn’t work about web server

    when entering the IP address the browser shows error

    The problem is the browser doesn’t show the page after entering the ip address….although I copy the just edited the wifi ssid and password

    Reply
    • Hi.
      The browser and the ESP32 need to be on the same network (connected to the same router).
      What is the exact error you’re getting?
      Regards,
      Sara

      Reply
  8. hello. i copied the sketch above, email alert. everything goes ok except the esp32 wont connect to my home wifi or phones hotspot. what could i be doing wrong?

    Reply
  9. Thank you for replying.for some reason it won’t connect to my phone’s hotspot but it connects to my home wifi fine. I copied the new file above that has a minimum and maximum threshold successfully. It works perfect just what I need. I would to know how to have it send a email at a specific time every day to show the system is working and connected to the network.

    Reply
  10. Is there a way to get help to have a soil sensor (which I have working on its own) instead of the temperature sensor to email status of the soil sensor? I’ve tried to switch out all places in the code from where it was “Temperature” to Moisture, and its not compiling too many errors (no matching function for call to ‘String(const char [48], uint16_t&)’
    the ‘uint16_t’ is the variable type from the working sketch for the soil sensor, I get readings from it, but when i try to put it into the emailing sketch here, it doesn’t compile in Arduino IDE.
    Thanks for any help if you have time.

    Reply
  11. Thank you, I’ve got it sending through gmail, but I’m not understanding a couple of things.
    Im not understanding the logic, it only sending once & not according to the interval of millis.
    I also had to change this : around lines 177 in arduino (but I’ve moved things around some, it may be different in your code) can I send the whole code? its close to working I just need help with the frequency & logic (If above threshold, if below, then send or not)
    !emailSent. when it was without the ! not symbol it wouldn’t send.
    // Check if Moisture is above threshold and if it needs to send the Email alert
    if(capread > inputMessage3.toFloat() && inputMessage2 == “true” && !emailSent){
    String emailMessage = String(“Moisture above threshold. Current Moisture: “)+
    String(capread)+ String(“%”);

    if(sendEmailNotification(emailMessage)) {
    Serial.println(emailMessage);
    emailSent = true;
    }
    else {
    Serial.println("Email failed to send");
    }
    }
    // Check if Moisture is below threshold and if it needs to send the Email alert
    else if((capread < inputMessage3.toFloat()) && inputMessage2 == "true" && !emailSent) {
    String emailMessage = String("Moisture below threshold. Current Moisture: ") +
    String(capread) + String("%");

    if(sendEmailNotification(emailMessage)) {
    Serial.println(emailMessage);
    emailSent = true;
    }
    else {
    Serial.println("Email failed to send");

    I thought it would send every – const long interval = 5000- that would be every 5 seconds? Ive changed it to 60000 for testing purposes, but I want to check every 4 hrs when its working better.
    Hope this is not confusing?
    I can present more specifics in smaller pieces of code if thats easier?

    Reply
  12. I noticed this bool type definition near the bottom of the code

    Its not within the braces of void loop() {
    code here……
    }
    bool sendEmailNotification(String emailMessage){
    code describing email send….
    Its outside the ending brace.
    If I put it within the void loop() code would that cause the emails to send as frequently as the interval time? (const long interval = 5000;)

    Reply
  13. is there a way to have to only one email sent when the threshold has been meet. on mine it keeps sending emails one after another until the alert has cleared . thank you.

    Reply
  14. i have the new code up and running . the upper and lower thresholds work great. ive been trying for weeks to figure out how to write into the code so it will email me once per day the temperature, kind of like a report to show me that everything is still working. could you please help me with this. thank you.

    Reply
  15. I built this project and loaded the code with no initial problems, but after about
    12 hours the web server drops it connection. It can no longer be accessed
    Via Safari or Edge browers. The error message on both browsers is “the web server
    Has stopped responding”. I tested it many times over several days with different
    Esp32 modules.

    I tried the solution suggested by Rui, in this link, but it doesn’t seem to match
    The code in this project.
    [SOLVED] ESP32/ESP8266 Web Server Drops Connection/Crashes (rntlab.com)

    I hope someone can offer a suggestion to solve this problem.
    Thanks in advance.
    Larry

    Reply
  16. Hi.
    Thank you for a nice tutorial.

    I’m struggling getting this to only send an email when going below the threshold. Could you provide me with a hint?

    Reply
  17. hello Mr. Rui Santos,

    Can you help me with this error with the code?
    Arduino: 1.8.19 (Windows Store 1.8.57.0) (Windows 10), Placa:”ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 115200, Core 1, Core 1, None”

    In file included from C:\Users\andre\OneDrive\Documentos\ArduinoData\packages\esp32\hardware\esp32\2.0.3\cores\esp32/Arduino.h:36,

    (…)

    Best regards

    André Gomes

    Reply
  18. Hi Sara,
    Struggling with the libraries in Arduino IDE. I have downloaded the files manually from github but getting invalid library found AsyncWebServer “missing version from library”

    can you let me know if I can try something else? There are no complete library ZIP files to download.

    Any help would be great

    Thanks

    Reply
  19. Hi thanks for the code & guide. Using a esp32 c3 board, but getting the following error. need your help please.

    Arduino: 1.8.19 (Linux), Board: “ESP32C3 Dev Module, Integrated USB JTAG, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 160MHz (WiFi), QIO, 80MHz, 4MB (32Mb), 921600, None, Disabled”

    /home/homepc/Arduino/libraries/ESPAsyncWebServer-master/src/AsyncWebSocket.cpp: In member function ‘IPAddress AsyncWebSocketClient::remoteIP()’:
    /home/homepc/Arduino/libraries/ESPAsyncWebServer-master/src/AsyncWebSocket.cpp:832:28: error: call of overloaded ‘IPAddress(unsigned int)’ is ambiguous
    return IPAddress(0U);
    ^
    In file included from /home/homepc/.arduino15/packages/esp32/hardware/esp32/2.0.6/cores/esp32/Arduino.h:170,
    from /home/homepc/Arduino/libraries/ESPAsyncWebServer-master/src/AsyncWebSocket.cpp:21:
    /home/homepc/.arduino15/packages/esp32/hardware/esp32/2.0.6/cores/esp32/IPAddress.h:51:5: note: candidate: ‘IPAddress::IPAddress(const uint8_t*)’
    IPAddress(const uint8_t *address);
    ^~~~~~~~~
    /home/homepc/.arduino15/packages/esp32/hardware/esp32/2.0.6/cores/esp32/IPAddress.h:50:5: note: candidate: ‘IPAddress::IPAddress(uint32_t)’
    IPAddress(uint32_t address);
    ^~~~~~~~~
    /home/homepc/.arduino15/packages/esp32/hardware/esp32/2.0.6/cores/esp32/IPAddress.h:29:7: note: candidate: ‘constexpr IPAddress::IPAddress(const IPAddress&)’
    class IPAddress: public Printable
    ^~~~~~~~~
    Multiple libraries were found for “SD.h”
    Used: /home/homepc/.arduino15/packages/esp32/hardware/esp32/2.0.6/libraries/SD
    Not used: /app/Arduino/libraries/SD
    Multiple libraries were found for “WiFi.h”
    Used: /home/homepc/.arduino15/packages/esp32/hardware/esp32/2.0.6/libraries/WiFi
    Not used: /app/Arduino/libraries/WiFi
    exit status 1
    Error compiling for board ESP32C3 Dev Module.

    Reply
  20. Hi , I’m new to Arduino & ESP32’s micros and I’m having a lot of trouble compiling this project code. ( note , I’ve had no trouble with a similar project on this site, ESP32 Email , which loaded error free and performs as expected ). My ESP board is an ESP32-WROOM-32 .

    Regarding this proj I’ve loaded all the required library’s as described in the proj listing and updated the ssid & psw as req’d, however the line #include “ESP32_MailClient.h” wouldn’t be excepted until I changed it to <ESP_Mail_Client.h>.
    Subsequent compiling attempts now produce 10+ errors . The first 3 errors I get are as follows ;

    …sketch_feb18a.ino:231:19: error: variable or field ‘sendCallback’ declared void sendCallback(SendStatus msg) {
    ^~~~~~~~~~
    …sketch_feb18a.ino:231:19: error: ‘SendStatus’ was not declared in this scope
    …sketch_feb18a.ino:231:19: note: suggested alternative: ‘SMTP_Status’
    void sendCallback(SendStatus msg) {
    ^~~~~~~~~~
    SMTP_Status

    I’m hoping someone can help me further with identifying the issue/s, thanks in Advance SamF.

    Reply
  21. Hi there , thankyou for an informative tutorial.

    I get the following error using #include “ESP32_MailClient.h” on line 6 of the coding ,
    “Compilation error: ESP32_MailClient.h: No such file or directory” .

    I have loaded all libraries as described in the project .

    Should this line read ESP_Mail_Client.h instead , otherwise I cant get the compile to progress any further ?

    Thanks.

    Reply
  22. Hi there , please ignore my two previous requests for help with this code . I have eventually worked out what the issues were and can now compile and use the Web App . Thanks SamF.

    Reply
      • I am actually having issues with header files not being found. I’ve included the libraries as requested above but I am receiving this error:

        ESP32_Mail_Client\src/ssl_client32.h:36:10: fatal error: mbedtls/net.h: No such file or directory

        Reply
        • Hi.
          Check the version of the ESP32 boards you have installed in Tools > Boards > Board Manager > ESP32.

          Or are you using VS Code?

          Regards
          Sara

          Reply
          • Hi Sara!
            Thank you for the response. I removed the ESP32 boards and redownloaded. Then I used the DOIT ESP32 DEVKIT V1 and everything compiled fine.

            Unfortunately now, my Gmail email is failing to send when the threshold is breached.

            The instructions mention both an SSL and TMS port but the code just has the SSL value of 465.

            I’m digging into this now.

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.