{"id":69087,"date":"2019-08-04T08:22:11","date_gmt":"2019-08-04T08:22:11","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=69087"},"modified":"2020-07-30T14:10:13","modified_gmt":"2020-07-30T14:10:13","slug":"esp32-web-server-with-bme280-mini-weather-station","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-web-server-with-bme280-mini-weather-station\/","title":{"rendered":"ESP32 Web Server with BME280 \u2013 Advanced Weather Station"},"content":{"rendered":"\n<p>In this tutorial you\u2019re going to learn how to create a web server with the ESP32 to display readings from the BME280 sensor module. The BME280 sensor measures temperature, humidity, and pressure. So, you can easily build a mini and compact weather station and monitor the measurements using your ESP32 web server. That&#8217;s what we&#8217;re going to do in this project.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME_ESP32_WEB_SERVER.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Web Server with BME280 Weather Station\" class=\"wp-image-69102\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME_ESP32_WEB_SERVER.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME_ESP32_WEB_SERVER.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME_ESP32_WEB_SERVER.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME_ESP32_WEB_SERVER.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n\n<p>Before proceeding with this tutorial you should have the ESP32 add-on installed in your Arduino IDE. Follow one of the following tutorials to install the ESP32 on the Arduino IDE, if you haven\u2019t already.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/installing-the-esp32-board-in-arduino-ide-windows-instructions\/\">Installing the ESP32 Board in Arduino IDE (Windows, Mac OS X, and Linux instructions)<\/a><\/li><\/ul>\n\n\n\n<p>You might also like reading other BME280 guides:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><span style=\"font-size: inherit; background-color: initial;\"><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bme280-arduino-ide-pressure-temperature-humidity\/\">ESP32 with BME280 Sensor using Arduino IDE<\/a><\/span><\/li><li><a style=\"font-size: inherit; background-color: initial;\" href=\"https:\/\/randomnerdtutorials.com\/esp8266-bme280-arduino-ide\/\">ESP8266 with BME280 using Arduino IDE<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme280-esp32-esp8266\/\">ESP32\/ESP8266 with BME280 using MicroPython<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/bme280-sensor-arduino-pressure-temperature-humidity\/\">Arduino Board with BME280<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Watch the Video Tutorial<\/h2>\n\n\n\n<p><em>This tutorial is available in video format (watch below) and in written format (continue reading).<\/em><\/p>\n\n\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/6LjbTgX046w?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Parts Required<\/h2>\n\n\n\n<p>To follow this tutorial you need the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\">ESP32 DOIT DEVKIT V1 Board<\/a>&nbsp;&#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/esp32-development-boards-review-comparison\/\" target=\"_blank\">read ESP32 Development Boards Review and Comparison<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/bme280-sensor-module\/\" target=\"_blank\">BME280 sensor module<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\">Breadboard<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\">Jumper wires<\/a><\/li><\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introducing the BME280 Sensor Module<\/h2>\n\n\n\n<p>The BME280 sensor module reads temperature, humidity, and pressure. Because pressure changes with altitude, you can also estimate altitude. There are several versions of this sensor module, but we&#8217;re using the one shown in the figure below.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"474\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME280-1.jpg?resize=750%2C474&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BME280 Sensor Module Read temperature, humidity, and pressure\" class=\"wp-image-69094\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME280-1.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME280-1.jpg?resize=300%2C190&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>The sensor can communicate using either SPI or I2C communication protocols (there are modules of this sensor that just communicate with I2C, these just come with four pins).<\/p>\n\n\n\n<p>To use SPI communication protocol, you use the following pins:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SCK &#8211; this is the SPI Clock pin<\/li><li>SDO&nbsp;&#8211; MISO<\/li><li>SDI&nbsp;&#8211; MOSI<\/li><li>CS&nbsp;&#8211; Chip Select<\/li><\/ul>\n\n\n\n<p>To use I2C communication protocol, the sensor uses the following pins:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SCK&nbsp;&#8211; this is also the SCL pin<\/li><li>SDI&nbsp;&#8211; this is also the SDA pin<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Schematic<\/h2>\n\n\n\n<p>We&#8217;re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the ESP32 <span class=\"rnthl rntcgreen\">SDA<\/span> and <span class=\"rnthl rntcblue\">SCL<\/span> pins, as shown in the following schematic diagram.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP32-bme280_bb_f-768x669.png?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"768\" height=\"669\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP32-bme280_bb_f-768x669.png?resize=768%2C669&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BME280 Schematic Wiring temperature, humidity, and pressure\" class=\"wp-image-69096\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP32-bme280_bb_f-768x669.png?resize=768%2C669&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP32-bme280_bb_f-768x669.png?resize=300%2C261&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/a><\/figure><\/div>\n\n\n\n<p><em>(This schematic uses the ESP32 DEVKIT V1 module version with 36 GPIOs \u2013 if you\u2019re using another model, please check the pinout for the board you\u2019re using.)<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing the BME280 library<\/h2>\n\n\n\n<p>To take readings from the BME280 sensor module we&#8217;ll use the <a href=\"https:\/\/github.com\/adafruit\/Adafruit_BME280_Library\" target=\"_blank\" rel=\"noreferrer noopener\">Adafruit_BME280 library<\/a>. Follow the next steps to install the library in your Arduino IDE:<\/p>\n\n\n\n<p>Open your Arduino IDE and go to&nbsp;<strong>Sketch&nbsp;<\/strong>&gt;&nbsp;<strong>Include Library<\/strong>&nbsp;&gt;&nbsp;<strong>Manage Libraries<\/strong>. The Library Manager should open.<\/p>\n\n\n\n<p>Search for \u201c<strong>adafruit bme280<\/strong> \u201d on the Search box and install the library.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"443\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/install-bme280.png?resize=786%2C443&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Installing the BME280 library Arduino IDE\" class=\"wp-image-70233\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/install-bme280.png?w=786&amp;quality=100&amp;strip=all&amp;ssl=1 786w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/install-bme280.png?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/install-bme280.png?resize=768%2C433&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Installing the Adafruit_Sensor library<\/h2>\n\n\n\n<p>To use the BME280 library, you also need to install the <a href=\"https:\/\/github.com\/adafruit\/Adafruit_Sensor\" target=\"_blank\" rel=\"noreferrer noopener\">Adafruit_Sensor library<\/a>. Follow the next steps to install the library in your Arduino IDE:<\/p>\n\n\n\n<p>Go to <strong>Sketch&nbsp;<\/strong>&gt;&nbsp;<strong>Include Library<\/strong>&nbsp;&gt;&nbsp;<strong>Manage Libraries<\/strong> and type \u201c<strong>Adafruit Unified Sensor<\/strong>\u201d in the search box. Scroll all the way down to find the library and install it.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/04\/adafruit_unified_sensor_library.png?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Installing Adafruit Unified Sensor library Arduino IDE\" class=\"wp-image-84295\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/04\/adafruit_unified_sensor_library.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/04\/adafruit_unified_sensor_library.png?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n\n\n\n<p>After installing the libraries, restart your Arduino IDE.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reading Temperature, Humidity, and Pressure<\/h2>\n\n\n\n<p>To get familiar with the BME280 sensor, we&#8217;re going to use an example sketch from the library to see how to read temperature, humidity, and pressure.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/bme280_circuit.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Reading Temperature, Humidity, and Pressure BME280 with Arduino IDE\" class=\"wp-image-69093\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/bme280_circuit.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/bme280_circuit.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>After installing the BME280 library, and the Adafruit_Sensor library, open the Arduino IDE and, go to <strong>File<\/strong> &gt; <strong>Examples<\/strong> &gt; <strong>Adafruit BME280 library<\/strong> &gt; <strong>bme280 test<\/strong>.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\n  Complete project details at http:\/\/randomnerdtutorials.com  \n*********\/\n\n#include &lt;Wire.h&gt;\n#include &lt;Adafruit_Sensor.h&gt;\n#include &lt;Adafruit_BME280.h&gt;\n\n\/*#include &lt;SPI.h&gt;\n#define BME_SCK 18\n#define BME_MISO 19\n#define BME_MOSI 23\n#define BME_CS 5*\/\n\n#define SEALEVELPRESSURE_HPA (1013.25)\n\nAdafruit_BME280 bme; \/\/ I2C\n\/\/Adafruit_BME280 bme(BME_CS); \/\/ hardware SPI\n\/\/Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); \/\/ software SPI\n\nunsigned long delayTime;\n\nvoid setup() {\n  Serial.begin(9600);\n  Serial.println(F(&quot;BME280 test&quot;));\n\n  bool status;\n\n  \/\/ default settings\n  \/\/ (you can also pass in a Wire library object like &amp;Wire2)\n  status = bme.begin(0x76);  \n  if (!status) {\n    Serial.println(&quot;Could not find a valid BME280 sensor, check wiring!&quot;);\n    while (1);\n  }\n\n  Serial.println(&quot;-- Default Test --&quot;);\n  delayTime = 1000;\n\n  Serial.println();\n}\n\n\nvoid loop() { \n  printValues();\n  delay(delayTime);\n}\n\nvoid printValues() {\n  Serial.print(&quot;Temperature = &quot;);\n  Serial.print(bme.readTemperature());\n  Serial.println(&quot; *C&quot;);\n  \n  \/\/ Convert temperature to Fahrenheit\n  \/*Serial.print(&quot;Temperature = &quot;);\n  Serial.print(1.8 * bme.readTemperature() + 32);\n  Serial.println(&quot; *F&quot;);*\/\n  \n  Serial.print(&quot;Pressure = &quot;);\n  Serial.print(bme.readPressure() \/ 100.0F);\n  Serial.println(&quot; hPa&quot;);\n\n  Serial.print(&quot;Approx. Altitude = &quot;);\n  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));\n  Serial.println(&quot; m&quot;);\n\n  Serial.print(&quot;Humidity = &quot;);\n  Serial.print(bme.readHumidity());\n  Serial.println(&quot; %&quot;);\n\n  Serial.println();\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-Course\/raw\/master\/code\/bme280test\/bme280test.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Libraries<\/h3>\n\n\n\n<p>The code starts by including the needed libraries<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;Wire.h>\n#include &lt;Adafruit_Sensor.h>\n#include &lt;Adafruit_BME280.h><\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">SPI communication<\/h3>\n\n\n\n<p>As we&#8217;re going to use I2C communication you can comment the following lines:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/*#include &lt;SPI.h>\n#define BME_SCK 18\n#define BME_MISO 19\n#define BME_MOSI 23\n#define BME_CS 5*\/<\/code><\/pre>\n\n\n\n<p><strong>Note:<\/strong> if you&#8217;re using SPI communication, you need to change the pin definition to use the ESP32 GPIOs. For SPI communication on the ESP32 you can use either the HSPI or VSPI pins, as shown in the following table.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>SPI<\/strong><\/td><td><strong>MOSI<\/strong><\/td><td><strong>MISO<\/strong><\/td><td><strong>CLK<\/strong><\/td><td><strong>CS<\/strong><\/td><\/tr><tr><td>HSPI <\/td><td>GPIO 13 <\/td><td>GPIO 12<\/td><td>GPIO 14<\/td><td>GPIO 15<\/td><\/tr><tr><td>VSPI <\/td><td>GPIO 23<\/td><td>GPIO 19<\/td><td>GPIO 18<\/td><td>GPIO 5<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Sea level pressure<\/h3>\n\n\n\n<p>A variable called <span class=\"rnthl rntliteral\">SEALEVELPRESSURE_HPA<\/span> is created.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define SEALEVELPRESSURE_HPA (1013.25)<\/code><\/pre>\n\n\n\n<p>This saves the pressure at the sea level in hectopascal (is equivalent to milibar). This variable is used to estimate the altitude for a given pressure by comparing it with the sea level pressure. This example uses the default value, but for more accurate results, replace the value with the current sea level pressure at your location.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">I2C<\/h3>\n\n\n\n<p>This example uses I2C communication by default. As you can see, you just need to create an <span class=\"rnthl rntliteral\">Adafruit_BME280<\/span> object called <span class=\"rnthl rntliteral\">bme<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Adafruit_BME280 bme; \/\/ I2C<\/code><\/pre>\n\n\n\n<p>If you would like to use SPI, you need to comment this previous line and uncomment one of the following lines depending on whether you\u2019re using hardware or software SPI.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/Adafruit_BME280 bme(BME_CS); \/\/ hardware SPI\n\/\/Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); \/\/ software SPI<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span> you start a serial communication<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(9600);<\/code><\/pre>\n\n\n\n<p>And the sensor is initialized:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>status = bme.begin(0x76); \nif (!status) {\n  Serial.println(\"Could not find a valid BME280 sensor, check wiring!\");\n  while (1);\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Printing values<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, the <span class=\"rnthl rntliteral\">printValues()<\/span> function reads the values from the BME280 and prints the results in the Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void loop() { \n  printValues();\n  delay(delayTime);\n}<\/code><\/pre>\n\n\n\n<p>Reading temperature, humidity, pressure, and estimate altitude is as simple as using:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><span class=\"rnthl rntliteral\">bme.readTemperature()<\/span><\/strong> &#8211; reads temperature in Celsius;<\/li><li><strong><span class=\"rnthl rntliteral\">bme.readHumidity()<\/span><\/strong> &#8211; reads absolute humidity;<\/li><li><strong><span class=\"rnthl rntliteral\">bme.readPressure()<\/span><\/strong> &#8211; reads pressure in hPa (hectoPascal = millibar);<\/li><li><span class=\"rnthl rntliteral\"><strong>bme.readAltitude(SEALEVELPRESSURE_HPA)<\/strong><\/span> &#8211; estimates altitude in meters based on the pressure at the sea level.<\/li><\/ul>\n\n\n\n<p>Upload the code to your ESP32, and open the Serial Monitor at a baud rate of 9600. You should see the readings displayed on the Serial Monitor.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"533\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/sensor_readings_serial_monitor.jpg?resize=756%2C533&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Demonstration Temperature, Humidity, and Pressure BME280 with Arduino IDE\" class=\"wp-image-69100\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/sensor_readings_serial_monitor.jpg?w=756&amp;quality=100&amp;strip=all&amp;ssl=1 756w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/sensor_readings_serial_monitor.jpg?resize=300%2C212&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 756px) 100vw, 756px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a Table in HTML<\/h2>\n\n\n\n<p>As you&#8217;ve seen in the beginning of the post, we&#8217;re displaying the readings in a web page with a table served by the ESP32. So, we need to write HTML text to build a table.<\/p>\n\n\n\n<p>To create a table in HTML you use the <span style=\"color: #333399;\">&lt;table&gt;<\/span> and <span style=\"color: #333399;\">&lt;\/table&gt;<\/span> tags.<\/p>\n\n\n\n<p>To create a row you use the <span style=\"color: #333399;\">&lt;tr&gt;<\/span> and <span style=\"color: #333399;\">&lt;\/tr&gt;<\/span> tags. The table heading is defined using the <span style=\"color: #333399;\">&lt;th&gt;<\/span> and <span style=\"color: #333399;\">&lt;\/th&gt;<\/span> tags, and each table cell is defined using the <span style=\"color: #333399;\">&lt;td&gt;<\/span>and <span style=\"color: #333399;\">&lt;\/td&gt;<\/span> tags.<\/p>\n\n\n\n<p>To create a table for our readings, you use the following html text:<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;table>\n  &lt;tr>\n    &lt;th>MEASUREMENT&lt;\/th>\n    &lt;th>VALUE&lt;\/th>\n  &lt;\/tr>\n  &lt;tr>\n    &lt;td>Temp. Celsius&lt;\/td>\n    &lt;td>--- *C&lt;\/td>\n  &lt;\/tr>\n  &lt;tr>\n    &lt;td>Temp. Fahrenheit&lt;\/td>\n    &lt;td>--- *F&lt;\/td>\n  &lt;\/tr>\n  &lt;tr>\n    &lt;td>Pressure&lt;\/td>\n    &lt;td>--- hPa&lt;\/td>\n  &lt;\/tr>\n  &lt;tr>\n    &lt;td>Approx. Altitude&lt;\/td>\n    &lt;td>--- meters&lt;\/td>&lt;\/tr>\n  &lt;tr>\n    &lt;td>Humidity&lt;\/td>\n    &lt;td>--- %&lt;\/td>\n  &lt;\/tr>\n&lt;\/table><\/code><\/pre>\n\n\n\n<p>We create the header of the table with a cell called MEASUREMENT, and another called VALUE. Then, we create six rows to display each of the readings using the <span style=\"color: #333399;\">&lt;tr&gt;<\/span> and <span style=\"color: #333399;\">&lt;\/tr&gt;<\/span> tags. Inside each row, we create two cells, using the <span style=\"color: #333399;\">&lt;td&gt;<\/span> and <span style=\"color: #333399;\">&lt;\/td&gt;<\/span> tags, one with the name of the measurement, and another to hold the measurement value. The three dashes &#8220;&#8212;&#8221; should then be replaced with the actual measurements from the BME sensor.<\/p>\n\n\n\n<p>You can save this text as <em>table.html<\/em>, drag the file into your browser and see what you have. The previous HTML text creates the following table.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"539\" height=\"316\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/raw-table-f.png?resize=539%2C316&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Demonstration HTML Temperature, Humidity, and Pressure BME280 with Arduino IDE\" class=\"wp-image-69099\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/raw-table-f.png?w=539&amp;quality=100&amp;strip=all&amp;ssl=1 539w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/raw-table-f.png?resize=300%2C176&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 539px) 100vw, 539px\" \/><\/figure><\/div>\n\n\n\n<p>The table doesn&#8217;t have any styles applied. You can use CSS to style the table with your own preferences. You may found this link useful: <a href=\"https:\/\/www.w3schools.com\/cSS\/css_table.asp\" target=\"_blank\" rel=\"noreferrer noopener\">CSS Styling Tables<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating the Web Server<\/h2>\n\n\n\n<p>Now that you know how to take readings from the sensor, and how to build a table to display the results, it\u2019s time to build the web server. If you&#8217;ve followed other ESP32 tutorials, you should be familiar with the majority of the code. If not, take a look at the <a href=\"https:\/\/randomnerdtutorials.com\/esp32-web-server-arduino-ide\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 Web Server Tutorial<\/a>.<\/p>\n\n\n\n<p>Copy the following code to your Arduino IDE. Don&#8217;t upload it yet. First, you need to include your SSID and password.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\n  Rui Santos\n  Complete project details at http:\/\/randomnerdtutorials.com  \n*********\/\n\n\/\/ Load Wi-Fi library\n#include &lt;WiFi.h&gt;\n#include &lt;Wire.h&gt;\n#include &lt;Adafruit_BME280.h&gt;\n#include &lt;Adafruit_Sensor.h&gt;\n\n\/\/uncomment the following lines if you're using SPI\n\/*#include &lt;SPI.h&gt;\n#define BME_SCK 18\n#define BME_MISO 19\n#define BME_MOSI 23\n#define BME_CS 5*\/\n\n#define SEALEVELPRESSURE_HPA (1013.25)\n\nAdafruit_BME280 bme; \/\/ I2C\n\/\/Adafruit_BME280 bme(BME_CS); \/\/ hardware SPI\n\/\/Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); \/\/ software SPI\n\n\/\/ Replace with your network credentials\nconst char* ssid     = &quot;REPLACE_WITH_YOUR_SSID&quot;;\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\n\n\/\/ Set web server port number to 80\nWiFiServer server(80);\n\n\/\/ Variable to store the HTTP request\nString header;\n\n\/\/ Current time\nunsigned long currentTime = millis();\n\/\/ Previous time\nunsigned long previousTime = 0; \n\/\/ Define timeout time in milliseconds (example: 2000ms = 2s)\nconst long timeoutTime = 2000;\n\nvoid setup() {\n  Serial.begin(115200);\n  bool status;\n\n  \/\/ default settings\n  \/\/ (you can also pass in a Wire library object like &amp;Wire2)\n  \/\/status = bme.begin();  \n  if (!bme.begin(0x76)) {\n    Serial.println(&quot;Could not find a valid BME280 sensor, check wiring!&quot;);\n    while (1);\n  }\n\n  \/\/ Connect to Wi-Fi network with SSID and password\n  Serial.print(&quot;Connecting to &quot;);\n  Serial.println(ssid);\n  WiFi.begin(ssid, password);\n  while (WiFi.status() != WL_CONNECTED) {\n    delay(500);\n    Serial.print(&quot;.&quot;);\n  }\n  \/\/ Print local IP address and start web server\n  Serial.println(&quot;&quot;);\n  Serial.println(&quot;WiFi connected.&quot;);\n  Serial.println(&quot;IP address: &quot;);\n  Serial.println(WiFi.localIP());\n  server.begin();\n}\n\nvoid loop(){\n  WiFiClient client = server.available();   \/\/ Listen for incoming clients\n\n  if (client) {                             \/\/ If a new client connects,\n    currentTime = millis();\n    previousTime = currentTime;\n    Serial.println(&quot;New Client.&quot;);          \/\/ print a message out in the serial port\n    String currentLine = &quot;&quot;;                \/\/ make a String to hold incoming data from the client\n    while (client.connected() &amp;&amp; currentTime - previousTime &lt;= timeoutTime) {  \/\/ loop while the client's connected\n      currentTime = millis();\n      if (client.available()) {             \/\/ if there's bytes to read from the client,\n        char c = client.read();             \/\/ read a byte, then\n        Serial.write(c);                    \/\/ print it out the serial monitor\n        header += c;\n        if (c == '\\n') {                    \/\/ if the byte is a newline character\n          \/\/ if the current line is blank, you got two newline characters in a row.\n          \/\/ that's the end of the client HTTP request, so send a response:\n          if (currentLine.length() == 0) {\n            \/\/ HTTP headers always start with a response code (e.g. HTTP\/1.1 200 OK)\n            \/\/ and a content-type so the client knows what's coming, then a blank line:\n            client.println(&quot;HTTP\/1.1 200 OK&quot;);\n            client.println(&quot;Content-type:text\/html&quot;);\n            client.println(&quot;Connection: close&quot;);\n            client.println();\n            \n            \/\/ Display the HTML web page\n            client.println(&quot;&lt;!DOCTYPE html&gt;&lt;html&gt;&quot;);\n            client.println(&quot;&lt;head&gt;&lt;meta name=\\&quot;viewport\\&quot; content=\\&quot;width=device-width, initial-scale=1\\&quot;&gt;&quot;);\n            client.println(&quot;&lt;link rel=\\&quot;icon\\&quot; href=\\&quot;data:,\\&quot;&gt;&quot;);\n            \/\/ CSS to style the table \n            client.println(&quot;&lt;style&gt;body { text-align: center; font-family: \\&quot;Trebuchet MS\\&quot;, Arial;}&quot;);\n            client.println(&quot;table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }&quot;);\n            client.println(&quot;th { padding: 12px; background-color: #0043af; color: white; }&quot;);\n            client.println(&quot;tr { border: 1px solid #ddd; padding: 12px; }&quot;);\n            client.println(&quot;tr:hover { background-color: #bcbcbc; }&quot;);\n            client.println(&quot;td { border: none; padding: 12px; }&quot;);\n            client.println(&quot;.sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }&quot;);\n            \n            \/\/ Web Page Heading\n            client.println(&quot;&lt;\/style&gt;&lt;\/head&gt;&lt;body&gt;&lt;h1&gt;ESP32 with BME280&lt;\/h1&gt;&quot;);\n            client.println(&quot;&lt;table&gt;&lt;tr&gt;&lt;th&gt;MEASUREMENT&lt;\/th&gt;&lt;th&gt;VALUE&lt;\/th&gt;&lt;\/tr&gt;&quot;);\n            client.println(&quot;&lt;tr&gt;&lt;td&gt;Temp. Celsius&lt;\/td&gt;&lt;td&gt;&lt;span class=\\&quot;sensor\\&quot;&gt;&quot;);\n            client.println(bme.readTemperature());\n            client.println(&quot; *C&lt;\/span&gt;&lt;\/td&gt;&lt;\/tr&gt;&quot;);  \n            client.println(&quot;&lt;tr&gt;&lt;td&gt;Temp. Fahrenheit&lt;\/td&gt;&lt;td&gt;&lt;span class=\\&quot;sensor\\&quot;&gt;&quot;);\n            client.println(1.8 * bme.readTemperature() + 32);\n            client.println(&quot; *F&lt;\/span&gt;&lt;\/td&gt;&lt;\/tr&gt;&quot;);       \n            client.println(&quot;&lt;tr&gt;&lt;td&gt;Pressure&lt;\/td&gt;&lt;td&gt;&lt;span class=\\&quot;sensor\\&quot;&gt;&quot;);\n            client.println(bme.readPressure() \/ 100.0F);\n            client.println(&quot; hPa&lt;\/span&gt;&lt;\/td&gt;&lt;\/tr&gt;&quot;);\n            client.println(&quot;&lt;tr&gt;&lt;td&gt;Approx. Altitude&lt;\/td&gt;&lt;td&gt;&lt;span class=\\&quot;sensor\\&quot;&gt;&quot;);\n            client.println(bme.readAltitude(SEALEVELPRESSURE_HPA));\n            client.println(&quot; m&lt;\/span&gt;&lt;\/td&gt;&lt;\/tr&gt;&quot;); \n            client.println(&quot;&lt;tr&gt;&lt;td&gt;Humidity&lt;\/td&gt;&lt;td&gt;&lt;span class=\\&quot;sensor\\&quot;&gt;&quot;);\n            client.println(bme.readHumidity());\n            client.println(&quot; %&lt;\/span&gt;&lt;\/td&gt;&lt;\/tr&gt;&quot;); \n            client.println(&quot;&lt;\/body&gt;&lt;\/html&gt;&quot;);\n            \n            \/\/ The HTTP response ends with another blank line\n            client.println();\n            \/\/ Break out of the while loop\n            break;\n          } else { \/\/ if you got a newline, then clear currentLine\n            currentLine = &quot;&quot;;\n          }\n        } else if (c != '\\r') {  \/\/ if you got anything else but a carriage return character,\n          currentLine += c;      \/\/ add it to the end of the currentLine\n        }\n      }\n    }\n    \/\/ Clear the header variable\n    header = &quot;&quot;;\n    \/\/ Close the connection\n    client.stop();\n    Serial.println(&quot;Client disconnected.&quot;);\n    Serial.println(&quot;&quot;);\n  }\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP32-Course\/raw\/master\/code\/WiFi_Web_Server_Sensor_Readings\/WiFi_Web_Server_Sensor_Readings.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Modify the following lines to include your SSID and password between the double quotes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* ssid     = \"\"; \nconst char* password = \"\";<\/code><\/pre>\n\n\n\n<p>Then, check that you have the right board and COM port selected, and upload the code to your ESP32. After uploading, open the Serial Monitor at a baud rate of 115200, and copy the ESP32 IP address.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"739\" height=\"222\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP-IP-address-1.png?resize=739%2C222&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 IP Address Web Server Arduino IDE Serial Monitor\" class=\"wp-image-69097\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP-IP-address-1.png?w=739&amp;quality=100&amp;strip=all&amp;ssl=1 739w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/ESP-IP-address-1.png?resize=300%2C90&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 739px) 100vw, 739px\" \/><\/figure><\/div>\n\n\n\n<p>Open your browser, paste the IP address, and you should see the latest sensor readings. To update the readings, you just need to refresh the web page.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"519\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/web_server_bme280-1024x519.jpg?resize=1024%2C519&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 with BME280 Sensor Web Server with Arduino IDE\" class=\"wp-image-69101\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/web_server_bme280-1024x519.jpg?resize=1024%2C519&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/web_server_bme280-1024x519.jpg?resize=300%2C152&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/web_server_bme280-1024x519.jpg?resize=768%2C389&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>This sketch is very similar with the sketch used in the&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/esp32-web-server-arduino-ide\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 Web Server Tutorial<\/a>. First, you include the WiFi library and the needed libraries to read from the BME280 sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Load Wi-Fi library\n#include &lt;WiFi.h>\n#include &lt;Wire.h>\n#include &lt;Adafruit_BME280.h>\n#include &lt;Adafruit_Sensor.h><\/code><\/pre>\n\n\n\n<p>The next line defines a variable to save the pressure at the sea level. For more accurate altitude estimation, replace the value with the current sea level pressure at your location.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define SEALEVELPRESSURE_HPA (1013.25)<\/code><\/pre>\n\n\n\n<p>In the following line you create an Adafruit_BME280 object called <span class=\"rnthl rntliteral\">bme<\/span> that by default establishes a communication with the sensor using I2C.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Adafruit_BME280 bme; \/\/ I2C<\/code><\/pre>\n\n\n\n<p>As mentioned previously, you need to insert your ssid and password in the following lines inside the double quotes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* ssid     = \"\";\nconst char* password = \"\";<\/code><\/pre>\n\n\n\n<p>Then, you set your web server to port 80.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Set web server port number to 80\nWiFiServer server(80);<\/code><\/pre>\n\n\n\n<p>The following line creates a variable to store the header of the HTTP request:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String header;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, we start a serial communication at a baud rate of 115200 for debugging purposes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(115200);<\/code><\/pre>\n\n\n\n<p>You check that the BME280 sensor was successfully initialized.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (!bme.begin(0x76)) {\n  Serial.println(\"Could not find a valid BME280 sensor, check wiring!\");\n  while (1);<\/code><\/pre>\n\n\n\n<p>The following lines begin the Wi-Fi connection with <span class=\"rnthl rntliteral\">WiFi.begin(ssid, password)<\/span>, wait for a successful connection and print the ESP IP address in the Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Connect to Wi-Fi network with SSID and password\nSerial.print(\"Connecting to \");\nSerial.println(ssid);\nWiFi.begin(ssid, password);\nwhile (WiFi.status() != WL_CONNECTED) {\n  delay(500);\n  Serial.print(\".\");\n}\n\/\/ Print local IP address and start web server\nSerial.println(\"\");\nSerial.println(\"WiFi connected.\");\nSerial.println(\"IP address: \");\nSerial.println(WiFi.localIP());\nserver.begin();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">loop()<\/h3>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">loop()<\/span>, we program what happens when a new client establishes a connection with the web server. The ESP is always listening for incoming clients with this line:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFiClient client = server.available(); \/\/ Listen for incoming clients<\/code><\/pre>\n\n\n\n<p>When a request is received from a client, we\u2019ll save the incoming data. The&nbsp;while loop that follows will be running as long as the client stays connected. We don\u2019t recommend changing the following part of the code unless you know exactly what you are doing.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if (client) { \/\/ If a new client connects,\n  Serial.println(\"New Client.\"); \/\/ print a message out in the serial port\n  String currentLine = \"\"; \/\/ make a String to hold incoming data from the client\n  while (client.connected()) { \/\/ loop while the client's connected\n    if (client.available()) { \/\/ if there's bytes to read from the client,\n      char c = client.read(); \/\/ read a byte, then\n      Serial.write(c); \/\/ print it out the serial monitor\n      header += c;\n      if (c == '\\n') { \/\/ if the byte is a newline character\n        \/\/ if the current line is blank, you got two newline characters in a row.\n        \/\/ that's the end of the client HTTP request, so send a response:\n        if (currentLine.length() == 0) {\n          \/\/ HTTP headers always start with a response code (e.g. HTTP\/1.1 200 OK)\n          \/\/ and a content-type so the client knows what's coming, then a blank line:\n          client.println(\"HTTP\/1.1 200 OK\");\n          client.println(\"Content-type:text\/html\");\n          client.println(\"Connection: close\");\n          client.println();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Displaying the HTML web page<\/h3>\n\n\n\n<p>The next thing you need to do is sending a response to the client with the HTML text to build the web page.<\/p>\n\n\n\n<p>The web page is sent to the client using this expression <span class=\"rnthl rntliteral\">client.println()<\/span>. You should enter what you want to send to the client as an argument.<\/p>\n\n\n\n<p>The following code snippet sends the web page to display the sensor readings in a table.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>client.println(\"&lt;!DOCTYPE html>&lt;html>\");\nclient.println(\"&lt;head>&lt;meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\">\");\nclient.println(\"&lt;link rel=\\\"icon\\\" href=\\\"data:,\\\">\");\n\/\/ CSS to style the on\/off buttons \n\/\/ Feel free to change the background-color and font-size attributes to fit your preferences\nclient.println(\"&lt;style>body { text-align: center; font-family: \\\"Trebuchet MS\\\", Arial;}\");\nclient.println(\"table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }\");\nclient.println(\"th { padding: 12px; background-color: #0043af; color: white; }\");\nclient.println(\"tr { border: 1px solid #ddd; padding: 12px; }\");\nclient.println(\"tr:hover { background-color: #bcbcbc; }\");\nclient.println(\"td { border: none; padding: 12px; }\");\nclient.println(\".sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px; }\");\n \n\/\/ Web Page Heading\nclient.println(\"&lt;\/style>&lt;\/head>&lt;body>&lt;h1>ESP32 with BME280&lt;\/h1>\");\nclient.println(\"&lt;table>&lt;tr>&lt;th>MEASUREMENT&lt;\/th>&lt;th>VALUE&lt;\/th>&lt;\/tr>\");\nclient.println(\"&lt;tr>&lt;td>Temp. Celsius&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(bme.readTemperature());\nclient.println(\" *C&lt;\/span>&lt;\/td>&lt;\/tr>\"); \nclient.println(\"&lt;tr>&lt;td>Temp. Fahrenheit&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(1.8 * bme.readTemperature() + 32);\nclient.println(\" *F&lt;\/span>&lt;\/td>&lt;\/tr>\"); \nclient.println(\"&lt;tr>&lt;td>Pressure&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(bme.readPressure() \/ 100.0F);\nclient.println(\" hPa&lt;\/span>&lt;\/td>&lt;\/tr>\");\nclient.println(\"&lt;tr>&lt;td>Approx. Altitude&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(bme.readAltitude(SEALEVELPRESSURE_HPA));\nclient.println(\" m&lt;\/span>&lt;\/td>&lt;\/tr>\"); \nclient.println(\"&lt;tr>&lt;td>Humidity&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(bme.readHumidity());\nclient.println(\" %&lt;\/span>&lt;\/td>&lt;\/tr>\"); \nclient.println(\"&lt;\/body>&lt;\/html>\");<\/code><\/pre>\n\n\n\n<p><strong>Note:<\/strong> you can <a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/ESP32-Course\/master\/code\/WiFi_Web_Server_Sensor_Readings\/table_with_css.html\" target=\"_blank\" rel=\"noreferrer noopener\">click here to view<\/a> the full HTML web page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Displaying the Sensor Readings<\/h3>\n\n\n\n<p>To display the sensor readings on the table, we just need to send them between the corresponding &lt;td&gt; and &lt;\/td&gt; tags. For example, to display the temperature:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>client.println(\"&lt;tr>&lt;td>Temp. Celsius&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(bme.readTemperature());\nclient.println(\" *C&lt;\/span>&lt;\/td>&lt;\/tr>\");<\/code><\/pre>\n\n\n\n<p><strong>Note<\/strong>: the &lt;span&gt; tag is useful to style a particular part of a text. In this case, we&#8217;re using the &lt;span&gt; tag to include the sensor reading in a class called &#8220;sensor&#8221;. This is useful to style that particular part of text using CSS.<\/p>\n\n\n\n<p>By default the table is displaying the temperature readings in both Celsius degrees and Fahrenheit. You can comment the following three lines, if you want to display the temperature only in Fahrenheit degrees.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/*client.println(\"&lt;tr>&lt;td>Temp. Celsius&lt;\/td>&lt;td>&lt;span class=\\\"sensor\\\">\");\nclient.println(bme.readTemperature());\nclient.println(\" *C&lt;\/span>&lt;\/td>&lt;\/tr>\");*\/<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Closing the Connection<\/h3>\n\n\n\n<p>Finally, when the response ends, we clear the <span class=\"rnthl rntliteral\">header<\/span> variable, and stop the connection with the client with <span class=\"rnthl rntliteral\">client.stop()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Clear the header variable\nheader = \"\";\n\/\/ Close the connection\nclient.stop();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In summary, in this project you&#8217;ve learned how to read temperature, humidity, pressure, and estimate altitude using the BME280 sensor module. You also learned how to build a web server that displays a table with sensor readings. You can easily modify this project to display data from any other sensor.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"594\" height=\"344\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/bme280-web-server-Copy.jpg?resize=594%2C344&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Web Server with BME280 Weather Station\" class=\"wp-image-69095\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/bme280-web-server-Copy.jpg?w=594&amp;quality=100&amp;strip=all&amp;ssl=1 594w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/bme280-web-server-Copy.jpg?resize=300%2C174&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 594px) 100vw, 594px\" \/><\/figure><\/div>\n\n\n\n<p>If you like this project you may also like the following tutorials:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/build-an-all-in-one-esp32-weather-station-shield\/\" target=\"_blank\" rel=\"noreferrer noopener\">Build an All-in-One ESP32 Weather Station Shield<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-publish-sensor-readings-to-google-sheets\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 Publish Sensor Readings to Google Sheets (ESP8266 Compatible)<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-data-logging-temperature-to-microsd-card\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 Data Logging Temperature to MicroSD Card<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-with-multiple-ds18b20-temperature-sensors\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 with Multiple DS18B20 Temperature Sensors<\/a><\/li><\/ul>\n\n\n\n<p><em>This is an excerpt from our course:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a>. If you like ESP32 and you want to learn more, we recommend enrolling in&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE course<\/a>.<\/em><\/p>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial you\u2019re going to learn how to create a web server with the ESP32 to display readings from the BME280 sensor module. The BME280 sensor measures temperature, humidity, &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 Web Server with BME280 \u2013 Advanced Weather Station\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-web-server-with-bme280-mini-weather-station\/#more-69087\" aria-label=\"Read more about ESP32 Web Server with BME280 \u2013 Advanced Weather Station\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":69102,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-69087","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/BME_ESP32_WEB_SERVER.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/69087","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=69087"}],"version-history":[{"count":0,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/69087\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/69102"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=69087"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=69087"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=69087"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}