Shop OBEX P1 Docs P2 Docs Learn Events
Swimming Pool Controller - With Gallons, Time and Inches — Parallax Forums

Swimming Pool Controller - With Gallons, Time and Inches

Prophead100Prophead100 Posts: 192
edited 2014-11-22 10:40 in Robotics
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.)
{{  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
               
1024 x 1365 - 370K
1024 x 1365 - 327K
1024 x 768 - 130K

Comments

Sign In or Register to comment.