{"id":93152,"date":"2023-03-27T10:23:55","date_gmt":"2023-03-27T10:23:55","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=93152"},"modified":"2023-03-27T10:24:48","modified_gmt":"2023-03-27T10:24:48","slug":"control-esp32-esp8266-gpios-from-anywhere","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/control-esp32-esp8266-gpios-from-anywhere\/","title":{"rendered":"Control ESP32 and ESP8266 GPIOs from Anywhere in the World"},"content":{"rendered":"\n<p>In this project, you&#8217;ll learn how to control your ESP32 or ESP8266 GPIOs from anywhere in the world. This can be very useful to control a relay, a thermostat, or any other device remotely.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-anywhere-cloud-php.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control ESP32 and ESP8266 GPIOs from Anywhere in the World\" class=\"wp-image-129701\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-anywhere-cloud-php.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-anywhere-cloud-php.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-anywhere-cloud-php.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-anywhere-cloud-php.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclgray\"><em>Updated on 27 March 2023<\/em><\/p>\n\n\n\n<p>This project is also very versatile. Through your cloud dashboard, you can easily control more outputs (without uploading new code to your board) and you can even connect multiple boards to your server.<\/p>\n\n\n\n<p>Previously, we&#8217;ve stored sensor readings into a database and we&#8217;ve used different methods to display sensor readings on a:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-mysql-database-php\/\">Table<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/visualize-esp32-esp8266-sensor-readings-from-anywhere\/\">Charts<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/cloud-weather-station-esp32-esp8266\/\">Gauges<\/a><\/li>\n<\/ul>\n\n\n\n<p>Now, I\u2019ve created this new project where you can create buttons in a dashboard and assign them to a Board and GPIO number. Then, you can use the toggle switches to control the ESP32 or ESP8266 outputs from anywhere.<\/p>\n\n\n\n<p>There are many ways of controlling outputs from anywhere, and even though this is a working solution there are other <a href=\"https:\/\/randomnerdtutorials.com\/firebase-control-esp32-gpios\/\" title=\"\">methods that provide a two-way communication with your devices<\/a>. I also recommend that you take this project further and add more features to fit your own needs.<\/p>\n\n\n\n<p>To build this project, you&#8217;ll use these technologies:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ESP32 or ESP8266 programmed with Arduino IDE<\/li>\n\n\n\n<li>Hosting server and domain name<\/li>\n\n\n\n<li>PHP scripts to store and retrieve the output states stored in a MySQL database<\/li>\n<\/ul>\n\n\n\n<p><strong>Table of Contents<\/strong><\/p>\n\n\n\n<p>This project is divided into the following main sections:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"#host-php-mysql\" title=\"\">Hosting Your PHP Application and MySQL Database<\/a><\/li>\n\n\n\n<li><a href=\"#prepare-mysql-database\" title=\"\">Preparing Your MySQL Database<\/a><\/li>\n\n\n\n<li><a href=\"#create-dashboard-files\" title=\"\">Creating Your Dashboard Files<\/a><\/li>\n\n\n\n<li><a href=\"#php-script-update-retrieve-output-states\" title=\"\">PHP Script &#8211; Update and Retrieve Output States<\/a><\/li>\n\n\n\n<li><a href=\"#php-script-database-functions\" title=\"\">PHP Script for Database Functions<\/a><\/li>\n\n\n\n<li><a href=\"#php-script-control-buttons\" title=\"\">PHP Script &#8211; Control Buttons<\/a><\/li>\n\n\n\n<li><a href=\"#set-up-esp8266-esp32\" title=\"\">Setting Up the ESP32 or ESP8266<\/a><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Watch the Video Demonstration<\/h2>\n\n\n\n<p>To see how the project works, you can watch the following video demonstration:<\/p>\n\n\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/4moPYxNYjCY?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">0. Download Source Code<\/h2>\n\n\n\n<p>For this project, you&#8217;ll need these files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SQL query to create your table: <a rel=\"noreferrer noopener\" aria-label=\"Outputs_and_Boards_Table.sql (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/Outputs_and_Boards_Table.sql\" target=\"_blank\">Outputs_and_Boards_Table.sql<\/a><\/li>\n\n\n\n<li>Insert and access database: <a rel=\"noreferrer noopener\" aria-label=\"esp-database.php (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-database.php\" target=\"_blank\">esp-database.php<\/a><\/li>\n\n\n\n<li>Handle HTTP requests: <a rel=\"noreferrer noopener\" aria-label=\"esp-outputs-action.php (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-outputs-action.php\" target=\"_blank\">esp-outputs-action.php<\/a><\/li>\n\n\n\n<li>CSS file to style your web page: <a rel=\"noreferrer noopener\" aria-label=\"esp-style.css (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-style.css\" target=\"_blank\">esp-style.css<\/a><\/li>\n\n\n\n<li>Display your control buttons: <a aria-label=\"esp-outputs.php (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-outputs.php\" target=\"_blank\" rel=\"noreferrer noopener\">esp-outputs.php<\/a><\/li>\n\n\n\n<li>Arduino Sketch for ESP32 (<strong>with HTTPS<\/strong>): <a href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/HTTPS_ESP32_GET_Request_JSON.ino\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP32_HTTPS_GET_Request_JSON.ino<\/a><\/li>\n\n\n\n<li>Arduino Sketch for ESP8266 (<strong>with HTTPS<\/strong>): <a href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/HTTPS_ESP8266_GET_Request_JSON.ino\" target=\"_blank\" rel=\"noopener\" title=\"\">ESP8266_HTTPS_GET_Request_JSON.ino<\/a><\/li>\n\n\n\n<li>Arduino Sketch for ESP32 (without HTTPS): <a aria-label=\"ESP32_HTTP_GET_Request_JSON.ino (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/ESP32_HTTP_GET_Request_JSON.ino.ino\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32_HTTP_GET_Request_JSON.ino<\/a><\/li>\n\n\n\n<li>Arduino Sketch for ESP8266 (without HTTPS): <a aria-label=\"ESP8266_HTTP_GET_Request_JSON.ino (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/ESP8266_HTTP_GET_Request_JSON.ino.ino\" target=\"_blank\" rel=\"noreferrer noopener\">ESP8266_HTTP_GET_Request_JSON.ino<\/a><\/li>\n\n\n\n<li><strong><a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/archive\/master.zip\" target=\"_blank\">Download all projects files<\/a><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"host-php-mysql\">1. Hosting Your PHP Application and MySQL Database<\/h2>\n\n\n\n<p>The goal of this project is to have your own domain name and hosting account that allows you to control your ESP32 or ESP8266 GPIOs from anywhere in the world.<\/p>\n\n\n\n<p>Here&#8217;s a high-level overview of how the project works:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-outputs-from-anywhere-project-overview.png?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"1000\" height=\"942\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-outputs-from-anywhere-project-overview.png?resize=1000%2C942&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control outputs from anywhere project overview\" class=\"wp-image-93160\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-outputs-from-anywhere-project-overview.png?w=1000&amp;quality=100&amp;strip=all&amp;ssl=1 1000w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-outputs-from-anywhere-project-overview.png?resize=300%2C283&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-outputs-from-anywhere-project-overview.png?resize=768%2C723&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure><\/div>\n\n\n<ol class=\"wp-block-list\">\n<li>You have a web page running a PHP script with some toggle buttons that allow you to control the outputs on and off;<\/li>\n\n\n\n<li>When you press the buttons, it updates the output state and saves it in your database;<\/li>\n\n\n\n<li>You can add more buttons or delete them from your dashboard;<\/li>\n\n\n\n<li>Then, you can have an ESP32 or ESP8266 or even multiple boards that make HTTP GET requests every X number of seconds to your server;<\/li>\n\n\n\n<li>Finally, according to the result of that HTTP GET request, the ESP board updates its GPIOs accordingly.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Hosting Services<\/h3>\n\n\n\n<p>I recommend using one of the following hosting services that can handle all the project requirements:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/randomnerdtutorials.com\/bluehost\" target=\"_blank\">Bluehost (user-friendly with cPanel)<\/a>: free domain name when you sign up for the 3-year plan. I recommend choosing the unlimited websites option;<\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" style=\"font-size: inherit; background-color: initial;\" href=\"https:\/\/randomnerdtutorials.com\/digitalocean\" target=\"_blank\">Digital Ocean<\/a><span style=\"font-size: inherit; background-color: initial;\">: Linux server that you manage through a command line. I only recommended this option for advanced users.<\/span><\/li>\n<\/ul>\n\n\n\n<p>Those two services are the ones that I use and personally recommend, but you can use any other hosting service. Any hosting service that offers PHP and MySQL will work with this tutorial. If you don&#8217;t have a hosting account, I recommend <a href=\"https:\/\/randomnerdtutorials.com\/bluehost\">signing up for Bluehost<\/a>.<\/p>\n\n\n\n<p style=\"text-align:center\"><a href=\"https:\/\/randomnerdtutorials.com\/bluehost\" target=\"_blank\" class=\"button\" rel=\"noopener noreferrer\">Get Hosting and Domain Name with Bluehost \u00bb<\/a><\/p>\n\n\n\n<p>When buying a hosting account, you&#8217;ll also have to purchase a domain name. This is what makes this project interesting: you&#8217;ll be able to go your domain name (http:\/\/example.com) and control your boards.<\/p>\n\n\n\n<p>If you like our projects, you might consider signing up for one of the recommended hosting services, because you&#8217;ll be supporting our work.<\/p>\n\n\n\n<p class=\"rntbox rntclgreen\"><strong>Note: <\/strong> you can also run a <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-apache-mysql-php-lamp-server\/\">LAMP (Linux, Apache, MySQL, PHP) server<\/a> on a Raspberry Pi to <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-raspberry-pi-lamp-server\/\">control your boards in your local network<\/a>. However, the purpose of this tutorial is to control the ESP outputs with your own domain name that you can access from anywhere in the world.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prepare-mysql-database\">2. Preparing Your MySQL Database<\/h2>\n\n\n\n<p>After signing up for a <a rel=\"noreferrer noopener\" aria-label=\"hosting and setting up a domain name (opens in a new tab)\" href=\"https:\/\/randomnerdtutorials.com\/bluehost\" target=\"_blank\">hosting account and setting up a domain name<\/a>, you can login to your cPanel or similar dashboard. After that, follow the next steps to create your database, username, password and SQL table.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a database and user<\/h3>\n\n\n\n<p>Open the &#8220;<strong>Advanced<\/strong>&#8221; tab:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"794\" height=\"543\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/cpanel-bluehost-advanced-tab.jpg?resize=794%2C543&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Bluehost Advanced tab\" class=\"wp-image-92154\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/cpanel-bluehost-advanced-tab.jpg?w=794&amp;quality=100&amp;strip=all&amp;ssl=1 794w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/cpanel-bluehost-advanced-tab.jpg?resize=300%2C205&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/12\/cpanel-bluehost-advanced-tab.jpg?resize=768%2C525&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 794px) 100vw, 794px\" \/><\/figure><\/div>\n\n\n<p><strong>1.<\/strong> Type &#8220;database&#8221; in the search bar and select &#8220;MySQL Database Wizard&#8221;.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"826\" height=\"300\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/A-CPanel-select-MySQL-database-wizard-to-create-db.png?resize=826%2C300&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"CPanel select MySQL database wizard to create db\" class=\"wp-image-88086\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/A-CPanel-select-MySQL-database-wizard-to-create-db.png?w=826&amp;quality=100&amp;strip=all&amp;ssl=1 826w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/A-CPanel-select-MySQL-database-wizard-to-create-db.png?resize=300%2C109&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/A-CPanel-select-MySQL-database-wizard-to-create-db.png?resize=768%2C279&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 826px) 100vw, 826px\" \/><\/figure><\/div>\n\n\n<p><strong>2.<\/strong> Enter your desired Database name. In my case, the database name is <span class=\"rnthl rntliteral\">esp_data<\/span>. Then, press the &#8220;Next Step&#8221; button:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"609\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Create-MySQL-Database.png?resize=609%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 CPanel Create MySQL Database\" class=\"wp-image-88072\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Create-MySQL-Database.png?w=609&amp;quality=100&amp;strip=all&amp;ssl=1 609w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Create-MySQL-Database.png?resize=300%2C207&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 609px) 100vw, 609px\" \/><\/figure><\/div>\n\n\n<p><strong>Note: <\/strong> later you&#8217;ll have to use the database name with the prefix that your host gives you (my database prefix in the screenshot above is blurred). I&#8217;ll refer to it as <span class=\"rnthl rntliteral\">example_esp_data<\/span> from now on.<\/p>\n\n\n\n<p><strong>3.<\/strong> Type your Database username and set a password. You must save all those details, because you&#8217;ll need them later to establish a database connection with your PHP code.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"590\" height=\"615\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Create-MySQL-Database-User-Password.png?resize=590%2C615&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 CPanel Create MySQL Database User and Password\" class=\"wp-image-88073\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Create-MySQL-Database-User-Password.png?w=590&amp;quality=100&amp;strip=all&amp;ssl=1 590w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Create-MySQL-Database-User-Password.png?resize=288%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 288w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/figure><\/div>\n\n\n<p>That&#8217;s it! Your new database and user were created successfully. Now, save all your details because you&#8217;ll need them later:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Database name<\/strong>: example_esp_data<\/li>\n\n\n\n<li><strong>Username<\/strong>: example_esp_board<\/li>\n\n\n\n<li><strong>Password<\/strong>: your password<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a SQL table<\/h3>\n\n\n\n<p>After creating your database and user, go back to cPanel dashboard and search for &#8220;phpMyAdmin&#8221;.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"570\" height=\"315\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Open-PHPMyAdmin.png?resize=570%2C315&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 CPanel Open PHPMyAdmin\" class=\"wp-image-88076\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Open-PHPMyAdmin.png?w=570&amp;quality=100&amp;strip=all&amp;ssl=1 570w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Open-PHPMyAdmin.png?resize=300%2C166&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 570px) 100vw, 570px\" \/><\/figure><\/div>\n\n\n<p>In the left sidebar, select your database name <span class=\"rnthl rntliteral\">example_esp_data<\/span> and open the &#8220;SQL&#8221; tab. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"797\" height=\"521\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-PHPMyAdmin-Open-Database.png?resize=797%2C521&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 PHPMyAdmin Open Database\" class=\"wp-image-88078\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-PHPMyAdmin-Open-Database.png?w=797&amp;quality=100&amp;strip=all&amp;ssl=1 797w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-PHPMyAdmin-Open-Database.png?resize=300%2C196&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-PHPMyAdmin-Open-Database.png?resize=768%2C502&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 797px) 100vw, 797px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntcorange\"><strong>Important: <\/strong> make sure you&#8217;ve opened the <span class=\"rnthl rntliteral\">example_esp_data<\/span> database. Then, click the SQL tab. If you don&#8217;t follow these exact steps and run the SQL query, you might create a table in the wrong database.<\/p>\n\n\n\n<p>Copy the SQL query in the following snippet:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">CREATE TABLE Outputs (\r\n    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,\r\n    name VARCHAR(64),\r\n    board INT(6),\r\n    gpio INT(6),\r\n    state INT(6)\r\n);\r\nINSERT INTO `Outputs`(`name`, `board`, `gpio`, `state`) VALUES (&quot;Built-in LED&quot;, 1, 2, 0);\r\n\r\nCREATE TABLE Boards (\r\n    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,\r\n    board INT(6),\r\n    last_request TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\r\n);\r\nINSERT INTO `Boards`(`board`) VALUES (1);\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/master\/Code\/Outputs_and_Boards_Table.sql\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Paste it in the SQL query field (highlighted with a red rectangle) and press the &#8220;Go&#8221; button to create your table:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"645\" height=\"395\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-MySQL-Tables-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?resize=645%2C395&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Create MySQL Tables for control ESP32 ESP8266 GPIOs Dashboard\" class=\"wp-image-93162\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-MySQL-Tables-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?w=645&amp;quality=100&amp;strip=all&amp;ssl=1 645w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-MySQL-Tables-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?resize=300%2C184&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 645px) 100vw, 645px\" \/><\/figure><\/div>\n\n\n<p>After that, you should see your newly created tables called <span class=\"rnthl rntliteral\">Boards<\/span> and <span class=\"rnthl rntliteral\">Outputs<\/span> in the <span class=\"rnthl rntliteral\">example_esp_data<\/span> database as shown in the figure below:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"670\" height=\"74\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/MySQL-Tables-created-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?resize=670%2C74&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"MySQL Tables created for control ESP32 ESP8266 GPIOs Dashboard\" class=\"wp-image-93169\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/MySQL-Tables-created-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?w=670&amp;quality=100&amp;strip=all&amp;ssl=1 670w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/MySQL-Tables-created-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?resize=300%2C33&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 670px) 100vw, 670px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"create-dashboard-files\">3. Creating Your Dashboard Files<\/h2>\n\n\n\n<p>In this section, we&#8217;re going to create the files that are responsible for creating your Dashboard. Here are the files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Insert and access database: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-database.php\" target=\"_blank\">esp-database.php<\/a><\/li>\n\n\n\n<li>Handle HTTP requests: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-outputs-action.php\" target=\"_blank\">esp-outputs-action.php<\/a><\/li>\n\n\n\n<li>CSS file to style your web page: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-style.css\" target=\"_blank\">esp-style.css<\/a><\/li>\n\n\n\n<li>Display your control buttons: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/esp-outputs.php\" target=\"_blank\">esp-outputs.php<\/a> <\/li>\n<\/ul>\n\n\n\n<p>If you&#8217;re using a hosting provider with cPanel, you can search for &#8220;File Manager&#8221;:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/ESP32-ESP8266-CPanel-Open-Edit-PHP-Files.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 CPanel Open Edit PHP Files with File Manager\"\/><\/figure><\/div>\n\n\n<p>Then, select the <strong>public_html<\/strong> option and press the &#8220;+ File&#8221; button to create a new file.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"849\" height=\"346\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/06\/ESP32-ESP8266-CPanel-Create-New-PHP-File.png?resize=849%2C346&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 CPanel Create New PHP File\" class=\"wp-image-85940\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/06\/ESP32-ESP8266-CPanel-Create-New-PHP-File.png?w=849&amp;quality=100&amp;strip=all&amp;ssl=1 849w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/06\/ESP32-ESP8266-CPanel-Create-New-PHP-File.png?resize=300%2C122&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/06\/ESP32-ESP8266-CPanel-Create-New-PHP-File.png?resize=768%2C313&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 849px) 100vw, 849px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>Note: <\/strong> if you&#8217;re following this tutorial and you&#8217;re not familiar with PHP, I recommend creating these exact files.<\/p>\n\n\n\n<p>Create four new files in <strong>\/public_html<\/strong> with these exact names and extensions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>esp-database.php<\/em><\/li>\n\n\n\n<li><em>esp-outputs-action.php<\/em><\/li>\n\n\n\n<li><em>esp-outputs.php<\/em><\/li>\n\n\n\n<li><em>esp-style.css<\/em><\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"249\" height=\"159\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-PHP-files-for-control-ESP32-ESP8266-GPIOs-Dashboard.png?resize=249%2C159&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Create PHP files for control ESP32 ESP8266 GPIOs Dashboard\" class=\"wp-image-93163\"\/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"php-script-update-retrieve-output-states\">4. PHP Script &#8211; Update and Retrieve Output States<\/h2>\n\n\n\n<p>In this section, we&#8217;re going to create a PHP script that is responsible for receiving incoming requests and interacting with your MySQL database.<\/p>\n\n\n\n<p>Edit the newly created file (<em>esp-outputs-action.php<\/em>) and copy the following snippet:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">&lt;?php\n    include_once('esp-database.php');\n\n    $action = $id = $name = $gpio = $state = &quot;&quot;;\n\n    if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;POST&quot;) {\n        $action = test_input($_POST[&quot;action&quot;]);\n        if ($action == &quot;output_create&quot;) {\n            $name = test_input($_POST[&quot;name&quot;]);\n            $board = test_input($_POST[&quot;board&quot;]);\n            $gpio = test_input($_POST[&quot;gpio&quot;]);\n            $state = test_input($_POST[&quot;state&quot;]);\n            $result = createOutput($name, $board, $gpio, $state);\n\n            $result2 = getBoard($board);\n            if(!$result2-&gt;fetch_assoc()) {\n                createBoard($board);\n            }\n            echo $result;\n        }\n        else {\n            echo &quot;No data posted with HTTP POST.&quot;;\n        }\n    }\n\n    if ($_SERVER[&quot;REQUEST_METHOD&quot;] == &quot;GET&quot;) {\n        $action = test_input($_GET[&quot;action&quot;]);\n        if ($action == &quot;outputs_state&quot;) {\n            $board = test_input($_GET[&quot;board&quot;]);\n            $result = getAllOutputStates($board);\n            if ($result) {\n                while ($row = $result-&gt;fetch_assoc()) {\n                    $rows[$row[&quot;gpio&quot;]] = $row[&quot;state&quot;];\n                }\n            }\n            echo json_encode($rows);\n            $result = getBoard($board);\n            if($result-&gt;fetch_assoc()) {\n                updateLastBoardTime($board);\n            }\n        }\n        else if ($action == &quot;output_update&quot;) {\n            $id = test_input($_GET[&quot;id&quot;]);\n            $state = test_input($_GET[&quot;state&quot;]);\n            $result = updateOutput($id, $state);\n            echo $result;\n        }\n        else if ($action == &quot;output_delete&quot;) {\n            $id = test_input($_GET[&quot;id&quot;]);\n            $board = getOutputBoardById($id);\n            if ($row = $board-&gt;fetch_assoc()) {\n                $board_id = $row[&quot;board&quot;];\n            }\n            $result = deleteOutput($id);\n            $result2 = getAllOutputStates($board_id);\n            if(!$result2-&gt;fetch_assoc()) {\n                deleteBoard($board_id);\n            }\n            echo $result;\n        }\n        else {\n            echo &quot;Invalid HTTP request.&quot;;\n        }\n    }\n\n    function test_input($data) {\n        $data = trim($data);\n        $data = stripslashes($data);\n        $data = htmlspecialchars($data);\n        return $data;\n    }\n?&gt;\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/master\/Code\/esp-outputs-action.php\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"php-script-database-functions\">5. PHP Script for Database Functions<\/h2>\n\n\n\n<p>Edit your file <em>esp-database.php<\/em> that inserts, deletes, and retrieves data. Copy the next PHP script:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">&lt;?php\n    $servername = &quot;localhost&quot;;\n    \/\/ Your Database name\n    $dbname = &quot;REPLACE_WITH_YOUR_DATABASE_NAME&quot;;\n    \/\/ Your Database user\n    $username = &quot;REPLACE_WITH_YOUR_USERNAME&quot;;\n    \/\/ Your Database user password\n    $password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\n\n    function createOutput($name, $board, $gpio, $state) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;INSERT INTO Outputs (name, board, gpio, state)\n        VALUES ('&quot; . $name . &quot;', '&quot; . $board . &quot;', '&quot; . $gpio . &quot;', '&quot; . $state . &quot;')&quot;;\n\n       if ($conn-&gt;query($sql) === TRUE) {\n            return &quot;New output created successfully&quot;;\n        }\n        else {\n            return &quot;Error: &quot; . $sql . &quot;&lt;br&gt;&quot; . $conn-&gt;error;\n        }\n        $conn-&gt;close();\n    }\n\n    function deleteOutput($id) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;DELETE FROM Outputs WHERE id='&quot;. $id .  &quot;'&quot;;\n\n       if ($conn-&gt;query($sql) === TRUE) {\n            return &quot;Output deleted successfully&quot;;\n        }\n        else {\n            return &quot;Error: &quot; . $sql . &quot;&lt;br&gt;&quot; . $conn-&gt;error;\n        }\n        $conn-&gt;close();\n    }\n\n    function updateOutput($id, $state) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;UPDATE Outputs SET state='&quot; . $state . &quot;' WHERE id='&quot;. $id .  &quot;'&quot;;\n\n       if ($conn-&gt;query($sql) === TRUE) {\n            return &quot;Output state updated successfully&quot;;\n        }\n        else {\n            return &quot;Error: &quot; . $sql . &quot;&lt;br&gt;&quot; . $conn-&gt;error;\n        }\n        $conn-&gt;close();\n    }\n\n    function getAllOutputs() {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;SELECT id, name, board, gpio, state FROM Outputs ORDER BY board&quot;;\n        if ($result = $conn-&gt;query($sql)) {\n            return $result;\n        }\n        else {\n            return false;\n        }\n        $conn-&gt;close();\n    }\n\n    function getAllOutputStates($board) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;SELECT gpio, state FROM Outputs WHERE board='&quot; . $board . &quot;'&quot;;\n        if ($result = $conn-&gt;query($sql)) {\n            return $result;\n        }\n        else {\n            return false;\n        }\n        $conn-&gt;close();\n    }\n\n    function getOutputBoardById($id) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;SELECT board FROM Outputs WHERE id='&quot; . $id . &quot;'&quot;;\n        if ($result = $conn-&gt;query($sql)) {\n            return $result;\n        }\n        else {\n            return false;\n        }\n        $conn-&gt;close();\n    }\n\n    function updateLastBoardTime($board) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;UPDATE Boards SET last_request=now() WHERE board='&quot;. $board .  &quot;'&quot;;\n\n       if ($conn-&gt;query($sql) === TRUE) {\n            return &quot;Output state updated successfully&quot;;\n        }\n        else {\n            return &quot;Error: &quot; . $sql . &quot;&lt;br&gt;&quot; . $conn-&gt;error;\n        }\n        $conn-&gt;close();\n    }\n\n    function getAllBoards() {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;SELECT board, last_request FROM Boards ORDER BY board&quot;;\n        if ($result = $conn-&gt;query($sql)) {\n            return $result;\n        }\n        else {\n            return false;\n        }\n        $conn-&gt;close();\n    }\n\n    function getBoard($board) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;SELECT board, last_request FROM Boards WHERE board='&quot; . $board . &quot;'&quot;;\n        if ($result = $conn-&gt;query($sql)) {\n            return $result;\n        }\n        else {\n            return false;\n        }\n        $conn-&gt;close();\n    }\n\n    function createBoard($board) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;INSERT INTO Boards (board) VALUES ('&quot; . $board . &quot;')&quot;;\n\n       if ($conn-&gt;query($sql) === TRUE) {\n            return &quot;New board created successfully&quot;;\n        }\n        else {\n            return &quot;Error: &quot; . $sql . &quot;&lt;br&gt;&quot; . $conn-&gt;error;\n        }\n        $conn-&gt;close();\n    }\n\n    function deleteBoard($board) {\n        global $servername, $username, $password, $dbname;\n\n        \/\/ Create connection\n        $conn = new mysqli($servername, $username, $password, $dbname);\n        \/\/ Check connection\n        if ($conn-&gt;connect_error) {\n            die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);\n        }\n\n        $sql = &quot;DELETE FROM Boards WHERE board='&quot;. $board .  &quot;'&quot;;\n\n       if ($conn-&gt;query($sql) === TRUE) {\n            return &quot;Board deleted successfully&quot;;\n        }\n        else {\n            return &quot;Error: &quot; . $sql . &quot;&lt;br&gt;&quot; . $conn-&gt;error;\n        }\n        $conn-&gt;close();\n    }\n\n?&gt;\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/master\/Code\/esp-database.php\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Before saving the file, you need to modify the <span class=\"rnthl rntliteral\">$dbname<\/span>, <span class=\"rnthl rntliteral\">$username<\/span> and <span class=\"rnthl rntliteral\">$password<\/span> variables with your unique details:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Your Database name\n$dbname = \"example_esp_data\";\n\/\/ Your Database user\n$username = \"example_esp_board\";\n\/\/ Your Database user password\n$password = \"YOUR_USER_PASSWORD\";<\/code><\/pre>\n\n\n\n<p>After adding the database name, username and password, save the file and continue with this tutorial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"php-script-control-buttons\">6. PHP Script &#8211; Control Buttons<\/h2>\n\n\n\n<p>You&#8217;ll also need to add a CSS file to style your dashboard (<em>esp-style.css<\/em>). Copy that CSS to your file and save it:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-css\">\/**\n  Rui Santos\n  Complete project details at https:\/\/RandomNerdTutorials.com\/control-esp32-esp8266-gpios-from-anywhere\/\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files.\n\n  The above copyright notice and this permission notice shall be included in all\n  copies or substantial portions of the Software.\n**\/\n\nhtml {\n    font-family: Arial;\n    display: inline-block;\n    text-align: center;\n}\n\nh2 {\n    font-size: 3.0rem;\n}\n\nbody {\n    max-width: 600px;\n    margin:0px auto;\n    padding-bottom: 25px;\n}\n\n.switch {\n    position: relative;\n    display: inline-block;\n    width: 120px;\n    height: 68px;\n}\n\n.switch input {\n    display: none\n}\n\n.slider {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background-color: #949494;\n    border-radius: 34px;\n}\n\n.slider:before {\n    position: absolute;\n    content: &quot;&quot;;\n    height: 52px;\n    width: 52px;\n    left: 8px; bottom: 8px;\n    background-color: #fff;\n    -webkit-transition: .4s;\n    transition: .4s;\n    border-radius: 68px;\n}\n\ninput:checked+.slider {\n    background-color: #008B74;\n}\n\ninput:checked+.slider:before {\n    -webkit-transform: translateX(52px);\n    -ms-transform: translateX(52px);\n    transform: translateX(52px);\n}\n\ninput[type=text], input[type=number], select {\n    width: 100%;\n    padding: 12px 20px;\n    margin: 8px 0;\n    display: inline-block;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    box-sizing: border-box;\n}\n\ninput[type=submit] {\n    width: 100%;\n    background-color: #008B74;\n    color: white;\n    padding: 14px 20px;\n    margin: 8px 0;\n    border: none;\n    border-radius: 4px;\n    cursor: pointer;\n}\n\ninput[type=submit]:hover {\n    background-color: #005a4c;\n}\n\ndiv {\n    text-align: left;\n    border-radius: 4px;\n    background-color: #efefef;\n    padding: 20px;\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/master\/Code\/esp-style.css\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Finally, copy the next PHP script to your <em>esp-outputs.php<\/em> files that will display your control buttons and allow you to create\/delete buttons:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">&lt;!--\n  Rui Santos\n  Complete project details at https:\/\/RandomNerdTutorials.com\/control-esp32-esp8266-gpios-from-anywhere\/\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files.\n\n  The above copyright notice and this permission notice shall be included in all\n  copies or substantial portions of the Software.\n--&gt;\n&lt;?php\n    include_once('esp-database.php');\n\n    $result = getAllOutputs();\n    $html_buttons = null;\n    if ($result) {\n        while ($row = $result-&gt;fetch_assoc()) {\n            if ($row[&quot;state&quot;] == &quot;1&quot;){\n                $button_checked = &quot;checked&quot;;\n            }\n            else {\n                $button_checked = &quot;&quot;;\n            }\n            $html_buttons .= '&lt;h3&gt;' . $row[&quot;name&quot;] . ' - Board '. $row[&quot;board&quot;] . ' - GPIO ' . $row[&quot;gpio&quot;] . ' (&lt;i&gt;&lt;a onclick=&quot;deleteOutput(this)&quot; href=&quot;javascript:void(0);&quot; id=&quot;' . $row[&quot;id&quot;] . '&quot;&gt;Delete&lt;\/a&gt;&lt;\/i&gt;)&lt;\/h3&gt;&lt;label class=&quot;switch&quot;&gt;&lt;input type=&quot;checkbox&quot; onchange=&quot;updateOutput(this)&quot; id=&quot;' . $row[&quot;id&quot;] . '&quot; ' . $button_checked . '&gt;&lt;span class=&quot;slider&quot;&gt;&lt;\/span&gt;&lt;\/label&gt;';\n        }\n    }\n\n    $result2 = getAllBoards();\n    $html_boards = null;\n    if ($result2) {\n        $html_boards .= '&lt;h3&gt;Boards&lt;\/h3&gt;';\n        while ($row = $result2-&gt;fetch_assoc()) {\n            $row_reading_time = $row[&quot;last_request&quot;];\n            \/\/ Uncomment to set timezone to - 1 hour (you can change 1 to any number)\n            \/\/$row_reading_time = date(&quot;Y-m-d H:i:s&quot;, strtotime(&quot;$row_reading_time - 1 hours&quot;));\n\n            \/\/ Uncomment to set timezone to + 4 hours (you can change 4 to any number)\n            \/\/$row_reading_time = date(&quot;Y-m-d H:i:s&quot;, strtotime(&quot;$row_reading_time + 7 hours&quot;));\n            $html_boards .= '&lt;p&gt;&lt;strong&gt;Board ' . $row[&quot;board&quot;] . '&lt;\/strong&gt; - Last Request Time: '. $row_reading_time . '&lt;\/p&gt;';\n        }\n    }\n?&gt;\n\n&lt;!DOCTYPE HTML&gt;\n&lt;html&gt;\n    &lt;head&gt;&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=utf-8&quot;&gt;\n\n        &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;\n        &lt;link rel=&quot;stylesheet&quot; type=&quot;text\/css&quot; href=&quot;esp-style.css&quot;&gt;\n        &lt;title&gt;ESP Output Control&lt;\/title&gt;\n    &lt;\/head&gt;\n&lt;body&gt;\n    &lt;h2&gt;ESP Output Control&lt;\/h2&gt;\n    &lt;?php echo $html_buttons; ?&gt;\n    &lt;br&gt;&lt;br&gt;\n    &lt;?php echo $html_boards; ?&gt;\n    &lt;br&gt;&lt;br&gt;\n    &lt;div&gt;&lt;form onsubmit=&quot;return createOutput();&quot;&gt;\n        &lt;h3&gt;Create New Output&lt;\/h3&gt;\n        &lt;label for=&quot;outputName&quot;&gt;Name&lt;\/label&gt;\n        &lt;input type=&quot;text&quot; name=&quot;name&quot; id=&quot;outputName&quot;&gt;&lt;br&gt;\n        &lt;label for=&quot;outputBoard&quot;&gt;Board ID&lt;\/label&gt;\n        &lt;input type=&quot;number&quot; name=&quot;board&quot; min=&quot;0&quot; id=&quot;outputBoard&quot;&gt;\n        &lt;label for=&quot;outputGpio&quot;&gt;GPIO Number&lt;\/label&gt;\n        &lt;input type=&quot;number&quot; name=&quot;gpio&quot; min=&quot;0&quot; id=&quot;outputGpio&quot;&gt;\n        &lt;label for=&quot;outputState&quot;&gt;Initial GPIO State&lt;\/label&gt;\n        &lt;select id=&quot;outputState&quot; name=&quot;state&quot;&gt;\n          &lt;option value=&quot;0&quot;&gt;0 = OFF&lt;\/option&gt;\n          &lt;option value=&quot;1&quot;&gt;1 = ON&lt;\/option&gt;\n        &lt;\/select&gt;\n        &lt;input type=&quot;submit&quot; value=&quot;Create Output&quot;&gt;\n        &lt;p&gt;&lt;strong&gt;Note:&lt;\/strong&gt; in some devices, you might need to refresh the page to see your newly created buttons or to remove deleted buttons.&lt;\/p&gt;\n    &lt;\/form&gt;&lt;\/div&gt;\n\n    &lt;script&gt;\n        function updateOutput(element) {\n            var xhr = new XMLHttpRequest();\n            if(element.checked){\n                xhr.open(&quot;GET&quot;, &quot;esp-outputs-action.php?action=output_update&amp;id=&quot;+element.id+&quot;&amp;state=1&quot;, true);\n            }\n            else {\n                xhr.open(&quot;GET&quot;, &quot;esp-outputs-action.php?action=output_update&amp;id=&quot;+element.id+&quot;&amp;state=0&quot;, true);\n            }\n            xhr.send();\n        }\n\n        function deleteOutput(element) {\n            var result = confirm(&quot;Want to delete this output?&quot;);\n            if (result) {\n                var xhr = new XMLHttpRequest();\n                xhr.open(&quot;GET&quot;, &quot;esp-outputs-action.php?action=output_delete&amp;id=&quot;+element.id, true);\n                xhr.send();\n                alert(&quot;Output deleted&quot;);\n                setTimeout(function(){ window.location.reload(); });\n            }\n        }\n\n        function createOutput(element) {\n            var xhr = new XMLHttpRequest();\n            xhr.open(&quot;POST&quot;, &quot;esp-outputs-action.php&quot;, true);\n\n            xhr.setRequestHeader(&quot;Content-Type&quot;, &quot;application\/x-www-form-urlencoded&quot;);\n\n            xhr.onreadystatechange = function() {\n                if (this.readyState === XMLHttpRequest.DONE &amp;&amp; this.status === 200) {\n                    alert(&quot;Output created&quot;);\n                    setTimeout(function(){ window.location.reload(); });\n                }\n            }\n            var outputName = document.getElementById(&quot;outputName&quot;).value;\n            var outputBoard = document.getElementById(&quot;outputBoard&quot;).value;\n            var outputGpio = document.getElementById(&quot;outputGpio&quot;).value;\n            var outputState = document.getElementById(&quot;outputState&quot;).value;\n            var httpRequestData = &quot;action=output_create&amp;name=&quot;+outputName+&quot;&amp;board=&quot;+outputBoard+&quot;&amp;gpio=&quot;+outputGpio+&quot;&amp;state=&quot;+outputState;\n            xhr.send(httpRequestData);\n        }\n    &lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/master\/Code\/esp-outputs.php\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>If you try to access your domain name in the following URL path, you&#8217;ll see the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;example.com\/esp-outputs.php<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"928\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp32-esp8266-gpios-from-anywhere-f.png?resize=750%2C928&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Output Control Default Button and Board\" class=\"wp-image-129695\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp32-esp8266-gpios-from-anywhere-f.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp32-esp8266-gpios-from-anywhere-f.png?resize=242%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 242w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>That&#8217;s it! You should see that web page with your default button. The default button is called <strong>Built-in LED<\/strong>, it&#8217;s assigned to <strong>Board 1<\/strong> and controls <strong>GPIO 2<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"set-up-esp8266-esp32\">7. Setting Up the ESP32 or ESP8266<\/h2>\n\n\n\n<p>This project is compatible with both the ESP32 and ESP8266 boards. You just need to assemble a simple circuit and upload the sketches provided.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/08\/esp32-vs-esp8266-devlopment-boards.jpg?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 vs ESP8266 Development Boards\"\/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Parts Required<\/h3>\n\n\n\n<p>To test this project, we&#8217;ll connect some LEDs to the ESP32 and ESP8266 GPIOs. Here&#8217;s a list of parts you need to build the circuit for this project:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\">ESP32 board<\/a>&nbsp;(read <a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/esp32-development-boards-review-comparison\/\" target=\"_blank\">Best ESP32 dev boards<\/a>)<\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp8266-esp-12e-nodemcu-wi-fi-development-board\/\" target=\"_blank\">ESP8266 board<\/a> (read <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\">Best ESP8266 dev boards<\/a>)<\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/3mm-5mm-leds-kit-storage-box\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"5x LEDs\u2028 (opens in a new tab)\">5x LEDs<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/resistors-kits\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"5x 220 Ohm resistors\u2028 (opens in a new tab)\">5x 220 Ohm resistors<\/a><\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\">Jumper wires<\/a><\/li>\n\n\n\n<li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\">Breadboard<\/a><\/li>\n<\/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<h3 class=\"wp-block-heading\">Schematics<\/h3>\n\n\n\n<p>For this example, we\u2019ll use an ESP32 board with 3 LEDs and an ESP8266 with 2 LEDs. Instead of LEDs, you can connect a relay module or any other device to the ESP GPIOs.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-relay-module-ac-web-server\/\">Relay module with ESP32<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp8266-relay-module-ac-web-server\/\">Relay module with ESP8266<\/a><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">LEDs wiring to ESP32 &#8211; Board #1<\/h4>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Control-LEDs-GPIOs-from-anywhere.png?resize=535%2C683&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Control LEDs GPIOs from anywhere circuit schematic diagram\" class=\"wp-image-93164\" width=\"535\" height=\"683\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Control-LEDs-GPIOs-from-anywhere.png?w=814&amp;quality=100&amp;strip=all&amp;ssl=1 814w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Control-LEDs-GPIOs-from-anywhere.png?resize=235%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 235w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Control-LEDs-GPIOs-from-anywhere.png?resize=801%2C1024&amp;quality=100&amp;strip=all&amp;ssl=1 801w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Control-LEDs-GPIOs-from-anywhere.png?resize=768%2C981&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 535px) 100vw, 535px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>Recommended reading:<\/strong> <a href=\"https:\/\/randomnerdtutorials.com\/esp32-pinout-reference-gpios\/\">which ESP32 GPIOs should you use.<\/a><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">LEDs wiring to ESP8266 &#8211; Board #2<\/h4>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP8266-Control-LEDs-GPIOs-from-anywhere.png?resize=430%2C643&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP8266 Control LEDs GPIOs from anywhere circuit schematic diagram\" class=\"wp-image-93168\" width=\"430\" height=\"643\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP8266-Control-LEDs-GPIOs-from-anywhere.png?w=588&amp;quality=100&amp;strip=all&amp;ssl=1 588w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP8266-Control-LEDs-GPIOs-from-anywhere.png?resize=200%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 200w\" sizes=\"(max-width: 430px) 100vw, 430px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>Recommended reading:<\/strong> <a href=\"https:\/\/randomnerdtutorials.com\/esp8266-pinout-reference-gpios\/\">which ESP8266 GPIOs should you use.<\/a> <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ESP32 Code &#8211; Board #1<\/h3>\n\n\n\n<p>We\u2019ll program the ESP32\/ESP8266 using Arduino IDE, so you must have the ESP add-on installed in your Arduino IDE. <\/p>\n\n\n\n<p>Follow one of the next tutorials depending on the board you&#8217;re using:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-the-esp32-board-in-arduino-ide-windows-instructions\/\">Install the ESP32 Board in Arduino IDE<\/a><\/li>\n\n\n\n<li><a style=\"font-size: inherit; background-color: initial;\" href=\"https:\/\/randomnerdtutorials.com\/how-to-install-esp8266-board-arduino-ide\/\">Install the ESP8266 Board in Arduino IDE<\/a><\/li>\n<\/ul>\n\n\n\n<p>You also need to install the <a rel=\"noreferrer noopener\" aria-label=\"Arduino_JSON library (opens in a new tab)\" href=\"http:\/\/github.com\/arduino-libraries\/Arduino_JSON\" target=\"_blank\">Arduino_JSON library<\/a>. You can install this library in the Arduino IDE Library Manager. Just go to <strong>Sketch <\/strong>&gt; <strong>Include Library<\/strong> &gt; <strong>Manage Libraries &#8230;<\/strong> and search for the library name as follows:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"443\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Install-Arduino-JSON-library-Arduino-IDE.png?resize=786%2C443&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install Arduino JSON library Arduino IDE\" class=\"wp-image-93172\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Install-Arduino-JSON-library-Arduino-IDE.png?w=786&amp;quality=100&amp;strip=all&amp;ssl=1 786w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Install-Arduino-JSON-library-Arduino-IDE.png?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Install-Arduino-JSON-library-Arduino-IDE.png?resize=768%2C433&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/figure><\/div>\n\n\n<p>After installing the necessary board add-ons and libraries, copy the following code to your Arduino IDE, but don\u2019t upload it yet. You need to make some changes to make it work for you.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\r\n  Rui Santos\r\n  Complete project details at https:\/\/RandomNerdTutorials.com\/control-esp32-esp8266-gpios-from-anywhere\/\r\n  \r\n  Permission is hereby granted, free of charge, to any person obtaining a copy\r\n  of this software and associated documentation files.\r\n  \r\n  The above copyright notice and this permission notice shall be included in all\r\n  copies or substantial portions of the Software.\r\n*\/\r\n\r\n#include &lt;WiFi.h&gt;\r\n#include &lt;HTTPClient.h&gt;\r\n#include &lt;WiFiClientSecure.h&gt;\r\n#include &lt;Arduino_JSON.h&gt;\r\n\r\nconst char* ssid = &quot;REPLACE_WITH_YOUR_SSID&quot;;\r\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\r\n\r\n\/\/Your IP address or domain name with URL path\r\nconst char* serverName = &quot;https:\/\/example.com\/esp-outputs-action.php?action=outputs_state&amp;board=1&quot;;\r\n\r\n\/\/ Update interval time set to 5 seconds\r\nconst long interval = 5000;\r\nunsigned long previousMillis = 0;\r\n\r\nString outputsState;\r\n\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  \r\n  WiFi.begin(ssid, password);\r\n  Serial.println(&quot;Connecting&quot;);\r\n  while(WiFi.status() != WL_CONNECTED) { \r\n    delay(500);\r\n    Serial.print(&quot;.&quot;);\r\n  }\r\n  Serial.println(&quot;&quot;);\r\n  Serial.print(&quot;Connected to WiFi network with IP Address: &quot;);\r\n  Serial.println(WiFi.localIP());\r\n}\r\n\r\nvoid loop() {\r\n  unsigned long currentMillis = millis();\r\n  \r\n  if(currentMillis - previousMillis &gt;= interval) {\r\n     \/\/ Check WiFi connection status\r\n    if(WiFi.status()== WL_CONNECTED ){ \r\n      outputsState = httpGETRequest(serverName);\r\n      Serial.println(outputsState);\r\n      JSONVar myObject = JSON.parse(outputsState);\r\n  \r\n      \/\/ JSON.typeof(jsonVar) can be used to get the type of the var\r\n      if (JSON.typeof(myObject) == &quot;undefined&quot;) {\r\n        Serial.println(&quot;Parsing input failed!&quot;);\r\n        return;\r\n      }\r\n    \r\n      Serial.print(&quot;JSON object = &quot;);\r\n      Serial.println(myObject);\r\n    \r\n      \/\/ myObject.keys() can be used to get an array of all the keys in the object\r\n      JSONVar keys = myObject.keys();\r\n    \r\n      for (int i = 0; i &lt; keys.length(); i++) {\r\n        JSONVar value = myObject[keys[i]];\r\n        Serial.print(&quot;GPIO: &quot;);\r\n        Serial.print(keys[i]);\r\n        Serial.print(&quot; - SET to: &quot;);\r\n        Serial.println(value);\r\n        pinMode(atoi(keys[i]), OUTPUT);\r\n        digitalWrite(atoi(keys[i]), atoi(value));\r\n      }\r\n      \/\/ save the last HTTP GET Request\r\n      previousMillis = currentMillis;\r\n    }\r\n    else {\r\n      Serial.println(&quot;WiFi Disconnected&quot;);\r\n    }\r\n  }\r\n}\r\n\r\nString httpGETRequest(const char* serverName) {\r\n  WiFiClientSecure *client = new WiFiClientSecure;\r\n  \r\n  \/\/ set secure client without certificate\r\n  client-&gt;setInsecure();\r\n  HTTPClient https;\r\n    \r\n  \/\/ Your IP address with path or Domain name with URL path \r\n  https.begin(*client, serverName);\r\n  \r\n  \/\/ Send HTTP POST request\r\n  int httpResponseCode = https.GET();\r\n  \r\n  String payload = &quot;{}&quot;; \r\n  \r\n  if (httpResponseCode&gt;0) {\r\n    Serial.print(&quot;HTTP Response code: &quot;);\r\n    Serial.println(httpResponseCode);\r\n    payload = https.getString();\r\n  }\r\n  else {\r\n    Serial.print(&quot;Error code: &quot;);\r\n    Serial.println(httpResponseCode);\r\n  }\r\n  \/\/ Free resources\r\n  https.end();\r\n\r\n  return payload;\r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/raw\/master\/Code\/HTTPS_ESP32_GET_Request_JSON.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p><strong>Note:&nbsp;<\/strong>Most servers require you to make HTTPS requests. The code above makes HTTPS requests to be compliant with the requirements of most cloud servers nowadays.<\/p>\n\n\n\n<p class=\"rntbox rntclgray\">Your server doesn\u2019t support HTTPS?\u00a0<a href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/ESP32_HTTP_GET_Request_JSON.ino.ino\" target=\"_blank\" rel=\"noopener\" title=\"\">Use this code instead<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Setting your network credentials<\/h4>\n\n\n\n<p>You need to modify the following lines with your network credentials: SSID and password. The code is well commented on where you should make the changes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Replace with your network credentials\nconst char* ssid     = \"REPLACE_WITH_YOUR_SSID\";\nconst char* password = \"REPLACE_WITH_YOUR_PASSWORD\";<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Setting your serverName<\/h4>\n\n\n\n<p>You also need to type your domain name, so the ESP makes the HTTP GET request to your own server.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char* serverName = \"https:\/\/example.com\/esp-outputs-action.php?action=outputs_state&amp;board=1\";<\/code><\/pre>\n\n\n\n<p>Notice that on the URL <span class=\"rnthl rntliteral\">serverName<\/span> we have a parameter <span class=\"rnthl rntliteral\">board=1<\/span>. This indicates the board ID. If you want to add more boards, you should change that ID. That identifies the board you want to control.<\/p>\n\n\n\n<p>Now, you can upload the code to your board. It should work straight away.<\/p>\n\n\n\n<p>This project is already quite long, so we won&#8217;t cover how the code works. In summary, your ESP32 makes an HTTP GET request to your server every X number of seconds to update the GPIOs states (by default it&#8217;s set to 5 seconds).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const long interval = 5000;<\/code><\/pre>\n\n\n\n<p>Then, the board will update its outputs accordingly to the request response.<\/p>\n\n\n\n<p>Open your Serial Monitor and you should see something similar:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"859\" height=\"525\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Arduino-IDE-Serial-Monitor-Example.png?resize=859%2C525&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Arduino IDE Serial Monitor Example\" class=\"wp-image-93173\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Arduino-IDE-Serial-Monitor-Example.png?w=859&amp;quality=100&amp;strip=all&amp;ssl=1 859w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Arduino-IDE-Serial-Monitor-Example.png?resize=300%2C183&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-Arduino-IDE-Serial-Monitor-Example.png?resize=768%2C469&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 859px) 100vw, 859px\" \/><\/figure><\/div>\n\n\n<p>The request retrieves a JSON object that contains the GPIO number and its state. In this case, it tells us that GPIO 2 should be LOW <span class=\"rnthl rntliteral\">{&#8220;2&#8243;:&#8221;0&#8221;}<\/span>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ESP8266 Code &#8211; Board #2<\/h3>\n\n\n\n<p>For this example, we&#8217;re controlling the outputs from two boards simultaneously. You can use next code for your ESP8266 board:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\r\n  Rui Santos\r\n  Complete project details at https:\/\/RandomNerdTutorials.com\/control-esp32-esp8266-gpios-from-anywhere\/\r\n  \r\n  Permission is hereby granted, free of charge, to any person obtaining a copy\r\n  of this software and associated documentation files.\r\n  \r\n  The above copyright notice and this permission notice shall be included in all\r\n  copies or substantial portions of the Software.\r\n*\/\r\n\r\n#include &lt;ESP8266WiFi.h&gt;\r\n#include &lt;ESP8266HTTPClient.h&gt;\r\n#include &lt;WiFiClientSecureBearSSL.h&gt;\r\n#include &lt;Arduino_JSON.h&gt;\r\n\r\nconst char* ssid = &quot;REPLACE_WITH_YOUR_SSID&quot;;\r\nconst char* password = &quot;REPLACE_WITH_YOUR_PASSWORD&quot;;\r\n\r\n\/\/Your IP address or domain name with URL path\r\n\/\/const char* serverName = &quot;https:\/\/example.com\/esp-outputs-action.php?action=outputs_state&amp;board=1&quot;;\r\n\r\n\/\/ Update interval time set to 5 seconds\r\nconst long interval = 5000;\r\nunsigned long previousMillis = 0;\r\n\r\nString outputsState;\r\n\r\nvoid setup() {\r\n  Serial.begin(115200);\r\n  \r\n  WiFi.begin(ssid, password);\r\n  Serial.println(&quot;Connecting&quot;);\r\n  while(WiFi.status() != WL_CONNECTED) { \r\n    delay(500);\r\n    Serial.print(&quot;.&quot;);\r\n  }\r\n  Serial.println(&quot;&quot;);\r\n  Serial.print(&quot;Connected to WiFi network with IP Address: &quot;);\r\n  Serial.println(WiFi.localIP());\r\n}\r\n\r\nvoid loop() {\r\n  unsigned long currentMillis = millis();\r\n  \r\n  if(currentMillis - previousMillis &gt;= interval) {\r\n     \/\/ Check WiFi connection status\r\n    if(WiFi.status()== WL_CONNECTED ){ \r\n      outputsState = httpGETRequest(serverName);\r\n      Serial.println(outputsState);\r\n      JSONVar myObject = JSON.parse(outputsState);\r\n  \r\n      \/\/ JSON.typeof(jsonVar) can be used to get the type of the var\r\n      if (JSON.typeof(myObject) == &quot;undefined&quot;) {\r\n        Serial.println(&quot;Parsing input failed!&quot;);\r\n        return;\r\n      }\r\n    \r\n      Serial.print(&quot;JSON object = &quot;);\r\n      Serial.println(myObject);\r\n    \r\n      \/\/ myObject.keys() can be used to get an array of all the keys in the object\r\n      JSONVar keys = myObject.keys();\r\n    \r\n      for (int i = 0; i &lt; keys.length(); i++) {\r\n        JSONVar value = myObject[keys[i]];\r\n        Serial.print(&quot;GPIO: &quot;);\r\n        Serial.print(keys[i]);\r\n        Serial.print(&quot; - SET to: &quot;);\r\n        Serial.println(value);\r\n        pinMode(atoi(keys[i]), OUTPUT);\r\n        digitalWrite(atoi(keys[i]), atoi(value));\r\n      }\r\n      \/\/ save the last HTTP GET Request\r\n      previousMillis = currentMillis;\r\n    }\r\n    else {\r\n      Serial.println(&quot;WiFi Disconnected&quot;);\r\n    }\r\n  }\r\n}\r\n\r\nString httpGETRequest(const char* serverName) {\r\n  std::unique_ptr&lt;BearSSL::WiFiClientSecure&gt;client(new BearSSL::WiFiClientSecure);\r\n\r\n  \/\/ Ignore SSL certificate validation\r\n  client-&gt;setInsecure();\r\n\r\n  HTTPClient https;\r\n    \r\n  \/\/ Your IP address with path or Domain name with URL path \r\n  https.begin(*client, serverName);\r\n  \r\n  \/\/ Send HTTP POST request\r\n  int httpResponseCode = https.GET();\r\n  \r\n  String payload = &quot;{}&quot;; \r\n  \r\n  if (httpResponseCode&gt;0) {\r\n    Serial.print(&quot;HTTP Response code: &quot;);\r\n    Serial.println(httpResponseCode);\r\n    payload = https.getString();\r\n  }\r\n  else {\r\n    Serial.print(&quot;Error code: &quot;);\r\n    Serial.println(httpResponseCode);\r\n  }\r\n  \/\/ Free resources\r\n  https.end();\r\n\r\n  return payload;\r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/raw\/master\/Code\/HTTPS_ESP8266_GET_Request_JSON.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>To prepare the code for your ESP8266, just enter the SSID, password, domain name, and board ID (in this case, it\u2019s board ID number 2).<\/p>\n\n\n\n<p><strong>Note:&nbsp;<\/strong>Most servers require you to make HTTPS requests. The code above makes HTTPS requests to be compliant with the requirements of most cloud servers nowadays.<\/p>\n\n\n\n<p class=\"rntbox rntclgray\">Your server doesn\u2019t support HTTPS?\u00a0<a href=\"https:\/\/github.com\/RuiSantosdotme\/control-esp32-esp8266-gpios-from-anywhere\/blob\/master\/Code\/ESP8266_HTTP_GET_Request_JSON.ino.ino\" target=\"_blank\" rel=\"noopener\" title=\"\">Use this code instead<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>After completing all the steps, power both your ESP boards.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-Anywhere-circuit-schematic-diagram.jpg?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Control GPIOs from Anywhere circuit schematic diagram\" class=\"wp-image-93165\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-Anywhere-circuit-schematic-diagram.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-Anywhere-circuit-schematic-diagram.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<p>If you open your domain name in this URL path:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;example.com\/esp-outputs.php<\/code><\/pre>\n\n\n\n<p>You should see the default button in your Dashboard:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"928\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp32-esp8266-gpios-from-anywhere-f.png?resize=750%2C928&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Output Control Default Button and Board\" class=\"wp-image-129695\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp32-esp8266-gpios-from-anywhere-f.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp32-esp8266-gpios-from-anywhere-f.png?resize=242%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 242w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>If you press that button on and off, you should be able to control GPIO 2 from your ESP32 &#8211; Board #1.<\/p>\n\n\n\n<p>You can add more buttons to your project, type a name (<strong>LED 2<\/strong>), set board the id to number <strong>1<\/strong>, then type the desired GPIO that you want to control (<strong>33<\/strong>).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"599\" height=\"526\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-Dashoard-switches-buttons-to-control-ESP32-ESP8266-GPIOs.png?resize=599%2C526&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Create Dashoard switches buttons to control ESP32 ESP8266 GPIOs\" class=\"wp-image-93161\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-Dashoard-switches-buttons-to-control-ESP32-ESP8266-GPIOs.png?w=599&amp;quality=100&amp;strip=all&amp;ssl=1 599w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Create-Dashoard-switches-buttons-to-control-ESP32-ESP8266-GPIOs.png?resize=300%2C263&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 599px) 100vw, 599px\" \/><\/figure><\/div>\n\n\n<p>Create another button for <strong>Board 1<\/strong> to control <strong>GPIO 32<\/strong>. Then, add two buttons for <strong>Board 2<\/strong> (<strong>GPIO 2<\/strong> and <strong>GPIO 4<\/strong>).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"702\" height=\"753\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp-gpios-from-anywhere-multiple-boards-f.png?resize=702%2C753&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Output Control Default Button and Board\" class=\"wp-image-129694\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp-gpios-from-anywhere-multiple-boards-f.png?w=702&amp;quality=100&amp;strip=all&amp;ssl=1 702w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-esp-gpios-from-anywhere-multiple-boards-f.png?resize=280%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 280w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/figure><\/div>\n\n\n<p>At any point in time, you can use the delete link to remove buttons from your Dashboard or use the form at the bottom to create more.<\/p>\n\n\n\n<p><strong>Note: <\/strong> in some devices, you might need to refresh the page to see your newly created buttons or to remove deleted buttons.<\/p>\n\n\n\n<p>Finally, there\u2019s a section that shows the last time a board made a request and updated its outputs.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"409\" height=\"135\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-gpios-anywhere-last-request-esp32-esp8266.png?resize=409%2C135&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-129693\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-gpios-anywhere-last-request-esp32-esp8266.png?w=409&amp;quality=100&amp;strip=all&amp;ssl=1 409w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/control-gpios-anywhere-last-request-esp32-esp8266.png?resize=300%2C99&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 409px) 100vw, 409px\" \/><\/figure><\/div>\n\n\n<p>Since this is not a two-way communication, when you press the buttons to control your outputs, your board doesn\u2019t update the outputs instantly. It will take a few seconds for your ESP board to make a new HTTP GET request and update its output states. With the <strong>Last Request Time<\/strong> section, you can see when that happened. Just refresh the page to see the updated values.<\/p>\n\n\n\n<p>The web page is also mobile responsive, so you can use any device to access your server.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-ESP32-ESP8266-GPIOs-from-Anywhere-in-the-World-dashboard-demo.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control ESP32 ESP8266 GPIOs from Anywhere in the World dashboard demonstration\" class=\"wp-image-93159\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-ESP32-ESP8266-GPIOs-from-Anywhere-in-the-World-dashboard-demo.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/Control-ESP32-ESP8266-GPIOs-from-Anywhere-in-the-World-dashboard-demo.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial you&#8217;ve learned how to control your ESP32 and ESP8266 outputs from anywhere in the world. This requires that you have your own <a rel=\"noreferrer noopener\" aria-label=\"server and domain name (opens in a new tab)\" href=\"https:\/\/randomnerdtutorials.com\/bluehost\" target=\"_blank\">server and domain name<\/a> (alternatively, you can use a <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-raspberry-pi-lamp-server\/\">Raspberry Pi LAMP Server for local access<\/a>).<\/p>\n\n\n\n<p>There are many other features that you can add to your server, you can merge it with our previous projects to <a href=\"https:\/\/randomnerdtutorials.com\/cloud-weather-station-esp32-esp8266\/\">display sensor readings<\/a>. Feel free to add more ESP boards to run simultaneously and define other outputs to control.<\/p>\n\n\n\n<p>I encourage you to change the web page appearance, add more features <a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-send-email-notification\/\">like email notifications<\/a>, publish data from different sensors, use multiple ESP boards, and much more.<\/p>\n\n\n\n<p><strong>You might also like reading:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/cloud-weather-station-esp32-esp8266\/\">DIY Cloud Weather Station with ESP32\/ESP8266 (MySQL Database and PHP)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-send-email-notification\/\">ESP32\/ESP8266 Send Email Notification using PHP Script<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/visualize-esp32-esp8266-sensor-readings-from-anywhere\/\">Visualize Your Sensor Readings from Anywhere in the World (ESP32\/ESP8266 + MySQL + PHP) using Charts<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/firebase-control-esp32-gpios\/\">Firebase: Control ESP32 GPIOs from Anywhere<\/a><\/li>\n<\/ul>\n\n\n\n<p>Learn more about the ESP32 and ESP8266 with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/home-automation-using-esp8266\/\">Home Automation using ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/build-web-servers-esp32-esp8266-ebook\/\">Build Web Servers with ESP32 and ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/firebase-esp32-esp8266-ebook\/\">Firebase Web App with ESP32 and ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/smart-home-ebook\/\">SMART HOME with Raspberry Pi, ESP32, and ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\">Free ESP32 Projects and Tutorials\u2026<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp8266\/\">Free ESP8266 Projects and Tutorials\u2026<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thank you for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this project, you&#8217;ll learn how to control your ESP32 or ESP8266 GPIOs from anywhere in the world. This can be very useful to control a relay, a thermostat, or &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Control ESP32 and ESP8266 GPIOs from Anywhere in the World\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/control-esp32-esp8266-gpios-from-anywhere\/#more-93152\" aria-label=\"Read more about Control ESP32 and ESP8266 GPIOs from Anywhere in the World\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":129701,"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":[276,281,277,299,264],"tags":[],"class_list":["post-93152","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32","category-esp32-project","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32-ESP8266-Control-GPIOs-from-anywhere-cloud-php.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\/93152","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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=93152"}],"version-history":[{"count":6,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/93152\/revisions"}],"predecessor-version":[{"id":129704,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/93152\/revisions\/129704"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/129701"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=93152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=93152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=93152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}