chuckpcsw
07-09-2008, 11:47 AM
I have a script that was written by you guys that was designed to use a float sensor to check water level (FloatSensor2.py), and if water was needed it would send an rpc request to another rf engine that would turn the engine on (PumpController2.py).
FloatSensor2.py was actually doing the opposite of what we needed (it was looking for shorts instead of opens to send the rpc request), so I modified it to do the opposite. Anyway, I was wondering about the wakeupOn() subroutine from pinWakeup.py. I changed the parameters from wakeupOn(WATER_HIGH, True, False) to wakeupOn(WATER_HIGH, False, True). Is that what I wanted to do? Following is the script after modifications (minus the comments at top of script):
from pinWakeup import *
# Set the following to True to use onboard LEDs to show what is going on
# Green LED ON, Yellow LED OFF - Unit is POWERED ON, and does not want water
# Green LED ON, Yellow LED ON - Unit is asking for water
# GREEN LED OFF, Yellow LED ON - request acknowledged, waiting for HIGH WATER
# Set DEMO_MODE to False to NOT use the LEDs (saving even more power)
DEMO_MODE = False
# NOTE - all times are in seconds
#sleepChunk = 300 # how long to sleep at a stretch (1-1073)
#sleepTime = 900 # total time to sleep (25 minutes)
sleepChunk = 60 # 1 Minutes
sleepTime = 180 # 3 Minutes
acked = False
secondCounter = 0
windowCounter = 30 # How many seconds do we listen for Portal?
WATER_LOW = 5 # GPIO Pin 5 (Pin 7 on chip)
WATER_HIGH = 6 # GPIO Pin 6 (Pin 8 on chip)
# Define different states
WINDOW = 0
INITIAL = 1
WANT_WATER = 2
FILLING = 3
def setSleepTime(newValue):
"""use this to change the sleep time from it's default of 25 minutes (for demos)"""
global sleepTime, sleepChunk
sleepTime = newValue
if sleepChunk > sleepTime:
sleepChunk = sleepTime
def requestPumpOn():
mcastRpc(1, 5, "pumpOn")
def doEverySecond():
"""Periodic polling - if pump is on, go to sleep for 25 minutes, else ask again"""
global acked, state, windowCounter
if state == INITIAL:
if DEMO_MODE:
# We are on but we do not need water
writePin(1, True)
writePin(2, False)
# WATER_LOW and WATER_HIGH are both open (not shorted),
# which means we need water. readPin returns 0 on true (short) and
# 1 on false (open)
if readPin(WATER_LOW) and readPin(WATER_HIGH):
acked = False
state = WANT_WATER
else:
sleep(1, 0) # we can sleep until a float sensor goes low
elif state == WANT_WATER:
if DEMO_MODE:
# We are on and need water, have NOT been acknowledged
writePin(1, True)
writePin(2, True)
if acked:
acked = False
state = FILLING
else:
requestPumpOn()
elif state == FILLING:
if DEMO_MODE:
# We are on, want water, which is being pumped
writePin(1, False)
writePin(2, True)
# Our lowest power sleep mode can only sleep for 1073 seconds max
# So, we sleep the total time by taking multiple "naps"
sleepCounter = 0
while sleepCounter < sleepTime:
sleep(1, sleepChunk)
# Did we wake up because float sensor changed? Or just time elapsed
# readPin() returns 0 for true (short) and 1 for false (open)
if readPin(WATER_HIGH): # sensor has NOT tripped yet...
sleepCounter += sleepChunk
else:
# Return to INITIAL state which is not requesting a pumpOn
# from the pump controller.
state = INITIAL
return
# full time interval counted down, and WATER_HIGH sensor has not tripped yet
state = WANT_WATER
requestPumpOn()
else: # initial time window to gain access to sleeper unit
if windowCounter > 0:
windowCounter -= 1
pulsePin(1, 500, True)
else:
state = INITIAL
def acknowledge():
"""PumpController calls this to let us know he heard us"""
global acked
acked = True
def startupEvent():
global state
state = WINDOW
# Default all pins to output/low for minimum power consumption
# Some of these will be changed further down
crossConnect(0,6) # no packet serial, we are shutting the UARTs down
initUart(0,0)
initUart(1,0)
flowControl(0, False)
flowControl(1, False)
pin = 0
while pin <= 18:
setPinDir(pin, True)
writePin(pin, False)
pin += 1
if DEMO_MODE:
writePin(1, True) # so you can tell we are ON
setPinDir(WATER_LOW, False) # NOT an output
setPinPullup(WATER_LOW, True) # we do want internal pullup resistor
monitorPin(WATER_LOW, True)
wakeupOn(WATER_LOW, False, True)
# wakeupOn(WATER_LOW, True, False)
setPinDir(WATER_HIGH, False) # NOT an output
setPinPullup(WATER_HIGH, True) # we do want internal pullup resistor
monitorPin(WATER_HIGH, True)
wakeupOn(WATER_HIGH, False, True)
# wakeupOn(WATER_HIGH, True, False)
def floatEvent(pinNum, isSet):
"""Invoked when a float input changes"""
global state
if pinNum == WATER_LOW:
if isSet:
if state == INITIAL:
# The WATER_HIGH sensor has priority
if readPin(WATER_HIGH): # meaning it is NOT active
state = WANT_WATER
elif pinNum == WATER_HIGH:
if not isSet:
if state != INITIAL:
state = INITIAL
def timer100msEvent(currentMs):
global secondCounter
secondCounter += 1
if secondCounter >= 10:
doEverySecond()
secondCounter = 0
snappyGen.setHook(SnapConstants.HOOK_STARTUP, startupEvent)
snappyGen.setHook(SnapConstants.HOOK_100MS, timer100msEvent)
snappyGen.setHook(SnapConstants.HOOK_GPIN, floatEvent)
FloatSensor2.py was actually doing the opposite of what we needed (it was looking for shorts instead of opens to send the rpc request), so I modified it to do the opposite. Anyway, I was wondering about the wakeupOn() subroutine from pinWakeup.py. I changed the parameters from wakeupOn(WATER_HIGH, True, False) to wakeupOn(WATER_HIGH, False, True). Is that what I wanted to do? Following is the script after modifications (minus the comments at top of script):
from pinWakeup import *
# Set the following to True to use onboard LEDs to show what is going on
# Green LED ON, Yellow LED OFF - Unit is POWERED ON, and does not want water
# Green LED ON, Yellow LED ON - Unit is asking for water
# GREEN LED OFF, Yellow LED ON - request acknowledged, waiting for HIGH WATER
# Set DEMO_MODE to False to NOT use the LEDs (saving even more power)
DEMO_MODE = False
# NOTE - all times are in seconds
#sleepChunk = 300 # how long to sleep at a stretch (1-1073)
#sleepTime = 900 # total time to sleep (25 minutes)
sleepChunk = 60 # 1 Minutes
sleepTime = 180 # 3 Minutes
acked = False
secondCounter = 0
windowCounter = 30 # How many seconds do we listen for Portal?
WATER_LOW = 5 # GPIO Pin 5 (Pin 7 on chip)
WATER_HIGH = 6 # GPIO Pin 6 (Pin 8 on chip)
# Define different states
WINDOW = 0
INITIAL = 1
WANT_WATER = 2
FILLING = 3
def setSleepTime(newValue):
"""use this to change the sleep time from it's default of 25 minutes (for demos)"""
global sleepTime, sleepChunk
sleepTime = newValue
if sleepChunk > sleepTime:
sleepChunk = sleepTime
def requestPumpOn():
mcastRpc(1, 5, "pumpOn")
def doEverySecond():
"""Periodic polling - if pump is on, go to sleep for 25 minutes, else ask again"""
global acked, state, windowCounter
if state == INITIAL:
if DEMO_MODE:
# We are on but we do not need water
writePin(1, True)
writePin(2, False)
# WATER_LOW and WATER_HIGH are both open (not shorted),
# which means we need water. readPin returns 0 on true (short) and
# 1 on false (open)
if readPin(WATER_LOW) and readPin(WATER_HIGH):
acked = False
state = WANT_WATER
else:
sleep(1, 0) # we can sleep until a float sensor goes low
elif state == WANT_WATER:
if DEMO_MODE:
# We are on and need water, have NOT been acknowledged
writePin(1, True)
writePin(2, True)
if acked:
acked = False
state = FILLING
else:
requestPumpOn()
elif state == FILLING:
if DEMO_MODE:
# We are on, want water, which is being pumped
writePin(1, False)
writePin(2, True)
# Our lowest power sleep mode can only sleep for 1073 seconds max
# So, we sleep the total time by taking multiple "naps"
sleepCounter = 0
while sleepCounter < sleepTime:
sleep(1, sleepChunk)
# Did we wake up because float sensor changed? Or just time elapsed
# readPin() returns 0 for true (short) and 1 for false (open)
if readPin(WATER_HIGH): # sensor has NOT tripped yet...
sleepCounter += sleepChunk
else:
# Return to INITIAL state which is not requesting a pumpOn
# from the pump controller.
state = INITIAL
return
# full time interval counted down, and WATER_HIGH sensor has not tripped yet
state = WANT_WATER
requestPumpOn()
else: # initial time window to gain access to sleeper unit
if windowCounter > 0:
windowCounter -= 1
pulsePin(1, 500, True)
else:
state = INITIAL
def acknowledge():
"""PumpController calls this to let us know he heard us"""
global acked
acked = True
def startupEvent():
global state
state = WINDOW
# Default all pins to output/low for minimum power consumption
# Some of these will be changed further down
crossConnect(0,6) # no packet serial, we are shutting the UARTs down
initUart(0,0)
initUart(1,0)
flowControl(0, False)
flowControl(1, False)
pin = 0
while pin <= 18:
setPinDir(pin, True)
writePin(pin, False)
pin += 1
if DEMO_MODE:
writePin(1, True) # so you can tell we are ON
setPinDir(WATER_LOW, False) # NOT an output
setPinPullup(WATER_LOW, True) # we do want internal pullup resistor
monitorPin(WATER_LOW, True)
wakeupOn(WATER_LOW, False, True)
# wakeupOn(WATER_LOW, True, False)
setPinDir(WATER_HIGH, False) # NOT an output
setPinPullup(WATER_HIGH, True) # we do want internal pullup resistor
monitorPin(WATER_HIGH, True)
wakeupOn(WATER_HIGH, False, True)
# wakeupOn(WATER_HIGH, True, False)
def floatEvent(pinNum, isSet):
"""Invoked when a float input changes"""
global state
if pinNum == WATER_LOW:
if isSet:
if state == INITIAL:
# The WATER_HIGH sensor has priority
if readPin(WATER_HIGH): # meaning it is NOT active
state = WANT_WATER
elif pinNum == WATER_HIGH:
if not isSet:
if state != INITIAL:
state = INITIAL
def timer100msEvent(currentMs):
global secondCounter
secondCounter += 1
if secondCounter >= 10:
doEverySecond()
secondCounter = 0
snappyGen.setHook(SnapConstants.HOOK_STARTUP, startupEvent)
snappyGen.setHook(SnapConstants.HOOK_100MS, timer100msEvent)
snappyGen.setHook(SnapConstants.HOOK_GPIN, floatEvent)