Swimming Pool Controller - With Gallons, Time and Inches
Prophead100
Posts: 192
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!!