Sump Pump Controller

From Wiki
Jump to: navigation, search

A friend of mine has a basement that leaks and he installed his own sump pump. The problem was he didn't like any of the switch arrangements out there, so we decided to build one. I had some water level sensors from another project, and wrote some code for a PIC12F629 to drive the pump relay based on the water level sensors. Below is the basic logic for the controller.


/*
 * GP0 is high sense input, 0 indicates sensing water
 * GP1 is low sense input, 0 indicates sensing water
 * GP2 is manual pump override, 0 indicates override
 * GP3 is MCLR/, active low reset
 * GP4 is pump enable, 1 runs pump
 * GP5 is alarm output, 1 enables open collector output
 *
 * OPTION_REG:
 *   GPPU     - 0 - GPIO pull-ups are enabled by individual port latch values
 *   INTEDG   - 0 - Interrupt on falling edge of GP2/INT pin
 *   T0CS     - 0 - Transition on GP2/T0CKI pin
 *   T0SE     - 0 - Increment on low-to-high transition on GP2/T0CKI pin
 *   PSA      - 0 - Prescaler is assigned to the TIMER0 module
 *   PS2:PS0  - 0 - TMR0 rate is 1:2 (needs fixing!)
 *
*/

volatile char secondsCounter;
volatile char minutesCounter;

void Timer_interrupt (void)
{
  static char count10ms = 0;

  if (++count10ms == 100)
  {
    count10ms = 0;

    if (++secoundsCounter == 60)
    {
      secondsCounter = 0;
      minutesCounter++;
    }
  }
}

void main (void)
{
  int secondsCounterLast = -1;
  char hysterisisTime = 0;
  char manualOverrideFlag = FALSE;

  ANSEL  = 0x00;    // Digital I/O only
  CMCON  = 0x07;    // Comparator off
  GPIO   = 0x07;    // Outputs GP4 & GP5 low, inputs ignored
  WPU    = 0x07;    // GP2..0 weak pull-ups enabled
  TRISIO = 0x07;    // GP5..3 outputs, GP2..0 inputs
  PCON   = 0x03;    // Clear /POR and /BOD (or 0?)
  INTCON = 0x00;    // No interrupts
  IOC    = 0x00;    // No interrupt on change for GPIO
  PIR1   = 0x00;    // Clear outstanding interrupts
  PIE1   = 0x01;    // Timer 1 overflow interrupt

  //
  // Configure timer for 10ms
  // Enable interrupts
  //

  disablePump ();
  disableAlarm ();

  while (1)
  {
    if (secondsCounter != secondsCounterLast)
    {
      toggleGreenLED ();
      secondsCounterLast = secondsCounter;

      if (manualOverride ())
      {
        pumpEnable ();
        manualOverrideFlag = TRUE;
      }
      else if (manualOverrideFlag)
      {
        pumpDisable ();
        manualOverrideFlag = FALSE;
      }

      if (manualOverrideFlag == FALSE)
      {
        if (pumpRunning () && (minutesCounter > FIFTEEN_MINUTES))
          enableAlarm ();

        if (highSense ())
        {
          if (hysterisisTime == 0)
            hysterisisTime = FIFTEEN_SECONDS;
          else if (--hysterisisTime == 0)
          {
            enablePump ();
            minutesCounter = 0;
          }
        }
        else if (!lowSense ())
        {
          if (hysterisisTime == 0)
            hysterisisTime = FIFTEEN_SECONDS;
          else if (--hysterisisTime == 0)
          {
            disablePump ();
            disableAlarm ();
          }
        }
      }
    }
    else
      sleep ();
  }
}