Projects

Wireless Switching

Multi-zone WiFi Controlled Switch using ESP8266

Fraser Border and Basem Adel

Issue 36, July 2020

This article includes additional downloadable resources.
Please log in to access.

Log in

Control multiple systems distributed across your WiFi network at the touch of just one button.

BUILD TIME: 30 MINUTES (+ 3D printing Time)
DIFFICULTY RATING: Intermediate

The original intention for this project was to distribute “ON AIR” signs around our office that would illuminate when the team were filming in the studio. The solution needed to be simple, take advantage of the WiFi network to reduce wiring, and expandable so that additional signs could be added around the office.

THE BROAD OVERVIEW

Thanks to Arduino-compatible modules becoming popular, wireless communication has become a viable, affordable option to be used in relatively simple projects like this. Many of these utilise Bluetooth or WiFi communication protocols, removing the constraints of wired network connections, which is why we have chosen to use the ESP8266 for this application.

The diagram shown here exemplifies the WiFi communication between devices using this popular ESP8266 microcontroller.

We will take advantage of this compact microcontroller and its WiFi communication for our project.

HOW IT WORKS

The project has been divided into two circuits, the server circuit and client circuit. The client circuit has a pushbutton, and upon being pressed, the LED connected to the client circuit will be turned on. A signal will then be sent from the client circuit to the server circuit via the local WiFi network connecting an ESP8266 module in each circuit. Upon receiving this signal, the server circuit then switches the server circuit’s LED on.

We will describe how to build and program a server and client circuit, which you can replicate for additional nodes. In our example, we will illuminate some LEDs for our "ON AIR" signage, however, you could use the output to meet your needs. For example, you could trigger a relay module to control 12V devices, and the like.

We will also include the 3D print files that we used for our "ON AIR" enclosures, which you can easily modify for your application.

ESP8266 WiFi Module

XC3802 WiFi Mini ESP8266 Main Board from Jaycar

The main board of the project is based on the ESP8266 WiFi module (Module ESP-12E Wemos). It is a self-contained system-on-chip (SOC) with an integrated TCP/IP protocol. The module comes pre-programmed with an AT command set firmware.

The board enables electrical circuits to communicate with each other and/or communicate with other devices that can access the same WiFi network. It is capable of acting as an access point server or as a client that can be connected to other access points, such as home routers.

The module’s on-board processing and storage capability allows it to be integrated with 11 general-purpose input/output (GPIO), and has an analogue-to-digital converter (ADC). The WiFi antenna is highly sensitive and can be found at the side of the PCB (printed circuit board).

The design of the circuit has a high degree of on-chip integration and hence exhibits minimal external circuitry, including the front-end module. The tiny board is designed to occupy minimal PCB area (approximately the size of a coin). Overall, this module is extremely maker-friendly, particularly as it is breadboard-compatible with the addition of a few pins.

Testing the client board's current draw.

Features:

  • 802.11 b/g/n
  • WiFi Direct (P2P), soft-AP
  • Integrated TCP/IP protocol stack
  • Integrated TR switch, balun, LNA, power amplifier and matching network
  • Integrated PLLs, regulators, DCXO and power management units
  • +19.5dBm output power in 802.11b mode
  • Power down leakage current of <10µA
  • Integrated low power 32-bit CPU could be used as an application processor
  • SDIO 1.1 / 2.0, SPI, UART
  • STBC, 1×1 MIMO, 2×1 MIMO
  • Flash: 4M
  • A-MPDU & A-MSDU aggregation & 0.4ms guard interval
  • Wake up and transmit packets in < 2ms
  • Standby power consumption of < 1.0mW (DTIM3)

ESP8266 PINOUT

Server with Enclosure.
Client with Enclosure

The Build:

PREPARATION

PARTS REQUIRED FOR 1 x SERVER & 1 x CLIENT:Jaycar
2 x Wi-Fi Mini ESP8266 ModulesXC3802
4 x 5mm Red LEDs (Or your preferred colour)ZD0150
1 × 10kΩ Resistor*RR0596
2 x 100Ω Resistors*RR0548
1 x Tactile PushbuttonSP0600
2 x 4xAA Battery HoldersPH9200
2 x 2-Way Screw TerminalsHM3130
8 x AA BatteriesSB2425

* Quantity shown, may only be available in packs. Breadboards and prototyping hardware is also required.

If not done so already, solder the header pins onto the ESP8266 modules so that they can fit into the breadboard.

Attach the battery holders to the 2-way screw terminals (before inserting the batteries in them).

Note: To avoid damage to the ESP8266 module, do not insert the batteries during the assembly stage. The modules will be powered after programming (later). This is to avoid connecting the module to the battery and laptop simultaneously, and therefore, applying too high a voltage for the module to withstand.

Follow the circuit diagrams and instructions to wire your Server and Client boards.

SERVER CIRCUIT

The anode of the LEDs on your server circuit go to pin 5 (D5) on the ESP8266.

CLIENT CIRCUIT

The anode of the LEDs on your server circuit go to pin 3 (D3) on the ESP8266.

The pushbutton connects across the breadboard divider such that the upper and lower legs are not connected.

The leg on one side of the pushbutton connects to pin 5 (D5) of the ESP8266.

Client Circuit Diagram.
Server Circuit Diagram.

Note: For our application, we added a 100Ω resistor to limit the current to the LEDs. You may need to use a different resistor value depending on the LEDs you use.

The leg on the opposite side of the pushbutton goes to the negative rail via a 10k resistor.

The other leg of the pushbutton switch on the same side connects to the 5V rail.

PROGRAMMING

Now, most of the hardware components are connected, this coming section will outline the steps required to program the ESP8266 board.

ESP8266 CONFIGURATION

One of the features of ESP8266 board is that it can be programmed using Arduino IDE, without the need for an additional Arduino adapter board. The configuration steps are:

Open the Arduino IDE

Add the ESP8266 to the board manger. File menu › Preferences, then add the link http://arduino.esp8266.com/stable/package_esp8266com_index.json to the additional boards manager URLs.

Add the ESP8266 library. Tools menu › Board: › Board Managers, then type Esp8266 and install the latest version of “esp8266 by ESP8266 Community”.

Based on the “ESP8266 WiFi Mini” datasheet, we need to select the “LOLIN(WEMOS) D1 R2 & mini” model type. Go to the Tools menu › Boards: › and select LOLIN(WEMOS) D1 R2 & mini.

Next, Tools menu › Upload Speed › 115200

Now the ESP8266 is ready to be programmed.

THE CODE

The code is available to download from our website and is commented appropriately.

The coding section is divided into three steps:

  1. A temporary code to be uploaded to get the IP assigned for each module.
  2. Upload the server code to the server module.
  3. Upload the client code to the client module.

GET IP CODE

When the ESP8266 board is connected to an access point router, the router assigns a random IP to the module. This IP can be thought of as the address of the board. To be able to communicate to this specific module, this IP is needed to be known. Thus, this code will be uploaded to each board, then the IP of each board will be saved to be used later.

The first part of the code adds the ESP8266.h library, which enables us to use the ESP8266 functions.

//Include the library
#include <ESP8266WiFi.h> 

Add the username and the password of the existing WiFi network.

const char* username = "your_network";
//Insert the WiFi network username
const char* password = "password";
//Insert the WiFi network password

Initiate the serial monitor and specifying the transfer baud rate.

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

Initiate the WiFi connection.

Serial.print("Attempting to connect to SSID");
  WiFi.begin(username, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }

Print the IP of the ESP8266 board on the serial monitor

Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

Connect the module to the computer through the USB cable.

From Tools menu › Port: › COM13.

Note: The port number will change depending on the port the board is connected to. In our case, it is port COM13.

Upload the code twice (for each ESP8266 board).

Open the serial monitor and save the IP somewhere.

These two IPs will be inserted later in the server and client code to enable them to communicate with each other.

SERVER CODE

This code will be uploaded to the ESP8266 board that will perform as a server. Similar to the previous code, there are some variables that will need to be inserted. Those variables are the username, password and the IP of the client board (obtained after uploading the previous code to it).

Firstly, the library that enables the ESP8266 functions to be employed is added to the Arduino sketch.

//Include the library
#include <ESP8266WiFi.h>

Next, the variables that are to be used are identified. Also, a number that is to be assigned to the port to transfer the data is identified. This number can be anything (we chose 80).

int led = D5;
const char * host = "192.168.1.106";
const char* Commands_Reply;
WiFiServer server(80);

Add the username and the password of the existing WiFi network.

const char* username = "your_network";
const char* password = "password"; 

Initiate the serial monitor and set the baud rate to 115200.

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

Connect to the WiFi and print the local IP of the board (it should be the same as the one obtained from uploading the “Get IP” code).

Serial.println("");
  Serial.println
("Server------------------------");
  Serial.print("Configuring access point");
  Serial.print
("Attempting to connect to Network");
  WiFi.begin(username, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

Start the server.

server.begin();
    Serial.println("Server started"); 

Check if the client is connected to the server.

WiFiClient client = server.available();
  if (!client) {
    return;
  }

Check if the client has sent any data.

Serial.println("Server-----------------");
  Serial.println("New client");
  Serial.print("From client = ");
  while(!client.available()){
    delay(1);
  }

Read the data received from the client and clear the buffer.

String req = client.readStringUntil(‘r’);
   Serial.println(req);
   client.flush();

This part of the code, the server receives the data from the client to turn the LED ON or OFF and accordingly.

  if (req.indexOf("LED_On") != -1){
      Commands_Reply = "LED Status : On";
      Serial.print("Server send = ");
      Serial.println(Commands_Reply);
      client.print(String("GET ") 
+ Commands_Reply + " HTTP/1.1rn" + "Host: " 
+ host + "rn" + "Connection: closernrn");
      digitalWrite(led, HIGH);
    }
   else if (req.indexOf("LED_Off") != -1){
    Commands_Reply = "LED Status : Off";
    Serial.print("Server send = ");
      Serial.println(Commands_Reply);
      client.print(String("GET ") 
+ Commands_Reply + " HTTP/1.1rn" + "Host: " 
+ host + "rn" + "Connection: closernrn");
      digitalWrite(led, LOW);
    }
   else {
     Serial.println("invalid request");
     client.stop();
     return;
    }
   client.flush();
   Serial.println("Client disonnected");
   Serial.println
("-------------------------------------");
   Serial.println("");

UPLOAD THE CODE

Connect the module to the computer through the USB cable.

Tools menu › Port: › COM13.

Note: The port number will change depending on the port the board is connected to. In our case, it is port COM13.

Upload the code to the server ESP8266 board.

Disconnect the board from the computer.

Now we have the code uploaded to the server board, the same steps will be repeated for the client (yet, obviously, with different code).

CLIENT CODE

This section will outline the various sections of the server code.

The IP address that will be inserted here is the IP of the server.

const char * host = "the_IP_address";
const int httpPort = 80;
const char* Commands;
int LED = D3;
int button = D5;
bool btn_press = true;
int con = 0;

This loop is to detect if the push button is pressed, save the number of presses and reset the counter if the number of presses is more than two. This allows the program to have the capability to determine whether to turn the LEDs ON (e.g. one press) or OFF (e.g. second press).

if (digitalRead(button) == LOW) {
    Serial.println("Client------------------");
    Serial.print("Send Command = ");
    if (btn_press == true){
      if (con >= 2) {
        con=0;
      }
      con++;

This part of the code turns the LED on and off, and sends the data to the server according to the number of presses.

     switch (con){
        case 1:
        digitalWrite(LED,HIGH);
          Commands="LED_On";
          Serial.println(Commands);
          send_commands();
          break;
        case 2:
         digitalWrite(LED,LOW);
          Commands="LED_Off";
          Serial.println(Commands);
          send_commands();
          break;  
      }
      
      btn_press = false;
    }
  }
  else {
    btn_press = true;
  }
  delay(100);
}

This part of the code handles the communication and sends the data to the server, establishing a connection with the server using the port number and IP...

  WiFiClient client;
  
  if (!client.connect(host, httpPort)) {
    Serial.println("Connection failed");
    return;
  }

...sending the commands to the server.

client.print(String("GET ") + Commands + " HTTP/1.1rn" + "Host: " + host + "rn" + "Connection: Closernrn");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout › 5000) {      
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

Check if the communication is established and whether there is a replay from the server.

Serial.print("Server Reply = "); 
  while(client.available()){
    String line = client.readStringUntil(‘r’);
    Serial.print(line);
  }

UPLOAD THE CODE

Connect the module to the computer through the USB cable.

From Tools menu › Port: › COM13.

Note: The port number will change depending on the port the board is connected to. In our case, it is port COM13.

Upload the code to the client ESP8266 board.

Disconnect the board from the computer.

Now we have the code uploaded to the client board.

TESTING

At this point, we have both of the circuits ready i.e. the server and the client, wired and programmed.

After we disconnect the modules from the computer, they will need a source of power to work on their own, and hence, are connected to their respective 6V battery holders. The positive of the battery is connected to the 5V pin, and the negative is connected to the GND pin.

Note: It is recommended not to exceed 7V due to the ratings of the voltage regulator on-board the ESP8266 module.

Now we have the completed project which operates such that:

  • Pressing the push button connected to the client will turn the LED ON connected to it.
  • Then the client module will send an “LED_ON” message to the server module through the WiFi network using the unique IP assigned to the server.
  • The server receives the message and then, triggered by its program, turn its LED ON.
  • By pressing the push button again, through the same mechanism, the program will count a repeated press, and turn both LEDs OFF.

Note: Due to the time required to both send and receive signals using the ESP8266 modules, there may be a small lag in communication.

Enclosure

Finally, an enclosure was designed to both encase the server and client modules, as well as add the aesthetics of an “ON AIR” sign that is lit by the circuits’ LEDs. The enclosure was designed using TinkerCAD, a free, web-browser based program that is easy to use without the need for much CAD (computer assisted design) experience. For the design to meet our criteria, the “ON AIR” sign was printed using transparent filament to enable the LED light to pass through the enclosure.

WHERE TO FROM HERE?

A few examples of how this project may be scaled include:

  • The addition of more client nodes that enables even more “ON AIR” lights to be positioned around the studio
  • The replacement of the hardware trigger (e.g. pushbutton) with a software trigger (e.g. a graphical user interface on a web server) whereby these circuits may be triggered through any device that may access the WiFi network (e.g. computer, tablet, mobile phone, etc.)
  • Through port forwarding, the ESP8266 module may be configured to allow this system to be triggered from anywhere in the world through the internet.
  • Use a more powerful battery (Li-ion or Lead Acid) to control an LED Strip or something more "visible".
  • To add additional artistic flair, or to customise the mounting or aesthetics of the “ON AIR” 3D printed sign (TinkerCAD working files will be included on our website for you to download)

Note: TinkerCAD can be downloaded for free at www.tinkercad.com. You will also find useful training guides on Fraser's website www.integratedstem.com.au

Whilst this project was focused on the design of an “ON AIR” sign for our recording studio, the ESP8266 module has almost limitless potential for makers looking to create a convenient, wireless control method for their own IoT (Internet-of-Things) projects.

Any of the client nodes created may trigger a circuit alternative to the LED circuit used in this project. For example, a simple relay circuit could be triggered by the client to turn on any household device (stick to low voltage only for the sake of safety i.e. below 50V). The possibilities of this module are limited only to your imagination – get out there and experiment with IoT for yourself!