Is it possible to use esp8266 and Uno as master/slave through web server

Hi folks,

After a long time with some work projects that prevented me from studying Arduino more, I finally got some time to dedicate myself.

So I would like to ask the masters for some help and ask questions about a project I'm developing, which is basically relays control via wifi and using a web server with esp8266. The problem is that I don't have many ports available on the esp8266 to control many relays/LEDs and so I would need to use another Arduino Uno/Nano/Mega card to extend the number of ports and thus be able to control more relays via wifi.
I read some articles about I2C communication, but I confess that I didn't quite understand the idea and I couldn't adapt the idea to the web server.

Dear friend, how can I use esp8266 and Arduino to extend more ports and control via the web server?

Below is my code for esp8266 with the web server.

//RELAY CONTROLLER

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <TimeLib.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
 
const char* ssid = "MeuSSID";
const char* password = "01000001.01100010";
int value0;
int value1;
int value2;
int value3;

int ledPin0 = D0;
int ledPin1 = D1;
int ledPin2 = D2;
int ledPin3 = D3;
WiFiServer server(80);

// NTP
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "br.pool.ntp.org", -10800);

void setup() {
  Serial.begin(9600);
  delay(10);
 
 
  pinMode(ledPin0, OUTPUT);
  digitalWrite(ledPin0, LOW);
  pinMode(ledPin1, OUTPUT);
  digitalWrite(ledPin1, LOW);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(ledPin2, LOW);
  pinMode(ledPin3, OUTPUT);
  digitalWrite(ledPin3, LOW);
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
    // Start the server
  server.begin();
  Serial.println("Server started");
 
  // Print the IP and MAC address
  Serial.print("Use this URL : ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
  Serial.print("Mac Adress: ");
  Serial.println(WiFi.macAddress());
  

//NTP Sync
  timeClient.update();
  Serial.print("Obtendo hora: ");
  Serial.println(timeClient.getFormattedTime());
  
}
 
void loop() {
  //Time variable
 String hora = timeClient.getFormattedTime();
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
 
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
 
  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
 
  // Match the request
 
  if (request.indexOf("/LED0=OFF") != -1) {
    digitalWrite(ledPin0, HIGH);
    value0 = HIGH;
  } 
  if (request.indexOf("/LED0=ON") != -1){
    digitalWrite(ledPin0, LOW);
    value0 = LOW;
  }
 
  if (request.indexOf("/LED1=OFF") != -1) {
    digitalWrite(ledPin1, HIGH);
    value1 = HIGH;
  } 
  if (request.indexOf("/LED1=ON") != -1){
    digitalWrite(ledPin1, LOW);
    value1 = LOW;
  }
 
   if (request.indexOf("/LED2=OFF") != -1) {
    digitalWrite(ledPin2, HIGH);
    value2 = HIGH;
  } 
  if (request.indexOf("/LED2=ON") != -1){
    digitalWrite(ledPin2, LOW);
    value2 = LOW;
  }
   if (request.indexOf("/LED3=OFF") != -1) {
    digitalWrite(ledPin3, HIGH);
    value3 = HIGH;
  } 
  if (request.indexOf("/LED3=ON") != -1){
    digitalWrite(ledPin3, LOW);
    value3 = LOW;
  }

//Turn on/off all
   if (request.indexOf("/LEDALL=OFF") != -1) {
    digitalWrite(ledPin0, HIGH);
    value0 = HIGH;
    digitalWrite(ledPin1, HIGH);
    value1 = HIGH;
    digitalWrite(ledPin2, HIGH);
    value2 = HIGH;
    digitalWrite(ledPin3, HIGH);
    value3 = HIGH;
  } 
  if (request.indexOf("/LEDALL=ON") != -1){
    digitalWrite(ledPin0, LOW);
    value0 = LOW;
    digitalWrite(ledPin1, LOW);
    value1 = LOW;
    digitalWrite(ledPin2, LOW);
    value2 = LOW;
    digitalWrite(ledPin3, LOW);
    value3 = LOW;
  }
 
  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head><META HTTP-EQUIV=\"refresh\" CONTENT=\"15\">");
  client.println("<TITLE>Alevino 1.1</TITLE>");
  client.println("<style>");
  client.println("body  {");
  client.println("background-repeat: no-repeat;");
  client.println("background-size: 53%;}");
  client.println("h4    {");
  client.println("font-family: verdana;");
  client.println("color: #FF4000;}");
  client.println("h3    {");
  client.println("font-family: verdana;");
  client.println("font-weight: bold;");
  client.println("color: teal;}");
  client.println("</style>");
  client.println("</head>");
  //Body
  client.println("<body>");
  client.println("<table border=\"2\" width=\"405\" cellpadding=\"10\">");
  client.println("<tbody>");
  client.println("<tr>");
  client.println("<td>");
  client.println("<h3>");
  client.println("Relay0 pin is now: ");
    if(value0 == HIGH) {
    client.println("Off");  
  } else {
    client.println("On");
  }

  client.println("<form action=""/LED0=ON\">");
  client.println("ON: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("<form action=""/LED0=OFF\">");
  client.println("OFF: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("<h3></td></tr>");
  client.println("<tr><td>");
  client.println("<h3>Relay1 pin is now: ");
  if(value1 == HIGH) {
    client.println("Off");  
  } else {
    client.println("On");
  }  
  
  client.println("<form action=""/LED1=ON\">");
  client.println("ON: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("<form action=""/LED1=OFF\">");
  client.println("OFF: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("</h3>");
  client.println("<h3></td></tr>");

  client.println("<tr><td>");
  client.println("<h3>Relay2 pin is now: ");
  if(value2 == HIGH) {
    client.println("Off");  
  } else {
    client.println("On");
  }  
  
  client.println("<form action=""/LED2=ON\">");
  client.println("ON: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("<form action=""/LED2=OFF\">");
  client.println("OFF: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("</h3>");
  client.println("<h3></td></tr>");
  
  client.println("<tr><td>");
  client.println("<h3>Relay3 pin is now: ");
  if(value3 == HIGH) {
    client.println("Off");  
  } else {
    client.println("On");
  }  
  
  client.println("<form action=""/LED3=ON\">");
  client.println("ON: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("<form action=""/LED3=OFF\">");
  client.println("OFF: <input type=""submit"" value=""Submit"">");
  client.println("</form>");  
  client.println("</h3>");
  client.println("</td></tr>");

  client.println("<tr><td>");
  client.println("<h3>Click to turn all relays ON/OFF");
  client.println("<form action=""/LEDALL=ON\">");
  client.println("ON: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("<form action=""/LEDALL=OFF\">");
  client.println("OFF: <input type=""submit"" value=""Submit"">");
  client.println("</form>");
  client.println("</h3></td></tr>");
  client.println("<h4>Last scan: ");
  client.println(hora);
  client.println("</h4></td></tr>");
  // End web server
  client.println("</tbody></table></body></html>");

  delay(1);
  Serial.println("Client disconnected");
  Serial.println("");
}'

Have you considered using a port expander / shift register before using multiple boards?

1 Like

Yes, you could use another Arduino to provide more output pins to drive relays. It is possible. But it's so much more difficult than using port expanders because you have to get 2 sketches working perfectly together. That's more than twice as difficult as getting one sketch to work. And then there's the problem of interfacing 5V logic to 3.3V logic.

So port expanders are the easiest answer. Can't say why you found them difficult, but the solution would be to have been to ask for help here on the forum. Well, you're here now!

1 Like

There are libraries to help to use the port expanders that take some of the complication away.

Both are available via the IDE library manager.

Tks at the past I've used an MCP3008 (to increase 8 pins) but at that time I was using it to read from sensors, I really not knew that it could be used to write, I will read more to understand which commands can be used, to my next sketch I will try MCP23017 to have even more ports.

I found it difficult to use the ports and the level shifter as well. Somehow my projects using I2C and the level shifter (to operate logic level 3.3v to 5v) never responded. I tested the ports and the level shifter many times, thinking that they could be defective, but finally I could ask here on the forum and I will study the documentation sent.

How many ports (and what kind) do you need?
Which 8266 board are you looking at?

Why a level shifter? The MCP23008, MCP32017 work fine at 3.3V. No level shifting required on the I2C line, just pullups.

They work great as inputs. Even have internal pullups on each pin and pin change interrupts.

Can we get a schematic of your proposed circuit, please. Hand drawn, photographed and posted is fine if you have no CAD program.

Well I am pleased we have ditched the idea of adding a clumsy Arduino.

Note that these can run at 3.3 V and control "low level trigger" opto-isolated relay modules with the module VCC connected to the 5 V supply that feeds the regulator to the ESP8266.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.