/****************************************************************************
NETWORK_RESET_01.C

This program is a network reseter.  It controls a solid-state-relay that
is in series with 110VAC.  It supplies power to a satellite receiver,
various routers, etc.  Once every 24 hours it drops power for 10 seconds
to allow the receiver and routers to start clean.

The LED flashes once per second.

The 24 hour reset occurs eight hours from the time the unit is powered on.
If it is desired to changed that delay, decide how many hours (from now)
that you want the unit to reset.  Press and hold the button for
greater than five seconds, and release it.  The LED will stop flashing.
Immediately press and hold the button until the LED starts flashing.  Count
the flashes as you hold the button.  Release the button when the LED has
flashed the number of hours you want to delay.  Normal operation will
occur after three seconds.

To drop power immediately, press and hold the button for two seconds.


                 +5
                  |
                  14
                ----------
     SW  ----6-|          |-17-- LED
               |          |-18-- SSR
               |          |
               |          |
               |  16F628  |
               |          |
               |          |-13--PROG_CLK
               |          |-12--PROG_DAT
  6MHz XTAL-15-|          |-4---MCLR
       XTAL-16-|          |     GND
                ----------
                     5
                     |
                    Gnd



***************************************************************************/

#include < 16F628.h >
#include < jonsinc.h >

#fuses HS, NOPROTECT, PUT, NOWDT, BROWNOUT, NOMCLR, NOLVP

#use standard_io ( A )
#use standard_io ( B )
#use delay ( clock = 6000000 )

#define LED       PIN_A0
#define SSR       PIN_A1
#define BUTTON    PIN_B0
// delay in hours
#define DELAY     8
// delay in mS
#define POWER_DROP_DURATION  10000
// delays in seconds
#define BUTTON_DELAY_TO_FORCE_RESET   1
#define BUTTON_DELAY_TO_SET_FIRST_POWER_DROP    5

void ResetPower ( void );

static char cPeriod;

void main ( void )
    {
    char cHourCnt, cButtonCnt;
    long iSecondCnt;

    delay_ms ( 200 );      // let stabilize
    port_b_pullups ( TRUE );
    output_low ( SSR );    // default to ON
    cPeriod = DELAY;        // delay to first power reset
    cButtonCnt = 0;

    while ( TRUE )
        {
        for ( cHourCnt = 0; cHourCnt < cPeriod; cHourCnt++ )
            {
            for ( iSecondCnt = 0;  iSecondCnt < 3600; iSecondCnt++ )
                {
                if ( input ( BUTTON ) == LOW )
                    {
                    cButtonCnt++;       // increment count
                    }
                else
                    {
                    // if high, check count
                    if ( cButtonCnt > BUTTON_DELAY_TO_SET_FIRST_POWER_DROP )
                        {
                        // query for new initial delay
                        cButtonCnt = 0;     // reset count
                        delay_ms ( 3000 );
                        for ( cPeriod = 0; cPeriod < 23; cPeriod++ )
                           {
                           output_high ( LED );
                           delay_ms ( 500 );
                           output_low ( LED );
                           delay_ms ( 500 );
                           if ( input ( BUTTON ) == HIGH )
                              {
                              break;
                              }
                           }
                        cHourCnt = 0;        // reset hour count
                        delay_ms ( 3000 );
                        }
                    else
                       {
                       if ( cButtonCnt > BUTTON_DELAY_TO_FORCE_RESET )
                           {
                           // do reset immediately
                           ResetPower();       // drop power to reset, don't change delay to 24 hour reset
                           cButtonCnt = 0;     // reset count
                           }
                       }
                    cButtonCnt = 0;     // reset to zero
                    }
                // delay one second
                output_high ( LED );
                delay_ms ( 100 );
                output_low ( LED );
                delay_ms ( 900 );
                }
            }
        ResetPower();       // drop power to reset
        cPeriod = 24;       // preset delay to next power reset
        }
    }

void ResetPower ( void )
    {
    // drop power for ten seconds, then reset to 24 hour period
    output_low ( SSR );     // SSR off
    output_high ( LED );    // LED on
    delay_ms ( POWER_DROP_DURATION );  // delay
    output_low ( LED );     // LED off
    output_low ( SSR );    // SSR on
    }