Project tutorial
Adding a Remote Switch to Sonoff: One Pin for Switch+LED

Adding a Remote Switch to Sonoff: One Pin for Switch+LED © LGPL

I want to use Sonoff-basic with a special switch, because it is equipped with an LED that I want to use as a remote indicator of the relay.

  • 1,332 views
  • 0 comments
  • 3 respects

Components and supplies

Sonoff esp8266 with box hackable
Itead Sonoff Basic
×1
Iutnjumlt88q8hki4k2k
Arduino Mini USB serial adapter
Any 3.3V FTDI USB-to-Serial Converter/Programmer
×1

Necessary tools and machines

09507 01
Soldering iron (generic)

Apps and online services

Ide web
Arduino IDE
Using compilate firmware enough esptool.py (https://github.com/espressif/esptool)
esp_mqtt

About this project

I want to use Sonoff-basic with the following switch, because it is equipped with an LED that I want to use as a remote indicator of the relay status.

This is the internal circuit diagram of the switch (3 pins):

The switch must operate in 'OR' with respect to the control MQTT commands.

  • If the switch is OFF, the relay is controlled with the MQTT commands or with the button included in Sonoff, and the LED indicates the status of the relay.
  • If the switch is ON, the relay is closed and the LED is on
  • When the ON switch goes OFF, the relay status depends on the received MQTT commands: the relay can be closed (and LED on) or open (and LED off).

You have to imagine a timed heating, with the possibility to switch it ON manually at any moment. Once the manual intervention has been completed, the timing must continue undisturbed.

By connecting the switch as shown in the figure (the added pulldown resistor is 4.7 KΩ):

  • if GPIO14 is programmed as input, the switch position can be read,
  • if GPIO14 is programmed as output, and has a high value, the LED will light even if the switch is open (required current: 1.7 mA).

The software must therefore operate in polling (it is not possible to generate an interrupt when the LED is ON and the switch goes from OFF to ON): the SW must read the switch status every 100 ms, and after must turn ON the LED with the switch open when necessary.

You could create an ad hoc SW with Arduino IDE, but it is easier to use esp_mqtt which offers, among other things, a MQTT broker + client with a script language that is ideal for these tasks.

In the firmware dir are the compiled files, so you can simply update the Sonoff FW using esptoot with the following command (in WIN 10, COM6 can change):

esptool.py --port COM6 write_flash -fs 1MB -fm dout 0x00000 0x00000.bin 0x10000 0x10000.bin

For more information on how to program a Sonoff, see http://randomnerdtutorials.com/how-to-flash-a-custom-firmware-to-sonoff/

You must then load on Sonoff the script code here (sonoffscript.txt), e.g. using a local web server:

script http://192.168.???.???/www/sonoff/sonoffscript.txt

Last you must wire the switch to 3.3V, GIPIO14, GND: all are on the 5 pin adapter used to program Sonoff.

Now you can control the Sonoff relay old-way, using the switch, or via any MQTT client (also on smartphone), and you don't neeed any external MQTT-broker.

Code

Extra switchPlain text
Script for Sonoff esp_mqtt
% implements MQTT ON/OFF, local TOGGLE (interrupt) + remote ON/OFF (polling)
% derived by script.sonoff (https://github.com/martin-ger/esp_mqtt/blob/master/scripts/script.sonoff)
% Config params, overwrite any previous settings from the commandline

config ap_ssid      MQTT_home
config ap_password	sonoffbroker
config ntp_server	  1.it.pool.ntp.org
config ntp_timezone 1
config broker_user      none
config broker_password	none
config mqtt_host	      192.168.???.???
config speed	          160

% Now the initialization, this is done once after booting
on init
do
	% Device number ("* 1" to make even "" a number)
	setvar $device_number = @1 * 1

	% @<num> vars are stored in flash and are persistent even after reboot 
	setvar $run = @2 + 1
	setvar @2 = $run

	% Status of the relay
	setvar $relay_status = 0
	gpio_out 12 $relay_status
  gpio_out 13 not($relay_status)

  % Switch status
 	gpio_pinmode 14 input
  setvar  $switch_status = not(gpio_in(14))
  
	% Command topic
	setvar $command_topic = "/martinshome/switch/" | $device_number | "/command"

	% Status topic
	setvar $status_topic = "/martinshome/switch/" | $device_number | "/status"

	% local subscriptions once in 'init'
	subscribe local $command_topic
  settimer 1 100

% Now the MQTT client init, this is done each time the client connects
on mqttconnect
do
% remote subscriptions for each connection in 'mqttconnect'
	subscribe remote $command_topic
  publish remote $status_topic "{Start:\"" | $timestamp | "\",Run:" | $run | "}" retained
   
% Now the events, checked whenever something happens

% Is there a remote command?
on topic remote $command_topic
do
	println "Received remote command: " | $this_data
  if $this_data = "on" then
		setvar $relay_status = 1
    endif
  if $this_data = "off" then
		setvar $relay_status = 0
    endif 
    
% republish this locally - this does the action
	publish local $command_topic $this_data

% Is there a local command?
on topic local $command_topic
do
	println "Received local command: " | $this_data
  
	if $this_data = "on" then
    println " -- do on "
	  gpio_out 12 1
 		gpio_out 13 0
    endif
    
	if $this_data = "off" then
    if $switch_status = 0 then
      println " -- do off"
	    gpio_out 12 $relay_status
		  gpio_out 13 not($relay_status)
      endif
	  endif
		
  if $this_data = "toggle" then
    if $switch_status = 0 then
      println " -- do toggle"
	  	setvar $relay_status = not($relay_status)
	  	gpio_out 12 $relay_status
 	   	gpio_out 13 not($relay_status)
      endif
	  endif
    
  publish remote $status_topic "{Time:\"" | $timestamp | "\",Power:" | ($relay_status + $switch_status) > 0 | "}" retained

% The local pushbutton, interrupt
on gpio_interrupt 0 pullup
do
	if $this_gpio = 0 then 
% toggle action only if switch off
     if $switch_status = 0 then
        publish remote $status_topic "{Time:" | $timestamp | ",TOGGLE}"  retained
 		    publish local $command_topic "toggle"
      endif
	  endif

% The remote switch, polling
on timer 1
do
	gpio_pinmode 14 input
% switch is changed?
  if $switch_status = not(gpio_in(14)) then
    setvar $switch_status = gpio_in(14)
    if $switch_status = 1 then
% publish user action and local command    
        publish remote $status_topic  "{Time:" | $timestamp | ",ON}" retained
        publish local $command_topic "on"  
    else
        publish remote $status_topic  "{Time:" | $timestamp | ",OFF}" retained
        publish local $command_topic "off"  
    endif
  endif
% restore the switch led on  
  if $switch_status = 0 then
     if $relay_status = 1 then
        gpio_out 14 1
     endif
  endif
	settimer 1 100
	

Schematics

extra switch
One line for switch+led
Schema02 czqs0tuusf

Comments

Similar projects you might like

Paint Your Dimmer Switch on the Wall

Project tutorial by Brian Carbonette

  • 13,082 views
  • 0 comments
  • 39 respects

IR Remote Controlled Power Switch for Rapsberry Pi 3

Project tutorial by Vilém Kužel

  • 2,421 views
  • 1 comment
  • 9 respects

Adding Bluetooth to Your Arduino (+Light Sensor)

Project tutorial by IoTaLabs

  • 5,407 views
  • 1 comment
  • 20 respects

Alexa Enabled USB Power Switch

Project tutorial by Stephen Harrison

  • 4,817 views
  • 7 comments
  • 31 respects

Add Remote Control to Your Lamp

Project tutorial by zhaoshentech

  • 1,939 views
  • 0 comments
  • 10 respects
Add projectSign up / Login