/*************************************************************************
PELLET.C

This program is duty cycle driver for a pellet stove auger motor.

Need to pullup RA0, RA1, RA2 with 1K resistors.

Eight auger motor times, incremented by nine seconds, starting with nine seconds.

If overheat input goes low,
   * all eight LEDs flash at a one second rate
   * auger motor relays goes off permanently

When overheat condition goes away and overheat input goes high again
   * unit may be reset by pressing either button
   * heat duty cycle is reset to 1



                   +5
                    |
                    14
                ------------
 -HOTTER ---17-|RA0      RB7|-6--- +LED MAX
 -COLDER ---18-|RA1      RB6|-7--- +LED
 -OVERHT ----1-|RA2      RB5|-8--- +LED
               |         RB4|-9--- +LED
               |  16F628 RB3|-10-- +LED
               |         RB2|-11-- +LED
               |         RB1|-12-- +LED
               |         RB0|-13-- +LED MIN
               |            |
               |         RA3|-2--- +RELAY
                ------------
                     5
                     |
                    Gnd

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

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

#use fast_io ( A )
#use standard_io ( B )
#use delay ( clock = 4000000 )

#byte PORT_A     = 5
#byte PORT_B     = 6
#bit HOT_SW      = PORT_A.0
#bit COLD_SW     = PORT_A.1
#bit OVERHEAT_SW = PORT_A.2
#bit RELAY       = PORT_A.3

#separate void DisplayLeds ( void );
#separate void CheckSwitches ( void );
#separate void HotterSwitch ( void );
#separate void ColderSwitch ( void );
#separate void OverheatSwitch ( void );

#define MAX_VAL    = 7
#define MIN_VAL    = 0

char const LED_TABLE [ 8 ] = { 1, 3, 7, 15, 31, 63, 127, 255 };
static char cLed;

void main ( void )
    {
    char cLevel, cSec, c10mS, cMult;


    RELAY = OFF;
    set_tris_a ( 0b11110111 );          // A3 is relay output
    output_b ( 0x00 );
    cLed = 0;                           // default LED
    output_b ( LED_TABLE [ cLed ] );    // illuminate the correct LED

    delay_ms ( 150 );                   // wait for 75mS nom PUT
    while ( TRUE )                      // do forever
        {
        // "ON" TIME                    // 9 seconds to 72 seconds
        RELAY = OFF;
        for ( cMult = 0; cMult < ( cLed + 1 ); cMult++ )
            {
            for ( cSec = 0; cSec < 9; cSec++ )
                {
                for ( c10mS = 0; c10mS < 100; c10mS++ )
                    {
                    CheckSwitches();
                    delay_ms ( 10 );
                    }
                }
            }

        // "OFF" TIME
        RELAY = OFF;                    // turn relay off
        for ( cSec = 0; cSec < 120; cSec++ )            // two minutes
            {
            for ( c10mS = 0; c10mS < 100; c10mS++ )
                {
                CheckSwitches();
                delay_ms ( 10 );
                }
            }
        }
    }
#separate void DisplayLeds ( void )
    {
    output_b ( LED_TABLE [ cLed ] ); // illuminate the correct LED
    }

#separate void CheckSwitches ( void )
    {
    HotterSwitch();
    ColderSwitch();
    OverheatSwitch();
    }

#separate void HotterSwitch ( void )
    {
    char cCnt;

    if ( HOT_SW == LOW )                // if switch is on
        {
        RELAY = OFF;                    // turn relay off
        while ( HOT_SW == LOW );        // delay while switch is on
        for ( cCnt = 0; cCnt < 30; cCnt++ )
            {
            delay_ms ( 1 );             // wait 1mS
            if ( HOT_SW != HIGH )       // if switch is found not high
                {
                cCnt = 0;               // glitch, reset count
                }
            }
        if ( cLed < 7 )           // if not max yet
            {
            cLed++;                     // increment
            }
        DisplayLeds();
        }
    }

#separate void ColderSwitch ( void )
    {
    char cCnt;

    if ( COLD_SW == LOW )               // if switch is on
        {
        RELAY = OFF;                    // turn relay off
        while ( COLD_SW == LOW );       // delay while switch is on
        for ( cCnt = 0; cCnt < 30; cCnt++ )
            {
            delay_ms ( 1 );             // wait 1mS
            if ( COLD_SW != HIGH )      // if switch is found not high
                {
                cCnt = 0;               // glitch, reset count
                }
            }
        if ( cLed > 0 )           // if not min yet
            {
            cLed--;                     // decrement
            }
        DisplayLeds();
        }
    }

#separate void OverheatSwitch ( void )
    {
    if ( OVERHEAT_SW == LOW )           // if overheat limit is reached
        {
        RELAY = OFF;                    // turn relay off
        while ( TRUE )                  // flash LED's forever
            {
            if ( ( HOT_SW == LOW ) || ( COLD_SW == LOW ) )       // reset from overheat condition
                {
                cLed = 0;       // set to lowest heat
                while ( ( HOT_SW == LOW ) || ( COLD_SW == LOW ) );  // wait until both high
                DisplayLeds();
                break;
                }
            output_b ( 0xff );
            delay_ms ( 500 );
            output_b ( 0x00 );
            delay_ms ( 500 );
            }
        }
    }