Follow the steps below to install the controller, connect WiFi, upload the program and control the four relays from the web dashboard.
| Switch | ESP8266 | GPIO | Relay |
|---|---|---|---|
| Switch 1 | D1 | GPIO5 | IN1 |
| Switch 2 | D2 | GPIO4 | IN2 |
| Switch 3 | D5 | GPIO14 | IN3 |
| Switch 4 | D6 | GPIO12 | IN4 |
#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);
}