ESP8266 • 4 CHANNEL RELAY

ESP8266 Setup Guide

Follow the steps below to install the controller, connect WiFi, upload the program and control the four relays from the web dashboard.

1. Relay Pin Connection

SwitchESP8266GPIORelay
Switch 1D1GPIO5IN1
Switch 2D2GPIO4IN2
Switch 3D5GPIO14IN3
Switch 4D6GPIO12IN4

2. Hardware Connection

1
Connect IN1Connect Relay IN1 to ESP8266 D1.
2
Connect IN2Connect Relay IN2 to ESP8266 D2.
3
Connect IN3Connect Relay IN3 to ESP8266 D5.
4
Connect IN4Connect Relay IN4 to ESP8266 D6.
5
Common GroundConnect ESP8266 GND and Relay GND together.

3. Arduino IDE Setup

1
Open Arduino IDEOpen Arduino IDE on your computer.
2
Select the ESP8266 BoardSelect your ESP8266 board and the correct COM port.
3
Copy the ProgramPress the Copy Code button below.
4
Paste into Arduino IDEPaste the complete program into the new sketch.
5
UploadConnect the ESP8266 by USB and upload the program.

4. WiFi Setup

1
Power OnPower on the ESP8266 after uploading.
2
Open WiFi SetupIf no saved WiFi is available, connect to the setup WiFi created by the ESP8266.
3
Scan NetworksOpen the setup page and scan for nearby networks.
4
Select Your WiFiSelect your network and enter the WiFi password.
5
Save & ConnectSave the settings and wait for the ESP8266 to connect.

5. Copy ESP8266 Code

Copy the complete code below and paste it into Arduino IDE. Keep the code unchanged unless you need to modify the configuration.
ESP8266_Control.ino
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <EEPROM.h>

// =====================================================
// EEPROM
// =====================================================

#define EEPROM_SIZE 256

#define SSID_ADDR 0
#define PASS_ADDR 64

// =====================================================
// SERVER
// =====================================================

const char* SERVER =
  "https://srice.in/api.php";

const char* DEVICE_KEY =
  "ESP8266_SECRET_12345";

// =====================================================
// RELAY PINS
// =====================================================

#define RELAY1 D1
#define RELAY2 D2
#define RELAY3 D5
#define RELAY4 D6

// Active LOW relay
#define RELAY_ON  LOW
#define RELAY_OFF HIGH

bool sw1 = false;
bool sw2 = false;
bool sw3 = false;
bool sw4 = false;

unsigned long lastServerRequest = 0;

const unsigned long REQUEST_INTERVAL = 10000;

// =====================================================
// SETUP SERVER
// =====================================================

WiFiServer setupServer(80);


// =====================================================
// EEPROM READ
// =====================================================

String readEEPROM(int address, int length)
{
  String value = "";

  for (int i = 0; i < length; i++)
  {
    byte c = EEPROM.read(address + i);

    if (c == 0 || c == 255)
      break;

    value += char(c);
  }

  return value;
}


// =====================================================
// EEPROM SAVE
// =====================================================

void saveEEPROM(
  int address,
  String value,
  int length
)
{
  for (int i = 0; i < length; i++)
  {
    if (i < value.length())
      EEPROM.write(
        address + i,
        value[i]
      );
    else
      EEPROM.write(
        address + i,
        0
      );
  }

  EEPROM.commit();
}


// =====================================================
// URL DECODE
// =====================================================

String urlDecode(String input)
{
  String decoded = "";

  for (int i = 0; i < input.length(); i++)
  {
    if (input[i] == '+')
    {
      decoded += ' ';
    }
    else if (
      input[i] == '%' &&
      i + 2 < input.length()
    )
    {
      String hex =
        input.substring(
          i + 1,
          i + 3
        );

      char c =
        strtol(
          hex.c_str(),
          NULL,
          16
        );

      decoded += c;

      i += 2;
    }
    else
    {
      decoded += input[i];
    }
  }

  return decoded;
}


// =====================================================
// RELAY
// =====================================================

void relayWrite(
  int pin,
  bool state
)
{
  digitalWrite(
    pin,
    state ? RELAY_ON : RELAY_OFF
  );
}


// =====================================================
// APPLY RELAYS
// =====================================================

void applyRelays()
{
  relayWrite(
    RELAY1,
    sw1
  );

  relayWrite(
    RELAY2,
    sw2
  );

  relayWrite(
    RELAY3,
    sw3
  );

  relayWrite(
    RELAY4,
    sw4
  );
}


// =====================================================
// HTTP RESPONSE
// =====================================================

void sendResponse(
  WiFiClient& client,
  String contentType,
  String body
)
{
  client.println(
    "HTTP/1.1 200 OK"
  );

  client.print(
    "Content-Type: "
  );

  client.println(
    contentType
  );

  client.println(
    "Cache-Control: no-cache"
  );

  client.println(
    "Connection: close"
  );

  client.println();

  client.print(body);
}


// =====================================================
// SETUP HTML
// =====================================================

String setupPage()
{
  String html = R"rawliteral(
<!DOCTYPE html>

<html>

<head>

<meta name="viewport"
content="width=device-width,initial-scale=1">

<title>ESP8266 WiFi Setup</title>

<style>

*{
box-sizing:border-box;
}

body{
margin:0;
padding:20px;
font-family:Arial,sans-serif;
background:#0f172a;
color:white;
}

.container{
max-width:500px;
margin:auto;
}

.card{
background:#1e293b;
padding:25px;
border-radius:20px;
}

h2{
margin-top:0;
}

p{
color:#cbd5e1;
}

button{
width:100%;
padding:14px;
margin-top:15px;
border:0;
border-radius:10px;
font-size:16px;
background:#22c55e;
color:white;
cursor:pointer;
}

button:disabled{
background:#64748b;
}

select,
input{
width:100%;
padding:14px;
margin-top:15px;
border-radius:10px;
border:0;
font-size:16px;
background:white;
color:#111827;
}

.status{
margin-top:15px;
padding:12px;
border-radius:10px;
background:#111827;
color:#cbd5e1;
}

</style>

</head>

<body>

<div class="container">

<div class="card">

<h2>ESP8266 WiFi Setup</h2>

<p>
Select a WiFi network and enter its password.
</p>

<button
id="scanButton"
onclick="scanWiFi()">

Scan WiFi

</button>

<select id="networks">

<option value="">
Select WiFi Network
</option>

</select>

<input
id="password"
type="password"
placeholder="WiFi Password">

<button
id="connectButton"
onclick="saveWiFi()">

Save & Connect

</button>

<div
id="status"
class="status">

Ready

</div>

</div>

</div>

<script>

function scanWiFi(){

let button =
document.getElementById("scanButton");

let select =
document.getElementById("networks");

let status =
document.getElementById("status");

button.disabled = true;

button.innerText =
"Scanning...";

status.innerText =
"Scanning for WiFi networks...";

select.innerHTML =
"<option>Scanning...</option>";

fetch("/scan")

.then(function(response){

return response.json();

})

.then(function(data){

select.innerHTML =
"<option value=''>Select WiFi Network</option>";

if(data.length === 0){

status.innerText =
"No WiFi networks found.";

return;

}

data.forEach(function(network){

let option =
document.createElement("option");

option.value =
network.ssid;

option.textContent =
network.ssid +
" (" +
network.rssi +
" dBm)";

select.appendChild(option);

});

status.innerText =
data.length +
" WiFi network(s) found.";

})

.catch(function(){

status.innerText =
"WiFi scan failed.";

})

.finally(function(){

button.disabled = false;

button.innerText =
"Scan WiFi";

});

}


function saveWiFi(){

let select =
document.getElementById("networks");

let password =
document.getElementById("password").value;

let ssid =
select.value;

let button =
document.getElementById("connectButton");

let status =
document.getElementById("status");

if(!ssid){

alert(
"Please select a WiFi network."
);

return;

}

if(password.length === 0){

alert(
"Please enter the WiFi password."
);

return;

}

button.disabled = true;

button.innerText =
"Connecting...";

status.innerText =
"Testing WiFi connection...";

fetch(
"/connect?ssid=" +
encodeURIComponent(ssid) +
"&password=" +
encodeURIComponent(password)
)

.then(function(response){

return response.text();

})

.then(function(data){

status.innerText =
data;

})

.catch(function(){

status.innerText =
"Connection request failed.";

})

.finally(function(){

button.disabled = false;

button.innerText =
"Save & Connect";

});

}

</script>

</body>

</html>
)rawliteral";

  return html;
}


// =====================================================
// SETUP CLIENT
// =====================================================

void handleSetupClient()
{
  WiFiClient client =
    setupServer.available();

  if (!client)
    return;

  String request = "";

  unsigned long timeout =
    millis();

  while(
    client.connected() &&
    millis() - timeout < 3000
  )
  {
    if(client.available())
    {
      char c =
        client.read();

      request += c;

      if(
        request.endsWith(
          "\r\n\r\n"
        )
      )
        break;
    }
  }

  Serial.println();
  Serial.println(
    "Setup Request:"
  );

  Serial.println(
    request
  );


  // HOME

  if(
    request.indexOf(
      "GET / "
    ) >= 0
  )
  {
    sendResponse(
      client,
      "text/html",
      setupPage()
    );
  }


  // SCAN

  else if(
    request.indexOf(
      "GET /scan"
    ) >= 0
  )
  {
    Serial.println(
      "Starting WiFi scan..."
    );

    WiFi.mode(
      WIFI_AP_STA
    );

    int count =
      WiFi.scanNetworks();

    Serial.print(
      "Networks found: "
    );

    Serial.println(count);

    String json = "[";

    for(
      int i = 0;
      i < count;
      i++
    )
    {
      String ssid =
        WiFi.SSID(i);

      if(
        ssid.length() == 0
      )
        continue;

      if(
        json != "["
      )
        json += ",";

      ssid.replace(
        "\\",
        "\\\\"
      );

      ssid.replace(
        "\"",
        "\\\""
      );

      json += "{";

      json += "\"ssid\":\"";
      json += ssid;
      json += "\",";

      json += "\"rssi\":";
      json += WiFi.RSSI(i);

      json += "}";
    }

    json += "]";

    sendResponse(
      client,
      "application/json",
      json
    );

    WiFi.scanDelete();
  }


  // CONNECT

  else if(
    request.indexOf(
      "GET /connect?"
    ) >= 0
  )
  {
    int queryStart =
      request.indexOf(
        "GET /connect?"
      ) + 13;

    int queryEnd =
      request.indexOf(
        " HTTP/"
      );

    String query =
      request.substring(
        queryStart,
        queryEnd
      );

    String ssid = "";

    String password = "";

    int ssidPos =
      query.indexOf(
        "ssid="
      );

    int passwordPos =
      query.indexOf(
        "&password="
      );

    if(
      ssidPos >= 0 &&
      passwordPos >= 0
    )
    {
      String encodedSSID =
        query.substring(
          ssidPos + 5,
          passwordPos
        );

      String encodedPassword =
        query.substring(
          passwordPos + 10
        );

      ssid =
        urlDecode(
          encodedSSID
        );

      password =
        urlDecode(
          encodedPassword
        );
    }

    Serial.println();

    Serial.print(
      "SSID: "
    );

    Serial.println(ssid);

    Serial.print(
      "Password length: "
    );

    Serial.println(
      password.length()
    );


    WiFi.mode(
      WIFI_AP_STA
    );

    WiFi.begin(
      ssid.c_str(),
      password.c_str()
    );

    Serial.println(
      "Testing WiFi..."
    );

    int attempts = 0;

    while(
      WiFi.status() != WL_CONNECTED &&
      attempts < 30
    )
    {
      delay(500);

      Serial.print(".");

      attempts++;
    }

    Serial.println();


    if(
      WiFi.status() ==
      WL_CONNECTED
    )
    {
      Serial.println(
        "WiFi connection successful!"
      );

      Serial.print(
        "IP Address: "
      );

      Serial.println(
        WiFi.localIP()
      );

      saveEEPROM(
        SSID_ADDR,
        ssid,
        60
      );

      saveEEPROM(
        PASS_ADDR,
        password,
        60
      );

      sendResponse(
        client,
        "text/plain",
        "WiFi connected successfully. Credentials saved. ESP8266 will restart."
      );

      delay(1500);

      ESP.restart();
    }
    else
    {
      Serial.println(
        "WiFi connection failed!"
      );

      WiFi.disconnect();

      sendResponse(
        client,
        "text/plain",
        "WiFi connection failed. Please check the password and try again."
      );
    }
  }

  else
  {
    client.println(
      "HTTP/1.1 404 Not Found"
    );

    client.println();

    client.println(
      "Not Found"
    );
  }

  delay(1);

  client.stop();
}


// =====================================================
// SETUP MODE
// =====================================================

void startSetupMode()
{
  Serial.println();

  Serial.println(
    "================================"
  );

  Serial.println(
    "ESP8266 WIFI SETUP MODE"
  );

  Serial.println(
    "================================"
  );

  WiFi.mode(
    WIFI_AP
  );

  WiFi.softAP(
    "ESP8266-Setup",
    "12345678"
  );

  Serial.println(
    "SSID: ESP8266-Setup"
  );

  Serial.println(
    "Password: 12345678"
  );

  Serial.print(
    "Setup IP: "
  );

  Serial.println(
    WiFi.softAPIP()
  );

  setupServer.begin();
}


// =====================================================
// CONNECT SAVED WIFI
// =====================================================

bool connectSavedWiFi()
{
  String ssid =
    readEEPROM(
      SSID_ADDR,
      60
    );

  String password =
    readEEPROM(
      PASS_ADDR,
      60
    );

  if(
    ssid.length() == 0
  )
  {
    Serial.println(
      "No saved WiFi credentials."
    );

    return false;
  }

  Serial.println();

  Serial.print(
    "Connecting to saved WiFi: "
  );

  Serial.println(ssid);

  WiFi.mode(
    WIFI_STA
  );

  WiFi.begin(
    ssid.c_str(),
    password.c_str()
  );

  int attempts = 0;

  while(
    WiFi.status() != WL_CONNECTED &&
    attempts < 30
  )
  {
    delay(500);

    Serial.print(".");

    attempts++;
  }

  Serial.println();

  if(
    WiFi.status() ==
    WL_CONNECTED
  )
  {
    Serial.println(
      "WiFi Connected!"
    );

    Serial.print(
      "IP Address: "
    );

    Serial.println(
      WiFi.localIP()
    );

    return true;
  }

  Serial.println(
    "Saved WiFi connection failed."
  );

  return false;
}


// =====================================================
// HEARTBEAT
// =====================================================

void sendHeartbeat()
{
  if(
    WiFi.status() !=
    WL_CONNECTED
  )
    return;


  WiFiClientSecure client;

  // Allow HTTPS connection
  // without certificate verification

  client.setInsecure();


  HTTPClient http;


  String url =
    String(SERVER) +
    "?action=heartbeat&key=" +
    DEVICE_KEY;


  Serial.println();

  Serial.println(
    "Sending heartbeat..."
  );

  Serial.println(
    url
  );


  http.setFollowRedirects(
    HTTPC_FORCE_FOLLOW_REDIRECTS
  );

  http.setRedirectLimit(5);


  if(
    !http.begin(
      client,
      url
    )
  )
  {
    Serial.println(
      "HTTP begin failed"
    );

    return;
  }


  int code =
    http.GET();


  Serial.print(
    "Heartbeat HTTP: "
  );

  Serial.println(code);


  if(code > 0)
  {
    String response =
      http.getString();

    Serial.print(
      "Response: "
    );

    Serial.println(
      response
    );
  }


  http.end();
}


// =====================================================
// GET SWITCH COMMANDS
// =====================================================

void getCommands()
{
  if(
    WiFi.status() !=
    WL_CONNECTED
  )
    return;


  WiFiClientSecure client;

  client.setInsecure();


  HTTPClient http;


  String url =
    String(SERVER) +
    "?action=get&key=" +
    DEVICE_KEY;


  Serial.println();

  Serial.println(
    "Getting switch status..."
  );

  Serial.println(
    url
  );


  http.setFollowRedirects(
    HTTPC_FORCE_FOLLOW_REDIRECTS
  );

  http.setRedirectLimit(5);


  if(
    !http.begin(
      client,
      url
    )
  )
  {
    Serial.println(
      "HTTP begin failed"
    );

    return;
  }


  int code =
    http.GET();


  Serial.print(
    "Command HTTP: "
  );

  Serial.println(code);


  if(code == 200)
  {
    String payload =
      http.getString();


    Serial.print(
      "Server: "
    );

    Serial.println(
      payload
    );


    sw1 =
      payload.indexOf(
        "\"sw1\":1"
      ) >= 0;


    sw2 =
      payload.indexOf(
        "\"sw2\":1"
      ) >= 0;


    sw3 =
      payload.indexOf(
        "\"sw3\":1"
      ) >= 0;


    sw4 =
      payload.indexOf(
        "\"sw4\":1"
      ) >= 0;


    applyRelays();
  }
  else if(code > 0)
  {
    Serial.print(
      "Response: "
    );

    Serial.println(
      http.getString()
    );
  }


  http.end();
}


// =====================================================
// SETUP
// =====================================================

void setup()
{
  Serial.begin(
    115200
  );

  delay(1000);


  EEPROM.begin(
    EEPROM_SIZE
  );


  pinMode(
    RELAY1,
    OUTPUT
  );

  pinMode(
    RELAY2,
    OUTPUT
  );

  pinMode(
    RELAY3,
    OUTPUT
  );

  pinMode(
    RELAY4,
    OUTPUT
  );


  // All OFF initially

  sw1 = false;
  sw2 = false;
  sw3 = false;
  sw4 = false;


  applyRelays();


  // Connect saved WiFi

  if(
    !connectSavedWiFi()
  )
  {
    startSetupMode();
  }
}


// =====================================================
// LOOP
// =====================================================

void loop()
{
  // Setup mode

  if(
    WiFi.getMode() ==
    WIFI_AP
  )
  {
    handleSetupClient();

    delay(10);

    return;
  }


  // WiFi disconnected

  if(
    WiFi.status() !=
    WL_CONNECTED
  )
  {
    Serial.println(
      "WiFi disconnected."
    );

    startSetupMode();

    return;
  }


  // Server communication

  unsigned long now =
    millis();


  if(
    now - lastServerRequest >=
    REQUEST_INTERVAL
  )
  {
    lastServerRequest =
      now;


    sendHeartbeat();

    getCommands();
  }


  delay(100);
}

6. Test the Controller

1
Check Device StatusOpen the web dashboard and confirm that the device shows Online.
2
Test Switch 1Turn Switch 1 ON/OFF and check Relay IN1.
3
Test Switch 2Turn Switch 2 ON/OFF and check Relay IN2.
4
Test Switch 3 and 4Test D5/IN3 and D6/IN4 in the same way.