Building a WiFi power switch – The UNIX client

In previous posts the hardware to build a power switch controlled by WiFi, using the ESP8266 module, as well the microcontroller code were depicted. The switch can be controlled via accessing a web URL:

  • "http://<IP address>/gpio/1" turns the switch ON
  • "http://<IP address>/gpio/0" turns the switch OFF
  • "http://<IP address>/gpio/status" displays the status

The aim of the power switch is to control the exterior lighting, so it needs to switch on and off every day. A UNIX system using the cron scheduler seems the perfect implementation. As the system needs to be autonomous, in case the ESP8266 does not respond, the client needs to make several attempts before giving up. In the meantime, it needs to log every failed attempt (using logger) for future reference. The time between each attempt is doubled each time. The DHCP server of the router is configured to give a permanent IP address to the ESP8266 module. The above requirements are embedded in a bash script. The script is used with two arguments, the first is the ip and the second is the state (0, 1 or status).

max_attempts=10 #maximum attempts to try to connect
timeout=2       #initial timeout in seconds
if [ "$arguments" -ne "2" ] 
then echo "usage: setstate <ip> <state>"
exit 1
while (($attempt &amp;lt; $max_attempts)) do curl -s --max-time 1 $url > /dev/null
    if [[ $exitCode == 0 ]]
    logger -p error "[WARNING] Wireless $ip not responding, retrying in $timeout"
    echo "Failure! Retrying in $timeout.." 1>&2
    sleep $timeout
    attempt=$(( attempt + 1 ))
    timeout=$(( timeout * 2 ))
if [[ $exitCode != 0 ]]
    logger -p error "[ERROR] Wireless $ip not responding"
    echo "Maximum attempts reached trying to connect ($@)" 1>&2
exit $exitCode

The full project for the ESP8266 power switch can be found on my Github page.

Building a WiFi power switch – The Software

Having built, as explained in a previous post a power switch controlled using an ESP8266 wireless module, it is now to develop the program running on the ESP8266. To recap, I am using an ESP8266-01 wireless module which has two GPIO pins (GPIO0 and GPIO2) and two UART pins (Tx and Rx).

  • GPIO2 will be used as an output to control the relay, active low.
  • GPIO0 will be used as an input to manually override the setting and activate the relay, active low.
  • Tx will be be used for debugging, to read the microcontroller events</li>

The ESP8266 is preloaded with some simple AT commands. There are many toolsets to program the module, but the easiest in my opinion is using the Arduino IDE, available on github. It supports all main functions and has a pretty good reference. Each time a new program is loaded on the microcontroller, the Arduino core is loaded as well, so it takes about a minute. To program the module, it needs to enter in bootloader mode, essentially to pull down GPIO0 before power up. To sum up:

Bootloader mode

  • GPIO2: high
  • GPIO0: low
  • RST: high
  • CH_PD: high

Normal mode

  • GPIO2: high
  • GPIO0: high
  • RST: high
  • CH_PD: high

The github page of the Arduino IDE for ESP8266 contains analytical instructions on how to install the toolset.

The developed program is a modification of the "WiFiWebServer" example with the following requirements:

  • Connect automatically on the network
  • Create a webserver that every device (client) can access.
    • By accessing "http://<ESP8266IP>/gpio/0", GPIO2 becomes low and the web server returns "ON"
    • By accessing "http://<ESP8266IP>/gpio/1", GPIO2 becomes high and the web server returns "OFF"
    • By accessing "http://<ESP8266IP>/gpio/status", the web server returns the status ("ON" or "OFF")
  • If GPIO0 is low, the ESP8266 enters manual mode, meaning it sets GPIO2 low, discarding any change from the web
  • If the network connection is lost, the ESP8266 attempts to reconnect
  • If the ESP8266 gets an IP from a DHCP server *.*.0.*, it disconnects and tries to reconnect.

This last behavior programmed is due to the repeater found in the house. If the main router becomes inoperable, then the repeater acts as a DHCP server providing IP address 192.168.0.*. When the router is active again, then the ESP8266 does not change address and it becomes unreachable. So, if this occurs, then the module reconnects only when the main router is present again.

#include "ESP8266WiFi.h"

const char* ssid = "SSID";
const char* password = "PASSWORD";

int val=1;
int flag=0;

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {

// Start the server
Serial.println("Server started");

void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi lost, trying to reconnect");

if (digitalRead(0) == LOW && flag==0) {
digitalWrite(2, val);

if (digitalRead(0) == HIGH && flag==1) {

// Check if a client has connected
WiFiClient client = server.available();
if (!client) {

// Wait until the client sends some data
Serial.println("new client");

// Read the first line of the request
String req = client.readStringUntil('\r');

// Match the request
val = 1;
val = 0;
else if (req.indexOf("/gpio/status") != -1)
Serial.println("getting status");
else {
Serial.println("invalid request");

// Set GPIO2 according to the request
digitalWrite(2, val);


// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>;\r\n<html>\r\n";
s += (val)?"OFF":"ON";
s += "</html>\n";

// Send the response to the client
Serial.println("Client disonnected");

// The client will actually be disconnected 

void WiFiBegin(){
pinMode(2, OUTPUT);
digitalWrite(2, val);
pinMode(0, INPUT);

// Connect to WiFi network
Serial.print("Connecting to ");

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi connected");

// Print the IP address
IPAddress IPadd = WiFi.localIP(); 
if (IPadd[2] == 0) {
Serial.println("Connected to repeater, disconnecting");




Building a WiFi power switch - The Hardware

I wanted to add some exterior lights using the existing wiring, which would operate during the night. The most common way is to install a programmable timer switch before the lights, which is a hardware or software timer and a relay. However this needs to be installed indoors (unacceptable for my case) or outdoor, on a waterproof enclosure, which however can not be easily programmable.

So, instead, I used some simple components to create a switch using a relay. The switch is connected to the home WiFi, so it can be operated using any other client connected on the same network, or via the internet, if enabled. The circuit is housed in a IP55 junction box, near each light.

The main component of the circuit is the ESP8266 WiFi module, which includes a microcontroller and a TCP/IP stack. The ESP8266 needs a 3.3V supply, which is provided by the ac grid. Finally, a GPIO port operates a high voltage relay which connects the light. The following figure shows the complete circuit schematic.

To provide the 3.3V, a USB power supply is used, together with a 3.3V LDO. The AMS1117 regulator needs to provide at least 9mA to operate correctly, so a resistive load needs to be added, together with bypass capacitors and a protection diode. For the current project, an external regulator board was used, which has all the necessary components. A supplemental 100nF capacitor is connected, since during transmission, the ESP8266 demands up to 250mA.

The ESP8266-01 module is used. The ESP8266 has many variants. Different boards, provide different ports. The ESP8266-01 board has the least amount of ports, two GPIOs and the UART peripheral Tx/Rx. For normal operation, during power-up, the GPIO2 needs to be high. The UART peripheral is not used during operation. So, Tx is not connected and Rx has a pull-up resistor, to not be affected by noise. The R3 resistor pulls GPIO2 to Vcc (although D1 does the same job by the manner it is connected). CH_PD enables the module, and needs to be pulled high. RST resets the module when low, so it is pulled to Vcc via R1. GPIO2 is used as an output to drive the relay, whereas GPIO0 is used an input to override manually the state, as it is (still) quicker than to connect via the mobile phone.

The light is connected via a high voltage relay (10A - 250V). Although for the current prototype an external relay board is used, it can be easily implemented in the same board, so it is analytically depicted in the circuit schematic. An optocoupler is used in the input, which can isolate the ground of the microcontroller with the ground of the relay. However, this is not necessary, as the relay provides isolation as well. LED3 shows that the relay is powered on, whereas LED2 shows if the relay is activated. The diode D4 is necessary, to dissipate the power of the relay coil. If this diode was not present, an overvoltage would occur during switch off, which could damage the nearby components. Connector P2 is a high current, high voltage connector.

The ESP8266 module, together with the regulator board were installed on a single sided veroboard. A connector is used for the ESP8266 module, in order to remove it for programming.

A 5V power supply from an old nokia bluetooth headset is used, which implements a flyback topology. The high voltage circuit (before the flyback transformer) is isolated with hot glue, to ensure that there will be no short circuiting when installed inside the enclosure.

In this photo, the whole circuit is depicted. Power comes from the connector strip shown on the left. The neutral and ground are bridged to the light, whereas the phase passes through the relay. The 5V supply is powered by the phase and the neutral which powers the ESP8266 board through the LDO. The ESP8266 board provides power to the relay board, as well as the signal to switch on the relay.

Finally, the installation is shown. A 8cm x 8cm waterproof (IP55) was used, although with careful wiring, the components could fit in a smaller enclosure. The optional manual override switch was not installed in this light box, as the installation hight makes it inaccessible to the user.

Ward-Leonard control system: Theory and demonstration

When choosing the main motor for large scale electromechanical systems, two are the main candidate solutions: The AC induction motor and the DC induction motor. In most cases, the AC motor is selected, because of its simplicity, lower price and higher reliability. However, there are cases where the DC machine is preferred and those are where the precision of the speed control is crucial. Since the speed and torque outputs of the DC motor are linear, the control algorithm is a lot simpler. The main objectives of power electronics drives for induction motors are to provide similar control capacity compared to DC motors.

The Ward-Leonard control system is the best solution to have a very smooth speed control for the full range of the DC motor. Nowadays similar results can be achieved using power electronics converters and those drives have gradually replaced older Ward-Leonard systems. Typically, to control the speed of a DC motor either the voltage of the armature or the current of the field coil. While the control of the field coil current has higher efficiency (when not using power electronics) the speed range is limited, as the armature current cannot exceed the nominal value. On the other hand, as the armature current value is a lot higher than the field coil current, the regulation of this current with resistive devices will lead to major power loss. The armature voltage regulation can be provided through a voltage divider or using a resistor connected in series. Due to the advances in the area of power electronics, nowadays it can also be provided using a thyristor 2 or 6 pulse bridge or using an AC/DC power supply.

The Ward-Leonard control system provides a DC voltage to the armature that can be adjusted. This voltage is provided by a DC generator. As a result, it can vary from zero to the nominal value of the DC motor, providing a wide range of speed control. The output voltage of a DC generator is mainly a function of the rotor speed as well as its field coil current. So, in the Ward-Leonard system, the speed is kept almost constant and the field current is adjusted using a voltage divider. By adjusting the field current of the DC generator, the armature voltage of the DC motor is adjusted, controlling in the end the rotor speed. Finally, a motor is needed to rotate the DC generator. The type of the motor is irrelevant so it can be a DC motor, an AC induction motor or even an internal combustion or steam engine. The use of such a system with an internal combustion engine was described in Ward Leonard's patent application in 1903. Typical applications of the Ward-Leonard control systems are elevators and radars where the speed as well as position need to be precise. With the advances of SCRs in the 1980s, thyristor bridges started to replace those systems. The thyristor bridges, while being a lot more power efficient, small and cost-effective have extremely low power factor. Those bridges are being replaced with PFC converters with IGBTs or drives with induction motors.

The following figure shows the control system schematic. The main DC motor is machine 3. The field coil is powered by a DC current supply (diode 6 pulse bridge) and the current is at its nominal value. Machine 2, which is the DC generator supplies the voltage to the DC motor armature. The field current varies from zero to its nominal value and is controlled by a DC power supply, or simply by a voltage divider from the DC source. Machine 1 is an induction motor which rotates the DC generator. The rotor speed is almost constant (there is a small variation depending on the load, however this can be counterbalanced by adjusting the voltage divider for the field current.

A common issue of the induction machine is the very high value of the inrush current. That is why a soft starter is usually applied, either using a star-delta topology or more frequently using a power electronics converter. In the following video, the operation of the star-delta topology is shown.

Finally, a laboratory Ward Leonard Control system is shown in the following video. The main DC motor is the front left (which makes the front right machine the load).

Comparison of 4 USB power supplies

Having recently installed a Raspberry Pi 2 server running 24/7, which is powered through a 5V micro USB port (recommended power supply nominal current: 1.8A), I wanted to test different USB supplies in order to see which is the most efficient to use.

The models I tested were:

  1. Apple A1400 charger from an iPhone 4. Max. Current: 1A.
  2. LG MCS-04 charger from an LG phone. Max. Current: 1.8A.
  3. LG MCS-02 charger from an LG phone. Max. Current: 0.85A.
  4. Garmin PSAI05R-050Q charger from an Edge 510. Max. Current: 0.5A.

The tests were done powering a constant current load through a 1.5m USB cable, with a total resistance of 1Ω. The power losses of the cable were neglected as the aim was to measure the absolute efficiency of the wall chargers. The chargers were powered by 230V/50Hz and Zes Zimmer precision power analyzer was used to measure the efficiency and the power factor of each charger.

The results of the test are shown in the following figures.

First the results of the power efficiency are shown. The Garmin Charger has the lowest power rating and also the lowest efficiency. The LG MCS-04 which has the highest power rating, has also the highest efficiency. However, the Apple charger has a lower power efficiency than the LG MCS-02 charger, which has a lower rating. On the other hand, the Apple charger has the lowest standby power consumption (the power analyzer couldn't measure it) whereas it could measure some mW on all the other chargers.

Next, the power factor measurements are shown in the following figure.

The power factor measurements are similar for all chargers and all very low. Yes, the chargers' input power is only some W, but there are millions plugged in at the same time. The power factor is expected to be this low due to the diode full bridge rectification of the ac voltage, followed by a capacitor, expected to have a high capacitance value, in order to help the output voltage stabilization (together with the DC/DC converter controller). Cheap counterfeits use a single-diode (half) rectification, so their power factor should be even lower.

All in all, although the power efficiency of the provided charger is not the main criterium when selecting a mobile phone, due to the large number of chargers, the suppliers were forced to improve the power efficiency of their chargers from 50% which was 15 years ago to over 75%. Also, certifications have been created (energy star, no load five star rating) to force the manufacturers to ship higher quality chargers.

The resistance of a 1.5m USB cable was 1Ω, which seems quite large. This means that for 1A, the voltage drop is 1V, and so, the phone would see only 4V during charging, so the power manager limits the demanded power, increasing the required time to charge. What is more, a complete measurement of the power efficiency of the complete system should also take into consideration the cable losses. That is why, in the modern era, 3m cables are extremely rare. To my knowledge only Nokia chargers for simple phones provide such a long cable. After sale long cables also exist for smart phones, designed to have similar resistance for an increased length at a cost of ~40$.