Electronic – Microcontroller hangs while switching off

attinyavresp8266hardware

In my application I have interfaced ESP8266 wifi chip with ATTiny828 micro-controller. We have developed our custom module with these two chips on it. The problem we are facing is that the micro-controller hangs sometimes when switching off the module. The button is the momentary type "push to On" switch and power ON/OFF functionality is implemented with the following circuit :
power ON/OFF circuit
when the switch is pressed npn transistor turns ON which in turn makes PMOS conduct current and makes the entire unit ON. As soon as the micro-controller gets started it puts ON/OFF pin in permanently HIGH state (to keep the unit powered on after the switch has been released). "SENSE" pin of the micro-controller senses the state of the switch (Pin change interrupts are active on this pin). So if the switch is pressed for more than a pre-programmed span of time, then micro-controller will make ON/OFF pin zero which will turn off the module.

we have taken care of debouncing in the software by adding delay of 100 ms.
here is our code

// PW pin is same as "SENSE" pin
ISR(PCINT0_vect) {
    static uint8_t tmr_pw_start = 0; 
    static uint8_t PW_prev = 1, GP2_prev = 1;

    uint8_t const PW = READ(PW);
    uint8_t const GP2 = READ(GPIO2);

    if (PW != PW_prev) {
        if (PW) {               // Start measuring button press time
            tmr_pw_start = 1;
            ovf0 = 0;
        } else if(tmr_pw_start){ 
            if (ovf0 > 60) {                            
                WRITE(On_off_pin, LOW);     // POWER OFF
                _delay_ms(100); 
            }            
            tmr_pw_start = 0;
        }
    }

    if (GP2 != GP2_prev) {
        TOGGLE(BLUE_LED);
    }
    PW_prev = PW;
    GP2_prev = GP2;
}

ISR(TIMER0_OVF_vect, ISR_NOBLOCK) {
    ovf0++;
    if(!(ovf0 % 16))    TOGGLE(GREEN_LED);
}

We keep timer 0 always running and its number of overflows are used to measure elapsed time. it takes approx. 32 ms for one overflow to occur.

Other than this UART interrupts are also active in which it just takes the data and assigns it to a global variable.

The problem is this :
By pressing the switch ON/OFF button for more than 2 seconds and then releasing it should switch off the unit which it does most of the time. But in 1 out of 15 cases micro-controller hangs while switching it off. It becomes unresponsive to button press and LEDs stop blinking. Or sometimes it becomes unresponsive with GREEN led still blinking.

Can anyone guess what can be the problem ?

Best Answer

When you hold the button down and the micro drives the ON/OFF line low, there's a low-impedance path directly from the battery, through the I/O protection diodes on the SENSE pin of the micro, to its power bus — this is a very bad thing. There's another path through your external diode and the ON/OFF pin, too.

At the very least, you should have a resistor in series with each of the I/O lines to limit the current that can flow under this condition. But the micro may still be able to keep running on this low amount of current, so you'll need to augment your design in other ways, too.

The most direct solution would probably be to put the micro on the "always powered" side of the switch, and simply put it into a low-power "sleep" mode when the system is supposed to be off. This would actually simplify the external circuitry required.


EDIT: Actually, after I thought about it a bit more, I realized that you don't turn off the transistors until after the button is released, so the problem described above is only an issue if the button bounces on release — but if it does, the system will immediately power up again, or get hung in a half-on condition.

Is it a snap-action button, or something "mushier"?