ATTINY 85 Sleep help

I am working with ATTINY 85. I have sketch which I took off of internet, I am not sure where i copied sketch from. I did modify it to blink 2 Led's alternately 30 times and stop. Here it is:

int ledPin[] = {0, 1,};

int blinkTime = 300;
bool eyesStinging = true;

void setup()
{
pinMode( 0, OUTPUT);
pinMode( 1, OUTPUT);
if (eyesStinging) //Only blink if it's absolutely necessary
blinkyBlinky(30, blinkTime); // 5 is number of blinks, blinkTime is the milliseconds in each state from above: int blinkTime = 500;
}
void loop()
{

}

void blinkyBlinky(int repeats, int time)
{
for (int i = 0; i < repeats; i++)
{
digitalWrite(0, HIGH);
delay(time);
digitalWrite(0, LOW);
delay(time);
digitalWrite(1, HIGH);
delay(time);
digitalWrite(1, LOW);
delay(time);

}
}

I now want to put sketch to sleep using "SLEEP-MODE_PWR_DOWN" , and wake with momentary push button switch. Whatever pin is designated as wake-up, I know I need 10k from pin to Plus and switch to ground.
This is where I am asking for help. I know there are a lot of sleep sketches out there but combining them is where I need the Forums help.
Thank You all in advance

You need help to combine a sketch which does blink two LEDs 30 times and then doesn't do anything more with a sketch that puts the Tiny into sleep? What for? That doesn't make any sense.

Hello Pylon, Thanks May seem silly, but I am making a gadget for a friend who has two flashing lights on his house (camera's) I have a 5x7 picture of house which is mounted on a 5 X 7 X3/4 piece of wood which I hollowed out. I have a second piece same dimensions also hollowed out for battery holder and electronics. I than screw both pieces together, so it look's like one piece. have reset (on/off ) switch on side. it's on for approx 30 seconds and then turn off. To preserve battery i figured the best way is to put to sleep.
I did something similar many years ago with Pic, was much easier, just put "sleep" in code
Thanks, hope you can help

But your complete code is in setup(), so it runs once and never again.

That's about the same if you're using an ATmega MCU, the Tinys are much less supported by the usual libraries. But I'm sure you had to do more on the PIC platform if you wanted the MCU to wake up by a button. That's the same here.

The Tiny has several sleep modes so you have to select,which one you want to use:

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

Enable sleeping:

sleep_enable();

Then when you want to actually put the MCU to sleep:

sleep_cpu();

To use these routines you have to make this include:
#include <avr/sleep.h>

Thanks pylon,
You are right, it will only cycle once, I am than looking for the most efficient sleep sketch to save battery power, as it will not be too easy to change batteries. It will wake up with reset switch, attached to designated wake up pin.
My problem is I do not know how to combine the two sketches.
Thanks

You actually posted only one sketch (and that one even without code tags!), so we have no clue what other sketch you want to include.

This example will put it to sleep... in your case it will never wake up... to recycle press reset.

#include <avr/sleep.h>                           // For sleeping.


void setup()
{
  goToSleep();
}


void loop()
{
  
}


void goToSleep()
{

  // The ATTiny85 supports 3 sleep modes:
  // SLEEP_MODE_IDLE 
  // SLEEP_MODE_ADC
  // SLEEP_MODE_PWR_DOWN
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  // ---------------------------------------------------------------------------------
  // <<<<<<< The program will continue from here after coming back from sleep >>>>>>>>
  // ---------------------------------------------------------------------------------

  sleep_disable();
}

I always use the ATTinyCore when using the ATTiny85.

Here is an example of how to sleep an ATtiny85 and have it wake up and light an LED when a button is pressed, so you can use it as a starting point and insert your LED blinking logic.

1 Like

Also, there is no need to use an external pull-up resistor on the button, the ATtiny85 has built-in pull up resistors on each of its pins that you can activate by setting the pin's mode to INPUT_PULLUP as described on Digital Pins. You can also do the 2 step process of assigning the pin to be an INPUT and then digital writting it HIGH as shown in the ATtiny85 sleep example that I linked to above...the INPUT_PULLUP just does these 2 steps in one line of code.

This instructable shows the reason why pullup and down resistors are needed.

1 Like

You are right, pylon, I only posted one sketch (Flashing) , I did not have a sleep sketch at that time, but have one now, thanks to dparson ,red-car, and Big Dan the Blogging Man.
Also, before I forget I am sorry about code tags, looked thru forum, and read about them, but to be honest, i do understand when and how to use them, also are they auto generated, or I have to add them. I know have 3 sketches, flash, sleep and my attempt to combine them, which did not work out. With you permission and the other members who replied I would like to post them.

Thank you dparson, I am using your suggested sleep sketch, and combine with flashig sketch, as i mention to pylon, I will post all three. I can compile sleep and flash sketch, but no luck trying to combine. Also thank you for resistor info, I learn from it.

Thank You for your sleep sketch, please read posts above

Here's the combined version, I put some comments that hopefully help.

#include <avr/sleep.h>
#include <avr/interrupt.h>

// Variables related to the button.
int switchPin = 3;

// Variables related to the leds.
int ledPin1 = 0;
int ledPin2 = 1;
int blinkTime = 300; // This is in milliseconds and controls how long the leds remain on between blinks.

// Setup runs 1 time when the microcontroller first boots up.
void setup()
{
    // Setup the pins that control the button and leds.
    pinMode(switchPin, INPUT_PULLUP);
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
}

// Loop runs over and over, but only when the microcontroller is awake.
void loop()
{
    // This function will put the microcontroller into a lower power sleep state
    // and it will stop processing code, waiting for the button to be pressed.
    sleep();

    // After the button is pressed and wakes up the microcontroller, this function will blink the leds.
    blinkyBlinky(30, blinkTime);
}

ISR(PCINT0_vect)
{
    // This is the interrupt service routine, the code that will run when the microcontroller
    // wakes from sleep due to the button press.  We don't need to do anything here but having
    // this function is required.
}

void sleep()
{
    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT3);                   // Use PB3 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off (saves power)
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // Put the microcontroller to sleep

    // Code execution stops here since the microcontroller is now asleep.  When the button connected to PB3
    // is pressed the microcontroller will awake, run the code in the interrupt service routine (ISR),
    // and then continue executing the code starting from here.

    cli();                                  // Disable interrupts

    PCMSK &= ~_BV(PCINT3);                  // Turn off PB3 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on (we turned it off the save power)

    sei();                                  // Enable interrupts
}

void blinkyBlinky(int repeats, int time)
{
    for (int i = 0; i < repeats; i++)
    {
        // Led 1
        digitalWrite(ledPin1, HIGH);
        delay(time);
        digitalWrite(ledPin1, LOW);
        delay(time);

        // Led 2
        digitalWrite(ledPin2, HIGH);
        delay(time);
        digitalWrite(ledPin2, LOW);
        delay(time);
    }
}

THANK YOU, dparson, It works exactly as I hoped it would. Your comments are also REALLY HELPFUL.
You may not be interested, but I am an older person, who has been involved in electronics since 1957, when I graduated a vocational High School in Radio/TV repair. It just a little harder to learn new things now.
Again, Thank You and the other members who replied.

1 Like

Good to hear, enjoy!

I am open to being wrong, as I claim no expertise here, but I think you don't want the second sei() in the sleep() routine.
I don't think it matters unless you want to use the pin as an input as well as a wake up pin, but I do, and it didn't work.
Seems to work now that I've removed it, except I haven't yet been able to test if it actually goes to sleep.
Also, isn't the ADC switched off in power down mode anyway?

@Hairyloon
"I think you don't want the second sei() in the sleep() routine"
Actually it's that first one that isn't needed but that second one is needed because I included the cli() call to disable interrupts right after waking from sleep. Interrupts need to be turned back on because Arduino sets up an interrupt to increment a variable on an interval so that millis() will work and it's required for delay to work, so interrupts need to be re-enabled for the blinking they wanted to do. But interrupts don't really need to be turned off in the first place, I just specifically provided these interrupt control commands in this sleeping code template because there are some projects where it's important, but not really for this situation. I was just trying to be thorough in case this template is copied by something else and it doesn't hurt to have the commands here. But if you wanted, you could remove all the sei and cli calls. In this case, since Arduino turns on interrupts by default they will always be enabled.

"isn't the ADC switched off in power down mode"
Unfortunately some part of the ADC's circuitry is still in play when sleeping. I learned about this from Nick Gammon's testing, https://www.gammon.com.au/power (search for "turn off adc") and later confirmed it with the ATtiny. Switching off the circuitry is a huge power saver, over 300uA. There are other things you can disable as well, like brown out detection, but it doesn't save nearly as much.

Ah, in that case I have entirely misunderstood what is going on...
Which may explain why my sketch doesn't behave as expected...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.