{"id":71851,"date":"2018-09-04T10:43:25","date_gmt":"2018-09-04T10:43:25","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=71851"},"modified":"2020-07-30T14:16:48","modified_gmt":"2020-07-30T14:16:48","slug":"esp8266-multisensor-shield","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp8266-multisensor-shield\/","title":{"rendered":"Build a Multisensor Shield for ESP8266"},"content":{"rendered":"\n<p>In this project you\u2019ll discover how to design and create a Multisensor Shield for the ESP8266 Wemos D1 Mini board.&nbsp;The shield has temperature sensor (DS18B20), a PIR motion sensor, an LDR, and a terminal to connect a relay module. We&#8217;ll start by preparing all the hardware and then program it.<\/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\/09\/Build-ESP8266-WeMos-D1-Mini-Multisensor-Shield.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72578\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/Build-ESP8266-WeMos-D1-Mini-Multisensor-Shield.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/Build-ESP8266-WeMos-D1-Mini-Multisensor-Shield.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/Build-ESP8266-WeMos-D1-Mini-Multisensor-Shield.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/Build-ESP8266-WeMos-D1-Mini-Multisensor-Shield.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<h2 class=\"wp-block-heading\">Watch the Video Tutorial<\/h2>\n\n\n\n<p>This project is available in video format and in written format. You can watch the video below or you can scroll down for the written instructions. This project is divided in two videos.<\/p>\n\n\n\n<p><strong>Design and Build the ESP8266 WeMos D1 Mini Multisensor Shield &#8211; Part 1<\/strong><\/p>\n\n\n\n<p>In this first video we\u2019ll decide the hardware that we\u2019re going to use. We\u2019ll also take a look at this project\u2019s main features and how to design and assemble your own WeMos D1 Mini Multisensor shield.<\/p>\n\n\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/nKFsNM5Q00k?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n\n\n\n<p><strong>Program and Test the ESP8266 WeMos D1 Mini Multisensor Shield &#8211; Part 2<\/strong><\/p>\n\n\n\n<p>In this second video, we&#8217;ll program the Wemos D1 Mini Multisensor Shield with a code that runs a web server&nbsp;that allows you to monitor and control the multisensor shield based on several configurable settings.<\/p>\n\n\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/hxRqLIfabqw?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<p>You can find all the resources needed to build this project in the links below (or you can visit the <a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub project<\/a>):<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/blob\/master\/Code\/ESP8266_Multisensor_Shield\/ESP8266_Multisensor_Shield.ino\" target=\"_blank\" rel=\"noreferrer noopener\">Web Server code (for Arduino IDE)<\/a><\/li><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/tree\/master\/Images\" target=\"_blank\" rel=\"noreferrer noopener\">Schematic diagram<\/a><\/li><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/raw\/master\/KiCad_PCB_ESP8266_Multisensor_Shield\/GERBERS\/WemosD1MiniShield.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Gerber files<\/a><\/li><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/tree\/master\/KiCad_PCB_ESP8266_Multisensor_Shield\" target=\"_blank\" rel=\"noreferrer noopener\">KiCad project to edit the PCB<\/a><\/li><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/tree\/master\/3D_Enclosure\" target=\"_blank\" rel=\"noreferrer noopener\">3D Printer Enclosure (STL files and SketchUp Project)<\/a><\/li><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Click here to download all the files<\/strong><\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>The shield consists of a temperature sensor, a motion sensor, an LDR, and a 3 pin socket where you can connect any output, we\u2019ll be using a relay module.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-labeled.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72389\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-labeled.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-labeled.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>We&#8217;ll also write a program that runs a web server to control the shield using 4 different modes with several configurable settings.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-web-server.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72390\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-web-server.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-web-server.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>By the end of this project, you\u2019ll have a similar looking gadget.<\/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\/09\/multisensor-shield-enclosure.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72391\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-enclosure.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-enclosure.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>You&#8217;ll be able to control the relay on and off in manual mode.<\/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\/09\/multisensor-shield-manual-mode.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72416\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-manual-mode.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-manual-mode.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>Or you can choose the automatic modes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Automatic motion mode, meaning that when it detects motion the relay stays on for a determined number of seconds.<\/li><li>Or you can use the luminosity mode, so the relay turns on when the light goes below a certain threshold value.<\/li><li>Finally, there\u2019s an option to control the relay based in the current luminosity value and if motion is detected.<\/li><\/ul>\n\n\n\n<p>We&#8217;ll show you all these features in action later in this project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">JLCPCB<\/h3>\n\n\n\n<p>This project was sponsored by&nbsp;<a href=\"https:\/\/jlcpcb.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">JLCPCB<\/a>. JLCPCB is a well known PCB prototype company in China. It is specialized in quick PCB prototype and small-batch production. You can order a minimum of 10 PCBs for just $2.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/jlcpcb.com\/\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"401\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/JLC-PCB-header-page.jpg?resize=1200%2C401&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-51958\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/JLC-PCB-header-page.jpg?w=1269&amp;quality=100&amp;strip=all&amp;ssl=1 1269w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/JLC-PCB-header-page.jpg?resize=300%2C100&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/JLC-PCB-header-page.jpg?resize=768%2C257&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/JLC-PCB-header-page.jpg?resize=1024%2C342&amp;quality=100&amp;strip=all&amp;ssl=1 1024w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>If you want to turn your breadboard circuits into real boards and make your projects look more professional, you just have to upload the Gerber files to order high quality PCBs for low prices. We\u2019ll show you how to do this later in this blog post.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ESP8266 Multisensor Shield Features<\/h2>\n\n\n\n<p>The Multisensor Shield features several sensors that can be useful to monitor your house. The shield allows you to control:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>1x SMD LED to indicate a status<\/li><li>1x Light dependent resistor (LDR)<\/li><li>1x DS18B20 temperature sensor<\/li><li>1x PIR motion sensor<\/li><\/ul>\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\/09\/multisensor-shield.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72393\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield.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>Additionally, it also features a terminal block that gives you access to GND, 5V and GPIO15. That terminal can be used to connect a relay, or any other output you might want to control.<\/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=\"461\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-terminal-block.jpg?resize=750%2C461&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72397\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-terminal-block.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-terminal-block.jpg?resize=300%2C184&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">ESP8266 Multisensor Shield Pin Assignment<\/h2>\n\n\n\n<p>The following table describes the pin assignment for each component of the multisensor shield:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Component<\/strong><\/td><td><strong>Wemos D1 Mini Pin Assingment<\/strong><\/td><\/tr><tr><td>PIR Motion Sensor<\/td><td>GPIO5 (D1)<\/td><\/tr><tr><td>DS18B20 Temperature Sensor<\/td><td>GPIO4 (D2)<\/td><\/tr><tr><td>Light Dependent Resistor<\/td><td>A0<\/td><\/tr><tr><td>LED<\/td><td>GPIO12 (D6)<\/td><\/tr><tr><td>Additional output<\/td><td>GPIO15 (D8)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If you want to assign and use different pins, <a href=\"https:\/\/randomnerdtutorials.com\/esp8266-pinout-reference-gpios\/\">read our ESP8266 Pinout Reference Guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the Circuit on a Breadboard<\/h2>\n\n\n\n<p>Before designing and building the PCB shield, it&#8217;s important to test the circuit on a breadboard. If you don&#8217;t want to make a PCB, you can still follow this project by assembling the circuit on a breadboard.<\/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\/09\/multisensor-shield-breadboard.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72399\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-breadboard.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-breadboard.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<h3 class=\"wp-block-heading\">Parts Required<\/h3>\n\n\n\n<p>To assemble the circuit on a breadboard you need the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/makeradvisor.com\/tools\/esp8266-wemos-d1-mini-wi-fi-board\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP8266 Wemos D1 Mini<\/a> &#8211; read <a href=\"https:\/\/makeradvisor.com\/best-esp8266-wi-fi-development-board\/\" target=\"_blank\" rel=\"noreferrer noopener\">Best ESP8266 Wi-Fi Development Board<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/3mm-5mm-leds-kit-storage-box\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x 5mm LED<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/resistors-kits\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x 330 Ohm resistor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/ds18b20-temperature-sensor-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x DS18B20 temperature sensor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/mini-hc-sr505-pir-motion-sensor\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x mini PIR motion sensor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/photoresistor-light-dependent-resistor-ldr\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x light dependent resistor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/resistors-kits\/\">2x 10k Ohm resistor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/5v-2-channel-relay-module-optocoupler\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x relay module<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noreferrer noopener\">Breadboard<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noreferrer noopener\">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\">Schematic<\/h2>\n\n\n\n<p>After gathering all the parts, assemble the circuit by following the next 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\/09\/wemos_shield_fritzing_diagram.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"657\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/wemos_shield_fritzing_diagram.jpg?resize=750%2C657&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72400\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/wemos_shield_fritzing_diagram.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/wemos_shield_fritzing_diagram.jpg?resize=300%2C263&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Here&#8217;s the circuit 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\/09\/KiCad-circuit-multisensor-shield.png?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"725\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/KiCad-circuit-multisensor-shield.png?resize=1200%2C725&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72401\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/KiCad-circuit-multisensor-shield.png?w=1416&amp;quality=100&amp;strip=all&amp;ssl=1 1416w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/KiCad-circuit-multisensor-shield.png?resize=300%2C181&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/KiCad-circuit-multisensor-shield.png?resize=768%2C464&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/KiCad-circuit-multisensor-shield.png?resize=1024%2C619&amp;quality=100&amp;strip=all&amp;ssl=1 1024w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Designing the PCB<\/h2>\n\n\n\n<p>After making sure the circuit was working properly on a breadboard, I\u2019ve designed a PCB on <a href=\"http:\/\/kicad-pcb.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">KiCad<\/a>. KiCad is an open-source software used to design PCBs.<\/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=\"406\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/kicad-multisensor-shield-2.jpg?resize=750%2C406&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72402\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/kicad-multisensor-shield-2.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/kicad-multisensor-shield-2.jpg?resize=300%2C162&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>Designing an ESP8266 PCB shield is fairly straightforward. There are already pre-made KiCad parts for the WeMos, and you can find a link to the KiCad parts below:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/jerome-labidurie\/d1_mini_kicad\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\">WeMos D1 Mini KiCad Part<\/a><\/li><\/ul>\n\n\n\n<p>All the other components already exist on KiCad, like the LED, LDR, resistors, terminal blocks, and so on.<\/p>\n\n\n\n<p>Designing the circuit works like in any other circuit software tool, you place some components and you wire them together. When you\u2019re happy with your circuit and pins usage, it\u2019s time to assign each component to a footprint.<\/p>\n\n\n\n<p>The WeMos D1 Mini was already created, and all the other components were also available by default on the KiCad parts library.<\/p>\n\n\n\n<p>Having the parts assigned, you can start placing each component. When you\u2019re happy with the layout, make all the connections and route your PCB.<br>Once you\u2019re done, save your project and export the Gerber files.<\/p>\n\n\n\n<p><strong>Note<\/strong>: if you\u2019re familiar with KiCad, you can grab the project files and edit them to customize the shield for your own needs.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/raw\/master\/KiCad_PCB_ESP8266_Multisensor_Shield\/GERBERS\/WemosD1MiniShield.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download GERBER .zip file<\/a><\/strong><\/li><li><a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/tree\/master\/KiCad_PCB_ESP8266_Multisensor_Shield\" target=\"_blank\" rel=\"noreferrer noopener\">KiCad project to edit the PCB<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Ordering the PCBs<\/h2>\n\n\n\n<p>If you don\u2019t know how to design the PCB yourself, but you still want to order them, it\u2019s very easy. You just have to:<\/p>\n\n\n\n<p>1. Download the Gerber files &#8211; <a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/raw\/master\/KiCad_PCB_ESP8266_Multisensor_Shield\/GERBERS\/WemosD1MiniShield.zip\" target=\"_blank\" rel=\"noreferrer noopener\">click here to download the .zip file<\/a><\/p>\n\n\n\n<p>2. Go to&nbsp;<a href=\"https:\/\/jlcpcb.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">JLCPCB.com<\/a>, click the \u201c<strong>QUOTE NOW<\/strong>\u201d button, and upload the .zip file you\u2019ve just downloaded.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"700\" height=\"228\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/jlcpcb-quote-now.png?resize=700%2C228&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-51963\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/jlcpcb-quote-now.png?w=700&amp;quality=100&amp;strip=all&amp;ssl=1 700w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/02\/jlcpcb-quote-now.png?resize=300%2C98&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>3. You\u2019ll see a success message at the bottom. Then, you can use the \u201cGerber Viewer\u201d link at the bottom right corner to check if everything went as expected. You can view the top and bottom of the PCB. You can view or hide the solder-mask, silkscreen, copper, etc.<\/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=\"445\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-jlcpcb.jpg?resize=750%2C445&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72403\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-jlcpcb.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-jlcpcb.jpg?resize=300%2C178&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>With the default settings, you can order 10 PCBs for just $2. However, if you want to select other settings like a different PCB Color it will cost you a few more dollars.<\/p>\n\n\n\n<p>4. When you\u2019re happy with your order, click the \u201c<strong>SAVE TO CART<\/strong>\u201d button to complete the order.<\/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=\"381\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-jlcpcb-save-tocart.jpg?resize=750%2C381&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72404\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-jlcpcb-save-tocart.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-jlcpcb-save-tocart.jpg?resize=300%2C152&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>My PCBs took 2 days to be manufactured and they arrived in 3 business days using DHL delivery option.<\/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\/09\/jlc-pcb.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72419\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/jlc-pcb.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/jlc-pcb.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<h2 class=\"wp-block-heading\">Unboxing<\/h2>\n\n\n\n<p>After approximately one week, I received the PCBs at my office. As usual, everything came well packed, and the PCBs are really high-quality.<\/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\/09\/multisensor-shield-pcb.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72405\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-pcb.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-pcb.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>The letters on the silkscreen are really well-printed and easy to read. I don\u2019t think you can get a better PCB service for this price.<\/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\/09\/multisensor-shield-pcb-silkscreen.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72406\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-pcb-silkscreen.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-pcb-silkscreen.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<h2 class=\"wp-block-heading\">Soldering the Components<\/h2>\n\n\n\n<p>The next step is soldering the components to the PCB. I\u2019ve used an SMD LED and SMD resistors. I know it\u2019s a bit difficult to solder SMD components, but they save a lot of space on the PCB.<\/p>\n\n\n\n<p>Here&#8217;s the soldering tools I&#8217;ve used:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/makeradvisor.com\/ts100-soldering-iron-review-best-portable-soldering-iron\/\" target=\"_blank\" rel=\"noreferrer noopener\">TS100 mini portable soldering iron<\/a><\/li><li><a href=\"https:\/\/www.banggood.com\/0_5mm-500g-Soldering-Wires-Welding-Iron-Rosin-Core-6040-Lead-Tin-Flux-2_0-Percent-p-1023387.html?p=MA240439985285201910\" target=\"_blank\" rel=\"noreferrer noopener\">Solder 60\/40 0.5mm diameter<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/soldering-mats-review\/\" target=\"_blank\" rel=\"noreferrer noopener\">Soldering mat<\/a><\/li><\/ul>\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\/09\/ts100-soldering-iron.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72413\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/ts100-soldering-iron.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/ts100-soldering-iron.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>Read our review about the TS100 Soldering Iron:&nbsp;<a href=\"https:\/\/makeradvisor.com\/ts100-soldering-iron-review-best-portable-soldering-iron\/\" target=\"_blank\" rel=\"noreferrer noopener\">TS100 Soldering Iron Review \u2013 Best Portable Soldering Iron<\/a>.<\/p>\n\n\n\n<p>Here&#8217;s a list of all the components you need to solder on the PCB (don&#8217;t forget the header pins to attach the shield to the Wemos D1 mini):<\/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\/09\/multisensor-shield-parts-required.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72408\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-parts-required.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-parts-required.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<ul class=\"wp-block-list\"><li><a href=\"https:\/\/makeradvisor.com\/smd-leds\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x SMD LED<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/smd-resistors\" target=\"_blank\" rel=\"noreferrer noopener\">1x 330 Ohm SMD resistors<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/smd-resistors\" target=\"_blank\" rel=\"noreferrer noopener\">2x 10k Ohm SMD resistor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/ds18b20-temperature-sensor-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x DS18B20 temperature sensor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/mini-hc-sr505-pir-motion-sensor\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x mini PIR motion sensor<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/photoresistor-light-dependent-resistor-ldr\/\" target=\"_blank\" rel=\"noreferrer noopener\">1x light dependent resistor<\/a><\/li><li><a href=\"http:\/\/shrsl.com\/roqk\" target=\"_blank\" rel=\"noreferrer noopener\">1x Screw terminal blocks<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/female-pin-header-socket\" target=\"_blank\" rel=\"noreferrer noopener\">Female pin header socket<\/a><\/li><\/ul>\n\n\n\n<p>Start by soldering the SMD components. Then, solder the header pins. Finally, solder the other components.<\/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=\"462\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-soldering-pcb.jpg?resize=750%2C462&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72412\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-soldering-pcb.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-soldering-pcb.jpg?resize=300%2C185&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>Here&#8217;s how the WeMos Multisensor Shield looks like after assembling all the parts. It should connect perfectly to the ESP8266 WeMos D1 mini.<\/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\/09\/multisensor-shield.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72393\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield.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<h2 class=\"wp-block-heading\">3D Printed Enclosure<\/h2>\n\n\n\n<p>Finally, you can buy an enclosure to place your circuit. If you have a 3D printer, you can build your own enclosure.<\/p>\n\n\n\n<p>I\u2019ve 3D printed a simple enclosure to place the multisensor shield using the <a href=\"https:\/\/randomnerdtutorials.com\/creality-3d-cr-10-3d-printer-review\/\" target=\"_blank\" rel=\"noreferrer noopener\">Creality CR-10 3D printer<\/a>.<\/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\/09\/multisensor-shield-3d-print-enclosure.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72409\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-3d-print-enclosure.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-3d-print-enclosure.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>The enclosure consists of two pieces: the bottom and the lid. The lid has a space for the PIR motion sensor, and a rectangular hole for the LDR and temperature sensor. At the side, there\u2019s a space for the relay wires and another for the USB cable to go through to power and program the ESP8266.<\/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\/09\/multisensor-shield-enclosure-bottom-lid.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72410\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-enclosure-bottom-lid.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-enclosure-bottom-lid.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>That\u2019s it, the shield is finished!<\/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\/09\/multisensor-shield-enclosure.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72391\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-enclosure.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-enclosure.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>Now, it&#8217;s time to write some code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Programming the Multisensor Shield<\/h2>\n\n\n\n<p>The code for this project runs a web server that allows you to monitor and control the multisensor shield based on several configurable settings.<\/p>\n\n\n\n<p>Before proceeding you should have the ESP8266 installed in your Arduino IDE. Follow the next tutorial to install the ESP8266 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\/how-to-install-esp8266-board-arduino-ide\/\" target=\"_blank\" rel=\"noreferrer noopener\">How to Install the ESP8266 Board in Arduino IDE<\/a><\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Web Server Overview<\/h3>\n\n\n\n<p>Let\u2019s continue with this project, the web server we\u2019ll build allows you to choose between 4 different modes to control the relay:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Manual (mode 0)<\/strong>: in which you have a button to turn the relay on and off.<\/li><li><strong>Auto PIR (mode 1)<\/strong>: turns the relay on when motion is detected. In this mode there is a field in which you can set the number of seconds the output will be on after motion is detected.<\/li><li><strong>LDR (mode 2)<\/strong>: the relay turns on when the luminosity goes below a certain threshold. You can set an LDR threshold value between 0 and 100%.<\/li><li><strong>Auto PIR and LDR (mode 3)<\/strong>: this mode combines the PIR motion sensor and the LDR. When this mode is selected, the relay turns on when the PIR sensor detects motion and if the luminosity value is below the threshold. In this mode you can set the timer and the LDR threshold value.<\/li><\/ul>\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\/09\/multisensor-shield-manual-mode.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72416\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-manual-mode.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-manual-mode.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>In the web server, there\u2019s also a button that you can press to request the temperature reading. After requesting the temperature readings, you can press the \u201cRemove Sensor Readings\u201d button to hide the readings to optimize the web server performance.<\/p>\n\n\n\n<p>In every mode there\u2019s a label that shows the selected mode, as well as the current output state.<\/p>\n\n\n\n<p>We want the ESP8266 to remember the last output state and the settings, in case it resets or suddenly loses power. So, we need to save those parameters in the ESP8266 EEPROM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installing libraries<\/h3>\n\n\n\n<p>Before uploading the code, you need to install two libraries in your Arduino IDE: the&nbsp;<a href=\"https:\/\/github.com\/PaulStoffregen\/OneWire\" target=\"_blank\" rel=\"noreferrer noopener\">OneWire library by Paul Stoffregen<\/a>&nbsp;and the&nbsp;<a href=\"https:\/\/github.com\/milesburton\/Arduino-Temperature-Control-Library\" target=\"_blank\" rel=\"noreferrer noopener\">Dallas Temperature library<\/a>, so that you can use the DS18B20 sensor.&nbsp;Follow the next steps to install those libraries.<\/p>\n\n\n\n<p><strong>OneWire library<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/PaulStoffregen\/OneWire\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Click here to download the OneWire&nbsp;library<\/a>. You should have a .zip folder in your Downloads<\/li><li>Unzip the&nbsp;<em>.zip<\/em>&nbsp;folder and you should get&nbsp;<strong>OneWire-master&nbsp;<\/strong>folder<\/li><li>Rename your folder from&nbsp;<del><strong>OneWire-master<\/strong><\/del>&nbsp;to<strong>&nbsp;OneWire<\/strong><\/li><li>Move the&nbsp;<strong>OneWire&nbsp;<\/strong>folder to your Arduino IDE installation&nbsp;<strong>libraries&nbsp;<\/strong>folder<\/li><li>Finally, re-open your Arduino IDE<\/li><\/ol>\n\n\n\n<p><strong>Dallas Temperature library<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/milesburton\/Arduino-Temperature-Control-Library\/archive\/master.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Click here to download the DallasTemperature&nbsp;library<\/a>. You should have a .zip folder in your Downloads<\/li><li>Unzip the&nbsp;<em>.zip<\/em>&nbsp;folder and you should get&nbsp;<strong>Arduino-Temperature-Control-Library-master&nbsp;<\/strong>folder<\/li><li>Rename your folder from&nbsp;<del><strong>Arduino-Temperature-Control-Library-master<\/strong><\/del>&nbsp;to&nbsp;<strong>DallasTemperature<\/strong><\/li><li>Move the&nbsp;<strong>DallasTemperature<\/strong>folder to your Arduino IDE installation&nbsp;<strong>libraries&nbsp;<\/strong>folder<\/li><li>Finally, re-open your Arduino IDE<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Code<\/h3>\n\n\n\n<p>Copy the following code to the Arduino IDE.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\n  Rui Santos\n  Complete project details at https:\/\/randomnerdtutorials.com  \n*********\/\n\n\/\/ Load libraries\n#include &lt;ESP8266WiFi.h&gt;\n#include &lt;EEPROM.h&gt;\n#include &lt;OneWire.h&gt;\n#include &lt;DallasTemperature.h&gt;\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\/\/ Auxiliary variables for temperature\nstatic char celsiusTemp[7];\nstatic char fahrenheitTemp[7];\nString temperatureString = &quot;&quot;;      \/\/ Variable to hold the temperature reading\n\n\/\/ EEPROM size\n\/\/ Address 0: Last output state (0 = off or 1 = on)\n\/\/ Address 1: Selected mode (0 = Manual, 1 = Auto PIR,\n\/\/ 2 = Auto LDR, or 3 = Auto PIR and LDR)\n\/\/ Address 2: Timer (time 0 to 255 seconds)\n\/\/ Address 3: LDR threshold value (luminosity in percentage 0 to 100%)\n#define EEPROM_SIZE 4\n\n\/\/ Set GPIOs for: output variable, status LED, PIR Motion Sensor, and LDR\nconst int output = 15;\nconst int statusLed = 12;\nconst int motionSensor = 5;\nconst int ldr = A0;\n\/\/ Store the current output state\nString outputState = &quot;off&quot;;\n\n\/\/ GPIO where the DS18B20 is connected to\nconst int oneWireBus = 4;          \n\/\/ Setup a oneWire instance to communicate with any OneWire devices\nOneWire oneWire(oneWireBus);\n\/\/ Pass our oneWire reference to Dallas Temperature sensor \nDallasTemperature sensors(&amp;oneWire);\n\n\/\/ Timers - Auxiliary variables\nunsigned long now = millis();\nunsigned long lastMeasure = 0;\nboolean startTimer = false;\nunsigned long currentTime = millis();\nunsigned long previousTime = 0; \nconst long timeoutTime = 2000;\n\n\/\/ Auxiliary variables to store selected mode and settings \nint selectedMode = 0;\nint timer = 0;\nint ldrThreshold = 0;\nint armMotion = 0;\nint armLdr = 0;\nString modes[4] = { &quot;Manual&quot;, &quot;Auto PIR&quot;, &quot;Auto LDR&quot;, &quot;Auto PIR and LDR&quot; };\n\n\/\/ Decode HTTP GET value\nString valueString = &quot;0&quot;;\nint pos1 = 0;\nint pos2 = 0;\n\/\/ Variable to store the HTTP request\nString header;\n\/\/ Set web server port number to 80\nWiFiServer server(80);\n\nvoid setup() {\n  \/\/ Start the DS18B20 sensor\n  sensors.begin();\n\n  \/\/ Serial port for debugging purposes\n  Serial.begin(115200);\n\n  \/\/ PIR Motion Sensor mode, then set interrupt function and RISING mode\n  pinMode(motionSensor, INPUT_PULLUP);\n  attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);\n  \n  Serial.println(&quot;start...&quot;);\n  EEPROM.begin(EEPROM_SIZE);\n  \n  \/\/ Uncomment the next lines to test the values stored in the flash memory\n  \/*Serial.println(&quot; bytes read from Flash . Values are:&quot;);\n  for(int i = 0; i &lt; EEPROM_SIZE; i++) {\n    Serial.print(byte(EEPROM.read(i))); \n    Serial.print(&quot; &quot;);\n  }*\/\n  \n  \/\/ Initialize the output variable and the LED as OUTPUTs\n  pinMode(output, OUTPUT);\n  pinMode(statusLed, OUTPUT);\n  digitalWrite(output, HIGH);\n  digitalWrite(statusLed, LOW);\n  \/\/ Read from flash memory on start and store the values in auxiliary variables\n  \/\/ Set output to last state (saved in the flash memory)\n  if(!EEPROM.read(0)) {\n    outputState = &quot;off&quot;;\n    digitalWrite(output, HIGH);\n  }\n  else {\n    outputState = &quot;on&quot;;\n    digitalWrite(output, LOW);\n  }\n  selectedMode = EEPROM.read(1);\n  timer = EEPROM.read(2);\n  ldrThreshold = EEPROM.read(3);\n  configureMode();\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  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            \/\/ 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 on\/off buttons \n            \/\/ Feel free to change the background-color and font-size attributes to fit your preferences\n            client.println(&quot;&lt;style&gt;html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}&quot;);\n            client.println(&quot;.button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;&quot;);\n            client.println(&quot;text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}&quot;);\n            client.println(&quot;.button2 {background-color: #555555;}&lt;\/style&gt;&lt;\/head&gt;&quot;);\n            \n            \/\/ Request example: GET \/?mode=0&amp; HTTP\/1.1 - sets mode to Manual (0)\n            if(header.indexOf(&quot;GET \/?mode=&quot;) &gt;= 0) {\n              pos1 = header.indexOf('=');\n              pos2 = header.indexOf('&amp;');\n              valueString = header.substring(pos1+1, pos2);\n              selectedMode = valueString.toInt();\n              EEPROM.write(1, selectedMode);\n              EEPROM.commit();\n              configureMode();\n            }\n            \/\/ Change the output state - turn GPIOs on and off\n            else if(header.indexOf(&quot;GET \/?state=on&quot;) &gt;= 0) {\n              outputOn();\n            } \n            else if(header.indexOf(&quot;GET \/?state=off&quot;) &gt;= 0) {\n              outputOff();\n            }\n            \/\/ Set timer value\n            else if(header.indexOf(&quot;GET \/?timer=&quot;) &gt;= 0) {\n              pos1 = header.indexOf('=');\n              pos2 = header.indexOf('&amp;');\n              valueString = header.substring(pos1+1, pos2);\n              timer = valueString.toInt();\n              EEPROM.write(2, timer);\n              EEPROM.commit();\n              Serial.println(valueString);\n            }\n            \/\/ Set LDR Threshold value\n            else if(header.indexOf(&quot;GET \/?ldrthreshold=&quot;) &gt;= 0) {\n              pos1 = header.indexOf('=');\n              pos2 = header.indexOf('&amp;');\n              valueString = header.substring(pos1+1, pos2);\n              ldrThreshold = valueString.toInt();\n              EEPROM.write(3, ldrThreshold);\n              EEPROM.commit();\n              Serial.println(valueString);\n            }\n            \n            \/\/ Web Page Heading\n            client.println(&quot;&lt;body&gt;&lt;h1&gt;ESP8266 Web Server&lt;\/h1&gt;&quot;);\n            \/\/ Drop down menu to select mode\n            client.println(&quot;&lt;p&gt;&lt;strong&gt;Mode selected:&lt;\/strong&gt; &quot; + modes[selectedMode] + &quot;&lt;\/p&gt;&quot;);\n            client.println(&quot;&lt;select id=\\&quot;mySelect\\&quot; onchange=\\&quot;setMode(this.value)\\&quot;&gt;&quot;);\n            client.println(&quot;&lt;option&gt;Change mode&quot;);\n            client.println(&quot;&lt;option value=\\&quot;0\\&quot;&gt;Manual&quot;);\n            client.println(&quot;&lt;option value=\\&quot;1\\&quot;&gt;Auto PIR&quot;);\n            client.println(&quot;&lt;option value=\\&quot;2\\&quot;&gt;Auto LDR&quot;);\n            client.println(&quot;&lt;option value=\\&quot;3\\&quot;&gt;Auto PIR and LDR&lt;\/select&gt;&quot;);\n          \n            \/\/ Display current state, and ON\/OFF buttons for output \n            client.println(&quot;&lt;p&gt;GPIO - State &quot; + outputState + &quot;&lt;\/p&gt;&quot;);\n            \/\/ If the output is off, it displays the ON button       \n            if(selectedMode == 0) {\n              if(outputState == &quot;off&quot;) {\n                client.println(&quot;&lt;p&gt;&lt;button class=\\&quot;button\\&quot; onclick=\\&quot;outputOn()\\&quot;&gt;ON&lt;\/button&gt;&lt;\/p&gt;&quot;);\n              } \n              else {\n                client.println(&quot;&lt;p&gt;&lt;button class=\\&quot;button button2\\&quot; onclick=\\&quot;outputOff()\\&quot;&gt;OFF&lt;\/button&gt;&lt;\/p&gt;&quot;);\n              }\n            }\n            else if(selectedMode == 1) {\n              client.println(&quot;&lt;p&gt;Timer (0 and 255 in seconds): &lt;input type=\\&quot;number\\&quot; name=\\&quot;txt\\&quot; value=\\&quot;&quot; + \n                              String(EEPROM.read(2)) + &quot;\\&quot; onchange=\\&quot;setTimer(this.value)\\&quot; min=\\&quot;0\\&quot; max=\\&quot;255\\&quot;&gt;&lt;\/p&gt;&quot;);\n            }\n            else if(selectedMode == 2) {\n              client.println(&quot;&lt;p&gt;LDR Threshold (0 and 100%): &lt;input type=\\&quot;number\\&quot; name=\\&quot;txt\\&quot; value=\\&quot;&quot; + \n                              String(EEPROM.read(3)) + &quot;\\&quot; onchange=\\&quot;setThreshold(this.value)\\&quot; min=\\&quot;0\\&quot; max=\\&quot;100\\&quot;&gt;&lt;\/p&gt;&quot;);\n            }\n            else if(selectedMode == 3) {\n              client.println(&quot;&lt;p&gt;Timer (0 and 255 in seconds): &lt;input type=\\&quot;number\\&quot; name=\\&quot;txt\\&quot; value=\\&quot;&quot; + \n                               String(EEPROM.read(2)) + &quot;\\&quot; onchange=\\&quot;setTimer(this.value)\\&quot; min=\\&quot;0\\&quot; max=\\&quot;255\\&quot;&gt;&lt;\/p&gt;&quot;);\n              client.println(&quot;&lt;p&gt;LDR Threshold (0 and 100%): &lt;input type=\\&quot;number\\&quot; name=\\&quot;txt\\&quot; value=\\&quot;&quot; + \n                               String(EEPROM.read(3)) + &quot;\\&quot; onchange=\\&quot;setThreshold(this.value)\\&quot; min=\\&quot;0\\&quot; max=\\&quot;100\\&quot;&gt;&lt;\/p&gt;&quot;);            \n            }\n            \/\/ Get and display DHT sensor readings\n            if(header.indexOf(&quot;GET \/?sensor&quot;) &gt;= 0) {\n              sensors.requestTemperatures(); \n              temperatureString = &quot; &quot; + String(sensors.getTempCByIndex(0)) + &quot;C  &quot; +  \n                        String(sensors.getTempFByIndex(0)) + &quot;F&quot;;   \n             \n              client.println(&quot;&lt;p&gt;&quot;);\n              client.println(temperatureString);\n              client.println(&quot;&lt;\/p&gt;&quot;);\n              client.println(&quot;&lt;p&gt;&lt;a href=\\&quot;\/\\&quot;&gt;&lt;button&gt;Remove Sensor Readings&lt;\/button&gt;&lt;\/a&gt;&lt;\/p&gt;&quot;);\n            }\n            else {\n              client.println(&quot;&lt;p&gt;&lt;a href=\\&quot;?sensor\\&quot;&gt;&lt;button&gt;View Sensor Readings&lt;\/button&gt;&lt;\/a&gt;&lt;\/p&gt;&quot;);\n            }\n            client.println(&quot;&lt;script&gt; function setMode(value) { var xhr = new XMLHttpRequest();&quot;); \n            client.println(&quot;xhr.open('GET', \\&quot;\/?mode=\\&quot; + value + \\&quot;&amp;\\&quot;, true);&quot;); \n            client.println(&quot;xhr.send(); location.reload(true); } &quot;);\n            client.println(&quot;function setTimer(value) { var xhr = new XMLHttpRequest();&quot;);\n            client.println(&quot;xhr.open('GET', \\&quot;\/?timer=\\&quot; + value + \\&quot;&amp;\\&quot;, true);&quot;); \n            client.println(&quot;xhr.send(); location.reload(true); } &quot;);\n            client.println(&quot;function setThreshold(value) { var xhr = new XMLHttpRequest();&quot;);\n            client.println(&quot;xhr.open('GET', \\&quot;\/?ldrthreshold=\\&quot; + value + \\&quot;&amp;\\&quot;, true);&quot;); \n            client.println(&quot;xhr.send(); location.reload(true); } &quot;);\n            client.println(&quot;function outputOn() { var xhr = new XMLHttpRequest();&quot;);\n            client.println(&quot;xhr.open('GET', \\&quot;\/?state=on\\&quot;, true);&quot;); \n            client.println(&quot;xhr.send(); location.reload(true); } &quot;);\n            client.println(&quot;function outputOff() { var xhr = new XMLHttpRequest();&quot;);\n            client.println(&quot;xhr.open('GET', \\&quot;\/?state=off\\&quot;, true);&quot;); \n            client.println(&quot;xhr.send(); location.reload(true); } &quot;);\n            client.println(&quot;function updateSensorReadings() { var xhr = new XMLHttpRequest();&quot;);\n            client.println(&quot;xhr.open('GET', \\&quot;\/?sensor\\&quot;, true);&quot;); \n            client.println(&quot;xhr.send(); location.reload(true); }&lt;\/script&gt;&lt;\/body&gt;&lt;\/html&gt;&quot;);\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  }\n  \n  \/\/ Starts a timer to turn on\/off the output according to the time value or LDR reading\n  now = millis();\n  \n  \/\/ Mode selected (1): Auto PIR\n  if(startTimer &amp;&amp; armMotion &amp;&amp; !armLdr) {\n    if(outputState == &quot;off&quot;) {\n      outputOn();\n    }\n    else if((now - lastMeasure &gt; (timer * 1000))) {\n      outputOff();\n      startTimer = false;     \n    }\n  }  \n  \n  \/\/ Mode selected (2): Auto LDR\n  \/\/ Read current LDR value and turn the output accordingly\n  if(armLdr &amp;&amp; !armMotion) {\n    int ldrValue = map(analogRead(ldr), 0, 1023, 0, 100); \n    Serial.println(ldrValue);\n    if(ldrValue &lt; ldrThreshold &amp;&amp; outputState == &quot;on&quot;) {\n      outputOff();\n    }\n    else if(ldrValue &gt; ldrThreshold &amp;&amp; outputState == &quot;off&quot;) {\n      outputOn();\n    }\n    delay(100);\n  }\n  \n  \/\/ Mode selected (3): Auto PIR and LDR\n  if(startTimer &amp;&amp; armMotion &amp;&amp; armLdr) {\n    int ldrValue = map(analogRead(ldr), 0, 1023, 0, 100);\n    Serial.println(ldrValue);\n    if(ldrValue &lt; ldrThreshold) {\n      outputOff();\n      startTimer = false;\n      Serial.println(&quot;a&quot;);\n    }\n    else if(ldrValue &gt; ldrThreshold &amp;&amp; outputState == &quot;off&quot;) {\n      outputOn();\n      Serial.println(&quot;b&quot;);\n    }\n    else if(now - lastMeasure &gt; (timer * 1000)) {\n      outputOff();\n      startTimer = false;\n      Serial.println(&quot;c&quot;);\n    }\n  }\n}\n\n\/\/ Checks if motion was detected and the sensors are armed. Then, starts a timer.\nICACHE_RAM_ATTR void detectsMovement() {\n  if(armMotion || (armMotion &amp;&amp; armLdr)) {\n    Serial.println(&quot;MOTION DETECTED!!!&quot;);\n    startTimer = true;\n    lastMeasure = millis();\n  }  \n}\nvoid configureMode() {\n  \/\/ Mode: Manual\n  if(selectedMode == 0) {\n    armMotion = 0;\n    armLdr = 0;\n    \/\/ Status LED: off\n    digitalWrite(statusLed, LOW);\n  }\n  \/\/ Mode: Auto PIR\n  else if(selectedMode == 1) {\n    outputOff();\n    armMotion = 1;\n    armLdr = 0;\n    \/\/ Status LED: on\n    digitalWrite(statusLed, HIGH);\n  }\n  \/\/ Mode: Auto LDR\n  else if(selectedMode == 2) {\n    armMotion = 0;\n    armLdr = 1;\n    \/\/ Status LED: on    \n    digitalWrite(statusLed, HIGH);\n  }\n  \/\/ Mode: Auto PIR and LDR\n  else if(selectedMode == 3) {\n    outputOff();\n    armMotion = 1;\n    armLdr = 1;\n    \/\/ Status LED: on\n    digitalWrite(statusLed, HIGH);\n  }\n}\n\n\/\/ Change output pin to on or off\nvoid outputOn() {\n  Serial.println(&quot;GPIO on&quot;);\n  outputState = &quot;on&quot;;\n  digitalWrite(output, LOW);\n  EEPROM.write(0, 1);\n  EEPROM.commit();\n}\nvoid outputOff() { \n  Serial.println(&quot;GPIO off&quot;);\n  outputState = &quot;off&quot;;\n  digitalWrite(output, HIGH);\n  EEPROM.write(0, 0);\n  EEPROM.commit();\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP8266-Multisensor-Shield\/raw\/master\/Code\/ESP8266_Multisensor_Shield\/ESP8266_Multisensor_Shield.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>This code is quite long to explain, so you can simply replace the following two variables with your network credentials and the code will work straight away.<\/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>If you want to learn how this code works, continue reading.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>Start by including the necessary libraries.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;ESP8266WiFi.h>\n#include &lt;EEPROM.h>\n#include &lt;OneWire.h>\n#include &lt;DallasTemperature.h><\/code><\/pre>\n\n\n\n<p>The <em>ESP8266WiFi<\/em> library is needed to use the ESP Wi-Fi capabilities. The <em>EEPROM<\/em> library allows you to read and write permanent data on the ESP8266 EEPROM, and the OneWire and DallasTemperature libraries allow you to read the temperature from the DS18B20 temperature sensor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting your Network Credentials<\/h3>\n\n\n\n<p>You need to add your network credentials in these two variables.<\/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>These are auxiliary variables to store the temperature in Celsius\/Fahrenheit:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Auxiliary variables for temperature and humidity\nstatic char celsiusTemp&#091;7];\nstatic char fahrenheitTemp&#091;7];\nstatic char humidityTemp&#091;7];\nString temperatureString = \"\"; \/\/ Variable to hold the temperature reading<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">EEPROM<\/h3>\n\n\n\n<p>Next, we define the EEPROM size we want to access.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define EEPROM_SIZE 4<\/code><\/pre>\n\n\n\n<p>We\u2019ll need to save four values in the flash memory: the last output state on address 0, the selected mode on address 1, the timer value on address 2, and the LDR threshold value on address 3. So, we need 4 bytes in the flash memory.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Address 0<\/strong>: Last output state (0 = off or 1 = on)<\/li><li><strong>Address 1<\/strong>: Selected mode (0 = Manual, 1 = Auto PIR, 2 = Auto LDR, or 3 = Auto PIR and LDR)<\/li><li><strong>Address 2<\/strong>: Timer (time 0 to 255 seconds)<\/li><li><strong>Address 3<\/strong>: LDR threshold value (luminosity in percentage 0 to 100%)<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Defining GPIOs<\/h3>\n\n\n\n<p>In this section, we define the GPIOs for the output, the status LED, PIR motion sensor, and the LDR.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const int output = 15;\nconst int statusLed = 12;\nconst int motionSensor = 5;\nconst int ldr = A0;<\/code><\/pre>\n\n\n\n<p>We also create a String variable to hold the outputState to be displayed on the web server.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>String outputState = \"off\";<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Temperature Sensor<\/h3>\n\n\n\n<p>Next, create the instances needed for the temperature sensor. The temperature sensor is connected to GPIO 4.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ GPIO where the DS18B20 is connected to\nconst int oneWireBus = 4; \n\/\/ Setup a oneWire instance to communicate with any OneWire devices\nOneWire oneWire(oneWireBus);\n\/\/ Pass our oneWire reference to Dallas Temperature sensor \nDallasTemperature sensors(&amp;oneWire);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Timers<\/h3>\n\n\n\n<p>Next, we create auxiliary variables for the timers:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>long now = millis();\nlong lastMeasure = 0;\nboolean startTimer = false;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Selected Mode and Settings<\/h3>\n\n\n\n<p>Here, we initialize variables to store the selected mode and settings:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>int selectedMode = 0;\nint timer = 0;\nint ldrThreshold = 0;\nint armMotion = 0;\nint armLdr = 0;\nString modes&#091;4] = { \"Manual\", \"Auto PIR\", \"Auto LDR\", \"Auto PIR and LDR\" };<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Variables for the Web Server<\/h3>\n\n\n\n<p>The following snippet of code is related to the web server. You can follow the <a href=\"https:\/\/randomnerdtutorials.com\/esp8266-web-server-with-arduino-ide\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP8266 Web Server tutorial<\/a> to get familiar with a basic web server code.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Decode HTTP GET value\nString valueString = \"0\";\nint pos1 = 0;\nint pos2 = 0;\n\/\/ Variable to store the HTTP request\nString header;\n\/\/ Set web server port number to 80\nWiFiServer server(80);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">setup()<\/h3>\n\n\n\n<p>In the <em>setup()<\/em>, start by initializing the DS18B20 temperature sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>sensors.begin();<\/code><\/pre>\n\n\n\n<p>Initialize the Serial Port 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<h4 class=\"wp-block-heading\">Interrupt<\/h4>\n\n\n\n<p>Set the PIR motion sensor as an INPUT_PULLUP, and define it as an interrupt in RISING mode.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>pinMode(motionSensor, INPUT_PULLUP);\nattachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Flash memory<\/h4>\n\n\n\n<p>This part of the code initializes the flash memory with the EEPROM size defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>EEPROM.begin(EEPROM_SIZE);<\/code><\/pre>\n\n\n\n<p>Set the status LED and the output pin as outputs.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>pinMode(output, OUTPUT);\npinMode(statusLed, OUTPUT);<\/code><\/pre>\n\n\n\n<p>We\u2019re controlling a relay with inverted logic, so we start by setting it to HIGH, so it actually starts off.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>digitalWrite(output, HIGH);\ndigitalWrite(statusLed, HIGH);<\/code><\/pre>\n\n\n\n<p>Then, set the output to the last saved state. The output state is saved on position 0, so use EEPROM.read(0).<\/p>\n\n\n\n<p>We check if the state saved is on or off to update the output state accordingly.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(!EEPROM.read(0)) {\n  outputState = \"off\";\n  digitalWrite(output, HIGH);\n}\nelse {\n  outputState = \"on\";\n  digitalWrite(output, LOW);\n}<\/code><\/pre>\n\n\n\n<p>We also update all variables that hold settings with the values saved in the EEPROM, like the selected mode, timer, and LDR threshold value.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>selectedMode = EEPROM.read(1);\ntimer = EEPROM.read(2);\nldrThreshold = EEPROM.read(3);<\/code><\/pre>\n\n\n\n<p>Then, we call the <em>configureMode()<\/em> function to assign the right values to each mode.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>configureMode();<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">configureMode() function<\/h4>\n\n\n\n<p>Let\u2019s take a look on how this function works. If the selected mode is Manual, the motion is not activated (<em>armMotion<\/em>), neither the LDR (<em>armLdr<\/em>). We also set the status LED to LOW to show that we are in manual mode (in the automatic modes, the status LED is on).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(selectedMode == 0) {\n  armMotion = 0;\n  armLdr = 0;\n  \/\/ Status LED: off\n  digitalWrite(statusLed, LOW);\n}<\/code><\/pre>\n\n\n\n<p>A similar process is done to configure the other modes. You change the arm variables to activate or deactivate a sensor. Now, let\u2019s go back to the <em>setup()<\/em>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Wi-Fi connection<\/h4>\n\n\n\n<p>Here, we connect to the Wi-Fi network and print the ESP8266 IP address in the Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Serial.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 <em>loop()<\/em>, we display the web server and make things happen accordingly to the selected mode and settings.<\/p>\n\n\n\n<p>We\u2019ve covered web servers in great detail in the <a href=\"https:\/\/randomnerdtutorials.com\/esp8266-web-server-with-arduino-ide\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP8266 Web Server Tutorial<\/a>. So, we\u2019ll just take a look at the parts that are more relevant for this project.<\/p>\n\n\n\n<p>This part of the code is easier to understand if we explain what\u2019s happening with a live demonstration.<\/p>\n\n\n\n<p>When you access the web server, you\u2019ll see a similar 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=\"527\" height=\"552\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/1-web-server-manual-mode.png?resize=527%2C552&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72422\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/1-web-server-manual-mode.png?w=527&amp;quality=100&amp;strip=all&amp;ssl=1 527w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/1-web-server-manual-mode.png?resize=286%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 286w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n\n<p>At the top you can select one of these four different modes.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"552\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/0-select-mode.png?resize=527%2C552&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72423\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/0-select-mode.png?w=527&amp;quality=100&amp;strip=all&amp;ssl=1 527w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/08\/0-select-mode.png?resize=286%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 286w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li>Manual (mode 0)<\/li><li>Auto PIR (mode 1)<\/li><li>Auto LDR (mode 2)<\/li><li>Auto PIR and LDR (mode 3)<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Manual mode<\/h4>\n\n\n\n<p>For example, if you choose Manual mode, the following part of the code is being executed.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(header.indexOf(\"GET \/?mode=\") >= 0) {\n  pos1 = header.indexOf('=');\n  pos2 = header.indexOf('&amp;');\n  valueString = header.substring(pos1+1, pos2);\n  selectedMode = valueString.toInt();\n  EEPROM.write(1, selectedMode);\n  EEPROM.commit();\n  configureMode();\n}<\/code><\/pre>\n\n\n\n<p>It saves the selected mode in the <em>selectedMode<\/em> variable and stores it in the flash memory with:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>EEPROM.write(1, selectedMode);<\/code><\/pre>\n\n\n\n<p>The web page look changes accordingly to the selected mode. In this case, since we\u2019ve selected the manual mode that corresponds to 0, the following if statement is true and the web page will display two buttons to control the output.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(selectedMode == 0) {\n  if(outputState == \"off\") {\n    client.println(\"&lt;p>&lt;button class=\\\"button\\\" onclick=\\\"outputOn()\\\">ON&lt;\/button>&lt;\/p>\");\n  } \n  else {\n    client.println(\"&lt;p>&lt;button class=\\\"button button2\\\" onclick=\\\"outputOff()\\\">OFF&lt;\/button>&lt;\/p>\");\n  }\n}<\/code><\/pre>\n\n\n\n<p>When you click the on and off buttons, the following code runs and one of these two else if statements turns the output on or off.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Change the output state - turn GPIOs on and off\nelse if(header.indexOf(\"GET \/?state=on\") >= 0) {\n  outputOn();\n} \nelse if(header.indexOf(\"GET \/?state=off\") >= 0) {\n  outputOff();\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Auto PIR mode<\/h4>\n\n\n\n<p>Now, in the drop-down menu select the Auto PIR mode.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"552\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/3-web-server-pir-motion-sensor.png?resize=527%2C552&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72426\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/3-web-server-pir-motion-sensor.png?w=527&amp;quality=100&amp;strip=all&amp;ssl=1 527w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/3-web-server-pir-motion-sensor.png?resize=286%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 286w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n\n<p>There\u2019s a new input field that shows up in the web page. This field allows you to type an int number from 0 to 255 to specify the number of seconds the output should remain on after motion is detected.<\/p>\n\n\n\n<p>When you change the number, it calls the following part of the code and changes the timer variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>else if(header.indexOf(\"GET \/?timer=\") >= 0) {\n  pos1 = header.indexOf('=');\n  pos2 = header.indexOf('&amp;');\n  valueString = header.substring(pos1+1, pos2);\n  timer = valueString.toInt();\n  EEPROM.write(2, timer);\n  EEPROM.commit();\n  Serial.println(valueString);\n}<\/code><\/pre>\n\n\n\n<p>In this mode (mode 1), it only displays the input field for the timer.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>else if(selectedMode == 1) {\n  client.println(\"&lt;p>Timer (0 and 255 in seconds): &lt;input type=\\\"number\\\" name=\\\"txt\\\" value=\\\"\" + \n  String(EEPROM.read(2)) + \"\\\" onchange=\\\"setTimer(this.value)\\\" min=\\\"0\\\" max=\\\"255\\\">&lt;\/p>\");\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Auto LDR mode<\/h4>\n\n\n\n<p>Select Auto LDR mode and a new input field appears.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"552\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/4-web-server-ldr-value.png?resize=527%2C552&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72427\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/4-web-server-ldr-value.png?w=527&amp;quality=100&amp;strip=all&amp;ssl=1 527w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/4-web-server-ldr-value.png?resize=286%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 286w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n\n<p>This sets the LDR threshold value and you can enter a number between 0 and 100 to indicate the % of luminosity. When you change this field, it calls the following part of the code to update the LDR threshold value:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>else if(header.indexOf(\"GET \/?ldrthreshold=\") >= 0) {\n  pos1 = header.indexOf('=');\n  pos2 = header.indexOf('&amp;');\n  valueString = header.substring(pos1+1, pos2);\n  ldrThreshold = valueString.toInt();\n  EEPROM.write(3, ldrThreshold);\n  EEPROM.commit();\n  Serial.println(valueString);\n}<\/code><\/pre>\n\n\n\n<p>This is mode 2, and it will display the ldr theshold input field.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>else if(selectedMode == 2) {\n  client.println(\"&lt;p>LDR Threshold (0 and 100%): &lt;input type=\\\"number\\\" name=\\\"txt\\\" value=\\\"\" + \n  String(EEPROM.read(3)) + \"\\\" onchange=\\\"setThreshold(this.value)\\\" min=\\\"0\\\" max=\\\"100\\\">&lt;\/p>\");\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Auto PIR and LDR mode<\/h4>\n\n\n\n<p>Selecting the Auto PIR and LDR mode activates both the PIR and LDR. It also loads a new web page with two input fields.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"552\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/5-web-server-auto-pir-ldr.png?resize=527%2C552&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72425\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/5-web-server-auto-pir-ldr.png?w=527&amp;quality=100&amp;strip=all&amp;ssl=1 527w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/5-web-server-auto-pir-ldr.png?resize=286%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 286w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n\n<p>Both input fields work the same way as we\u2019ve described earlier.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Sensor readings<\/h4>\n\n\n\n<p>Lastly, there\u2019s a button to request and display temperature readings.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"552\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/2-web-server-sensor-readings.png?resize=527%2C552&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72424\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/2-web-server-sensor-readings.png?w=527&amp;quality=100&amp;strip=all&amp;ssl=1 527w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/2-web-server-sensor-readings.png?resize=286%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 286w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>if(header.indexOf(\"GET \/?sensor\") >= 0) {\n  sensors.requestTemperatures(); \n  temperatureString = \" \" + String(sensors.getTempCByIndex(0)) + \"C \" + \n  String(sensors.getTempFByIndex(0)) + \"F\"; \n\n  client.println(\"&lt;p>\");\n  client.println(temperatureString);\n  client.println(\"&lt;\/p>\");<\/code><\/pre>\n\n\n\n<p>There\u2019s also a button you can press to remove those readings.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>client.println(\"&lt;p>&lt;a href=\\\"\/\\\">&lt;button>Remove Sensor Readings&lt;\/button>&lt;\/a>&lt;\/p>\");<\/code><\/pre>\n\n\n\n<p>That\u2019s how you configure the settings of your multisensor. Then, accordingly to the mode and settings selected, another part of the <em>loop()<\/em> is running to check whether the output should be on or off.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Controlling the Output State<\/h4>\n\n\n\n<p>For example, when motion is detected, it calls the <em>detectsMovement()<\/em> function that starts a timer.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>void detectsMovement() {\n  if(armMotion || (armMotion &amp;&amp; armLdr)) {\n    Serial.println(\"MOTION DETECTED!!!\");\n    startTimer = true;\n    lastMeasure = millis();\n  } \n}<\/code><\/pre>\n\n\n\n<p>Then, depending on the elapsed time, it turns the output on or off.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Mode selected (1): Auto PIR\nif(startTimer &amp;&amp; armMotion &amp;&amp; !armLdr) {\n  if(outputState == \"off\") {\n    outputOn();\n  }\n  else if((now - lastMeasure > (timer * 1000))) {\n    outputOff();\n    startTimer = false; \n  }\n}<\/code><\/pre>\n\n\n\n<p>There\u2019s also the following section of the code to turn the output on or off accordingly to the luminosity of the threshold value.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Mode selected (2): Auto LDR\n\/\/ Read current LDR value and turn the output accordingly\nif(armLdr &amp;&amp; !armMotion) {\n  int ldrValue = map(analogRead(ldr), 0, 1024, 0, 100); \n  \/\/Serial.println(ldrValue);\n  if(ldrValue > ldrThreshold &amp;&amp; outputState == \"on\") {\n    outputOff();\n  }\n  else if(ldrValue &lt; ldrThreshold &amp;&amp; outputState == \"off\") {\n    outputOn();\n  }\n  delay(100);\n}<\/code><\/pre>\n\n\n\n<p>Finally, the following snippet of code runs when the auto PIR and LDR mode is selected and motion is detected.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Mode selected (3): Auto PIR and LDR\nif(startTimer &amp;&amp; armMotion &amp;&amp; armLdr) {\n  int ldrValue = map(analogRead(ldr), 0, 4095, 0, 100);\n  \/\/Serial.println(ldrValue);\n  if(ldrValue > ldrThreshold) {\n    outputOff();\n    startTimer = false;\n  }\n  else if(ldrValue &lt; ldrThreshold &amp;&amp; outputState == \"off\") {\n    outputOn();\n  }\n  else if(now - lastMeasure > (timer * 1000)) {\n    outputOff();\n    startTimer = false;\n  }\n}<\/code><\/pre>\n\n\n\n<p>That\u2019s pretty much how the code works, we\u2019ve also put an effort to write a bunch of comments in the code to make it easier to understand.<\/p>\n\n\n\n<p>We\u2019ve programmed the WeMos Multisensor shield with this code, but you can write your own code to integrate with any home automation platform. You just need to take into account the pin assignment of the multisensor shield.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Upload the Code<\/h2>\n\n\n\n<p>Click the upload button to upload the code to your ESP8266. Make sure you have the right board and COM port selected.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"34\" height=\"29\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2016\/12\/arduino-ide-upload-button.png?resize=34%2C29&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-65439\"\/><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the Multisensor Shield<\/h2>\n\n\n\n<p>Open the Serial Monitor at a baud rate of 112500. Press the ESP8266 enable button to print the ESP 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=\"732\" height=\"461\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/serial-monitor-ip-address-multisensor.png?resize=732%2C461&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72436\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/serial-monitor-ip-address-multisensor.png?w=732&amp;quality=100&amp;strip=all&amp;ssl=1 732w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/serial-monitor-ip-address-multisensor.png?resize=300%2C189&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 732px) 100vw, 732px\" \/><\/figure><\/div>\n\n\n\n<p>Open your browser and type the ESP8266 IP address. The following page should load.<\/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\/09\/multisensor-shield-access-web-server.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72429\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-access-web-server.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-access-web-server.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>We\u2019ve connected a relay module to the output terminal socket, so we\u2019re controlling a 12V lamp, but you can control any output that you want.<\/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\/09\/multisensor-shield-relay.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72430\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-relay.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-relay.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>Now, select each mode, try to set different settings to check if everything is working properly.<\/p>\n\n\n\n<p>For example, select Manual mode and turn the lamp on and off.<\/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\/09\/multisensor-shield-manual-mode.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72416\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-manual-mode.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-manual-mode.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>Select the Auto PIR mode. In this mode the lamp turns on for the number of seconds you set, when motion is detected.<\/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\/09\/multisensor-shield-auto-pir.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72433\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-auto-pir.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-auto-pir.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>On the LDR mode, you can set the threshold value that will make the lamp light up. When I cover the LDR, the luminosity goes below the threshold, and the lamp lights up.<\/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\/09\/multisensor-shield-auto-ldr.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72432\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-auto-ldr.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-auto-ldr.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>In Auto PIR and LDR mode, I can set the timer and the LDR threshold.<\/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\/09\/multisensor-shield-auto-pir-ldr.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72431\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-auto-pir-ldr.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-auto-pir-ldr.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>If motion is detected, but the light intensity is above the threshold, nothing happens. But if I cover the LDR, which means there\u2019s no light, and motion is detected, the lamp turns on for the number of seconds I\u2019ve defined in the settings.<\/p>\n\n\n\n<p>You can also click the \u201cView Sensor Readings\u201d button to request the latest temperature readings.<\/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\/09\/multisensor-shield-sensor-readings.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72434\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-sensor-readings.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-sensor-readings.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<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>We&#8217;re giving away 5 bare PCBs to someone that posts a comment below! Simply post a comment in this blog post about what you would like to do with the PCB and you&#8217;re entered for a chance to win one of these bare PCBs.&nbsp;The winners will be announced next week! So, stay tuned!&nbsp;<strong>[Update] the giveaway ended and the winners are:&nbsp;Ram Chivukula,&nbsp;Phillip R. Hickman,&nbsp;Douglas W Murray,&nbsp;Terry Wegener, and&nbsp;Dale Wolver.<\/strong><\/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\/09\/multisensor-shield-pcb.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-72405\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-pcb.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/multisensor-shield-pcb.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>That\u2019s it for this project. We hope you\u2019ve found this project useful and you\u2019re able to build it yourself. You can program the Multisensor Shield with other code suitable for your needs. For example, you can control the output based on the current temperature value. You can also edit the gerber files and add other features to the ESP8266 Multisensor Shield.<\/p>\n\n\n\n<p>If you like this project you may also like other related projects:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/home-automation-using-esp8266\/\">Home Automation Using ESP8266 Course<\/a><\/li><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-web-server-with-bme280-mini-weather-station\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 Web Server with BME280 \u2013 Mini Weather Station<\/a><\/li><\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this project you\u2019ll discover how to design and create a Multisensor Shield for the ESP8266 Wemos D1 Mini board.&nbsp;The shield has temperature sensor (DS18B20), a PIR motion sensor, an &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Build a Multisensor Shield for ESP8266\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp8266-multisensor-shield\/#more-71851\" aria-label=\"Read more about Build a Multisensor Shield for ESP8266\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":72578,"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":[265,214,246,300,294,264,257,218],"tags":[],"class_list":["post-71851","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp8266-project","category-esp8266","category-esp8266-arduino-ide","category-0-esp8266","category-home-assistant","category-project","category-web-server-2","category-web-server"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/09\/Build-ESP8266-WeMos-D1-Mini-Multisensor-Shield.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\/71851","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=71851"}],"version-history":[{"count":0,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/71851\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/72578"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=71851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=71851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=71851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}