Struggling with code to move through cycle within if statements after sleepmode.

Hi

Thank you for your time reading this, I have spent about 3 weeks on this problem and just nothing seems to work, I'm stuck :frowning:

I have a little program that uses a Attiny85 and a shift register to light 16 LED's in what will be different patterns.

Everything works perfect without the sleep and interrupt functions but when I use the interrupt with a push button it behaves strangely. The sleep works fine as it should, It wakes up fine but when it awakens I use an int count to move to the next if statement in loop() which checks if the cycle count is more than 1 and then sends it back to 0 which then should put the Attiny85 back into sleep mode..

What happens though is after pressing the push button during the light pattern in cycle 1 it then starts the light pattern again as if it's still at 1 in the cycle even though I have cycle++; in the interrupt which works and adds 1 to move it onto the pattern in the first place but now it won't add anything to cycle with a button press any longer. I can't get my head around how it would be either skipping 0 or somehow it's restarting the same loop where it was put into sleep? It's difficult to tell without serial.println.

Any help would be much appreciated.

Thanks

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

    const int latchPin = 0;
    const int clockPin = 1;
    const int dataPin = 2;
    const int buttonPin = 3;

    //Count for stage in cycle of patterns
    int cycle = 0;

    //Push button debouncer
    int buttonState;
    int lastButtonState = LOW;
    unsigned long lastDebounceTime = 0;
    unsigned long debounceDelay = 50;

    //Count for first pattern of LED's and count for Millis of that pattern
    int aCount = 0;
    unsigned long pat1preMillis = 0;

    void setup() {

    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(buttonPin, INPUT);

    //Basic flash of LED's to confirm setup, Will be deleted when finished
    byte flash1 = B10001000;
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, flash1);
    digitalWrite(latchPin, HIGH);
    delay(500);
    byte flash2 = B01001000;
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, flash2);
    digitalWrite(latchPin, HIGH);
    delay(500);
    byte flash3 = B10001000;
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, flash3);
    digitalWrite(latchPin, HIGH);
    delay(500);

    wipe();
    
    }

    void loop() {

    unsigned long currentMillis = millis();

    int reading = digitalRead(buttonPin);
    if (reading != lastButtonState) {
      lastDebounceTime = millis();      
    }
    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != buttonState) {
        buttonState = reading;
        if (buttonState == HIGH) {
          wipe();
          cycle++;
        }
      }
    }
    
    lastButtonState = reading;   

    if (cycle == 0) {
    sleep(); 
    }

    else if (cycle == 1) {
    byte seq1[16] = {B10001000,B01001000,B00101000,B00011000,
                    B00010100,B00100100,B01000100,B10000100,
                    B10000010,B01000010,B00100010,B00010010,
                    B00010001,B00100001,B01000001,B10000001};
    int ledGap = 300;
    if (currentMillis - pat1preMillis > ledGap) {
      if (aCount < 16) {
          digitalWrite(latchPin, LOW);
          shiftOut(dataPin, clockPin, MSBFIRST, seq1[aCount]);
          digitalWrite(latchPin, HIGH);
          aCount++;
      }
      if (aCount == 16) {
        aCount = 0;
      }
      pat1preMillis = currentMillis;
      }
    }
    
    else if (cycle > 1) {
      cycle = 0;
    }
    
    }

    //Turn all LED's off and reset pattern counts to 0
    void wipe() {
    byte pattern = B00000000;
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, pattern);
    digitalWrite(latchPin, HIGH);
    aCount = 0;
    }

    //Attiny85 sleep code
    void sleep() {

    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT3);                   // Use PB3 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

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

    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT3);                  // Turn off PB3 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();

    }

    //Attiny85 interrupt code
    ISR(PCINT0_vect) {
      cycle++;
    }

Hi Delta_G

Thank you for your response..

I have just tried changing it to

volatile int cycle = 0;

Unfortunately though it made no difference, It still restarts the light pattern after pressing the button while in that part of the cycle.

Anything I'm missing?

Thanks

I think it's a problem with my interrupt code? It seems maybe the cycle is adding one twice maybe as it is also doing it for my button press in loop().

I have tried to set a boolean to check if it was waking from a sleep to not add one in my button press code in loop() but that didn't work :frowning:

It's so annoying as this is the last thing I need to solve and then I'm ready to write a few light patterns and then build it.