Swimming Pool Controller - With Gallons, Time and Inches
In case it is useful for others, this is a small project I put together a quick project to manage the amount of water going into our small above ground pool and educate the kids on just how much water they are using when cleaning the pool, splashing, etc... This Propeller based project uses an older version of the serial project board and is run with two buttons. When the kids want to add water, they request a specific number of inches they want to raise the pool by pressing the red button (each 1/4 second adds 1" up to 48") then the program uses a count down timer to open a sprinkler valve via a small relay (surplus COTO reed) and displays the remaining inches, gallons. They can also reduce the remaining gallons to be added by pressing and holding the black button. This works by calculating the flow rates and volumes of the pool then extrapolating to seconds per gallon or inch of fill. It also totals the gallons and stores the value in the EEPROM usung JonnyMac's object. That way they can see the gallons over a whole season. For trouble shooting the hardware also has indicator LEDs for power, valve control and flow.
If your interested in launching a cog that runs by reading global variables, storing variables in EEPROM, sharing variables between cogs, doing timers, or using an LCD display this may be useful for you. (or if you want to educate the kids and control water use.)
If your interested in launching a cog that runs by reading global variables, storing variables in EEPROM, sharing variables between cogs, doing timers, or using an LCD display this may be useful for you. (or if you want to educate the kids and control water use.)
{{ Pool Refilling Program
This program is designed to carefully fill a swimming pool with a minimum of
components and simple operations while informing the user of the amount of
water being used and how long filling will take. It is designed to reduce the
risk of overfilling the pool and encourage conservation by understanding the
amount of water used. It works by measuring the rate of filling to flow rates
and time factors. This approximately is rough but works at a low cost.
After initialization as so noted on the display, the screen then indicates
the amount used the last time water was added and the cummulative number of
total gallons used. The user can request more water by simply pressing the
red button or reduce the request by pressing the black button. Each time the
button is pushed for more than 1/4 second the program assumes the user wants
to change the amount of fill by 1". While it is filling, the display is backlit
and indicates the time, gallons and inches that are remaining during the fill.
At the completion of a fill cycle, it turns off the backlight and displays the
amount of water last used and cummulative amount used.
An output pin(0) powers a normally-open COTO read relay to energize a typical
irrigation/sprinkler valve that operates on 24 VAC at < 500mA. A small diode
is placed across the 465 ohm relay coil to prevent voltage spikes.
Three output pins (2,4,6) power red, yellow, and flashing green LEDs through
100 ohm resistors to indicate power, relay energized, and flow respectively.
One output pin (11) is connected directly to an 2x16 LCD screen to display status,
progress and water used.
Two input pins (8,9) with 10K pull-up resistors are connected to normally
open momentary button to detect requests to increase or decrease the requested
water to fill the pool.
One output (28) and one input/output pin(29) are used as the clock and data connections to the EEPROM for
store persistent data.
Note: This program the FullDuplexSerial, JM_I2C objects and builds upon the demo code by
Daniel Harris, JonnyMac, the team working on the Propeller PE Kit, and others.
}}
CON
'Set the clock frequency and mode to PLL and 80 MHz
_clkmode = xtal1 + pll16x ' use the crystal and PLL mode
_xinfreq = 5_000_000 ' frequency of crystal is 5 MHz
'Set the default constants for conversions
SecondsPerInch=960 ' Measured rate of volume change = 4.5 inches over 73 minutes (4320 seconds))
GallonsPerInch=282 ' Volume of pool per inch= radius (12' x 12")^2 x Pi / 231" cubic per gal
SecondsPerGallon=SecondsPerInch/GallonsPerInch ' Calculated rate of flow
'Define the I/O pins
ValvePin=0 ' Run a reed relay
PowerPin=2 ' Indicator LEDs
IndicatorPin=4 '
FlowPin=6 '
UpPin=8 ' Buttons for Up and Down
DownPin=9 '
Displaypin=11 ' Serial connection to LCD
SDA = 29 ' Connect to EEPROM - Already connected in the Protoboard
SCL = 28 '
VAR
Long Inches ' Inches to Add
Long Pulses ' Pulses = One pulse is one second
Long Gallons ' Gallons to Add
Long stack[100] ' Stack for launching valve cog (not optimized)
OBJ
serial : "FullDuplexSerial" ' Connection for LCD
i2c : "jm_i2c" ' Connection for EEPROM
PUB Main | x
' Initialization Routines
i2c.setup(SCL, SDA)
waitcnt(clkfreq+cnt)
' Set up display communication and indicate status
serial.start(displayPin, displayPin, 00, 9_600)
waitcnt(clkfreq+cnt ) '
serial.tx($0C)
serial.tx($11)
serial.str(string("Initializing")) 'print a test string
waitcnt(clkfreq+cnt)
serial.tx($DA)
serial.tx($0C)
' Set pin directions for input buttons and power led
dira[UpPin]~
dira[DownPin]~
dira[PowerPin]~~
outa[PowerPin]~~
' Set default values
Inches:=0
Gallons:=Inches * GallonsPerInch
Pulses:=Inches * SecondsPerInch
' Launch Cogs
cognew(ValveControl(ValvePin,IndicatorPin,FlowPin,@Pulses,@LastGallonsAdded,@TotalGallons), @stack[0])
repeat ' Program main loop for interface and display
if ina[UpPin] == 0 ' If up pushbutton is pressed
waitcnt(clkfreq / 3 + cnt) ' wait 1/4 second the planned seconds of flow by enough to increase
if ina[UpPin]==0 ' fill with enough gallons to increase the surface by one inch
pulses:=pulses+(SecondsPerInch)
pulses<#=48*SecondsPerInch
serial.tx($0C)
waitcnt(clkfreq / 20 + cnt)
if ina[DownPin] == 0 ' If down pushbutton pressed
waitcnt(clkfreq / 3 + cnt) ' wait 1/4 second then decrease the planned seconds of flow by enough
if ina[DownPin]==0 ' to reduce the fill by one inch
pulses:=pulses-(SecondsPerInch)
pulses#>=0
waitcnt(clkfreq / 20 + cnt)
if Pulses>0 ' If there is time remaining (pulses) then display
' remaining time, gallons and inches
serial.tx($11)
serial.tx($80) ' Display Remaining Time
serial.str(string("Time "))
if (pulses/3600)<10
serial.str(string("0"))
serial.dec(pulses/3600)
serial.str(string(":"))
if pulses//3600/60<10
serial.str(string("0"))
serial.dec(pulses//3600/60)
serial.str(string(":"))
if pulses//60<10
serial.str(string("0"))
serial.dec(pulses//60)
serial.str(string(" "))
serial.tx($94) ' Display Inches Remaining
serial.dec(Pulses/SecondsPerInch)
serial.str(string("."))
serial.dec(10*(Pulses//SecondsPerInch)/SecondsPerInch)
serial.tx(34)
serial.str(string("H"))
serial.tx($9B)
if Pulses/SecondsperGallon<10000 ' Display Gallons Remaining
serial.tx(" ")
if Pulses/SecondsperGallon<1000
serial.tx(" ")
if Pulses/SecondsperGallon<100
serial.tx(" ")
if Pulses/SecondsperGallon<10
serial.tx(" ")
serial.dec(Pulses/SecondsperGallon)
serial.str(string(" Gal"))
waitcnt(clkfreq/2+cnt)
else ' If no time remains then show totals
serial.tx($0C)
serial.Str(STRING("Last Fill ")) ' Display the last fill and store the value in EEPROM
serial.dec(Long[@LastGallonsAdded])
serial.str(string(" G"))
serial.tx($94)
serial.str(string("Total ")) ' Display the cummulative gallons and store the value in EEPROM
serial.dec(Long[@TotalGallons])
serial.str(string(" G"))
serial.tx($12)
waitcnt(clkfreq/2+cnt)
' Valve Control Methods for launching into a new cog
PUB ValveControl(_valvepin,_indicatorpin,_flowpin,_pulsePtr,_lastaddPtr,_totalPtr)| _secondcount,_pause,_shutdown,_zz
dira[_valvepin]~~ ' Set direction and value of output pins
outa[_valvepin]~
dira[_indicatorpin]~~
outa[_indicatorpin]~~
dira[_flowpin]~~
outa[_flowpin]~
_secondcount:=0 ' Set default values
_shutdown:=true
repeat ' Method Loop
_pause:=clkfreq+cnt
if Long[_pulsePtr]>0 ' If time remaining...
if _shutdown ' Set flip/flop if first time not shut down
_shutdown:=false
_secondcount:=_secondcount+1 ' Increment cumulative run time
outa[_valvepin]~~ ' Energize the valve
outa[_indicatorpin]~~ ' Indicate valve is on
Long[_pulsePtr]:=Long[_pulsePtr]-1 ' Decrement the planned run time
if (_secondcount//(SecondsPerGallon/4))==0 ' Flash Flow LED once per quart
!outa[_flowpin]
waitcnt(clkfreq/2+cnt)
!outa[_flowpin]
Else ' If no time remaining then...
if not _shutdown ' Set flip/flop if first time in shut down then...
long[_totalPtr]:=Long[_totalPtr]+(_secondcount/SecondsPerGallon) ' Add latest fill to cummulative
long[_lastaddPtr]:=_secondcount/secondsPerGallon ' Store last fill
_zz:=long[_totalPtr]
i2c.putlongx($A0,_totalPtr,_zz) ' Copy cummulative to EEPROM
i2c.putlongx($A0,_lastaddPtr,_secondcount/secondspergallon) ' Copy last fill to EEPROM
_secondcount:=0 ' Reset cummulative run time
_shutdown:=true
outa[_valvepin]~ ' Turn off valve and indicator
outa[_indicatorpin]~
waitcnt(_pause) ' Time delay
DAT
TotalGallons Long $00000000,$0,$0,$0 ' Cummulative gallons - copy to EEPROM
LastGallonsAdded Long $00000000,$0,$0,$0 ' Last Fill - copy to EEPROm

Comments
Next thing would be to educate them using the metric system...
:-)
http://forums.parallax.com/showthread.php/144211-Must-start-thinking-in-metric!!