- Fri May 06, 2016 1:33 am
#46960
ESP_Basic Driving Lessons - Chapter 7.RelayESP_Basic uses 0 as a gpio 'On' and 1 as a gpio 'Off', which is the opposite to the 1 and 0 On/Off markings you would expect to find on a switch or appliance.
That's because an ESP's gpio's would normally ground an LED which is supplied by VCC, so the gpio pin is taken 'Low' to turn the LED 'On'. Therefore the LED is normally 'Active Low'.
A relay usually requires more current to operate than an LED so is often driven via a transistor, which doesn't need much 'base' current to switch typically 100 times more 'collector' current for driving the relay coil, but when in that configuration the transistor acts as an inverter (inverting the logic), therefore although the relay itself is active low, the transistor input requires a High voltage on its 'base' in order to switch On the relay... so the transistorised relay is effectively 'Active High'.
It's easy enough to know what gpio levels are needed to turn On or Off either active highs or active lows, but it gets very complicated trying to keep track of what's required to cause a change of state when toggling them. Rather than using different variables that require constant updating and keeping in sync, I use a much more economical method that is perhaps not intuitive and therefore needs a quick explanation, but is worth knowing.
To keep things relevent, we will assume the very cheap and readily available Sonoff mains switching relay module (which I will be coming back to shortly), but the same applies to whatever switched relay module you care to use, including any 'home brew' creations.
At the start of your script you define your LED and relay gpio pins, and also whether they are active high or active low by defining their default Off states. That is eazy-peazy, and allows simple configuration for all combinations which you might need to cater for - which in our Sonoff example requires an active high relay on pin 12, and an active low LED on pin 13.
let relaypin = 12
let ledpin = 13
let relaylogic = 0 'Relay pin is active high, so its default Off state is Low
let ledlogic = 1 'LED pin is active low, so its default Off state is High
We want the LED to 'echo' the relay state and act as a Relay indicator, and we therefore need them both to initialise to Off, so we use our defined 'logics' as their Off states.
io(po,relaypin,relaylogic) ' turns the active high relay Off as defined by the relaylogic
io(po,ledpin,ledlogic) ' turns the active low led Off as defined by the ledlogic
Once you understand the concept of using their relative 'logics' as their Off states - irrespective of absolute highs or lows or whether active high or active low - then you can use the logics to similarly discover their states at any time just by doing an appropriate compare with the logic, ie...
if io(laststat,relaypin) == relaylogic then wprint "Relay is Off" else wprint "Relay is On"
and similarly...
if io(laststat,ledpin) == ledlogic then wprint "LED is Off" else wprint "LED is On"
So now that you know what the code is doing, we can add it into the script without causing confusion. Combining things together, our Toolbox will now aquire different methods of controlling a relay, and availability of multiple web pages which allows us to offer a Help page, plus a Configuration page which will include an option to save changes to non-volatile memory for automatic re-reading at the next restart or power-up.
We may not have much configuration info to save at the moment, but that will soon change - so in a moment when you check out the next script you should pay particular attention to how we avoid overwriting configuration defaults with any un-saved optional empty read variables. You should also be aware for future reference that numeric variables are saved and read back from file i/o as text variables - so 'writing' a numeric variable called mynumber with a numeric value of 123 will cause you problems when 'reading' it back to the same mynumber variable which will then be changed into a text variable and have the text value of "123", and therefore subsequently cause invalid variable 'type' errors.
The only way around it at the moment with Alpha24 is to convert your numeric variables into text variables for writing and reading, which works ok, but means you require 2 lots of variable names for each numeric variable you wish to use and save to memory. On the plus side, writing and reading variable length text info into non-volatile memory is an absolute doddle.
We have also introduced a hardware pin interrupt into our toolkit, offering the facility to locally toggle the relay using the gpio0 flashing button. ESP_Basic makes the daunting subject of hardware interrupts very easy to use - you just need to be aware that both rising and falling interrupts are generated (will be dealt with later), and that software pullups are not currently available so a hardware pullup resistor (typically about 10K) may need to be added (the Sonoff module already contains a hardware pullup resistor, but the Ser Dev Kit module does not).
Sonoff ModuleThe Sonoff is a ready-built low-cost ESP-8266-based small switched-mains module available from places like ebay for about £6. It has some issues you need to be aware of, but it is cheap and convenient and readily hackable, and the issues are not any worse than you would face if making your own home-brew equivalent.
There is a Sonoff version available which includes an RF remote control capability, but for the purposes of this tutorial I am going to be assuming the basic non-RF version.
The relay is single-pole, so for obvious safety reasons you should ensure that the relay switches the live rather than the neutral, else everything live will remain permanently live.
Also for obvious safety reasons it is advisable to connect up a pass-through earth wire between the mains input and switched mains output.
Pay attention to the marked mains input and mains output directions because they are not bi-directional.
Although the relay is rated at 10Amps, I would not recommend switching 10A loads via the soldered pcb tracks which have to carry that mains current - if you wish to control high currents for heaters etc, better to use the Sonoff just to switch an external higher current double-pole mains relay.
IMPORTANT - The Sonoff onboard 3.3v supply is derived from the mains, and could be at mains potential, so you are strongly advised against making any physical non-mains connection to the Sonoff while it is connected to the mains. YOU HAVE BEEN WARNED.
Flashing Pins hack.The first thing to do is solder pins into the vacant 4 or 5 0.1" pitch holes which connect to 3.3v, RX, TX, GND (and in the newer 5 hole versions, gpio14).
This will then allow connecting the unit to an external 3.3v supply and a uart for flashing.
One of the great advantages of ESP_Basic of course, is that once flashed, all subsequent programming is non-contact OTA using wifi.
The onboard gpio00 button can be used to enter flashing mode at bootup. It already has a pullup resistor, so can also be used for user input during normal operation. The relay is driven by gpio12 and is active high. The green side of the bi-colour led connects to gpio13 and is active low. I believe the red side connects to the optional RF module, but it's not something we need to bother with.
If you have a recent version it will have a 5th pin hole which is connected to gpio14 and can be used to connect a DHT temperature and humidity sensor if wished, and details will be given later for turning the Sonoff into a temperature or humidity stat.
Button hack. It is possible to do a button hack to extend the buttons pins out via a pair of wires to an external button. As previously mentioned, the following code allows use of the onboard button to locally toggle the relay if required.
So if you think about that, it is quite feasible to use a wall switch connected to the Sonoff by low voltage extended button wires to control mains room lighting, and of course along with the already existing capability of also controlling the room lighting via tablet or mobile wifi connection (and possibly also by RF remote control if you have the RF version!). By default the wall switch would need to be a momentary press switch, but you are in control of sensing the 'press' and 'release' interrupts, so you could modify for normal on/off switch operation if wished.
The Sonoff is claimed to work from 90 to 250 V AC - so for less than a tenner per switch you could convert all your room lighting to wifi and/or RF remote control no matter wherever you live in the world... now that's got to be better than a kick up the bum, init!
5v hack. Suppose you want the relay to switch some other voltage instead of the mains. The problem is that the onboard 5v supply is taken from the mains tracks on the pcb, so if you do not supply the Sonoff with mains you will not have the onboard 5v supply to power the electronics.
There is a 5v hack that lets you supply the board with 5v from an external supply (eg: USB) across diode D5 on the underside of the pcb, which therefore allows you to use the relay switched contacts for low voltages other than mains.
Or you could similarly supply external 3.3v to the flashing pins, and the relay will still operate ok (mine does anyway). The alternative would be to use the unhacked switched mains to operate an external mains relay and use those contacts for low volts use.
Relay Control code Code: Select all'SonOff example
memclear
let ledpin = 13
let ledlogic = 1 ' Default led pin off state
let relaypin = 12
let relaylogic = 0 ' Default relay pin off state
io(po,ledpin,ledlogic)
io(po,relaypin,relaylogic)
let localbutton = 0 ' Uses onboard GOIO00 flashing button by default, change to suit.
interrupt localbutton [PRESSED] ' Interrupt pin requires a pull-up resistor to work.
gosub [READVARS]
if name == "" then let name = "Electroguard"
if description == "" then let description = "Switched Mains Relay - version 1"
let esp_basic = " - Developed on Alpha 24"
[HOME]
cls
print " "
button " ? " [HELP]
wprint " "
wprint name & " " & description & esp_basic
print " "
wprint "<BR><BR><BR>"
if io(laststat,relaypin) == relaylogic then wprint "Relay is OFF" else wprint "Relay is ON"
wprint "<BR><BR><BR>"
button "On" [RELAYON]
button "toggle" [TOGGLE]
button "Off" [RELAYOFF]
wprint "<BR><BR><BR>"
button "Configuration" [CONFIG]
wait
[HELP]
cls
print " "
button "X" [HOME]
wprint " "
wprint name & " " & description & esp_basic
print " "
wprint "<BR>"
wprint "<BR><BR>"
wprint "On, Off and Toggle switching of relay"
wprint "<BR><BR>"
wprint "Also offers local hardware button toggle of relay."
wprint "<BR><BR>"
wprint "Configuration options allow changing of title Name and Description."
wprint "<BR><BR>"
wprint "Home button changes are temporary, Save button changes are permanent to non-volatile flash memory."
wprint "<BR><BR>"
wprint "This script is configured for a Sonoff module, but should be adaptable for any alternative "
wprint "switched relay modules."
wprint "<BR><BR>"
wprint "Sonoff pins - button=0, led=12, relay=13. "
wprint "<BR>"
wprint "Sonoff relay is active high, so relaylogic=0 (OFF default=0)."
wprint "<BR>"
wprint "Ledlogic=1 (active low),"
wprint "<BR>"
wprint "<BR><BR>"
button "Home" [HOME]
wait
[CONFIG]
cls
print " "
button "X" [HOME]
wprint " "
wprint name & " " & description & esp_basic
print " "
wprint "<BR><BR>"
html "Name: "
textbox name
wprint " "
html "Description: "
textbox description
'html "<BR><BR>"
wprint "<BR><BR><BR>"
button "Home" [HOME] ' don't save edits
wprint " "
button "Save" [SAVE] ' save details to persistent memory
wprint " "
wprint "HOME loses changes at power-off, SAVE holds changes in non-volatile flash memory. "
wprint "<BR><BR>"
wait
[READVARS]
read Name name ' "Name" = flash memory var name, "name" = ESP_Basic var name
read Description description
return
[SAVE]
write Name name
write Description description
goto [HOME]
[RELAYON]
if relaylogic == 0 then io(po,relaypin,1) else io(po,relaypin,0)
if ledlogic == 0 then io(po,ledpin,1) else io(po,ledpin,0)
goto [HOME]
[RELAYOFF]
if relaylogic == 0 then io(po,relaypin,0) else io(po,relaypin,1)
if ledlogic == 0 then io(po,ledpin,0) else io(po,ledpin,1)
goto [HOME]
[TOGGLE]
if io(laststat,relaypin) = 0 then io(po,relaypin,1) else io(po,relaypin,0)
if io(laststat,ledpin) = 0 then io(po,ledpin,1) else io(po,ledpin,0)
goto [HOME]
[PRESSED]
if io(laststat,localbutton) = 0 then goto [TOGGLE] ' (toggles only on button press instead of on button release)
goto [HOME]
This gives you several things to check out and be comfortable with - try temporarily changing info in the configuration, then exiting and restarting the program, then do likewise after permanently saving changes to non-voltaile memory. Be aware that there are currently no housekeeping file commands in Alpha 24, so whatever variables you create will stick with you like a fart in a spacesuit until you do a reformat and reflash of the wee beastie.
Note also how responsive the actual relay and led changes are, even though there may be some slight lag in the browser status being updated.
Don't forget to try toggling the relay with the gpio00 hardware button.
Note that the script is looking for just the button presses and not toggling on the releases, otherwise it would act like a momentary switch just while the button is held down... which perhaps may be the sort of behaviour you might need for some future project. Something else you may want to consider for the future is that if you change the interrupt to only act on the release (instead of the press), it would allow you to time how long the button was pressed down and enable you to take different actions for long or short presses if you wished... ie a short press could toggle the relay, whereas a long press might blink the IP address on the led. But we are getting ahead of ourselves, because different actions are something which can be selected and saved as default behaviour using a configuration setting if wished.
Last edited by Electroguard on Mon May 30, 2016 5:08 pm, edited 2 times in total.