PDA

View Full Version : wakeupOn() in FloatSensor2.py


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)

kbanks
07-09-2008, 01:11 PM
I changed the parameters from wakeupOn(WATER_HIGH, True, False) to wakeupOn(WATER_HIGH, False, True).

You had the right idea, but changed too much. Here is the definition for the wakeupOnPin() function.


def wakeupOn(pin, isEnabled, polarity): # default to enabling, falling edge
"""Controls "wakeup" feature for the specified GPIO (1,2,5,6,9 or 10)"""


Since you still want to "wake up" on a change in signal level, you want to leave the second parameter (isEnabled) set to True.

The third parameter (polarity) is the only one you want to change.

wakeupOn(pin, False, xxx) is how you turn OFF the feature.

I think what you want is wakeupOn(WATER_xxx, True, True)

chuckpcsw
07-09-2008, 03:22 PM
I think what you want is wakeupOn(WATER_xxx, True, True)

I changed those 2 lines, and uploaded the new script. I'm getting no pumpOn requests from the floatSensor RF engine, now. And, I don't see that RF engine with portal anymore. I've power cycled the rf engine, but still don't see it with portal (I should have 30 seconds). Any way to erase the snappy image or reprogram it without being able to see it with portal?

Thanks!

kbanks
07-09-2008, 03:58 PM
Yes you can, but you will have to know which serial port (or USB) connects to the node.

Look under the Options menu for "Erase SNAPpy Image..."

If you are currently connected to a SNAP network, it will prompt you about the disconnect. Click OK (you can reconnect after you are done).

You choose the interface (COM1, COM2, etc.), and then click the Erase button.

You are then prompted to reset the node.

When Portal sees the node restart (because you power-cycled it, or pushed a reset button), it will command it to erase any SNAPpy script it may have.

Reconnect your network, and see if that brings the node back online.

If this does not get you going, there is a similiar procedure to "Factory Default NV Params" (also under the Options menu).

If THAT does not get the node talking again, there is a final option "Firmware Upgrade" (also under the Options menu)

chuckpcsw
07-10-2008, 09:10 AM
Look under the Options menu for "Erase SNAPpy Image..."

If you are currently connected to a SNAP network, it will prompt you about the disconnect. Click OK (you can reconnect after you are done).

You choose the interface (COM1, COM2, etc.), and then click the Erase button.

You are then prompted to reset the node.

When Portal sees the node restart (because you power-cycled it, or pushed a reset button), it will command it to erase any SNAPpy script it may have.

Reconnect your network, and see if that brings the node back online.

If this does not get you going, there is a similiar procedure to "Factory Default NV Params" (also under the Options menu).

If THAT does not get the node talking again, there is a final option "Firmware Upgrade" (also under the Options menu)
http://forums.synapse-wireless.com/images/buttons/quote.gif (http://forums.synapse-wireless.com/newreply.php?do=newreply&p=312)


When I choose any of those options, it looks for a com port, and just sits there. It doesn't seem to be looking for the USB port.

Also, these nodes are not connected to a computer. Is that the only way to erase the snappy script?

kbanks
07-10-2008, 09:12 AM
(maybe you have already done this)

We've talked about how to change the "wakeup" criteria, but you also need to be sure you've changed all the code that reads and then acts upon those same input pins.

If you have not already accounted for the "polarity reversal" (logic level inversion), look in the script for calls to readPin(WATER_xxx).

The easiest fix is probably to add the keyword "not" before each one. Something like:


if readPin(WATER_LOW) blah blah blah


would become


if not readPin(WATER_LOW) blah blah blah


In more complicated expressions, you may find that parentheses "(" ")" are required.

mgenti
07-10-2008, 09:46 AM
When I choose any of those options, it looks for a com port, and just sits there. It doesn't seem to be looking for the USB port.

Also, these nodes are not connected to a computer. Is that the only way to erase the snappy script?

Yes, the only way to erase a SNAPpy script from a unit that you cannot communicate with is via the RS-232 port. You will need to have the node attached to the PC running portal via a RS-232 COM port. Portal may not detect the SNAP node depending on how things are configured so you will need to select the appropriate COM port manually.