[SOLVED] ATTiny85 won't wake up properly.

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

 

I created a simple PCB that uses an ATTiny85 to control an OLED screen. Since the PCB uses a battery, I added a standby function that uses the power save feature of the ATTiny. When the ATTiny is in sleep mode, a button is used to wake it up again. 

Till now I made 25 copies of the same PCB with the same firmware. Some of the boards are having issues with waking up after going to sleep. I need to reset te chip (pull reset low) in order to wake it up again. I tried changing the sleep script, but it really looks like only some of them are affected. 

 

The sleep code I'm using is the following code: 

 

void sleep() {
    byte adcsra, mcucr1, mcucr2;

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    MCUCR &= ~(_BV(ISC01) | _BV(ISC00));      //INT0 on low level
    GIMSK |= _BV(INT0);                       //enable INT0
    adcsra = ADCSRA;                          //save ADCSRA
    ADCSRA &= ~_BV(ADEN);                     //disable ADC

    cli();                                    //stop interrupts to ensure the BOD timed sequence executes as required
    mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
    mcucr2 = mcucr1 & ~_BV(BODSE);            //if the MCU does not have BOD disable capability,
    MCUCR = mcucr1;                           //  this code has no effect
    MCUCR = mcucr2;
    sei();                                    //ensure interrupts enabled so we can wake up again

    sleep_cpu();                              //go to sleep
    sleep_disable();                          //wake up here
    ADCSRA = adcsra;                          //restore ADCSRA
}

Is there anything I could try to solve the issue? Or is this probably a hardware issue? I must admit that I'm using cheap Ali-express ATTiny85's, which of course could be the cause of the problems. 

 

Any pointers in the right direction are welcome! Thanks!

Last Edited: Thu. Nov 16, 2017 - 06:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IF it works on some but not others, it is most likely a H/W issue....

  but I always start troubleshooting sleep apps using idle sleep mode first, if it works there, then I will move on to deeper sleep modes.

 

Please post a schematic or at least a picture of your h/w.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
Please post a schematic or at least a picture of your h/w.

Indeed.  Also a complete test program, including wakeup ISRs.  Describe wakeup mechanism.  What voltage is RIGHT ON THE AVR PIN when attempting a wakeup?

 

MichMich wrote:
mcucr2 = mcucr1 & ~_BV(BODSE); //if the MCU does not have BOD disable capability, MCUCR = mcucr1; // this code has no effect

Think about that for a moment.  If that model doesn't have sleeping BOD feature, then those bits in that register could be used for some other function...

 

However, you are probably still "safe", as if the model does not have that functionality the chip-include file will probably not have a definition for BODSE etc. and there will be compile errors.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Thu. Nov 16, 2017 - 05:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've added the schematics as a pdf, as you can see it is pretty straight forward. (The SSD1306 part is most of the work).  I also played around with different fuse settings. But that doesn't seem to make much of a difference.

 

Great suggestion about the idle mode. I'll give that a try.

 

Any other recommendation would be welcome (Although I don't really have the option to change the schematics. ;))

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MichMich wrote:
Great suggestion about the idle mode. I'll give that a try.

I guess; I tend to go the other way starting with powerdown.  Meh--to each his own.  Powerdown has lowest current making distinction between sleeping or not easier.  Most limited set of wakeup sources.  But if your target is powerdown, then changing to idle will just lead to red herrings IMO.

 

I'm suspicious of the level interrupt, and its handling.  I haven't used one of those for wakeup since pinchange became available.

 

I assume you are aiming at powerdown sleep to save power.  I'd expect to see careful attention to PRR, if so.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, while playing with your suggestions if figured out something interesting: - If the sleep mode is caused by a timed function (power off after 30sec), the device will wake of without any issues. - If the sleep mode is caused by pressing a sleep button (actually, it's a long press, but the sleep is activated when the button is pressed). The device won't wake up properly.

 

Since the sleep button is the same button as the wake up button, this might cause an issue with interrupts not firing? Something to figure out! 

A good starting point in solving the issue! Thanks for your help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since the low power mode was initiated with the same button which wakes up the device, bouncing caused an issue where the interrupt would not work. I solved it with a simple piece of code:

 

    if (longPressRelease) {
        //Pretend we go off by clearing the display.
        TinyOLED.clear();

        // Wait till the button is released.
        // Debounce: wait until the button is released for at least 250ms.
        unsigned char debounce = 0;
        while (debounce < 250) {
            _delay_ms(1);
            debounce++;
            if (!(PINB & (1 << 2))) debounce = 0;
        }
        
        //Good to go! Go to sleep.
        sleep();
    }

 

Thanks for your help guys! You are awesome!

Last Edited: Thu. Nov 16, 2017 - 06:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MichMich wrote:
bouncing caused an issue where the interrupt would not work.

I'd wager that further investigation might reveal that "interrupts actually work".  But the bouncing might cause multiple invocations; always interesting with level-triggered.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If that is not it, the next, possible grievous gotcha could be an INT0 interrupt pulse that is shorter than a RESET time. Consider:

... if a level triggered interrupt is used for wake-up from Power-down, the required level must be held long enough for the MCU to complete the wake-up to trigger the level interrupt. If the level disappears before the end of the Start-up Time, the MCU will still wake up, but no interrupt will be generated. {49 2586Q–AVR–08/2013, p 49}

And then:

When the BOD has been disabled, the wake-up time from sleep mode will be the same as that for waking up from RESET. {2586Q-AVR-08/2013, p. 35}

 

I am also suspicious of the level interrupt.

 

 

- John

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jfiresto wrote:
I am also suspicious of the level interrupt.

It is just "trickier" to handle.  But indeed, for wakeup, the startup time could be quite long, and it looks like an interrupt would be lost.

 

For OP:

 

-- Use a properly-debounced input signal to decide when to go to sleep.  Generally when we discuss debouncing here, there is no external interrupt involved but rather some kind of a timer "tick" to move signal reads through the debounce engine.

-- Use pin-change as the wakeup source.  Often, the ISR will be empty, or perhaps just set a flag to indicate which wakeup source.  Again, debounce the wakeup event to make sure it is "real" and not a glitch.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks all! Very valuable information.

 

I've debounced the sleep signal and that seems to have solved the issue. If the issue does occur again, I'll investigate the wake up signal. Unfortunately, I can't debounce it in hardware, so hopefully the issue is fixed now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MichMich wrote:
I've debounced the sleep signal and that seems to have solved the issue. If the issue does occur again, I'll investigate the wake up signal. Unfortunately, I can't debounce it in hardware, so hopefully the issue is fixed now.

AArgh!  Are you listening at all?!?  Don't use low-level external interrupt for awakening, and all your problems [related to the wakening signal] go away.  If you need further processing of that signal, e.g. one-of-many, then take care of it as you would when awake -- take a sample each "tick", enter samples into debounce engine, process confirmed states/edges each tick.

 

While clean signals are needed in certain cases -- quadrature comes to mind -- generally there is no external debounce needed.  Uncle Bob might aprove of your "solution" but few here would sit in one place for some milliseconds.  No need; wasteful; complicated.

 

I'm done.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry man, I was in the assumption I understood and did what you were saying. But I clearly misunderstood. I apologize: working with interrupts in regards to sleep/wake up is very new to me and results in me not understanding the terminology.

I’ll investigate the approach you suggested and give it a try to see how it works out.

Thanks for your help once again! Hope I didn’t frustrate you too much. We all need to start somewhere. ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MichMich wrote:
working with interrupts in regards to sleep/wake up is very new to me

In an AVR8, indeed you need an enabled interrupt source4 and corresponding ISR to awaken successfully.

 

But as you are seeing, handling a low-level interrupt can be tricky.  At least much more fraught with pitfalls than awakening with pinchange.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.