In this project, you’ll build an ESP32 / ESP8266 Thermostat Web Server with an input field to set a temperature threshold value. This allows you to automatically control an output based on the current temperature reading. The output will be set to on if the temperature is above or set to off if it’s below the threshold – this can be used to build a simple thermostat project.
As an example, we’ll read the temperature using a DS18B20 temperature sensor. You can use any other temperature sensor like DHT11/DHT22, BME280 or LM35.
To better understand how this project works, we recommend reading these tutorials:
- Input Data on HTML Form ESP32/ESP8266 Web Server (Arduino IDE)
- ESP32 with DS18B20 (one sensor, multiple sensors, web server)
- ESP8266 NodeMCU with DS18B20 (one sensor, multiple sensors, web server)
- ESP32 Web Server or ESP8266 NodeMCU Web Server
Project Overview
The following image shows a high-level overview of the project we’ll build.
- The ESP32/ESP8266 hosts a web server that shows the latest temperature readings from a DS18B20 temperature sensor.
- There’s an input field to set up a temperature threshold value. When the temperature goes above the threshold, an output will be automatically turned on. You can invert this logic depending on your project application.
- When the temperature goes below the threshold, the output will be turned off.
- The system can be activated or deactivated through the web server. If you choose to deactivate the system, the output will keep its state, no matter the temperature value.
The following image shows how the web server page looks like.
Prerequisites
Make sure you check each of the following prerequisites before proceeding with this project.
1. ESP32 or ESP8266 Add-on Arduino IDE
This project is compatible with both the ESP32 and ESP8266 boards. We’ll program these boards using Arduino IDE, so make sure you have the necessary add-ons installed:
2. Async Web Server Libraries
To build the asynchronous web server, you need to install these libraries.
- ESP32: install the ESPAsyncWebServer and the AsyncTCP libraries.
- ESP8266: install the ESPAsyncWebServer and the ESPAsyncTCP libraries.
These libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the libraries you’ve just downloaded.
3. Parts Required
To follow this tutorial you need the following parts:
- ESP32 (read Best ESP32 boards) or ESP8266 (read Best ESP8266 boards)
- LED
- 220 Ohm resistor
- DS18B20 temperature sensor (waterproof version)
- 4.7k Ohm resistor
- Jumper wires
- Breadboard
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
Before proceeding, wire the DS18B20 temperature sensor to your board.
ESP32 with DS18B20 and LED
If you’re using an ESP32, wire the DS18B20 temperature sensor as shown in the following schematic diagram, with the data pin connected to GPIO 4.
ESP8266 with DS18B20 and LED
If you’re using an ESP8266, wire the DS18B20 temperature sensor as shown in the following schematic diagram, with the data pin connected to GPIO 4 (D2).
Code – Thermostat Web Server with Threshold Input
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 your network credentials and your default threshold value.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-thermostat-web-server/
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.
*********/
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Default Threshold Temperature Value
String inputMessage = "25.0";
String lastTemperature;
String enableArmChecked = "checked";
String inputMessage2 = "true";
// HTML web page to handle 2 input fields (threshold_input, enable_arm_input)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>Temperature Threshold Output Control</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<h2>DS18B20 Temperature</h2>
<h3>%TEMPERATURE% °C</h3>
<h2>ESP Arm Trigger</h2>
<form action="/get">
Temperature Threshold <input type="number" step="0.1" name="threshold_input" value="%THRESHOLD%" required><br>
Arm Trigger <input type="checkbox" name="enable_arm_input" value="true" %ENABLE_ARM_INPUT%><br><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 == "THRESHOLD"){
return inputMessage;
}
else if(var == "ENABLE_ARM_INPUT"){
return enableArmChecked;
}
return String();
}
// Flag variable to keep track if triggers was activated or not
bool triggerActive = false;
const char* PARAM_INPUT_1 = "threshold_input";
const char* PARAM_INPUT_2 = "enable_arm_input";
// Interval between sensor readings. Learn more about ESP32 timers: https://RandomNerdTutorials.com/esp32-pir-motion-sensor-interrupts-timers/
unsigned long previousMillis = 0;
const long interval = 5000;
// GPIO where the output is connected to
const int output = 2;
// 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);
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());
pinMode(output, OUTPUT);
digitalWrite(output, LOW);
// 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?threshold_input=<inputMessage>&enable_arm_input=<inputMessage2>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
// GET threshold_input value on <ESP_IP>/get?threshold_input=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
// GET enable_arm_input value on <ESP_IP>/get?enable_arm_input=<inputMessage2>
if (request->hasParam(PARAM_INPUT_2)) {
inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
enableArmChecked = "checked";
}
else {
inputMessage2 = "false";
enableArmChecked = "";
}
}
Serial.println(inputMessage);
Serial.println(inputMessage2);
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);
Serial.print(temperature);
Serial.println(" *F");*/
lastTemperature = String(temperature);
// Check if temperature is above threshold and if it needs to trigger output
if(temperature > inputMessage.toFloat() && inputMessage2 == "true" && !triggerActive){
String message = String("Temperature above threshold. Current temperature: ") +
String(temperature) + String("C");
Serial.println(message);
triggerActive = true;
digitalWrite(output, HIGH);
}
// Check if temperature is below threshold and if it needs to trigger output
else if((temperature < inputMessage.toFloat()) && inputMessage2 == "true" && triggerActive) {
String message = String("Temperature below threshold. Current temperature: ") +
String(temperature) + String(" C");
Serial.println(message);
triggerActive = false;
digitalWrite(output, LOW);
}
}
}
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 (or ESP8266WiFi), AsyncTCP (or ESPAsyncTCP) and ESPAsyncWebServer are required to build the web server.
The OneWire and DallasTemperature are required to interface with the DS18B20.
The code automatically imports the right libraries accordingly to the selected board (ESP32 or ESP8266).
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#else
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.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";
Default Temperature Threshold Value
In the inputMessage variable insert your default temperature threshold value. We’re setting it to 25.0, but you can set it yo any other value.
String inputMessage = "25.0";
Auxiliar Variables
The lastTemperature variable will hold the latest temperature reading to be compared with the threshold value.
String lastTemperature;
The enableArmChecked variable will tell us whether the checkbox to automatically control the output is checked or not.
String enableArmChecked = "checked";
In case it’s checked, the value saved on the inputMessage2 should be set to true.
String inputMessage2 = "true";
HTML Text
Then, we have some basic HTML text to build a page with two input fields: a temperature threshold input field and a checkbox to enable or disable automatically controlling the output.
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% °C</h3>
The %TEMPERATURE% is a placeholder that will be replaced by the actual temperature value when the ESP32/ESP8266 serves the page.
Then, we have a form with two input fields and a “Submit” button. When the user types some data and clicks the “Submit” button, those values are sent to the ESP to update the variables.
<form action="/get">
Temperature Threshold <input type="number" step="0.1" name="threshold_input" value="%THRESHOLD%" required><br>
Arm Trigger <input type="checkbox" name="enable_arm_input" value="true" %ENABLE_ARM_INPUT%><br><br>
<input type="submit" value="Submit">
</form>
The first input field is of type number and the second input field is a checkbox. 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?threshold_input=value&enable_arm_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/ESP8266, read: Input Data on HTML Form ESP32/ESP8266 Web Server using Arduino IDE.
processor()
The processor() function replaces all placeholders in the HTML text with the actual values.
- %TEMPERATURE% » lastTemperature
- %THRESHOLD% » inputMessage
String processor(const String& var){
//Serial.println(var);
if(var == "TEMPERATURE"){
return lastTemperature;
}
else if(var == "THRESHOLD"){
return inputMessage;
}
else if(var == "ENABLE_ARM_INPUT"){
return enableArmChecked;
}
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 = "threshold_input";
const char* PARAM_INPUT_2 = "enable_arm_input";
Interval Between Readings
Every 5000 milliseconds (5 seconds), we’ll get a new temperature reading from the DS18B20 temperature sensor and compare it with the threshold value. To keep track of the time, we use timers.
Change the interval variable if you want to change the time between each sensor reading.
unsigned long previousMillis = 0;
const long interval = 5000;
GPIO Output
In this example, we’ll control GPIO 2. This GPIO is connected to the ESP32 and ESP8266 built-in LED, so it allows us to easily check if the project is working as expected. You can control any other output and for many applications you’ll want to control a relay module.
// GPIO where the output is connected to
const int output = 2;
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 ESP board, read:
setup()
In the setup(), connect to Wi-Fi in station mode and print the ESP 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());
Set GPIO 2 as an output and set it to LOW when the ESP first starts.
pinMode(output, OUTPUT);
digitalWrite(output, LOW);
Initialize the DS18B20 temperature sensor:
sensors.begin();
Handle Web Server
Then, define what happens when the ESP32 or ESP8266 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 ESP receives a request on the following URL:
<ESP_IP>/get?threshold_input=<inputMessage>&enable_arm_input=<inputMessage2>
So, we check whether the request contains input parameters, and save those parameters into variables:
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
// GET threshold_input value on <ESP_IP>/get?threshold_input=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
// GET enable_arm_input value on <ESP_IP>/get?enable_arm_input=<inputMessage2>
if (request->hasParam(PARAM_INPUT_2)) {
inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
enableArmChecked = "checked";
}
else {
inputMessage2 = "false";
enableArmChecked = "";
}
}
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 temperature threshold value and the inputMessage2 saves whether the checkbox is ticked or not (if we should control the GPIO or not).
After submitting the values on the form, it displays a new page saying the request was successfully sent to your board an 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);
Serial.print(temperature);
Serial.println(" *F");*/
lastTemperature = String(temperature);
After getting a new temperature reading, we check whether it is above or below the threshold and turn the output on or off accordingly.
In this example, we set the output state to HIGH, if all these conditions are met:
- The current temperature is above the threshold;
- Automatic output control is enabled (the checkbox is ticked on the web page);
- If the output hasn’t been triggered yet.
// Check if temperature is above threshold and if it needs to trigger output
if(temperature > inputMessage.toFloat() && inputMessage2 == "true" && !triggerActive){
String message = String("Temperature above threshold. Current temperature: ")
+ String(temperature) + String("C");
Serial.println(message);
triggerActive = true;
digitalWrite(output, HIGH);
}
Then, if the temperature goes below the threshold, set the output to LOW.
else if((temperature < inputMessage.toFloat()) && inputMessage2 == "true" && triggerActive) {
String message = String("Temperature below threshold. Current temperature: ")
+ String(temperature) + String(" C");
Serial.println(message);
triggerActive = false;
digitalWrite(output, LOW);
}
Depending on your application, you may want to change the output to LOW, when the temperature is above the threshold and to HIGH when the output is below the threshold.
Demonstration – ESP Thermostat
Upload the code to your ESP board (with the DS18B20 wired to your ESP32 or ESP8266 board).
Open the Serial Monitor at a baud rate of 115200 and press the on-board RST/EN button. The ESP will print its IP address and it will start displaying new temperature values every 5 seconds.
Open a browser and type the ESP IP address. A similar web page should load with the default values (defined in your code):
If the arm trigger is enabled (checkbox ticked) and if the temperature goes above the threshold, the LED should turn on (output is set to HIGH).
After that, if the temperature goes below the threshold, the output will turn off.
You can use the web page input fields to change the threshold value or to arm and disarm controlling the output. 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.
Wrapping Up
In this project you’ve learn how to create a web server with a threshold value to automatically control an output accordingly to the current temperature reading thermostat web server). As an example, we’ve controlled an LED. For real world applications, you’ll probably want to control a relay module. You can read the following guides to learn how to control a relay with the ESP:
- ESP32 Relay Module – Control AC Appliances (Web Server)
- ESP8266 NodeMCU Relay Module – Control AC Appliances (Web Server)
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. You may also want to add email notifications to this project.
If you want to learn more about the ESP32 and ESP8266, try our projects and resources:
- Learn ESP32 with Arduino IDE
- Home Automation using ESP8266
- MicroPython Programming with ESP32 and ESP8266
- More ESP32 resources…
- More ESP8266 resources…
Thanks for reading.
Been looking for something like this for awhile. Can we expand the project to include cooling. I live in a part of the world where cooling is needed especially in the summer months.
Yes, you can modify the part that triggers the LED to work how you prefer (either cooling or heating)
Need both heat and cool. Could tolerate a switch for summer and winter.
Would be very cool to incorporate a local touch display to alter temperature as well as programming for day and night.
Hi Frank.
Thanks for the suggestion.
Regards,
Sara
This is a very nice project. I can imagine replacing my old therostats with these IoT enabled devices.
One thing puzzles me however: I’d like to tuck the device into an installation socket (caja de conexión) but how do I power the whole thing? Using a USB Power Suppy (wall wart) or a battery in not really an option.
I would love to have an instruction on how to make a super miniature 230V power suppy which is part of the assemby and can provide the energy for an ESPxxx board (3.3V or 5V and 300mA).
Keep on with the exellent work!
Chris
Thanks for the suggestion! You could probably run this code on a SONOFF and trigger the GPIO. The SONOFF will give you a better enclosure for wall mount in a final application.
On Ebay you can buy very small 240 VAC to 3.3V DC converters. See below:
ebay.co.uk/itm/AC-to-DC-220V-3-3V-Step-Down-Buck-Voltage-Regulator-Power-Supply-Module/331938666556?hash=item4d4916183c:g:~5MAAOSwopRYalBK
This one is a bit expensive. I found some costing between £ 1-2 each including
shipping to Norway. Search on Ebay. Good luck.
I have a similar project that is a DHT22 hooked up to an arduino board that powers a relay switch to turn a plug in outlet on and off. Bit of a side note if you’re using something like this along side a relay to power an outlet. Relays really don’t last very long if you check them every five seconds. Mine ran for about 5 months before giving out until I changed the interval to 60 seconds. Given, my relay was a fairly cheap one i got off Wish but still.
I’m probably going to do this project when I get the time and I might even use it to replace my current setup since it’s so robust.
Hi Nickolas!
Thanks for sharing that.
Regards,
Sara
Instead of a mechanical relay you can use a Triac with opto coupler for isolation. The same Triac used in light dimmers. They come in 2 Amps and up to 16 Amps capacity at a reasonable price.
Hey man, could you help me out. Im using DHT11 and want to trigger a relay when the temp goes above a threshold. My programming knowledge isnt that great.
Thanks 🙂
Hi.
You just need to adapt this project to use a DHT.
Instead of using the functions to read the DS18B20 sensor, use the functions to read from a DHT.
Learn more about getting readings from a DHT sensor with this tutorial: https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide/
Regards,
Sara
Boa tarde,
É possível alguém me ajudar a fazer este projeto utilizando o sensor DHT11?
Obrigado!
Olá.
Pode seguir o tutorial do sensor de DHT11 e tentar adaptar o projeto.
Está aqui o tutorial: https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide/
Cumprimentos,
Sara
If you are using a relay to control a furnace or air-conditioner, normally you want to have 2 setpoints, a min-max temperature range, e.g. for a furnace a turn-on minimum temperature, and higher maximum turn-off temperature. (For cooling it’s reversed.)
Limiting the time interval is one approach, but HVAC equipment runs inefficiently if turned on and off in short intervals.
A programmable offset could be used, e.g. .5 degC or 1 degF so a 20.5 setting would have a turn-on at 20.0 and turn off at 21.0. In the loop, the prior on/off state would need to be saved (or else read the GPIO), then used to add or subtract an offset.
If you are logging, and rounding to 1degF or .5degC, then you also might want to add some hysteresis to the rounding. If the temperature is 20.25, the rounded value might flip between 20.0 and 20.5. If you record the prior rounded value and the new temperature is increasing, then add .25 to the recorded temperature before rounding. If decreasing, subtract .25 to the temperature.
Hi Carl.
You are absolutely right!
The aim of this project was to show how to add a threshold to your web servers. But for cooling/heating, having an interval is a better option.
You can modify the web server to include two input fields for the interval.
Thanks for sharing that information.
Regards,
Sara
Hi Sara! Also you can use a PID control for better perfomance! Thanks!!!
Rui,
This is great work. I have been attempting to build a temperature controller for some time. Thanks, you have saved me a lot of time.
Best regards
Phil
Hi Phil.
Thank you! I’m glad you find it useful 😀
Regards,
Sara
Great project, I have a wood stove off site from my house (car barn), I would like to monitor water jacket temperature, currently it has a 3” analog glass faced thermometer sticking out of it.
It would be great if I could get information from the water jacket to my home and iPhone, this project appears that it could do this. I have seen several projects similar to this one but the one caveat that always stops me or stumps me is how to convert code from C to F . I know a formula that states temp /9 then * 5 + 32 or / 5 * 9 -32 but none of this helps me when converting from C to F . Celcius always seams to be the default values in these projects. It would be nice to see how to convert to F . Thanks, your projects are great.
Hi Larry.
Our code shows how to convert to F.
You just need to comment the following lines as follows:
// Temperature in Celsius degrees
// float temperature = sensors.getTempCByIndex(0);
// Serial.print(temperature);
// Serial.println(” *C”);
And uncomment these ones
// Temperature in Fahrenheit degrees
float temperature = sensors.getTempFByIndex(0);
Serial.print(temperature);
Serial.println(” *F”);
Basically, you use the getTempFByIndex() function instead of the getTempCByIndex() function.
I hope this helps.
Regards,
Sara
Very nice these examples!
question: the first line is #ifdef ESP32
shouldn’t there also be a line #define ESP32; or #define ESP8266;
Regards, Jan.
Hi Jan.
That is automatically done when you select your board in the Boards menu.
Regards
Sara
hello
could you please show us how to password protect the webserver ?
What lines to include in the code?
So we can use this themostat to control home heating without worry that someone else can play with our temperatures?
thank you
Tutorial looks great, well laid out but I keep getting -127, I am up north but don’t think it is that cold. Have tried replacing parts, checking twice but not getting anywhere. Help would be appreciated.
Hi Don.
That usually happens when there’s something wrong with the sensor or with the wiring.
Without more information, it is very difficult to find out what might be wrong.
Regards,
Sara
Absolutely agree – these are great tutorials.
I do have a question please… if the ESP32 restarts (or is restarted), then does the threshold temp revert to its initial setting (the default value in the code)? Should I store the updated threshold value in SPIFFS or is there a better way of holding it ‘persistently’?
Many thanks, Malcolm
Hi.
In this particular example the value is not permanently saved. When it is restarted, it goes back to the default value.
You can save the value in SPIFFS, for example, and read it every time the ESP32 restarts.
To easily save a value, you can use the EEPROM library. For example, see this tutorial: https://randomnerdtutorials.com/esp32-flash-memory/
I hope this helps.
Regards,
Sara
Hi Sara
Lovely Project. I have one question:
I tried this and it works great, but I need to keep refreshing the web page to update the temperature value.
Is this normal and is it possible to have it update automatically without refreshing?
Thank you
Hi.
Yes, you can have it automatically updated without refreshing.
You can make a request for the temperature every x number of seconds using JavaScript.
You can use websockets or server-sent events to update the web page whenever a new readings is ready.
We don’t have (yet) a dedicated tutorial about websockets or server-sent events.
We have these projects that use server-sent events that you can take a look to see how they are used:
https://randomnerdtutorials.com/esp32-iot-shield-pcb-dashboard/
https://randomnerdtutorials.com/esp32-esp-now-wi-fi-web-server/
We’ll also create a tutorial soon about websockets. Meanwhile, you can read this article published by one of our readers: https://rntlab.com/question/full-tutorial-esp32-remote-control-with-websocket/
Regards,
Sara
Hey, loved the project and have been trying to use it. But I’ve been having a problem. If the device is fresh started everything works well, but after some time (ESP8266) it shows -127 degrees and it stops working! Could you please help me figure out what’s wrong? And why does it go to this state? If restarted it starts working again.
Best Regards,
João Graça
Hi.
The -127 means that the sensor was not able to get a valid reading.
You can add something in your code that checks if the reading is valid. And if not, you can either try to get another reading, or reset the ESP8266 via software.
I hope this helps.
Regards,
Sara
Hi Sara,
The DS18B20 are addressable Temp Sensors.
In the current program is it possible to add 2 more sensors and read them vis the web server
I really enjoy your courses and articles
Thanks
Kevin
Hi.
To learn how to handle multiple temperature sensors, you can follow this tutorial:https://randomnerdtutorials.com/esp32-multiple-ds18b20-temperature-sensors/
Regards,
Sara
I’m wanting to do this in AP Access point mode, I’ve had good success with the esp8266 going from server (connecting to my wifi router),to access point, all I did was change a few things but its not working with these recently received ESP32 boards.
I changed:
WiFi.mode(WIFI_STA); to WiFi.mode(WIFI_AP);
WiFi.begin(ssid, password); to WiFi.softAP(ssid, password);
Serial.print(“ESP IP Address: http://“); to Serial.print(“AP IP address: “);
Serial.println(WiFi.localIP()); to IPAddress IP = WiFi.softAPIP();
Serial.println(IP);
I get this error: WiFi Failed!, and I cant get to any web page or see the IP address print out on serial monitor.
It works fine as Server mode(WiFi_STA).
But it doesn’t as Access Point mode (WiFi_AP), is there something else that needs to be done to run ESP32 as access point?
Hi Stephen.
Everything seems fine.
However, take a look at the ESP32 Access Point tutorial and see if you figure out anything that might be wrong: https://randomnerdtutorials.com/esp32-access-point-ap-web-server/
Regards,
Sara
Where was this tutorial a couple of years ago? It would have save me a lot of time 🙂 I wrote something like this about that long ago. It’s indeed very similar (variable names different), the only difference is that it took me COUNTLESS hours to achieve this (I’m NOT a programmer) and a lot of google-ing. Keep up the great job.
Hello, I want to take advantage of thanking you for this wonderful work, but I have a question about the display of the temperature variation on the web page, it is not up to date, each time you have to refresh the page to give us the temperature of our sensor, I tried to add refrech in the code but the value entered in the setpoint becomes 0, so you can tell us how to display the temperature value every 5 seconds on the web page ? Thank you and good day
Hi.
Take a look at this tutorial: https://randomnerdtutorials.com/esp32-web-server-sent-events-sse/
Regards,
Sara
interesting page
hope i can make it to use
https://github.com/ldijkman/ART-ESP32-Touch-TFT-Thermostat/
Page does not exist!!
Great project, I have a garden house off site from my home, I would like to monitor the room temperature with one DS18 Sensor.
My problem ist das ich auf dem Smartphone no real readings, only the last according the start.
Is it possible to get the same measurings like on the seriell monitor
( at the same time )
Sorry for my english,
best regards and thanks, Kurt
Hi.
You can save all the readings in a file on the filesystem or sd card and then, serve that file on a specific path.
Unfortunately, at the moment, we don’t have any example about that.
I’ll add it to my list of future tutorials.
Regards,
Sara
Hi Sara
Great project. can this code be added into the senser email alert or viceversa so as well as email an output to a relay can be activated
Great tutorial. It’s been a few years since I’ve done any thing with the esp8266 but found this very usefull. I added “-3” to
else if((temperature < inputMessage.toFloat()- 3) && inputMessage2 == “true” && triggerActive) { so the it has a buffer between on and off, similar to a thermostat. Now I’m
trying to add a couple of relays to the code to turn on fan and UV light. Any help would be greatly appreciated.
I managed to merge the Relay web server sketch with the Thermostat web server. Mechanically everything works, but I’m stuck trying to get %TEMPERATURE% AND %THRESHOLD% to display on the web page. Any advice? Code looks like this…
const char index_html[] PROGMEM = R”rawliteral(
Temperature Threshold Output Control
ESP Arm Trigger
%TEMPERATURE% °F
Temperature Threshold
Arm Trigger
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
.slider:before {position: absolute; content: “”; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #2196F3}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
Home Automation ESP8266 Web Server
%BUTTONPLACEHOLDER%
function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){ xhr.open(“GET”, “/update?relay=”+element.id+”&state=1”, true); }
else { xhr.open(“GET”, “/update?relay=”+element.id+”&state=0″, true); }
xhr.send();
}
)rawliteral”;
Solved
Hi
Great tutorial
I have a question
If we want the system to stop working when the sensor connection is broken ,what should we add to the code ?
Sensor sends -127 when there is a problem with the sensor wiring or itself .
Check the string
const int one Wire Bus = 15
The GPIO must be the one of that. where the your sensor connected to.
I want to move this project to SPIFFS. I moved part of the code to a file index.html
Temperature Threshold Output Control
DS18B20 Temperature
%TEMPERATURE% °C
ESP Arm Trigger
Temperature Threshold
Arm Trigger
What else should I must edit? What should I pay attention to?
Thank you for your support!
Hi.
Take a look at our SPIFFS web server example. It will help: https://randomnerdtutorials.com/esp32-web-server-spiffs-spi-flash-file-system/
Regards,
Sara
I made an addition to the lesson. Moved it to SPIFFS and changed the sensor. Now BME280. Who is interested in this here:
https://github.com/humaxoid/thermostat_spiffs
If anyone knows how to make a cutoff on the lower and upper temperature threshold, add your commits.
Hello Guys,
I am wondering how the line
request->send(200, “text/html”, “HTTP GET request sent to your ESP.Return to Home Page“);
sends you back to the main page?
I would like to modify the code to send you back to the main page after a few seconds. Any Idea How?
I decided it like this:
Change the line-
request->send(200, “text/html”, “HTTP GET request sent to your ESP.Return to Home Page“);
on this-
request->send_P(200, “text/html”, index_html, processor);
This will redirect you to the main page instead of the replacement page.
Yes, I had tried that as well, and it works fine, but, there is no way to tell if you actually pressed the submit button or not. (It immediately displays the main page, and nothing changes, so there is no visual indication anything has happened.) That is why I was wanting it to display the page telling you it had updated first, then, automatically return to the main page.
Hi guys! A wonderful lesson. But I would like to combine this code, with this https://randomnerdtutorials.com/esp32-websocket-server-arduino So that the load can be turned on not only according to the temperature sensor, but also manually with the help of a button. Has anyone succeeded?
Hi.
You can see Steph’s example here: https://github.com/m1cr0lab-esp32/asynchronous-web-controlled-thermostat
Regards,
Sara
Thank you so much Sara for the link.The project you specified only works in the thermostat mode. A small clarification. Two modes of operation are required.
1-Auto when this code is running in thermostat mode.
2-Manual, the LED turns on from the button. For example, as in your lesson ESP32 WebSocket Server: Control Output. I took two of your lessons as a basis:
https://randomnerdtutorials.com/esp 32-esp8266-thermostat-web-server/ and
https://randomnerdtutorials.com/esp32-websocket-server-arduino/
But I can’t put it all together in one code.. My knowledge is not enough.
We have this tutorial: https://randomnerdtutorials.com/esp32-esp8266-web-server-physical-button/
But, it doesn’t use websocket.
Steph also created a similar tutorial but using websocket: https://rntlab.com/question/full-tutorial-esp32-remote-control-with-websocket/
I hope this helps.
Regards,
Sara
Hi Rui and Sara!
There is no need to set the values triggerActive = false; and triggerActive = false; in the loop. You have already registered a variable for checking the activation of triggers at the global level. bool triggerActive = false;
Many thanks!
Cool project, but one thing….
Ive seen a few of these projects and none of them have a time veritable.
Most people turn up/dow their temps around bed time, then back to a set point after waking, that’s how my store bought one is set.
Be a cool project to play with if you’d ever consider adding in a time function to alter the temps automatically, and then make those start/end times adjustable on the web page.
Thank you for your great tutorials. I have learnt a lot about ESP8266, but I’ve got a question you might be able to Answer. I read your tutorial about ESP8266 Insert Data into MySQL Database using PHP and Arduino IDE and I wondered If I could operate the ESP8266 both as a web server and as an HTTP client at the same time. The idea is to control the temperature of a process and record it on an SQL database, but I want the temperature to be adjustable by conecting to the ESP8266 from my phone and introducing a threshold value just as in this example. Is it possible for the ESP to work as a client and server at the same time? Thank you in advance
Thanks so much for the great tutorials. This one will save me a lot of time developing my current project. In case anyone out there is using Platformio to run this code here is how to handle the library issues:
Add this to the platformio.ini file.
lib_deps =
ottowinter/AsyncTCP-esphome@^1.2.1
ottowinter/ESPAsyncWebServer-esphome@^2.1.0
paulstoffregen/OneWire@^2.3.6
milesburton/DallasTemperature@^3.9.1
I hope this helps.
Thanks again
Brian
I’m sure this is a simple to answer / straight forward question, where is esp32 defined? In your conditional compilation code you include different files based on processor type (#ifdef ESP32
#include <WiFi.h>).
Hi.
It is automatically defined when you select a board in Tools > Boards.
Regards,
Sara
Thanks.
I thought that was the case but I would have thought it would be a entry in the platformio.ini file.
Hi.
If you’re using PlatformIO, the board is defined in the platformio.ini file.
Regards,
Sara
Hi! I want image 1, to be displayed in the browser when the temperature threshold reaches 25 degrees. If below the threshold of 25 degrees, then image 2. Can you tell me the condition for javascript?
script.js
if (what should be here?)
{
document.getElementById(“winimg”).src = “image1.gif”;
}
else{
document.getElementById(“winimg”).src = “image2.gif”;
}
index.html
Hi.
First, give an IDE to h3 where the temperature is displayed.
Then, get the temperature using document.getElementByID(“THE_ID_YOU_GAVE_TO_THE_ELEMETN”).
Then, compare it with the threshold.
I hope this helps.
Regards,
Sara
Thank you very much, Sara. This is what I need!
Dear Sara an Rui,
this is a very nice project. I`d rebuild it and it works great.
Now i want made a AP- Server to connect directly with my smartphone,
because it would be a cool gadget as heating scarf an so on…
Is anywere on randomnerdtuorials a sketch for the Arduino IDE?
Thank you and best Regards
Michael Baur
Hi.
To learn how to set an access point, we have the following tutorials:
– ESP32: https://randomnerdtutorials.com/esp32-access-point-ap-web-server/
– ESP8266: https://randomnerdtutorials.com/esp8266-nodemcu-access-point-ap-web-server/
I hope this helps.
Regards,
Sara
Hello
how can i connect single channel relay and run a dc motor?
can I use 5v as input?
please answer
I’m using Safari browser on iphone but the server stops working after an hour or so. Is there a fix for this? I saw a fix for Crome browser does safari need same timeout? Thank you for great tutorials!
Thank you!!
I found this when I woke to the thermostat in my home dead, just to get the heat going with stuff I had on-hand.
However, it served 2 purposes…. 1) keep me from freezing 2) I got to see how you did the “input for output” of the temperature.
I first wanted to say thank you for those, but wanted to ask…. Do you have an example of this but with time I can learn from?
I’ve been trying to build an aquarium controller with WiFi using the EPS32, and this was the break through for me to see how to do the water heater part. Lights (time based on/off) with internet time is part 2.
Hi.
There are many different ways to control things based on time.
It really depends on how your setup is built.
You can take a look at this simple example developed by one of our readers: https://gist.github.com/Tech500/bc4bd77a357b8d401cd13487ef6de800?fbclid=IwAR3ehkbwGDNe8VOQHMUD32YMx4MC7HDqjI_av5dkzzj-Ce2TYgzuR1PrhbE
I hope this helps.
Regards,
Sara
Thank you for the reply, I just seen the email today.
I’ve got the code you linked too and will take a look at it today and see what/how it works.
My ultimate goal (slow going as it is) is the make this or something similar.
https://github.com/DavidJ1975/EPS32-Aquarium-Controller
Made a page a while back to show what I’m trying to learn towards.
Figured my first steps were to make each part independent, and then merge all the parts.
Might not be the ideal way to do this or to learn, but it makes sense to me to do it this way…. till a better way presents itself.
Hi Sara, Rui, great project.
Still I have to speak a very important warning.
This will work greatly with a Central Heating System which uses the simple On/Off.
Many CHS work with OpenTherm protocol, this is a digital system which works completely different.
It would be nice to work this out, but this project above would not work and I think the results will be unpredictable.
Sorry for this critical note.
Kind regards
Hans
Hi, thanks for the project.
However, I have noticed that if the power goes out the system does not restart. I have to set a new threshold below the temperature read by the sensor and only then does it start again. you can help me.
Thank you
damian
Hi.
Yes.
You can save those values permanently on the flash memory and then when the ESP starts, it first reads those values.
You can save the values using the Preferences library: https://randomnerdtutorials.com/esp32-save-data-permanently-preferences/
I hope this helps.
Regards,
Sara
It’s been awhile since I did any sketches, so I a little rusty. I am looking to use another esp8266 as a remote sensor to trigger the thermostat, any advice would be greatly appreciated.
Thanks
Hi.
What do you mean?
Can you provide more details?
Regards,
Sara
Yes, I would like to use one esp8266 as the temperature sensor(dht11) and send the readings to a second esp8266 that would trigger gpio’s based on the temperature.
Thanks Sara
Bill
Yes, I would like to use one esp8266 as the temperature sensor(dht11) and send the readings to a second esp8266 that would trigger gpio’s based on the temperature.
Thanks Sara
Bill
Through wifi, AP
Hi.
Check this tutorial: https://randomnerdtutorials.com/esp8266-nodemcu-client-server-wi-fi/
I hope this helps.
Regards,
Sara
I probably still wasn’t clear. I want to connect the 2 esp8266 through wifi, maybe with esp NOW or some kind of client-server set up. Hope that makes sense.
Yes, I looked at that, probably a good start. I get lost trying to combine the thermostat sketch with the client-server sketch.
Thanks
How do i adapt this to using the DHT11 sensor instead DS18B20 sensor?
Hi.
You can learn how to use the DHT sensor with the following tutorial:
– https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide/
Then, you just need to make slighty changes to use the DHT instead.
Regards,
Sara
I think you didn’t understand my question
I know how to use the DHT sensor
I just want to know how to adapt the code to use the DHT11 sensor instead of the DS18B20 sensor
Hi,
It works very well. But I can only access it via wifi at home. How can I access it from outside my home?
thanks..
Hi Sara and Rui,
have found this project and have “one” question.
Every time i start up this project i have the same conditions on the values “Threashold” and “Arm Trigger”. This is probably because the two parameters are hard-coded and are always reset at startup.
I have build a smal extension with the LittleFS-System to save parameters in a coresponding text-file (e.g. inputmessage.txt and enablearmchecked.txt) to save the last state(s). LittleFS is realy easy to handle and should help to save parameters and values to the FileSystem on the ESP8266-Chip.
But there is a realy tricky problem found on the checkbox. How could i save the actual state of the checkbox to a file (how to handle save and load with LittleFS is not the problem) and read it back at startup within the processor()-task. The value “checked” is not a real parameter of the input-element and we have to handle it over the string-processor and parameters manually. But how to do this tricky thing? Did you have a idea, solution or maybe a equal tutorial to handle this?
Thanks a lot and i think there are many follower to have the same idea/problem?
Sunny greetings from germany,
Manfred
another version with websockets
so that it changes settings in all browser windows
esp8266
https://github.com/ldijkman/async-esp-fs-webserver/tree/master/docs/ino/thermostat_web_flash