Home Automation blog

Skip to Content

Wifi enabled lamp

Article image for Wifi enabled lamp

Posted by Chris

Date posted:

Using Sonoff, a wifi enabled AC mains relay switch, I upgraded my bedside lamp to be controllable by my home automation system - A Raspberry Pi running Node-RED with HomeKit nodes communitcating to the Sonoff via MQTT. And with a capacitive touch sensor.

Arduino IDE

  1. You'll need to install additional board libraries for the IDE to be able to flash the Sonoff, this esp8266 package URL goes into the IDE's settings "Additional Boards Manager URLs".
  2. Open Boards Manager window. You'll be prompted to install the additional boards for the esp8266 chip.
  3. Board: Generic ESP8266 Module
  4. Flash mode: DOUT - This is a recent change by the Sonoff manufacturer and can leave your Sonoff bricked after flashing if not set correctly.
  5. Flash size: 1M (64K SPIFFS)

Flashing the Sonoff

Diagram of wiring Sonoff to FTDI module

Using an FTDI USB to Serial module you can flash the sonoff to run your own Arduino code. See diagram above for wiring guide. Be sure to connect RX to TX, TX to RX. And switch the FTDI module to 3.3v mode. Before connecting the 3.3v line, hold the GPIO-0 button down keeping it pressed as you connect the 3.3v, then release. This puts the sonoff into flash mode, enabling the sonoff to be re-programmed. Otherwise the Sonoff will run it's current program and communication via USB will fail.

Never connect live AC input while flashing / working with the Sonoff. High voltage current is dangerous.

The code

Using my multi-function buttons libray the Sonoff can receive input from the capacitive touch sensor and from the home automation system. In my code the Sonoff doesn't store the "mode/state" of the lamp. It state is determined by the home automation system. The Sonoff receives a "1" to swtich the lamp on, "0" for off.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <MultiFunctionButton.h>


// WIFI
const char wifi_user[] = "XXXX";
const char wifi_pass[] = "XXXX";
WiFiClient sonoff;

// MQTT
IPAddress mqtt_server(XX, XX, XX, XX);
PubSubClient mqtt(sonoff);
String mqtt_client = "bedlamp1";
const char mqtt_user[] = "XXXX";
const char mqtt_pass[] = "XXXX";
const char mqtt_sub[] = "device/bed1/lamps/1";

// Sonoff outputs
const int RELAY = 12;
const int LED = 13;

// Button
MultiFunctionButton btn1;



void setup()
{
	pinMode(LED, OUTPUT);
	pinMode(RELAY, OUTPUT);
	btn1.configure(14, 0, onPress, onDblPress, onHold);

	WiFi.begin(wifi_user, wifi_pass);
	while (WiFi.status() != WL_CONNECTED)
	{
		delay(500);
	}
	
	randomSeed(micros());

	mqtt.setServer(mqtt_server, 1883);
	mqtt.setCallback(callBack);
}



void loop()
{
	if (!mqtt.connected())
	{
		reconnect();
  	}

	mqtt.loop();
	btn1.check();
}



/**
 * Reconnect to MQTT server
 */
void reconnect()
{
	while (!mqtt.connected())
	{
		mqtt_client += String(random(0xffff), HEX);
		
		if (mqtt.connect(mqtt_client.c_str(), mqtt_user, mqtt_pass))
		{
			mqtt.subscribe(mqtt_sub);
			digitalWrite(LED, HIGH); // LED off, setup is complete
		}
		else
		{
			delay(5000);
		}
	}
}



/**
 * Receive MQTT message
 */
void callBack(char* topic, byte* payload, unsigned int length)
{
	if (payload[0] == 49)
	{
		// 1 = ON
		digitalWrite(RELAY, HIGH);
	
	}
	else if (payload[0] == 48)
	{
		// 0 = OFF
		digitalWrite(RELAY, LOW);
	}
}



/**
 * Single press
 * Send MQTT message
 */
void onPress(int pin)
{
	mqtt.publish("nodered/bed1/lamp/1","pressed");
}



/**
 * Double press
 * Send MQTT message
 */
void onDblPress(int pin)
{
	mqtt.publish("nodered/bed1/lamp/1","double");
}



/**
 * Holding button
 * Send MQTT message
 */
void onHold(int pin)
{
	mqtt.publish("nodered/bed1/lamp/1","hold");
}

 

The button

The capacitive touch sensor connects to the Sonoff's 3.3v, GND and GIO-14 pins. In the above code within the setup function, the button is configured to listen on pin 14.

The touch events are sent to Node-RED via MQTT topics which then Node-RED determines what "state/mode" the lamp should be and sends a MQTT message back to the Sonoff to either switch the lamp on or off.

The touch events could be used to trigger actions for other devices other than the lamp itself. Example: the double press event could toggle all lamps in that room. Which is why the code on the Sonoff only sends the touch events and receives it's state from Node-Red. Allowing you to "re-program" what these touch events are to action without having to reflash your Sonoff.

Diagram of wiring capacitive touch sensor to Sonoff