Your Pages‎ > ‎Users Pages‎ > ‎Robin‎ > ‎shelved‎ > ‎

Project - Controlled Relay



Adds CycleON and CycleOFF buttons to the previous Simple Relay, which now
offers an optional Delay and an optional Duration to the On and Off operations.
Delays and Durations can be enabled/disabled using the appropriate checkboxs.
A disabled Delay will operate immediately irrespective of the set value.
A disabled Duration will not return to it's previous state after it has been triggered.
Taking the above screenshot values as examples, and referring to the (unrelated) right-hand timing diagrams...
CycleON button would immediately switch (eg:) a lamp On (because delay is unchecked) then switch it back Off after the elapsed 1 min duration.
CycleOFF button would delay 7 seconds then switch power Off to (eg:) reboot a router then switch it back On again after an 8 sec Off duration.

NOTE:  We cannot use the 'pause' instruction for timing our intervals because it is 'blocking' so would prevent anything else from happening.
We cannot directly assign a timer for all intervals because there are not enough timers available, plus we will need more for a later project.
So our solution is to use a timer to provide a 1sec clock, and define appropriate 'virtual timer' interval countdowns decremented every second until they each reach 0 and trigger their appropriate events. This allows us to have multiple virtual timers which are all non-blocking.
The onboard Sonoff green LED behaviour has been modified to blink while any virtual timers are still pending, rather than echo relay status.
 
NOTE:  Wifi-Basic timer values are specified in milliseconds, where 1000 ms = 1 secs.
So * 60 would be 1 mins, another * 60 would be 1 hours, and then * 24 would be 1 days ... these same multiplier values are used by the script.

CiccioCB NOTE:
All works ok when first RUN, but the only problem is that as soon as anything is clicked (even Toggle or Instant On or Off which have nothing to do with any controlled params), it loses the listbox 'multiplier' contents (secs or mins etc)... the actual parameter is still ok, but just not displayed
Eg: if you change CycleON  'On duration' to 1 secs instead of 1 mins then click CycleON button the relay will correctly turn off after just 1 sec.
 
I thought it must be a Refresh problem, which is how come those irrelevant Refreshes got included in the stripped down Simple Relay version...
cos I had Refreshes dotted around like a chicken-pox rash trying to fix the problem - but I must give in and hope Mr Wizard can fix it for me.

Basic:
title$  = "Controlled Relay" 
led = 1                                                 'Onscreen LED$ variable, 0=on 1=off,
ledpin = 13                                           'Sonoff green LED (active low)
ledoff = 1                                              'Sonoff LED Off state
pin.mode ledpin, output
pin(ledpin) = ledoff
relaypin = 12                                         'Sonoff relay (active high)
relayoff = 0                                            'Sonoff Relay Off state
pin.mode relaypin, output
pin(relaypin) = 0
buttonpin = 0                                         'Sonoff button (active low)
pin.mode buttonpin, input, pullup
interrupt buttonpin, pressed
ledstat$ = "green"                                  'Toggle button colour
unitslist$ = "secs, mins, hours, days"    'Displayed time multiplier
secs = 1: mins = secs * 60: hours = mins * 60: days = hours * 24
interval = 1
delayon = 0
ondelay = 5
ondelaycountdown = -1
ondelunits$ = "secs"
timedon = 1
onduration = 1
ondurationcountdown = -1
ondurunits$ = "mins"
delayoff = 1
offdelay = 7
offdelaycountdown = -1
offdelunits$ = "secs"
timedoff = 1
offduration = 8
offdurationcountdown = -1
offdurunits$ = "secs"
timer0 1000, ticker                           
gosub paint
onhtmlreload paint
wait

ticker:
'jscall "_$('date').innerHTML = """ + date$ + """"        ' updates the digital display
'jscall "_$('clock').innerHTML = """ + time$ + """"       ' updates the digital display
if ondelaycountdown >= 0 then
 pin(ledpin) = 1 - pin(ledpin)
 if ondelaycountdown > 0 then
  ondelaycountdown = ondelaycountdown -1
 else
  ondelaycountdown = -1
  gosub relayon
  COMMAND "interval=" + ondurunits$
  if timedon = 1 then ondurationcountdown = onduration * interval
 endif
endif
if ondurationcountdown >= 0 then
 if pin(ledpin) = 0 then pin(ledpin) = 1 else pin(ledpin) = 0
 if ondurationcountdown > 0 then
  ondurationcountdown = ondurationcountdown -1
 else
  ondurationcountdown = -1
  gosub relayoff
 endif
endif
if offdelaycountdown >= 0 then
 if pin(ledpin) = 0 then pin(ledpin) = 1 else pin(ledpin) = 0
 if offdelaycountdown > 0 then
  offdelaycountdown = offdelaycountdown -1
 else
  offdelaycountdown = -1
  gosub relayoff
  COMMAND "interval=" + offdurunits$
  if timedoff = 1 then offdurationcountdown = offduration * interval
 endif
endif
if offdurationcountdown >= 0 then
 if pin(ledpin) = 0 then pin(ledpin) = 1 else pin(ledpin) = 0
 if offdurationcountdown > 0 then
  offdurationcountdown = offdurationcountdown -1
 else
  offdurationcountdown = -1
  gosub relayon
 endif
endif
refresh
return


paint:
cls
a$ = a$ + cssid$("tb40", "width:40;")
a$ = a$ + cssid$("tb60", "width:60;")
a$ = a$ + cssid$("butled", "height:3em; font-size:1.5em; border-radius:.4em; padding:.5em; color:white; background:" + ledstat$ + ";")
a$ = a$ + |<br><div style='display: table; margin-right:auto;margin-left:auto;text-align:center;'>|
a$ = a$ + title$ + "<br><br>"
a$ = a$ + led$(led)
a$ = a$ + "<br><br>"
a$ = a$ + button$("Instant On",relayon) + string$(9,"&nbsp;") + button$("Toggle", toggle, "butled") + string$(9,"&nbsp;") + button$("Instant Off",relayoff)
a$ = a$ + "<br>"
a$ = a$ + |<table align='center'><tr><td>|
 a$ = a$ + button$("CycleON&nbsp;", cycleon) + |</td><td>| + " delay " + |</td><td>|
 a$ = a$ + " " + checkbox$(delayon) + |</td><td>|
 a$ = a$ + " " + textbox$(ondelay,"tb40") + |</td><td>|
 a$ = a$ + listbox$(ondelunits$,unitslist$,"tb60") + |</td><td>|
 a$ = a$ + string$(9,"&nbsp;")+ "  On  duration " + |</td><td>|
 a$ = a$ + checkbox$(timedon) + |</td><td>|
 a$ = a$ + " " + textbox$(onduration,"tb40") + |</td><td>| + listbox$(ondurunits$,unitslist$,"tb60") + |</td></tr><br><br><tr><td>|
 a$ = a$ + button$("CycleOFF", cycleoff) + |</td><td>| + " delay " + |</td><td>|
 a$ = a$ + " " + checkbox$(delayoff) + |</td><td>| + " " + textbox$(offdelay,"tb40") + |</td><td>| + listbox$(offdelunits$,unitslist$,"tb60") + |</td><td>|
 a$ = a$ + string$(9,"&nbsp;")+ "  Off duration " + |</td><td>| + checkbox$(timedoff) + |</td><td>| + " " + textbox$(offduration,"tb40")
 a$ = a$ + |</td><td>| + listbox$(offdurunits$,unitslist$,"tb60")  + |</td></tr></table><br>|
a$ = a$ + |</div>|
html a$
a$ = ""
return

pressed:
if pin(buttonpin) = 0 then gosub toggle
return

relayon:
if pin(relaypin) = relayoff then
 if relayoff = 0 then pin(relaypin) = 1 else pin(relaypin) = 0
endif
pin(ledpin) = 1 - ledoff
html cssid$("butled", "background:red;")
led = 0
refresh
return

relayoff:
refresh
if pin(relaypin) <> relayoff then pin(relaypin) = relayoff
pin(ledpin) = ledoff
html cssid$("butled", "background:green;")
led = 1
refresh
return

toggle:
if pin(relaypin) = relayoff then gosub relayon else gosub relayoff
return

cycleon:
COMMAND "interval=" + ondelunits$
if delayon > 0 then ondelaycountdown = ondelay * interval else ondelaycountdown = 0
return

cycleoff:
COMMAND "interval=" + offdelunits$
if delayoff > 0 then offdelaycountdown = offdelay * interval else offdelaycountdown = 0
return

'-------------------- End ---------------------





Margaret Baker,
Mar 5, 2018, 7:02 AM
v.1