NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Car defrost button circuit replacement

September 19, 2015
by scootergarrett
scootergarrett's Avatar

The rear defrost circuit in my POS car never seemed to work correctly, I tested the button and the relay and found nothing. The button to turn on/off the defrost is a momentary contact button that some how latches; there was no way I was going to be able to find and trouble shoot that circuit so I decided to completely bypass it. I ran a new wire from relay through the fire wall to behind the dash, controlling this signal controls the defrost. I initially tried making a completely analog circuit, but the bouncing of the signal from the input button was killing me. I then decided that the ATtiny85 would be a good solution.

What I wanted the MCU to do was:

1) When circuit is power up (turning on car) have the rear defrost off

2) If button is pressed switch state of the defrost signal, and switch the light on the button.

3) If the button is held down (~2sec) enter a timed mode where the defrost will turn off after a set amount of time (~5min)

3a) Show that the button has been held for long enough by blinking light on button until buttton released

The MCU has one input from the button, and two outputs that go to the relay and the light inside the button. A lot of the code is getting the 3rd task to work correctly and to de-bounce the button.

#define ButtonSig B,0
#define DefrostSig B,2
#define IndicatorSig B,1
#define AutoOffTime 10000             // Every 100 is about 4 sec 10000 -> about 6min
#define ButtonHoldTime 22
#define DeBounceMax 100

volatile bool TempOnMode;
volatile bool CurrentState;
volatile uint16_t DeBounceCounter;

int main()
{
    uint16_t TimerCounter;
    /// Set up IO //
    OUTPUT(DefrostSig);
    CLEAR(DefrostSig);

    OUTPUT(IndicatorSig);
    CLEAR(IndicatorSig);

    INPUT(ButtonSig);
    PULLUP_ON(ButtonSig);

    TempOnMode = false;
    CurrentState = false;

    /// Set up Interrupt button ///
    GIMSK = (1<<PCIE);
    PCMSK = (1<<PCINT0);

    /// Interrupt Timing setup ///
    TCCR0B |= (1<<CS12) | (1<<CS10) | (1<<WGM02);
    TCCR0A |= (1<<WGM01);
    TIMSK |= (1<<OCIE0A);
    OCR0A = 40;                         // Interrupt timing 200Hz (5ms)

    DeBounceCounter = DeBounceMax;      // 5ms * DeBounceMax is de-bounce time

    delay_ms(1);
    sei();                              // Enable interrupts

    while(1)
    {
        // If TempOnMode then start count down ///
        if(TempOnMode)
        {
            for(TimerCounter=0;TimerCounter<AutoOffTime;++TimerCounter)
            {
                // If state is changed off by user end count down //
                if(!CurrentState)
                    goto end;

                delay_ms(10);
            }
            // After for loop complete normally turn off defrost //
            CurrentState = false;
            TempOnMode = false;
            CLEAR(DefrostSig);
            CLEAR(IndicatorSig);

        }
        end:;

    }

    return 0;
}

/// Button press interrupt ///
ISR(PCINT0_vect)
{
    uint8_t k;

    // If button recently hit ignore interrupt //
    if(DeBounceCounter)
        return;
    DeBounceCounter = DeBounceMax;      // Else reset DeBounceCounter

    delay_ms(20);

    // If button is being pressed act //
    if(!READ(ButtonSig))
    {
        // If current state is on then shut off //
        if(CurrentState)
        {
            CurrentState = false;
            TempOnMode = false;
            CLEAR(DefrostSig);
            CLEAR(IndicatorSig);
        }
        // If current state is off then turn on //
        else
        {
            CurrentState = true;
            TempOnMode = false;
            SET(DefrostSig);
            SET(IndicatorSig);

            for(k=0;k<ButtonHoldTime;++k)
            {
                // If button is released in reasonable time end interrupt //
                if(READ(ButtonSig))
                    return;

                delay_ms(10);
            }

            // If button was held turn on temp mode
            TempOnMode = true;

            // Blink indicator light until button released //
            while(!READ(ButtonSig))
            {
                TOGGLE(IndicatorSig);
                delay_ms(50);
            }
            SET(IndicatorSig);
        }
    }

    return;
}

/// Timer interrupt ///
ISR(TIMER0_COMPA_vect)
{
    // Counts down DeBounceCounter to de-bounce button //
    if(DeBounceCounter)
        --DeBounceCounter;

    return;
}

Here are some pics of the complete project board and the circuit diagram. I hope no one ever owns this car after me. Just another little project.

September 21, 2015
by JKITSON
JKITSON's Avatar

Scooter...

Neat idea. I have an old clunker with similar problem. Thanks for documenting the project & code. This will make it much easier for me to try & fix my car. The schematic really helps.

Thanks again for a nice project

JIm

Post a Reply

Please log in to post a reply.

Did you know that using an alternating excitation voltage can reduce the noise in many sensor measurements? Learn more...