ESP8266 Basic Relay Clock
Posted: Sat Jan 07, 2017 1:08 pm
Here is a little project I made for a friend of mine. Its a programmable relay/clock. All relay times are added using the web interface. It only uses 2 components, 4 dupont wires and a 5 volt wall wart. The main module is from Olimex and has an ESP8266 with 2M, power supply, button, relay and gpio pins. The display is an I2C module from Adafruit. The Olimex board has the pullups on GPIO 2 and GPIO 4 already for the I2C (how convenient). There are more things that can be added of course, like dim the display with a slider or at a certain time, or getting rid of the 30 second start up time, etc. I am not the greatest coder, so if you see something that can be improved, please let me know.
When you first power it up and it hasn't connected to your wifi network, it will display 192 then 168 then 4 then 1, then you would connect to the AP and go to 192.168.4.1 in your browser. It will display a simple web page to ask for your wifi data then reboot. It will then display the IP address so you can connect to it using a browser. It will then just display the current time and check every second to see if the relay should be on or off. It will also adjust for the daylight savings time. You can also toggle the relay from the webpage. The stand is 1/8" acrylic that was bent using a hotwire bender. Other than putting the adafruit display together, there is no other soldering necessary.
The on board button has 2 operations. If you press it quickly, it will toggle the relay. If you hold it for more than 2 seconds and release, it will display its IP address in case you forget it. This excellent piece of code is from Electroguard. The I2C display code is from Viscomjim. Most all of the code was found on this forum and of course, the excellent work of Mike!!!
I am still having a problem with adding more than 5 on off times and the winsock connect/disconnect working correctly, but will keep playing. Please let me know if you have any ideas about this.
Display - https://www.adafruit.com/product/879
ESPboard - https://www.olimex.com/Products/IoT/ESP ... e-hardware
available here... https://www.digikey.com/product-detail/ ... ND/5226245
The power and I2C connections for the display are shown in red in the board schematic below...
When you first power it up and it hasn't connected to your wifi network, it will display 192 then 168 then 4 then 1, then you would connect to the AP and go to 192.168.4.1 in your browser. It will display a simple web page to ask for your wifi data then reboot. It will then display the IP address so you can connect to it using a browser. It will then just display the current time and check every second to see if the relay should be on or off. It will also adjust for the daylight savings time. You can also toggle the relay from the webpage. The stand is 1/8" acrylic that was bent using a hotwire bender. Other than putting the adafruit display together, there is no other soldering necessary.
The on board button has 2 operations. If you press it quickly, it will toggle the relay. If you hold it for more than 2 seconds and release, it will display its IP address in case you forget it. This excellent piece of code is from Electroguard. The I2C display code is from Viscomjim. Most all of the code was found on this forum and of course, the excellent work of Mike!!!
I am still having a problem with adding more than 5 on off times and the winsock connect/disconnect working correctly, but will keep playing. Please let me know if you have any ideas about this.
Display - https://www.adafruit.com/product/879
ESPboard - https://www.olimex.com/Products/IoT/ESP ... e-hardware
available here... https://www.digikey.com/product-detail/ ... ND/5226245
The power and I2C connections for the display are shown in red in the board schematic below...
Code: Select all
cls
memclear
localip = ip()
brightness = 15
relay = D1
'led = 1
buttonpin = D3
address = 112
count = 1
col = 0
dot = 0
timer 0
gosub [relayoff]
dim digits(11)
digits(0) = 63
digits(1) = 6
digits(2) = 91
digits(3) = 79
digits(4) = 102
digits(5) = 109
digits(6) = 125
digits(7) = 7
digits(8) = 127
digits(9) = 111
digits(10) = 0
'************ INITIALIZE DISPLAY
i2c.setup(D4,D2)
i2c.begin(address)
i2c.write(33)
i2c.end()
i2c.begin(address)
i2c.write(129)
i2c.end()
i2c.begin(address)
bright = 224 + brightness
i2c.write(bright)
i2c.end()
delay 10
i2c.begin(address)
i2c.write(4)
i2c.write(0)
i2c.end()
gosub [showip]
'************ CHECK IF AP MODE
if localip = "192.168.4.1" then
cls
wprint "Welcome to Relay Clock <br>"
wprint "Enter your WIFI info below <br>"
wprint "Hit Save and Reboot <br><br>"
wprint "WIFI Name:"
textbox wifiname
wprint "<br>"
wprint "WIFI Pass:"
textbox wifipass
wprint "<br><br>"
button "Save WIFI Settings",[wifiupdate]
wprint "<br> <br>"
button "Reboot Clock",[reboot]
wprint "<br> <br>"
wait
end if
'************ GET SAVED INFO
dst = read.val(DaylightSavings)
timezone = read.val(TZ)
wifiname = read(WIFIname)
wifipass = read(WIFIpass)
ontime1 = read(ontimes1)
ontime2 = read(ontimes2)
ontime3 = read(ontimes3)
ontime4 = read(ontimes4)
ontime5 = read(ontimes5)
offtime1 = read(offtimes1)
offtime2 = read(offtimes2)
offtime3 = read(offtimes3)
offtime4 = read(offtimes4)
offtime5 = read(offtimes5)
if dst = 1 then
tz = timezone + 1
else
tz = timezone
endif
timesetup(tz,dst)
delay 5000
interrupt buttonpin, [pressed]
serialprintln "flash 1 " & flashfree()
serialprintln "ram 1 " & ramfree()
wprint "<h2>RELAY CLOCK V1.0</h2>"
wprint "<br>"
curtime = time("hour:min:sec")
wprint "Time Now: "
textbox curtime
wprint "<br><br>"
wprint "Timezone: "
textbox timezone
wprint "<br>"
wprint "DST 1 or 0: "
textbox dst
wprint "<br><br>"
button "Update Time Info",[timeupdate]
wprint "<br><br>"
wprint "Enter relay times in HH:MM:SS 24 hour format"
wprint "<br>"
wprint |Press "Save Relay Times" button when done|
wprint "<br><br>"
wprint "On Time 1 "
textbox ontime1
wprint "Off Time 1"
textbox offtime1
wprint "<br>"
wprint "On Time 2 "
textbox ontime2
wprint "Off Time 2"
textbox offtime2
wprint "<br>"
wprint "On Time 3 "
textbox ontime3
wprint "Off Time 3"
textbox offtime3
wprint "<br>"
wprint "On Time 4 "
textbox ontime4
wprint "Off Time 4"
textbox offtime4
wprint "<br>"
wprint "On Time 5 "
textbox ontime5
wprint "Off Time 5"
textbox offtime5
wprint "<br>"
button "Save Relay Times",[updrelay]
wprint "<br><br>"
button "Toggle Relay",[togrelay]
textbox relaystat
wprint "<br><br>"
button "End Program",[exit]
returngui
timer 1000,[colon]
wait
'************ COLON 1000ms *************
[colon]
if col = 0 then dot = 0 else dot = 2
i2c.begin(address)
i2c.write(4)
i2c.write(dot)
i2c.end()
delay 10
if col = 1 then col = 0 else col = 1
curtime = time("hour:min:sec")
gosub [checkrelay]
gosub [refresh]
wait
'************ BUTTON PRESSED *************
[pressed]
if io(laststat,buttonpin) == 0 then start = millis() else stop = millis()
if stop > start then
if stop-start < 2000 then goto [togrelay] else gosub [showip]
endif
wait
'************ CHECK RELAY TIMES *************
[checkrelay]
if curtime = ontime1 then gosub [relayon]
if curtime = offtime1 then gosub [relayoff]
if curtime = ontime2 then gosub [relayon]
if curtime = offtime2 then gosub [relayoff]
if curtime = ontime3 then gosub [relayon]
if curtime = offtime3 then gosub [relayoff]
if curtime = ontime4 then gosub [relayon]
if curtime = offtime4 then gosub [relayoff]
if curtime = ontime5 then gosub [relayon]
if curtime = offtime5 then gosub [relayoff]
return
'************ REFRESH TIME *************
[refresh]
minx = val(time("min"))
hourx = val(time("hour"))
dig4 = minx%10
dig3 = int((minx/10))
dig2 = hourx%10
dig1 = int((hourx/10))
'remove leading zeros
if dig1 = 0 then
dig1 = 10
if dig2 = 0 then
dig2 = 10
if dig3 = 0 then
dig3 = 10
if dig4 = 0 then
dig4 = 10
end if
end if
end if
end if
gosub [write4dig]
if curtime = "02:00:00" then
gosub [checkdst]
timesetup(tz,dst)
delay 5000
endif
return
'************ SHOW IP ADDRESS *************
[showip]
i2c.begin(address)
i2c.write(4)
i2c.write(0)
i2c.end()
connum = 0
gosub [convertdig]
gosub [write4dig]
for zz = 1 to 4
ipnumstr = word(localip,zz,".")
connum = val(ipnumstr)
gosub [convertdig]
gosub [write4dig]
delay 1000
connum = 0
gosub [convertdig]
gosub [write4dig]
delay 400
next zz
delay 500
return
'************ CONVERT DIGITS *************
[convertdig]
dig1 = int(connum/1000)
dig2 = int((connum%1000)/100)
dig3 = int((connum%100)/10)
dig4 = int(connum%10)
'remove leading zeros
if dig1 = 0 then
dig1 = 10
if dig2 = 0 then
dig2 = 10
if dig3 = 0 then
dig3 = 10
if dig4 = 0 then
dig4 = 10
end if
end if
end if
end if
return
'************ WRITE 4 DIGITS *************
[write4dig]
i2c.begin(address)
i2c.write(0)
i2c.write(digits(dig1))
i2c.end()
delay 10
i2c.begin(address)
i2c.write(2)
i2c.write(digits(dig2))
i2c.end()
delay 10
i2c.begin(address)
i2c.write(6)
i2c.write(digits(dig3))
i2c.end()
delay 10
i2c.begin(address)
i2c.write(8)
i2c.write(digits(dig4))
i2c.end()
delay 10
return
'************ TOGGLE RELAY *************
[togrelay]
if io(laststat,relay) = 0 then gosub [relayon] else gosub [relayoff]
wait
'************ UPDATE RELAY ON/OFF TIMES *************
[updrelay]
write(ontimes1,ontime1)
write(offtimes1,offtime1)
write(ontimes2,ontime2)
write(offtimes2,offtime2)
write(ontimes3,ontime3)
write(offtimes3,offtime3)
write(ontimes4,ontime4)
write(offtimes4,offtime4)
write(ontimes5,ontime5)
write(offtimes5,offtime5)
wait
'************ UPDATE TIME INFO *************
[timeupdate]
write(DaylightSavings,str(dst))
write(TZ,str(timezone))
if dst = 1 then
tz = timezone + 1
else
tz = timezone
endif
timesetup(tz,dst)
delay 5000
curtime = time("hour:min:sec")
wait
'************ UPDATE WIFI INFO *************
[wifiupdate]
write(WIFIname,wifiname)
write(WIFIpass,wifipass)
wprint "WIFI info saved..."
wait
'************ REBOOT CLOCK *************
[reboot]
cls
wprint "REBOOTING..."
delay 1000
reboot
wait
'************ RELAY ON SUB *************
[relayon]
relaystat = "Relay is ON"
io(po,relay,1)
return
'************ RELAY OFF SUB *************
[relayoff]
relaystat = "Relay is OFF"
io(po,relay,0)
return
'************ CHECK DST *************
[checkdst]
dow = time("dow")
day = time("day")
month = time("month")
hour = time("hour")
if ((dst = 1) and (dow = "Sun") and (month = "Nov") and (day >= 3) and (day <= 5)) then
dst = 0
write(DaylightSavings,str(dst))
endif
if ((dst = 0) and (dow = "Sun") and (month = "Mar") and (day >=8) and (day < 15)) then
dst = 1
write(DaylightSavings,str(dst))
endif
return
'************ EXIT PROGRAM *************
[exit]
timer 0
wprint "<a href='/'>Menu</a>"
end