Sunspot Home

more notes for backup and a bad memory - -
BEWARE- Lesson 1 programmer. . . .

Reprogram a Sonoff power switch for use on my home LAN

Objective - Control mains powered devices using verbal commands to Amazon Alexa


Many thanks to Pete Scargill for all the information

MQTT is still on my "learn about it soon list" so I used the web page control method as in the Arduino example sketches.
For Alexa verbal control see the blue text in the Python code here .

I also learned how to use an interrupt to get the relay to toggle under manual control (the main loop in the sketch does not loop if there are no http commands) .

I have a white LED in series with 1Kohm wired across the relay coil (they are very bright these days and the 1Kohm could be increased).

I connected gpio14 via 1Kohm to the red LED in the two colour LED. The centre pin of that LED goes to 3.3V. See photos below.
The bare wire on the antenna side of the LED goes to the red light. The light source was on the side of my LED, not under the focus, so it was not very bright. I suspect Sonoff are using up half faulty LEDs in the non radio versions! I cut the wire on the LED but that is not essential since many components used for radio control are missing.

I used an external 3.3 volt supply for testing since I had trouble on another project with the weak 3.3 volt supply in my USB serial link

I found that the solder pad on the push button ( the one that is not at the board edge but near the gpio strip ) connects directly to gpio0 via zero ohms. I had wondered if it could be used as an output pin but the push button would have to removed in case a button push shorted a high gpio0)
Anyway -I need the button!

The ESP8266 sketch below is loaded by the Arduino IDE

!!!!! NB only use mains power when all testing is done and the box is closed !!!!!

/* NB! - this is the Sonoff device with no radio remote control components
* This sketch demonstrates how to set up a simple HTTP-like server.
* The server will set GPIO pins depending on the request
* NB! modified for fixed WIFI address
sonoff header
1 - vcc 3v3
2 - rx
3 - tx
4 - gnd
5 - gpio 14
esp8266 connections
gpio 0 - button
gpio 12 - relay
gpio 13 - green led - active low
gpio 14 - connect via 1 kohm to the red led in the two colour led
(the bare led wire nearest the antenna end of the board)

#include <ESP8266WiFi.h>

// from a terminal or bash script send one of -
// curl "" //gpio12relay off (pin low)
// curl "" //gpio12relay on (pin high)
// curl "" //gpio13greenled on (pin low)
// curl "" //gpio13greenled off (pin high)
// curl "" //gpio14redled on (pin low)
// curl "" //gpio14redled off (pin high)
// - or just place in the address box of a browser
// - Lines below like "if (req.indexOf("(01)") != -1)" could detect more descriptive texts)

const char* ssid = "my WIFI SSID";
const char* password = "my password";
int gpio12relay_pin = 12;
int gpio13greenled_pin = 13;
int gpio14redled_pin = 14;
int val0 = 0;
int val2 = 0;
int val3 = 0;
int old_val0 = 0;
int old_val2 = 0;
int old_val3 = 0;

//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' for Interrupt
volatile int state = LOW; // so we can toggle the relay
const byte BUTTON = 0; // push the button (on GPIO 0) to toggle the relay

// Interrupt Service Routine (ISR)
void switchPressed ()
state = !state;
digitalWrite (gpio12relay_pin, state);

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup start
void setup() {

// prepare GPIO12
pinMode(gpio12relay_pin, OUTPUT);
digitalWrite(gpio12relay_pin, 0);

// prepare GPIO13
pinMode(gpio13greenled_pin, OUTPUT);
digitalWrite(gpio13greenled_pin, 0);

// prepare GPIO14
pinMode(gpio14redled_pin, OUTPUT);
digitalWrite(gpio14redled_pin, 0);

//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' for Interrupt
digitalWrite (BUTTON, HIGH); // internal pull-up resistor
attachInterrupt (digitalPinToInterrupt (BUTTON), switchPressed, FALLING); // attach interrupt handler

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

WiFi.begin(ssid, password);

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

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

// config static IP
IPAddress ip(192, 168, 0, xxx); // the desired IPAddress
IPAddress gateway(192, 168, 0, xxx); // set gateway to match your network
Serial.print(F("Setting static ip to : "));
IPAddress subnet(255, 255, 255, 0); // set subnet mask to match your network
WiFi.config(ip, gateway, subnet);

// Print the IP address
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup end

//======================================================== loop start
void loop() {
// 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
// first digit is led/relay code number second digit is state requested

if (req.indexOf("(00)") != -1) //not equal to -1 means it was present
{val0 = 0; val2 = old_val2; val3 = old_val3;} // gpio12relay turns off, gpio13greenled does not change, gpio14redled_pin does not change
if (req.indexOf("(01)") != -1)
{val0 = 1; val2 = old_val2; val3 = old_val3;} // gpio12relay turns on, gpio13greenled does not change, gpio14redled_pin does not change

if (req.indexOf("(20)") != -1)
{val0 = old_val0; val2 = 0; val3 = old_val3;} // gpio12relay does not change, gpio13greenled turns off, gpio14redled_pin does not change
if (req.indexOf("(21)") != -1)
{val0 = old_val0; val2 = 1; val3 = old_val3;} // gpio12relay does not change, gpio13greenled turns on, gpio14redled_pin does not change

if (req.indexOf("(30)") != -1)
{val0 = old_val0; val2 = old_val2; val3 = 0;} // gpio12relay does not change, gpio13greenled does not change, gpio14redled_pin turns off
if (req.indexOf("(31)") != -1)
{val0 = old_val0; val2 = old_val2; val3 = 1;} // gpio12relay does not change, gpio13greenled does not change, gpio14redled_pin turns on

Serial.print("old_val0 = "); Serial.println(old_val0);
Serial.print("old_val2 = "); Serial.println(old_val2);
Serial.print("val0 = "); Serial.println(val0);
Serial.print("val2 = "); Serial.println(val2);

old_val0 = val0; // relay
old_val2 = val2; // green led
old_val3 = val3; // red led

//else {
//Serial.println("invalid request");

if (val0 == 1)
{ state = HIGH; }
{ state = LOW; } // a button press will toggle this value

// Set GPIO according to the request
digitalWrite(gpio12relay_pin, state);
digitalWrite(gpio13greenled_pin, val2);
digitalWrite(gpio14redled_pin, val3);


// 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\nThe power relay is now ";
s += (val0)?"on":"off";
s += "<BR>";

// Send the response to the client
// just a test - build a decent web page with buttons etc here

if (val2 == 0) { client.print("the green LED is on <BR>");}
else { client.print("the green LED is off <BR>");}

if (val3 == 0) { client.print("the red LED is on <BR>");}
else { client.print("the red LED is off <BR></html>");}

Serial.println("Client disonnected");

// The client will actually be disconnected
// when the function returns and 'client' object is destroyed
//=================================================== loop end

The .ino sketch above

Drive the red lamp in the red/green LED - 1 Kohm to gpio14


The white LED connected to the relay coil


Use the radio pins to send signals to the other side of the board
- the white LED and 1Kohm series resistor connect to the relay coil

Please email me if you want to swap notes