Control ESP32 and ESP8266 GPIOs from Anywhere in the World

In this project you’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.

Control ESP32 and ESP8266 GPIOs from Anywhere in the World

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.

Previously, we’ve stored sensor readings into a database and we’ve used different methods to display sensor readings on a:

Now, I’ve 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.

There are many ways of controlling outputs from anywhere, and even though this a working solution there are other methods that provide a two way communication with your devices. I also recommend that you take this project further and add more features to fit your own needs.

To build this project, you’ll use these technologies:

  • ESP32 or ESP8266 programmed with Arduino IDE
  • Hosting server and domain name
  • PHP scripts to store and retrieve the output states stored in a MySQL database

Watch the Video Demonstration

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

0. Download Source Code

For this project, you’ll need these files:

1. Hosting Your PHP Application and MySQL Database

The goal of this project is to have your own domain name and hosting account that allows you control your ESP32 or ESP8266 GPIOs from anywhere in the world.

Here’s a high level overview on how the projects works:

Control outputs from anywhere project overview
  1. You have a web page running a PHP script with some toggle buttons that allow you to control the outputs on and off;
  2. When you press the buttons, it updates the output state and saves it in your database;
  3. You can add more buttons or delete them from your dashboard;
  4. 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;
  5. Finally, according to the result of that HTTP GET request, the ESP board updates its GPIOs accordingly.

Hosting Services

I recommend using one of the following hosting services that can handle all the project requirements:

  • Bluehost (user-friendly with cPanel): free domain name when you sign up for the 3-year plan. I recommend choosing the unlimited websites option;
  • Digital Ocean: Linux server that you manage through a command line. I only recommended this option for advanced users.

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’t have a hosting account, I recommend signing up for Bluehost.

Get Hosting and Domain Name with Bluehost »

When buying a hosting account, you’ll also have to purchase a domain name. This is what makes this project interesting: you’ll be able to go your domain name (http://example.com) and control your boards.

If you like our projects, you might consider signing up to one of the recommended hosting services, because you’ll be supporting our work.

Note: you can also run a LAMP (Linux, Apache, MySQL, PHP) server on a Raspberry Pi to control your boards in your local network. 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.

2. Preparing Your MySQL Database

After signing up for a hosting account and setting up a domain name, you can login to your cPanel or similar dashboard. After that, follow the next steps to create your database, username, password and SQL table.

Creating a database and user

Open the “Advanced” tab:

Bluehost Advanced tab

1. Type “database” in the search bar and select “MySQL Database Wizard”.

CPanel select MySQL database wizard to create db

2. Enter your desired Database name. In my case, the database name is esp_data. Then, press the “Next Step” button:

ESP32 ESP8266 CPanel Create MySQL Database

Note: later you’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’ll refer to it as example_esp_data from now on.

3. Type your Database username and set a password. You must save all those details, because you’ll need them later to establish a database connection with your PHP code.

ESP32 ESP8266 CPanel Create MySQL Database User and Password

That’s it! Your new database and user were created successfully. Now, save all your details because you’ll need them later:

  • Database name: example_esp_data
  • Username: example_esp_board
  • Password: your password

Creating a SQL table

After creating your database and user, go back to cPanel dashboard and search for “phpMyAdmin”.

ESP32 ESP8266 CPanel Open PHPMyAdmin

In the left sidebar, select your database name example_esp_data and open the “SQL” tab.

ESP32 ESP8266 PHPMyAdmin Open Database

Important: make sure you’ve opened the example_esp_data database. Then, click the SQL tab. If you don’t follow these exact steps and run the SQL query, you might create a table in the wrong database.

Copy the SQL query in the following snippet:

CREATE TABLE Outputs (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(64),
    board INT(6),
    gpio INT(6),
    state INT(6)
);
INSERT INTO `Outputs`(`name`, `board`, `gpio`, `state`) VALUES ("Built-in LED", 1, 2, 0);

CREATE TABLE Boards (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    board INT(6),
    last_request TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
INSERT INTO `Boards`(`board`) VALUES (1);

View raw code

Paste it in the SQL query field (highlighted with a red rectangle) and press the “Go” button to create your table:

Create MySQL Tables for control ESP32 ESP8266 GPIOs Dashboard

After that, you should see your newly created tables called Boards and Outputs in the example_esp_data database as shown in the figure below:

MySQL Tables created for control ESP32 ESP8266 GPIOs Dashboard

3. Creating Your Dashboard Files

In this section, we’re going to create the files that are responsible for creating your Dashboard. Here are the files:

If you’re using a hosting provider with cPanel, you can search for “File Manager”:

ESP32 ESP8266 CPanel Open Edit PHP Files with File Manager

Then, select the public_html option and press the “+ File” button to create a new file.

ESP32 ESP8266 CPanel Create New PHP File

Note: if you’re following this tutorial and you’re not familiar with PHP, I recommend creating these exact files.

Create four new files in /public_html with these exact names and extensions:

  • esp-database.php
  • esp-outputs-action.php
  • esp-outputs.php
  • esp-style.css
Create PHP files for control ESP32 ESP8266 GPIOs Dashboard

4. PHP Script – Update and Retrieve Output States

In this section, we’re going to create a PHP script that is responsible for receiving incoming requests and interacting with your MySQL database.

Edit the newly created file (esp-outputs-action.php) and copy the following snippet:

<?php
    include_once('esp-database.php');

    $action = $id = $name = $gpio = $state = "";

    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $action = test_input($_POST["action"]);
        if ($action == "output_create") {
            $name = test_input($_POST["name"]);
            $board = test_input($_POST["board"]);
            $gpio = test_input($_POST["gpio"]);
            $state = test_input($_POST["state"]);
            $result = createOutput($name, $board, $gpio, $state);

            $result2 = getBoard($board);
            if(!$result2->fetch_assoc()) {
                createBoard($board);
            }
            echo $result;
        }
        else {
            echo "No data posted with HTTP POST.";
        }
    }

    if ($_SERVER["REQUEST_METHOD"] == "GET") {
        $action = test_input($_GET["action"]);
        if ($action == "outputs_state") {
            $board = test_input($_GET["board"]);
            $result = getAllOutputStates($board);
            if ($result) {
                while ($row = $result->fetch_assoc()) {
                    $rows[$row["gpio"]] = $row["state"];
                }
            }
            echo json_encode($rows);
            $result = getBoard($board);
            if($result->fetch_assoc()) {
                updateLastBoardTime($board);
            }
        }
        else if ($action == "output_update") {
            $id = test_input($_GET["id"]);
            $state = test_input($_GET["state"]);
            $result = updateOutput($id, $state);
            echo $result;
        }
        else if ($action == "output_delete") {
            $id = test_input($_GET["id"]);
            $board = getOutputBoardById($id);
            if ($row = $board->fetch_assoc()) {
                $board_id = $row["board"];
            }
            $result = deleteOutput($id);
            $result2 = getAllOutputStates($board_id);
            if(!$result2->fetch_assoc()) {
                deleteBoard($board_id);
            }
            echo $result;
        }
        else {
            echo "Invalid HTTP request.";
        }
    }

    function test_input($data) {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
    }
?>

View raw code

5. PHP Script for Database Functions

Edit your file esp-database.php that inserts, deletes, and retrieves data. Copy the next PHP script:

<?php
    $servername = "localhost";
    // Your Database name
    $dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
    // Your Database user
    $username = "REPLACE_WITH_YOUR_USERNAME";
    // Your Database user password
    $password = "REPLACE_WITH_YOUR_PASSWORD";

    function createOutput($name, $board, $gpio, $state) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "INSERT INTO Outputs (name, board, gpio, state)
        VALUES ('" . $name . "', '" . $board . "', '" . $gpio . "', '" . $state . "')";

       if ($conn->query($sql) === TRUE) {
            return "New output created successfully";
        }
        else {
            return "Error: " . $sql . "<br>" . $conn->error;
        }
        $conn->close();
    }

    function deleteOutput($id) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "DELETE FROM Outputs WHERE id='". $id .  "'";

       if ($conn->query($sql) === TRUE) {
            return "Output deleted successfully";
        }
        else {
            return "Error: " . $sql . "<br>" . $conn->error;
        }
        $conn->close();
    }

    function updateOutput($id, $state) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "UPDATE Outputs SET state='" . $state . "' WHERE id='". $id .  "'";

       if ($conn->query($sql) === TRUE) {
            return "Output state updated successfully";
        }
        else {
            return "Error: " . $sql . "<br>" . $conn->error;
        }
        $conn->close();
    }

    function getAllOutputs() {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "SELECT id, name, board, gpio, state FROM Outputs ORDER BY board";
        if ($result = $conn->query($sql)) {
            return $result;
        }
        else {
            return false;
        }
        $conn->close();
    }

    function getAllOutputStates($board) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "SELECT gpio, state FROM Outputs WHERE board='" . $board . "'";
        if ($result = $conn->query($sql)) {
            return $result;
        }
        else {
            return false;
        }
        $conn->close();
    }

    function getOutputBoardById($id) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "SELECT board FROM Outputs WHERE id='" . $id . "'";
        if ($result = $conn->query($sql)) {
            return $result;
        }
        else {
            return false;
        }
        $conn->close();
    }

    function updateLastBoardTime($board) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "UPDATE Boards SET last_request=now() WHERE board='". $board .  "'";

       if ($conn->query($sql) === TRUE) {
            return "Output state updated successfully";
        }
        else {
            return "Error: " . $sql . "<br>" . $conn->error;
        }
        $conn->close();
    }

    function getAllBoards() {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "SELECT board, last_request FROM Boards ORDER BY board";
        if ($result = $conn->query($sql)) {
            return $result;
        }
        else {
            return false;
        }
        $conn->close();
    }

    function getBoard($board) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "SELECT board, last_request FROM Boards WHERE board='" . $board . "'";
        if ($result = $conn->query($sql)) {
            return $result;
        }
        else {
            return false;
        }
        $conn->close();
    }

    function createBoard($board) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "INSERT INTO Boards (board) VALUES ('" . $board . "')";

       if ($conn->query($sql) === TRUE) {
            return "New board created successfully";
        }
        else {
            return "Error: " . $sql . "<br>" . $conn->error;
        }
        $conn->close();
    }

    function deleteBoard($board) {
        global $servername, $username, $password, $dbname;

        // Create connection
        $conn = new mysqli($servername, $username, $password, $dbname);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        }

        $sql = "DELETE FROM Boards WHERE board='". $board .  "'";

       if ($conn->query($sql) === TRUE) {
            return "Board deleted successfully";
        }
        else {
            return "Error: " . $sql . "<br>" . $conn->error;
        }
        $conn->close();
    }

?>

View raw code

Before saving the file, you need to modify the $dbname, $username and $password variables with your unique details:

// Your Database name
$dbname = "example_esp_data";
// Your Database user
$username = "example_esp_board";
// Your Database user password
$password = "YOUR_USER_PASSWORD";

After adding the database name, username and password, save the file and continue with this tutorial.

6. PHP Script – Control Buttons

You’ll also need to add a CSS file to style your dashboard (esp-style.css). Copy that CSS to your file and save it:

/**
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/control-esp32-esp8266-gpios-from-anywhere/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
**/

html {
    font-family: Arial;
    display: inline-block;
    text-align: center;
}

h2 {
    font-size: 3.0rem;
}

body {
    max-width: 600px;
    margin:0px auto;
    padding-bottom: 25px;
}

.switch {
    position: relative;
    display: inline-block;
    width: 120px;
    height: 68px;
}

.switch input {
    display: none
}

.slider {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #949494;
    border-radius: 34px;
}

.slider:before {
    position: absolute;
    content: "";
    height: 52px;
    width: 52px;
    left: 8px; bottom: 8px;
    background-color: #fff;
    -webkit-transition: .4s;
    transition: .4s;
    border-radius: 68px;
}

input:checked+.slider {
    background-color: #008B74;
}

input:checked+.slider:before {
    -webkit-transform: translateX(52px);
    -ms-transform: translateX(52px);
    transform: translateX(52px);
}

input[type=text], input[type=number], select {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

input[type=submit] {
    width: 100%;
    background-color: #008B74;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

input[type=submit]:hover {
    background-color: #005a4c;
}

div {
    text-align: left;
    border-radius: 4px;
    background-color: #efefef;
    padding: 20px;
}

View raw code

Finally, copy the next PHP script to your esp-outputs.php files that will display your control buttons and allow you to create/delete buttons:

<!--
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/control-esp32-esp8266-gpios-from-anywhere/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
-->
<?php
    include_once('esp-database.php');

    $result = getAllOutputs();
    $html_buttons = null;
    if ($result) {
        while ($row = $result->fetch_assoc()) {
            if ($row["state"] == "1"){
                $button_checked = "checked";
            }
            else {
                $button_checked = "";
            }
            $html_buttons .= '<h3>' . $row["name"] . ' - Board '. $row["board"] . ' - GPIO ' . $row["gpio"] . ' (<i><a onclick="deleteOutput(this)" href="javascript:void(0);" id="' . $row["id"] . '">Delete</a></i>)</h3><label class="switch"><input type="checkbox" onchange="updateOutput(this)" id="' . $row["id"] . '" ' . $button_checked . '><span class="slider"></span></label>';
        }
    }

    $result2 = getAllBoards();
    $html_boards = null;
    if ($result2) {
        $html_boards .= '<h3>Boards</h3>';
        while ($row = $result2->fetch_assoc()) {
            $row_reading_time = $row["last_request"];
            // Uncomment to set timezone to - 1 hour (you can change 1 to any number)
            //$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time - 1 hours"));

            // Uncomment to set timezone to + 4 hours (you can change 4 to any number)
            //$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time + 7 hours"));
            $html_boards .= '<p><strong>Board ' . $row["board"] . '</strong> - Last Request Time: '. $row_reading_time . '</p>';
        }
    }
?>

<!DOCTYPE HTML>
<html>
    <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">

        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" type="text/css" href="esp-style.css">
        <title>ESP Output Control</title>
    </head>
<body>
    <h2>ESP Output Control</h2>
    <?php echo $html_buttons; ?>
    <br><br>
    <?php echo $html_boards; ?>
    <br><br>
    <div><form onsubmit="return createOutput();">
        <h3>Create New Output</h3>
        <label for="outputName">Name</label>
        <input type="text" name="name" id="outputName"><br>
        <label for="outputBoard">Board ID</label>
        <input type="number" name="board" min="0" id="outputBoard">
        <label for="outputGpio">GPIO Number</label>
        <input type="number" name="gpio" min="0" id="outputGpio">
        <label for="outputState">Initial GPIO State</label>
        <select id="outputState" name="state">
          <option value="0">0 = OFF</option>
          <option value="1">1 = ON</option>
        </select>
        <input type="submit" value="Create Output">
        <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>
    </form></div>

    <script>
        function updateOutput(element) {
            var xhr = new XMLHttpRequest();
            if(element.checked){
                xhr.open("GET", "esp-outputs-action.php?action=output_update&id="+element.id+"&state=1", true);
            }
            else {
                xhr.open("GET", "esp-outputs-action.php?action=output_update&id="+element.id+"&state=0", true);
            }
            xhr.send();
        }

        function deleteOutput(element) {
            var result = confirm("Want to delete this output?");
            if (result) {
                var xhr = new XMLHttpRequest();
                xhr.open("GET", "esp-outputs-action.php?action=output_delete&id="+element.id, true);
                xhr.send();
                alert("Output deleted");
                setTimeout(function(){ window.location.reload(); });
            }
        }

        function createOutput(element) {
            var xhr = new XMLHttpRequest();
            xhr.open("POST", "esp-outputs-action.php", true);

            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

            xhr.onreadystatechange = function() {
                if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
                    alert("Output created");
                    setTimeout(function(){ window.location.reload(); });
                }
            }
            var outputName = document.getElementById("outputName").value;
            var outputBoard = document.getElementById("outputBoard").value;
            var outputGpio = document.getElementById("outputGpio").value;
            var outputState = document.getElementById("outputState").value;
            var httpRequestData = "action=output_create&name="+outputName+"&board="+outputBoard+"&gpio="+outputGpio+"&state="+outputState;
            xhr.send(httpRequestData);
        }
    </script>
</body>
</html>

View raw code

If you try to access your domain name in the following URL path, you’ll see the following:

http://example.com/esp-outputs.php
ESP32 ESP8266 Output Control Default Button and Board

That’s it! You should see that web page with your default button. The default button is called Built-in LED, it’s assigned to Board 1 and controls GPIO 2.

7. Preparing Your ESP32 and ESP8266

This project is compatible with both the ESP32 and ESP8266 boards. You just need to assemble a simple circuit and upload the sketches provided.

ESP32 vs ESP8266 Development Boards

Parts Required

To test this project, we’ll connect some LEDs to the ESP32 and ESP8266 GPIOs. Here’s a list of parts you need to build the circuit for this project:

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

Schematics

For this example, we’ll 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.

LEDs wiring to ESP32 – Board #1

ESP32 Control LEDs GPIOs from anywhere circuit schematic diagram

Recommended reading: which ESP32 GPIOs should you use.

LEDs wiring to ESP8266 – Board #2

ESP8266 Control LEDs GPIOs from anywhere circuit schematic diagram

Recommended reading: which ESP8266 GPIOs should you use.

ESP32 Code – Board #1

We’ll program the ESP32/ESP8266 using Arduino IDE, so you must have the ESP add-on installed in your Arduino IDE.

Follow one of the next tutorials depending on the board you’re using:

You also need to install the Arduino_JSON library. You can install this library in the Arduino IDE Library Manager. Just go to Sketch > Include Library > Manage Libraries … and search for the library name as follows:

Install Arduino JSON library Arduino IDE

After installing the necessary board add-ons and libraries, copy the following code to your Arduino IDE, but don’t upload it yet. You need to make some changes to make it work for you.

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

#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

//Your IP address or domain name with URL path
const char* serverName = "http://example.com/esp-outputs-action.php?action=outputs_state&board=1";

// Update interval time set to 5 seconds
const long interval = 5000;
unsigned long previousMillis = 0;

String outputsState;

void setup() {
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= interval) {
     // Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED ){ 
      outputsState = httpGETRequest(serverName);
      Serial.println(outputsState);
      JSONVar myObject = JSON.parse(outputsState);
  
      // JSON.typeof(jsonVar) can be used to get the type of the var
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(myObject);
    
      // myObject.keys() can be used to get an array of all the keys in the object
      JSONVar keys = myObject.keys();
    
      for (int i = 0; i < keys.length(); i++) {
        JSONVar value = myObject[keys[i]];
        Serial.print("GPIO: ");
        Serial.print(keys[i]);
        Serial.print(" - SET to: ");
        Serial.println(value);
        pinMode(atoi(keys[i]), OUTPUT);
        digitalWrite(atoi(keys[i]), atoi(value));
      }
      // save the last HTTP GET Request
      previousMillis = currentMillis;
    }
    else {
      Serial.println("WiFi Disconnected");
    }
  }
}

String httpGETRequest(const char* serverName) {
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

View raw code

Setting your network credentials

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.

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Setting your serverName

You also need to type your domain name, so the ESP makes the HTTP GET request to your own server.

const char* serverName = "http://example.com/esp-outputs-action.php?action=outputs_state&board=1";

Notice that on the URL serverName we have a parameter board=1. 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.

Now, you can upload the code to your board. It should work straight away.

This project is already quite long, so we won’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’s set to 5 seconds).

const long interval = 5000;

Then, the board will update its outputs accordingly to the request response.

Open your Serial Monitor and you should see something similar:

ESP32 Arduino IDE Serial Monitor Example

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 {“2″:”0”}.

ESP8266 Code – Board #2

For this example, we’re controlling the outputs from two boards simultaneously. You can use next code for your ESP8266 board:

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

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>

#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Your IP address or domain name with URL path
const char* serverName = "http://example.com/esp-outputs-action.php?action=outputs_state&board=2";

// Update interval time set to 5 seconds
const long interval = 5000;
unsigned long previousMillis = 0;

String outputsState;

void setup() {
  Serial.begin(115200);
  
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(ssid, password);
  while((WiFiMulti.run() == WL_CONNECTED)) { 
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Connected to WiFi");
}

void loop() {
  unsigned long currentMillis = millis();
  
  if(currentMillis - previousMillis >= interval) {
     // Check WiFi connection status
    if ((WiFiMulti.run() == WL_CONNECTED)) {
      outputsState = httpGETRequest(serverName);
      Serial.println(outputsState);
      JSONVar myObject = JSON.parse(outputsState);
  
      // JSON.typeof(jsonVar) can be used to get the type of the var
      if (JSON.typeof(myObject) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(myObject);
    
      // myObject.keys() can be used to get an array of all the keys in the object
      JSONVar keys = myObject.keys();
    
      for (int i = 0; i < keys.length(); i++) {
        JSONVar value = myObject[keys[i]];
        Serial.print("GPIO: ");
        Serial.print(keys[i]);
        Serial.print(" - SET to: ");
        Serial.println(value);
        pinMode(atoi(keys[i]), OUTPUT);
        digitalWrite(atoi(keys[i]), atoi(value));
      }
      // save the last HTTP GET Request
      previousMillis = currentMillis;
    }
    else {
      Serial.println("WiFi Disconnected");
    }
  }
}

String httpGETRequest(const char* serverName) {
  WiFiClient client;
  HTTPClient http;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(client, serverName);
  
  // Send HTTP POST request
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();

  return payload;
}

View raw code

To prepare the code for your ESP8266, just enter the SSID, password, domain name and board ID (in this case, it’s board ID number 2).

Demonstration

After completing all the steps, power both your ESP boards.

ESP32 ESP8266 Control GPIOs from Anywhere circuit schematic diagram

If you open your domain name in this URL path:

http://example.com/esp-outputs.php

You should see the the default button in your Dashboard:

ESP32 ESP8266 Output Control Default Button and Board

If you press that button on and off, you should be able to control GPIO 2 from your ESP32 – Board #1.

You can add more buttons to your project, type a name (LED 2), set board the id to number 1, then type the desired GPIO that you want to control (33).

Create Dashoard switches buttons to control ESP32 ESP8266 GPIOs

Create another button for Board 1 to control GPIO 32. Then, add two buttons for Board 2 (GPIO 2 and GPIO 4).

Control ESP32 ESP8266 from Anywhere switches buttons outputs GPIOs pins

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.

Note: in some devices, you might need to refresh the page to see your newly created buttons or to remove deleted buttons.

Finally, there’s a section that shows the last time a board made a request and updated its outputs.

Control ESP32 ESP8266 from Anywhere last board request time updated output states

Since this is not a two-way communication, when you press the buttons to control your outputs, your board doesn’t 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 Last Request Time section, you can see when that happened. Just refresh the page to see the updated values.

The web page is also mobile responsive, so you can use any device to access your server.

Control ESP32 ESP8266 GPIOs from Anywhere in the World dashboard demonstration

Wrapping Up

In this tutorial you’ve learned how to control your ESP32 and ESP8266 outputs from anywhere in the world. This requires that you have your own server and domain name (alternatively, you can use a Raspberry Pi LAMP Server for local access).

There are many other features that you can add to your server, you can merge it with our previous projects to display sensor readings. Feel free to add more ESP boards to run simultaneously and define other outputs to control.

I encourage you to change the web page appearance, add more features like email notifications, publish data from different sensors, use multiple ESP boards, and much more.

You might also like reading:

I hope you liked this project. If you have any questions, post a comment below and we’ll try to get back to you.

If you like ESP32, you might consider enrolling in our course “Learn ESP32 with Arduino IDE“. You can also access our free ESP32 resources here.

Thank you for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

73 thoughts on “Control ESP32 and ESP8266 GPIOs from Anywhere in the World”

  1. Fascinating and all that, but how is the security?
    That was the first thing that I thought of when I saw it using a domain name and cloud services.
    I also thought about what would happen if the server goes down.
    Sure, you can do some smart programming with backup servers, but personally I don’t trust running stuff remotely (unless it’s secure and redundant).
    Especially if you’re running something vital, like burglar alarm (Controlling on/off for sections, sensors, alarms etc).

    Sure, it’s one in a million that someone would both find your tech, hack it and then burglarize you, but it can happen.

    But, it’s something less vital which doesn’t affect anything, sure. As long as it’s something that doesn’t attract too much attention.
    Otherwise, it has to be secured.

    Also seem to be dependent on many factors, PHP-scripts, db-server, webserver and the connection between these servers and softwares.
    I’m sure a home-server can be set up too, in case you feel that’s any better.
    But, still, it can malfunction with all these components.
    It would be awesome if there were some db-engine which could be incorporated in the ESP module directly, without having it need to read/write into the flash (Don’t even know if it has a writable area, just spit-balling here) or so, and thereby eliminating any third-party provider.
    The fewer services required, the better IMHO.

    Reply
    • I didn’t want to make this project much longer, yes it’s currently available for anyone to guess your URL and access the Dashboard.
      However if you search online for PHP login script, you can add it to your page protect the control Dashboard with a login system and that’s going to be very secure (that’s going to be one of my next projects).
      I’ve been personally running a similar server since 2014 (it’s been 6 years now) and I’ve only encountered a issue once while updating the server (it has daily backups, so you can always go back).

      Reply
    • While authentication is important and maybe a good topic for a separate tutorial, it would be good to illustrate some defensive programming practices. For example, assume the json packet retrieved could be malicious. It doesn’t take much to check for invalid input, not just for hacking defense, but software bugs. Rather than blindly setting pinMode and digitalWrite, first verify the pin numbers as being ones suitable for writing, and maybe check the value for “0” or “1”. The atoi returns 0 on an invalid number, but supposedly sets the errno global which could be checked.

      Only a few extra lines of code are required to set a mask of allowable output pins and then check the json values are OK.

      Rui, Thanks for a nice tutorial. Maybe for this application there are simpler ways but it’s a good illustration of using these software packages. There are tradeoffs using a remote server for control vs ESP-embedded server with portal in a router. The latter could make a different tutorial.

      I can see how some security gets complex, and makes a pretty detailed tutorial longer. Setting up https can be complex, but Bluehost supposedly includes an SSL certificate. Httpd login, cookies, OATH, etc. can be complex, so maybe good to isolate these in a separate IoT security tutorial.

      Reply
      • Carl,

        You mean something like this?

        if ((atoi(keys[i]) >= 0 && atoi(keys[i]) <= 99) &&
        (atoi(value) == 0 || atoi(value) == 1)) {
        Serial.print("GPIO: ");
        Serial.print(keys[i]);
        Serial.print(" – SET to: ");
        Serial.println(value);
        pinMode(atoi(keys[i]), OUTPUT);
        digitalWrite(atoi(keys[i]), atoi(value));
        }
        else Serial.println("GPIO or status in not an integer");

        Reply
  2. Thanks Rui, excellent how-to as usual! I’ve been waiting for this one to see how you’d save the IO state on the server and if you’d use web sockets or get requests. I’ve been thinking of how to implement this sort of thing without using an mqtt server as I already have a hosting plan, (no mqtt and I don’t think they allow one to be installed). A quick question, do you think if multiple devices, say 50-75, are making get requests to the server I may need to alter the time delay? Or would another type of connection/protocol be better for that situation?

    Reply
    • Hello Mark, I haven’t tested this project with so many devices, but for such application I would run an MQTT server. The idea behind this project is for those who already have a hosting account can take advantage and control the outputs from anywhere. For more than 10 devices I would definitely go with MQTT.

      Reply
  3. This looks great; thanks for sharing.

    Just a quick question. How secure is this i.e. how easy would it be for some to hack this and gain access to your system?

    Reply
    • I didn’t want to make this project much longer, yes it’s currently available for anyone to guess your URL. However if you search online for PHP login script, you can add it to your page protect the control Dashboard with a login system (that’s going to be one of my next projects).

      Reply
  4. WOW
    Excelente tutorial, se entiende facil y rápido. Muy bien, dejarnos la tarea de agregar la lectura de sensores y cosas así.
    Pronto espero poder mostrarte mi proyecto mas avanzado.

    Muchas gracias por compartir tu conocimiento.

    “Excellent tutorial, it is easy and fast. All right, leave us the task of adding sensor reading and things like that.
    Soon I hope to show you my most advanced project.

    Thank you very much for sharing your knowledge.”

    Reply
  5. I’m guessing nobody will probably accidentally go to my ESP webpage but what if someone does? Can they control the off and on buttons from their browser?

    Reply
    • I didn’t want to make this project much longer, yes it’s currently available for anyone to guess your URL. However if you search online for PHP login script, you can add it to your page protect the control Dashboard with a login system (that’s going to be one of my next projects).

      Reply
    • A login script or page can be drafted and you will be able to secure it by your login credentials.
      Other wise it is not secure.

      Reply
  6. Can one 1 guide me when any GPIO already high or ON, while getting http response and change its state again to High or On, will GPIO or relay will off for a second?

    Reply
  7. Hi Sir,
    For the project posted yesterday “Control ESP32 and ESP8266 GPIOs from Anywhere in the World”.

    The URl to be set to ESP8266 is: “http://example.com/esp-outputs-action.php?action=outputs_state&board=2”.

    As you are using the domain bluehost, I wonder if the URL is in detail?

    Reply
  8. The concat of Gpio and board value should be unique, so that a specific board with specific GPIO can be registered once, overall you did great, very nicely I have completed my all project, which has 2 pzem004 for two supplies and which send voltage, current, power to mysql, then after a specified consumption or manually switch to another supply.
    Thankyou so much for your projects.

    Reply
  9. Hello and thanks for this amazing work
    i done the job but i get this message in serial monitor:

    Error code: -11
    {}
    JSON object = {}

    what is the reason and how can fix it?

    Reply
  10. Dear Rui,
    this is a project which I was waiting for for a long time.
    Thank you.
    I’m owning a domain already and php is running.
    I followed the steps of the project and it seemed to work.
    But there are 2 things which don’t:
    1. In the “ESP Output Control” dashboard no additional outputs can be created. But outputs can be deleted.
    2. The ESP32 sketch shows in the serial monitor:
    ….
    {“2″:”0”}
    Parsing input failed!
    HTTP Response code: 200
    ….
    But it acts when I toggle the button in the dashboard and shows
    …..
    {“2″:”1”}
    Parsing input failed!
    HTTP Response code: 200
    ….
    Any idea?

    Reply
  11. Good job as usual, thank you for sharing!

    Just a question: All the functions work except the createOutput(element).

    For it to work, I had to add a line before the last one.
    Would you know why? It’s driving me nuts. Thank you

    alert(xhr.send(httpRequestData)); <——
    xhr.send(httpRequestData);

    Reply
  12. hi again
    i modify server name and now i get this message in serial monitor:
    HTTP Response code: 200
    outputsState:⸮
    Parsing input failed!

    Reply
  13. I’m getting an error when trying to upload sketch to esp32

    HTTPClient.h: No such file or directory

    Not sure whats going on there, I’ve been following the tutorial closely. Thanks.

    Reply
  14. Excellent and very practical tutorial to learn PHP techniques and use and communications with ESP devices!

    I have connected the two types of modules and receive constantly, in ESP32 (
    the same happens to me in ESP8266).

    HTTP Response code: 200

    {“26”: “1”, “27”: “0”, “25”: “1”}
    Parsing input failed!

    And I can’t activate any output. In neither of the two programs.
    Where can I have the error?
    Where does all the comment type text appear after the code:
    HTTP Response 200?
    Because the Parsing input failed !?

    Any problem with the Arduino_Json?
    Could you adapt to the ArduinoJson de Benoit Blanchon from the Arduino library?

    I hope this helps other followers if the same thing has happened to them.
    Go ahead Rui and congratulations.

    Reply
    • Hi Rui.
      I still marvel at your tutorials but in this one I still can’t make it work for me.
      Although I reloaded all the PHP files and the Wi-Fi module files, I still can’t “advance” in the JSON part:

      JSONVar myObject = JSON.parse (outputsState);

      if (JSON.typeof (myObject) == “undefined”) {Serial.println (“Parsing input failed!”);
      return;
      }
      Serial.print (“JSON object =”); Serial.println (myObject);

      Always run “return” because the response to JSON.typeof (myObject) is null or empty.
      And I can’t keep going.
      To the other members of the forum this has not happened?

      It’s amazing that it happens to me alone!
      Will I have library problems?
      There is only one version of Arduino_JSON.

      If someone can give me a hand with this it would be spectacular!

      One more issue but it is from PWM.

      Where should I write about a question I have on the subject?

      On Facebook ?
      I am already part of the forum or in the PWM tutorial that is already on your page for led control?

      But it refers to generating a very low PWM frequency and it only works up to 1 Hz and I need 0.44 Hz.

      Thanks for your attention.
      And I will continue learning from all your new tutorials.

      Alejandro
      Buenos Aires

      Reply
  15. I must add this since it was not sent in my previous post and it is the “comment” that appears after the reply:

    HTTP Response code: 200
    >
    Rui Santos
    Complete project details at https://RandomNerdTutorials.com/control-esp32-esp8266-gpios-from-anywhere/

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files.

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    ->

    is always
    prior to {“26”: “1”, “27”: “0”, “25”: “1”}
    Parsing input failed!
    Thank you.

    Reply
  16. Hi, thank you for the tuto,
    I followed all what you wrote but got this message “Connection failed: No such file or directory” in the web page.
    What to do? thank you…

    Reply
  17. Great project!! I thought this was possible but didn’t know how to approach it.
    I had one problem. The string that that was retrieved by httpGETRequest started with the comments in the esp-outputs.php file, then the JSON info. I stripped out the comment portion and was able to get it working. I don’t know php (something new to learn) so I couldn’t figure out why the comment got included.

    Reply
  18. Since i don’t have ESP’s, i want to use Ethernet shield to turn on/off the arduino pins.
    Does this work with Ethernet ? If not ,
    Could you adapt to the ArduinoJson de Benoit Blanchon from the Arduino library?
    Thanks in advance !

    Reply
  19. Hello !! It’s working fine, but the message displays in the browse: Notice: Undefined variable: html_buttons in /storage/ssd5/988/11371988/public_html/esp-outputs.php on line 24
    and Undefined variable: html_board … on line 31.
    Can you help me ? Thanks

    Reply
  20. cool project. i had to mess around with schematics a bit but eventually got it figured out. I cant figure out why but im assuming the 5 minute delay is server side? Im hosting with bluehost is there somewhere in cpanel i can adjust database update schedule?

    Reply
      • well kind of, the board updates every 5 minutes. so i can press the button at anytime during the 5 minute interval, depending when the button is pushed within the interval is how long it takes to activate. i dont believe it has anything to do with the code because everything is working fine, except the 5 minute intervals.

        Reply
  21. Notice: Undefined variable: html_buttons in /home/luijay60/public_html/esp-outputs.php on line 24

    Notice: Undefined variable: html_boards in /home/luijay60/public_html/esp-
    outputs.php on line 31
    is what i get tried both scripts and i dont remember much of php last i saw it was over 2o years ago it mostly working i think Santos is a genious!

    Reply
  22. Two buttons (GPIO2, GPIO13) are now displayed.
    I have the button with:
    INSERT INTO `Outputs` (` name`, `board`,` gpio`, `state`) VALUES (” LED_RED “, 1, 13, 0);
    added to the database.
    The board page now shows:
    JSON object = “1 1”
    HTTP response code: 200
    “1 1”
    Nothing else is displayed (GPIO?)
    The corresponding GPIO is also not controlled.

    Reply
  23. Hi Rui, congratulations for an excellent website and work. I purchased your training but found this free tutorial which i’m interested in learning. I employ exaclty the same components you do (ESP32 DOIT Dev Kit and ESP8266). I verified that the output from the Http request is {“2″:”0”} but the Arduino IDE serial com window shows the following:
    {“2″:”0”}
    Parsing input failed!
    Evidently this is turning TRUE:
    if (JSON.typeof(myObject) == “undefined”)
    but I don’t know why since the typeof should be an object, or am I wrong. I am fairly new to PHP, JAVA, so please explain as if you where talking to a moron.
    Thanks

    Reply
    • Did you modify the URL in the code that you uploaded your board?

      Is your URL set as follows: http://www.your-domain-name.com/esp-outputs-action.php?action=outputs_state&board=1

      ?

      Reply
  24. HTTP Response code: 200

    This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support.

    Parsing input failed!

    Reply
      • Hi Rui,

        I found another reason for “Parsing input failed!”. If you are using plesk panel or similar and if you set SSL, this problem happening. Also if you just installed plesk, SSL option comes as active. So you need to go to the domain settings and remove the checkbox “SSL/TLS support”.

        Hey Rui, is there a way for SSL support?

        Best Regards.

        Reply
  25. Hi Rui, nevermind my last comment. I copied the new files onto the Bluehost files and that solved the parse error message. The problem I have is that the slides buttons state do not have any effect on the LEDs (I only tried one LED on the ESP32 (COM3) and one in the ESP8266 (COM8)). If I change the state manually for LED GPIO2 for ESP32 in the database using pHpMyAdmin to “1” and then enter this in the URL: esp-outputs-action.php?action=outputs_state&board=1, I will have this result in the web page result: {“2″:”1”}, but it doesn’t turn on the LED in GPIO2 of board 1 and COM3 keeps displaying the object as {“2″:”0”}. While writing this I noticed that sometimes the LEDs on both boards come on and off randomly. That’s weird. Before I start from scratch again (even dumping the MySQL Database) do you recommend anything?. Thanks.

    Reply
    • Hello Emiliano,
      Note: it takes up to 5 seconds for your boards to update the outputs states (so, if you press the buttons very quickly, you won’t see them change in real time).
      Does your ESP8266 board is set to board=2 in the server variable?

      For example for board #2:
      http://www.your-domain-name.com/esp-outputs-action.php?action=outputs_state&board=2

      Then, in your Dashboard you should create buttons and assign them to Board 2.

      Reply
      • hi rui thanks for the tutorial, I want to ask, on my serial monitor I have an error JSON Object = {}
        Error Code = -11
        help me please

        Reply
  26. Hello Rui Santos,
    Thank you for sharing this cool project. Congratulations!..
    I need your help. I configured my database and php files like above but I didnt reached mywebpage.com/esp-outputs.php file on my web page. I get this error “Connection failed: Access denied for user ‘myweb_esp’@’localhost’ to database ‘myweb_esp_data’ ”
    And also, I checked error.log in my web page. I get this error “PHP Warning: mysqli::mysqli(): (HY000/1044): Access denied for user ‘myweb_esp’@’localhost’ to database ‘myweb_esp_data’ in /home/myweb/public_html/esp-database.php on line 78
    Do you have an idea for this error.

    Reply
    • It looks like your database user doesn’t have full permissions to access the database or you didn’t include the right credentials in your esp-database.php file. Double-check that you’ve replaced those lines with your exact credentials:
      // Your Database name
      $dbname = "REPLACE_WITH_YOUR_DATABASE_NAME";
      // Your Database user
      $username = "REPLACE_WITH_YOUR_USERNAME";
      // Your Database user password
      $password = "REPLACE_WITH_YOUR_PASSWORD";

      Reply
  27. Hi Rui,

    Again thank you so much for this project.

    I want to use DHT11 or DHT22 with this project. So i need set a degree, then the DHT sensor will check current degree and stop or start a GPIO port. How can i implement it to this project?

    Best Regards.

    Reply
  28. Good day,

    I would like to use the program code for other projects (e.g. smart home system).
    I have the following question:
    Which program code is used to transmit the data (e.g. {“2”: “0”, “13”: “0”}) for controlling the selected GPIOs?
    Could you please tell me.
    Many thanks in advance.

    Kind Regards

    Juergen B.

    Reply
  29. Hello Rui Santos and Sara Santos,

    good evening,
    thank you very much for your sketch on this project.

    really helpful, i modify the script to work with raspberry.

    thank you,
    Panji P

    Reply
  30. Hell Rui
    The Connection failed issue was resolved after discussion with technical team of Blue Host.in. The problem was due to corruption of data base.

    Thanks

    Reply
  31. Hello,
    I have made your project and it works perfect. Can you help me to modify it and the buttons to be monostabile? I need it when i push the button to give me output 1 second and then off until next push. So no slide button.
    Thank you

    Reply

Leave a Reply to Tanju Gurler Cancel reply

Download our Free eBooks and Resources

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