Help. 328P can not go to sleep mode

Hello~

Here is my sketch for 2 string LED control.
I currently have a problem for sleep mode.
My sketch has no sleep mode when LED idle, so battery power consumption is too high.
I add " #include <Enerlib.h>" and "energy.PowerDown();" in sketch, but sketch can not work.
Any one can help me to verify how to improve the sketch.
The purpose is 328P goto sleep after 2 minutes if LED and charger no usage and press button to wake up.
In actually, I'm not sure sleep sketch and code position are correctly, but it can't go to sleep mode.

Thank you very much for your help!

#include <Wire.h>
#include <Enerlib.h>
Energy energy;

#define whiteLED_ON_OFF 5
#define yellowLED_ON_OFF 8
#define buttonPush 2
#define LEDdimming 3
#define Charge_detect A3 //電池充電
#define Discharge_detect 4 //USB放電按鈕
#define Vusb_out A7 // 偵測power bank 是否有在放電

#define read_Vbat A0
#define batval_1 9    //LED電量
#define batval_2 10   //LED電量
#define batval_3 11  //LED電量
#define batval_4 12  //LED電量


int button_bounce = 10;  // 預防開關彈跳
int brightness_level_adj = 80 ; // 開關按下要大於80ms 才有動作
int brightness_level_timeout = 900 ;
int color_SEL_adj = 2000 ;  // detect press BTN more than 2 second
int color_SEL_adj_timeout = 2100 ;  // 0.5秒
int discharge_start = 3000 ; // 開關按下時間大於3S開始放電
int discharge_timeout = 4000 ; // 開關時間大於4S 不動做
int brightness_SEL = 0;
int color_SEL = 1 ;
int button_flag = 0;
int charge_flag = 0;
int BBB;



// ===========================Brightness adjuset for PWM output
//int brightness_100 =  250;   //98%
int brightness_100 =  255;   //100%

//int brightness_75 = 192 ;    //75%
int brightness_75 = 128 ;    //50%


int brightness_50 = 64 ;    //50%
//int brightness_25 = 64 ;    //25%

int brightness_25 = 32 ;    //12%
int brightness_0 = 0 ;      //0% , LED OFF



//================================Vbat  status  :  5V:1023 = Vbat_status:X
int Vbat_status_43 = 840; //4.3V
int Vbat_status_42 = 825; //4.2V
int Vbat_status_41 = 820; //4.1V
int Vbat_status_40 = 810; //4.0V
int Vbat_status_39 = 790; //3.9V
int Vbat_status_38 = 780; //3.8V
int Vbat_status_37 = 760; //3.7V
int Vbat_status_36 = 740; //3.6V
int Vbat_status_35 = 720; //3.5V
int Vbat_status_34 = 700; //3.4V
int Vbat_status_33 = 680; //3.3V
int Vbat_status_32 = 660; //3.2V
int Vbat_status_31 = 640;  //3.1V




unsigned long startTime = 0;     // 按鈕被按下的起始時間
unsigned long duration_time = 0; // 持續時間
unsigned long previousMillis = 0;
const long interval = 1000;  //每次讀取電池的時間 : 1秒

unsigned long currentsleepTime = 0;     // 休眠計時起始時間
unsigned long durationsleepTime = 120000; // 計時2分鐘
unsigned long previousseleepTime = 0;


void setup()
{
  //CLKPR = 1 << CLKPCE;
  //CLKPR = 8;// 将CPU速度设置为 16MHz / 256

  //TCCR2A = 0b00100011;   //62.5KHz
  //TCCR2B = 0b00000001;   //62.5KHz

  //TCCR2A = 0b00100011; //1.92KHz
  //TCCR2B = 0b00000011; //1.92KHz

  TCCR2A = 0b00100011; // 975Hz
  TCCR2B = 0b00000100; // 975Hz
  attachInterrupt(0, wakeISR, LOW);


  pinMode(whiteLED_ON_OFF, OUTPUT);
  pinMode(yellowLED_ON_OFF, OUTPUT);
  pinMode(LEDdimming, OUTPUT);
  pinMode(buttonPush, INPUT);
  pinMode(read_Vbat, INPUT);
  pinMode(Charge_detect, INPUT);
  pinMode(Discharge_detect, OUTPUT);
  pinMode(Vusb_out, INPUT);

  // battery voltage detect
  pinMode(batval_1, OUTPUT);
  pinMode(batval_2, OUTPUT);
  pinMode(batval_3, OUTPUT);
  pinMode(batval_4, OUTPUT);

  digitalWrite (whiteLED_ON_OFF, LOW); // default, white LED is off
  digitalWrite (yellowLED_ON_OFF, LOW); // default, yellow LED is off
  digitalWrite (buttonPush, HIGH); // internal pull high
  // digitalWrite (Charge_detect, HIGH); // default ACT2813 BTN = high
  digitalWrite (Discharge_detect, HIGH); // default ACT2813 BTN = high


  digitalWrite (batval_1, HIGH);
  digitalWrite (batval_2, HIGH);
  digitalWrite (batval_3, HIGH);
  digitalWrite (batval_4, HIGH);


  analogWrite(LEDdimming, 0); //default, LED PWM output =0

  Serial.begin(9600);
}



void loop()
{

  
  unsigned long currentMillis = millis();
  previousMillis = currentMillis;
  
  currentsleepTime = millis();
  
  
  int vbattread = analogRead(Charge_detect);
  
  if (vbattread <=  512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899) //沒有插USB充電器,LED沒有亮時,USB沒有在放電,  LED電量指示燈關閉, 並開始計時是否睡眠
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);
    // 計時睡眠時間 -----------------------------------------------------
    
    previousseleepTime = previousseleepTime + currentsleepTime; 
    
    if (millis()-previousseleepTime > durationsleepTime) // 大於2分鐘
    {
      delay(100);
      Serial.println ( "Sleep now");
      
      energy.PowerDown();
    }  // ----------------------------------------------------------------------








    if (vbattread >= 513) // USB充電時,讀取充電LED電量
    {
      Charge_ReadVbat ();
    }

    //   if (vbattread >= 513 && analogRead(Vusb_out) >= 900) // USB同時充電與放電時,讀取充電LED 電量
    //   {
    //     Charge_ReadVbat ();
    //   }



    //    if (vbattread <= 512 && brightness_SEL >0 || analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
    if (analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
    {
      ReadVbat ();
    }

  }




  if (digitalRead(buttonPush) == LOW)
  {
    // ----------------------------- Long button detect --------------------------------------------
    if (digitalRead(buttonPush) == LOW)// Read status of tack switch
    {
      ReadVbat ();  // 偵測到LOW 即顯示電量

      startTime = millis();                //  按鈕起始時間計數開始
      while (digitalRead(buttonPush) == LOW)
      {
        if (millis() - startTime > color_SEL_adj && millis() - startTime < color_SEL_adj_timeout && millis() - startTime > button_bounce ) // 按鈕按下時間介於設定起始值與中止值, 並且忽略掉開關彈跳時間, 當開關介於這時間內時,執行BTN_push

        {
          color_SEL++;   // 顏色選擇判斷
          if (color_SEL > 3)
          {
            color_SEL = 1;
          }

          BTN_push ();  // 開關大於2s 後,依照Color sel 的設定執行顏色切換, 若按鈕仍沒有放開,則不會切換顏色,直到按鈕放開後,會跳開 while迴圈

        }


      }//=============================================== ultill button be released
      duration_time = millis() - startTime;   //按鍵總秒數統計

      if (duration_time  > discharge_start )
      {
        digitalWrite (Discharge_detect, LOW);
        delay (300);
        digitalWrite (Discharge_detect, HIGH);
      }




      button_flag = 1;
    }
    //--------------------------------END OF long button detect -------------------------------------






    //===============Button detect for function select====================
    if (button_flag == 1 && duration_time > brightness_level_adj && duration_time < brightness_level_timeout && duration_time > button_bounce)
      // if (button_flag == 1 && duration_time > brightness_level_adj && duration_time > button_bounce)
      // 當上面的回圈離開後,duration_time會統計秒數,如過秒數 250 ~ 1000 ms 之間,則認為要切換亮度,如過按鈕超過1S的話就不會執行亮度切換

    {
      //if (duration_time < brightness_level_adj)
      //{
      brightness_SEL++;

      if (brightness_SEL > 4)
      {
        //RST_ALL ();
        brightness_SEL = 0;
      }
      //}
      BTN_push ();

    } // end of button flag
    button_flag = 0;


  }



  //======================================================

}    //loop END mark



//=======================================================

void RST_ALL ()
{
  analogWrite(LEDdimming, brightness_0);
  digitalWrite (whiteLED_ON_OFF, LOW);
  digitalWrite (yellowLED_ON_OFF, LOW);

  brightness_SEL = 0;
}

//==================放電時的電壓指示 Battery voltage detect==================================

void ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val >= Vbat_status_40 )
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }


  if (val <= Vbat_status_39 && val >= Vbat_status_38 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  if (val <= Vbat_status_37 && val >= Vbat_status_36 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  /* if (val <=Vbat_status_37 && val>=Vbat_status_36) // <3.6V >3.5V
   {
   digitalWrite (batval_1,HIGH);
   digitalWrite (batval_2,HIGH);
   digitalWrite (batval_3,HIGH);
   digitalWrite (batval_4,LOW);
   }
   */
  if (val <= Vbat_status_35) //<3.5
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    //digitalWrite (batval_4,LOW);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }



  }


}

//==================充電時的電壓指示 Battery voltage detect==================================
void Charge_ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val  > Vbat_status_43)
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_42 && val >= Vbat_status_40)
  {
    //digitalWrite (batval_1,HIGH);


    if ( BBB == HIGH)
    {
      digitalWrite (batval_1, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_1, HIGH);
      BBB = HIGH;
    }

    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }



  if (val <= Vbat_status_39 && val >= Vbat_status_38)
  {
    digitalWrite (batval_1, HIGH);
    //digitalWrite (batval_2, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_2, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_2, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_37 && val >= Vbat_status_36)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    //digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_3, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_3, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_4, LOW);
  }





  if (val <= Vbat_status_35) //<3.5V    //有插電LED就會亮
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }
  }
}















void BTN_push ()
{

  //=========================WHITE LED ====================================
  if (brightness_SEL == 0)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);
    analogWrite (LEDdimming, brightness_0);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }
  //======================================================
  if (brightness_SEL == 1 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 2 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 3 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 4 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }


  //==========================YELLOW LED ==============================
  if (brightness_SEL == 1 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }



  //========================BOTH White and Yellow=================================================
  if (brightness_SEL == 1 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }
}





void wakeISR()
{
  Serial.println ( "Wake up");

}

The low power library from Rocket Scream works. Read the documentation and run the example programs to learn how to use it.

If you actually want to understand what is happening, there is no better tutorial than this one.

1 Like

Maybe also look here, depending on how the button is wired:
pinMode(buttonPush, INPUT); // INPUT_PULLUP ?
attachInterrupt(0, wakeISR, LOW); // FALLING ?

Hello~ 6v6gt

For the button, I use an external pull-up resistor.

thanks.

It appears you want the device to enter sleep mode when there has been no activity for 2 minutes.
I'd use the following example logic to force a sleep after a certain idle time has been exceeded.

// globals
uint32_t lastActivityAtMs = millis() ;
uint32_t maximumIdleTimeMs = 120000UL ;

// copy this line where ever there is activity which should reset the timer
// so that the system knows it is not idle.
lastActivityAtMs = millis() ;  // reset timer when activity detected.


// force sleep mode if the system has been idle for maximumIdleTimeMs
if ( millis() - lastActivityAtMs > maximumIdleTimeMs ) {
      Serial.println ( "Sleep now");
      delay(100);
      Serial.flush() ;  // force message out before sleep
      energy.PowerDown();
} 


// ensure lastActivityAtMs is reset also immediately on wake
void wakeISR()
{
  Serial.println ( "Wake up");
  lastActivityAtMs = millis() ;  // reset timer
}

Hello~ 6v6gt

I updated the sketch but the 328P going to sleep mode right away and can't wake up anyway.

thanks for you help.


#include <Wire.h>
#include <Enerlib.h>
Energy energy;

#define whiteLED_ON_OFF 5
#define yellowLED_ON_OFF 8
#define buttonPush 2
#define LEDdimming 3
#define Charge_detect A3 //電池充電
#define Discharge_detect 4 //USB放電按鈕
#define Vusb_out A7 // 偵測power bank 是否有在放電

#define read_Vbat A0
#define batval_1 9    //LED電量
#define batval_2 10   //LED電量
#define batval_3 11  //LED電量
#define batval_4 12  //LED電量


int button_bounce = 10;  // 預防開關彈跳
int brightness_level_adj = 80 ; // 開關按下要大於80ms 才有動作
int brightness_level_timeout = 900 ;
int color_SEL_adj = 2000 ;  // detect press BTN more than 2 second
int color_SEL_adj_timeout = 2100 ;  // 0.5秒
int discharge_start = 3000 ; // 開關按下時間大於3S開始放電
int discharge_timeout = 4000 ; // 開關時間大於4S 不動做
int brightness_SEL = 0;
int color_SEL = 1 ;
int button_flag = 0;
int charge_flag = 0;
int BBB;



// ===========================Brightness adjuset for PWM output
//int brightness_100 =  250;   //98%
int brightness_100 =  255;   //100%

//int brightness_75 = 192 ;    //75%
int brightness_75 = 128 ;    //50%


int brightness_50 = 64 ;    //50%
//int brightness_25 = 64 ;    //25%

int brightness_25 = 32 ;    //12%
int brightness_0 = 0 ;      //0% , LED OFF



//================================Vbat  status  :  5V:1023 = Vbat_status:X
int Vbat_status_43 = 840; //4.3V
int Vbat_status_42 = 825; //4.2V
int Vbat_status_41 = 820; //4.1V
int Vbat_status_40 = 810; //4.0V
int Vbat_status_39 = 790; //3.9V
int Vbat_status_38 = 780; //3.8V
int Vbat_status_37 = 760; //3.7V
int Vbat_status_36 = 740; //3.6V
int Vbat_status_35 = 720; //3.5V
int Vbat_status_34 = 700; //3.4V
int Vbat_status_33 = 680; //3.3V
int Vbat_status_32 = 660; //3.2V
int Vbat_status_31 = 640;  //3.1V




unsigned long startTime = 0;     // 按鈕被按下的起始時間
unsigned long duration_time = 0; // 持續時間
unsigned long previousMillis = 0;
const long interval = 1000;  //每次讀取電池的時間 : 1秒

unsigned long currentsleepTime = 0;     // 休眠計時起始時間
unsigned long durationsleepTime = 120000; // 計時2分鐘
unsigned long previousseleepTime = 0;


void setup()
{
  //CLKPR = 1 << CLKPCE;
  //CLKPR = 8;// 将CPU速度设置为 16MHz / 256

  //TCCR2A = 0b00100011;   //62.5KHz
  //TCCR2B = 0b00000001;   //62.5KHz

  //TCCR2A = 0b00100011; //1.92KHz
  //TCCR2B = 0b00000011; //1.92KHz

  TCCR2A = 0b00100011; // 975Hz
  TCCR2B = 0b00000100; // 975Hz
  attachInterrupt(0, wakeISR, LOW);


  pinMode(whiteLED_ON_OFF, OUTPUT);
  pinMode(yellowLED_ON_OFF, OUTPUT);
  pinMode(LEDdimming, OUTPUT);
  pinMode(buttonPush, INPUT_PULLUP);
  pinMode(read_Vbat, INPUT);
  pinMode(Charge_detect, INPUT);
  pinMode(Discharge_detect, OUTPUT);
  pinMode(Vusb_out, INPUT);

  // battery voltage detect
  pinMode(batval_1, OUTPUT);
  pinMode(batval_2, OUTPUT);
  pinMode(batval_3, OUTPUT);
  pinMode(batval_4, OUTPUT);

  digitalWrite (whiteLED_ON_OFF, LOW); // default, white LED is off
  digitalWrite (yellowLED_ON_OFF, LOW); // default, yellow LED is off
  digitalWrite (buttonPush, HIGH); // internal pull high
  // digitalWrite (Charge_detect, HIGH); // default ACT2813 BTN = high
  digitalWrite (Discharge_detect, HIGH); // default ACT2813 BTN = high


  digitalWrite (batval_1, HIGH);
  digitalWrite (batval_2, HIGH);
  digitalWrite (batval_3, HIGH);
  digitalWrite (batval_4, HIGH);


  analogWrite(LEDdimming, 0); //default, LED PWM output =0

  Serial.begin(9600);
}



void loop()
{

  
  unsigned long currentMillis = millis();
  previousMillis = currentMillis;
  
  currentsleepTime = millis();
  
  
  int vbattread = analogRead(Charge_detect);
  
  if (vbattread <=  512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899) //沒有插USB充電器,LED沒有亮時,USB沒有在放電,  LED電量指示燈關閉, 並開始計時是否睡眠
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);
    // 計時睡眠時間 -----------------------------------------------------
    
    //previousseleepTime = previousseleepTime + currentsleepTime; 
    
    if (millis()-currentsleepTime > durationsleepTime) // 大於2分鐘
    {
      delay(100);
      Serial.println ( "Sleep now");
      
      energy.PowerDown();
    }  // ----------------------------------------------------------------------








    if (vbattread >= 513) // USB充電時,讀取充電LED電量
    {
      Charge_ReadVbat ();
    }

    //   if (vbattread >= 513 && analogRead(Vusb_out) >= 900) // USB同時充電與放電時,讀取充電LED 電量
    //   {
    //     Charge_ReadVbat ();
    //   }



    //    if (vbattread <= 512 && brightness_SEL >0 || analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
    if (analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
    {
      ReadVbat ();
    }

  }




  if (digitalRead(buttonPush) == LOW)
  {
    // ----------------------------- Long button detect --------------------------------------------
    if (digitalRead(buttonPush) == LOW)// Read status of tack switch
    {
      ReadVbat ();  // 偵測到LOW 即顯示電量

      startTime = millis();                //  按鈕起始時間計數開始
      while (digitalRead(buttonPush) == LOW)
      {
        if (millis() - startTime > color_SEL_adj && millis() - startTime < color_SEL_adj_timeout && millis() - startTime > button_bounce ) // 按鈕按下時間介於設定起始值與中止值, 並且忽略掉開關彈跳時間, 當開關介於這時間內時,執行BTN_push

        {
          color_SEL++;   // 顏色選擇判斷
          if (color_SEL > 3)
          {
            color_SEL = 1;
          }

          BTN_push ();  // 開關大於2s 後,依照Color sel 的設定執行顏色切換, 若按鈕仍沒有放開,則不會切換顏色,直到按鈕放開後,會跳開 while迴圈

        }


      }//=============================================== ultill button be released
      duration_time = millis() - startTime;   //按鍵總秒數統計

      if (duration_time  > discharge_start )
      {
        digitalWrite (Discharge_detect, LOW);
        delay (300);
        digitalWrite (Discharge_detect, HIGH);
      }




      button_flag = 1;
    }
    //--------------------------------END OF long button detect -------------------------------------






    //===============Button detect for function select====================
    if (button_flag == 1 && duration_time > brightness_level_adj && duration_time < brightness_level_timeout && duration_time > button_bounce)
      // if (button_flag == 1 && duration_time > brightness_level_adj && duration_time > button_bounce)
      // 當上面的回圈離開後,duration_time會統計秒數,如過秒數 250 ~ 1000 ms 之間,則認為要切換亮度,如過按鈕超過1S的話就不會執行亮度切換

    {
      //if (duration_time < brightness_level_adj)
      //{
      brightness_SEL++;

      if (brightness_SEL > 4)
      {
        //RST_ALL ();
        brightness_SEL = 0;
      }
      //}
      BTN_push ();

    } // end of button flag
    button_flag = 0;


  }



  //======================================================

}    //loop END mark



//=======================================================

void RST_ALL ()
{
  analogWrite(LEDdimming, brightness_0);
  digitalWrite (whiteLED_ON_OFF, LOW);
  digitalWrite (yellowLED_ON_OFF, LOW);

  brightness_SEL = 0;
}

//==================放電時的電壓指示 Battery voltage detect==================================

void ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val >= Vbat_status_40 )
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }


  if (val <= Vbat_status_39 && val >= Vbat_status_38 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  if (val <= Vbat_status_37 && val >= Vbat_status_36 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  /* if (val <=Vbat_status_37 && val>=Vbat_status_36) // <3.6V >3.5V
   {
   digitalWrite (batval_1,HIGH);
   digitalWrite (batval_2,HIGH);
   digitalWrite (batval_3,HIGH);
   digitalWrite (batval_4,LOW);
   }
   */
  if (val <= Vbat_status_35) //<3.5
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    //digitalWrite (batval_4,LOW);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }



  }


}

//==================充電時的電壓指示 Battery voltage detect==================================
void Charge_ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val  > Vbat_status_43)
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_42 && val >= Vbat_status_40)
  {
    //digitalWrite (batval_1,HIGH);


    if ( BBB == HIGH)
    {
      digitalWrite (batval_1, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_1, HIGH);
      BBB = HIGH;
    }

    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }



  if (val <= Vbat_status_39 && val >= Vbat_status_38)
  {
    digitalWrite (batval_1, HIGH);
    //digitalWrite (batval_2, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_2, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_2, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_37 && val >= Vbat_status_36)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    //digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_3, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_3, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_4, LOW);
  }





  if (val <= Vbat_status_35) //<3.5V    //有插電LED就會亮
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }
  }
}















void BTN_push ()
{

  //=========================WHITE LED ====================================
  if (brightness_SEL == 0)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);
    analogWrite (LEDdimming, brightness_0);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }
  //======================================================
  if (brightness_SEL == 1 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 2 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 3 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 4 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }


  //==========================YELLOW LED ==============================
  if (brightness_SEL == 1 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }



  //========================BOTH White and Yellow=================================================
  if (brightness_SEL == 1 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }
}





void wakeISR()
{
  Serial.println ( "Wake up");
currentsleepTime = millis() ; 
}







Start by changing this line to prevent the immediate sleep:
unsigned long previousseleepTime = millis() ; // was 0

I don't think the name is very appropriate because it is used as the time stamp of the last activity. This is so the idle time can be calculated.

Anyway, can you say how you determine where there is activity which is relevant for your 2 minute timeout. For example, do you want the system to remain awake during this condition (vbattread <= 512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899) ? Or do you also want the button press to be counted as relevant activity for calculating the idle time ?

Hello~ 6v6gt

I would like 328P go to sleep mode when the following conditions are met after 2 minutes, this is unused status.

(vbattread <= 512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899
vbattread <= 512 // no 5V adapter charger input
brightness_SEL == 0  // no any LED ligh up
analogRead(Vusb_out) <= 899 // no 5V output, there have a 5V charger  in schematic

thanks for you help.

If the 328 goes to sleep. millis() is stoped, too :slight_smile:

But if it wakes up, it will go on again.
The current problem is that I don't know where to put the condition and sleep command.
No matter where I put sketch, it either won't go to sleep or won't wake up.

thanks.

I've placed the sleep code at the end of the loop. I can't test it though.

#include <Wire.h>
#include <Enerlib.h>
Energy energy;

#define whiteLED_ON_OFF 5
#define yellowLED_ON_OFF 8
#define buttonPush 2
#define LEDdimming 3
#define Charge_detect A3 //電池充電
#define Discharge_detect 4 //USB放電按鈕
#define Vusb_out A7 // 偵測power bank 是否有在放電

#define read_Vbat A0
#define batval_1 9    //LED電量
#define batval_2 10   //LED電量
#define batval_3 11  //LED電量
#define batval_4 12  //LED電量


int button_bounce = 10;  // 預防開關彈跳
int brightness_level_adj = 80 ; // 開關按下要大於80ms 才有動作
int brightness_level_timeout = 900 ;
int color_SEL_adj = 2000 ;  // detect press BTN more than 2 second
int color_SEL_adj_timeout = 2100 ;  // 0.5秒
int discharge_start = 3000 ; // 開關按下時間大於3S開始放電
int discharge_timeout = 4000 ; // 開關時間大於4S 不動做
int brightness_SEL = 0;
int color_SEL = 1 ;
int button_flag = 0;
int charge_flag = 0;
int BBB;



// ===========================Brightness adjuset for PWM output
//int brightness_100 =  250;   //98%
int brightness_100 =  255;   //100%

//int brightness_75 = 192 ;    //75%
int brightness_75 = 128 ;    //50%


int brightness_50 = 64 ;    //50%
//int brightness_25 = 64 ;    //25%

int brightness_25 = 32 ;    //12%
int brightness_0 = 0 ;      //0% , LED OFF



//================================Vbat  status  :  5V:1023 = Vbat_status:X
int Vbat_status_43 = 840; //4.3V
int Vbat_status_42 = 825; //4.2V
int Vbat_status_41 = 820; //4.1V
int Vbat_status_40 = 810; //4.0V
int Vbat_status_39 = 790; //3.9V
int Vbat_status_38 = 780; //3.8V
int Vbat_status_37 = 760; //3.7V
int Vbat_status_36 = 740; //3.6V
int Vbat_status_35 = 720; //3.5V
int Vbat_status_34 = 700; //3.4V
int Vbat_status_33 = 680; //3.3V
int Vbat_status_32 = 660; //3.2V
int Vbat_status_31 = 640;  //3.1V




unsigned long startTime = 0;     // 按鈕被按下的起始時間
unsigned long duration_time = 0; // 持續時間
unsigned long previousMillis = 0;
const long interval = 1000;  //每次讀取電池的時間 : 1秒

// unsigned long currentsleepTime = 0;     // 休眠計時起始時間
// unsigned long durationsleepTime = 120000; // 計時2分鐘
// unsigned long previousseleepTime = 0;

uint32_t lastActivityAtMs = millis() ;
uint32_t maximumIdleTimeMs = 120000UL ;



void setup()
{
  //CLKPR = 1 << CLKPCE;
  //CLKPR = 8;// 将CPU速度设置为 16MHz / 256

  //TCCR2A = 0b00100011;   //62.5KHz
  //TCCR2B = 0b00000001;   //62.5KHz

  //TCCR2A = 0b00100011; //1.92KHz
  //TCCR2B = 0b00000011; //1.92KHz

  TCCR2A = 0b00100011; // 975Hz
  TCCR2B = 0b00000100; // 975Hz
  attachInterrupt(0, wakeISR, LOW);


  pinMode(whiteLED_ON_OFF, OUTPUT);
  pinMode(yellowLED_ON_OFF, OUTPUT);
  pinMode(LEDdimming, OUTPUT);
  pinMode(buttonPush, INPUT_PULLUP);
  pinMode(read_Vbat, INPUT);
  pinMode(Charge_detect, INPUT);
  pinMode(Discharge_detect, OUTPUT);
  pinMode(Vusb_out, INPUT);

  // battery voltage detect
  pinMode(batval_1, OUTPUT);
  pinMode(batval_2, OUTPUT);
  pinMode(batval_3, OUTPUT);
  pinMode(batval_4, OUTPUT);

  digitalWrite (whiteLED_ON_OFF, LOW); // default, white LED is off
  digitalWrite (yellowLED_ON_OFF, LOW); // default, yellow LED is off
  digitalWrite (buttonPush, HIGH); // internal pull high
  // digitalWrite (Charge_detect, HIGH); // default ACT2813 BTN = high
  digitalWrite (Discharge_detect, HIGH); // default ACT2813 BTN = high


  digitalWrite (batval_1, HIGH);
  digitalWrite (batval_2, HIGH);
  digitalWrite (batval_3, HIGH);
  digitalWrite (batval_4, HIGH);


  analogWrite(LEDdimming, 0); //default, LED PWM output =0

  Serial.begin(9600);
}



void loop()
{


  // unsigned long currentMillis = millis();
  // previousMillis = currentMillis;

  // currentsleepTime = millis();


  int vbattread = analogRead(Charge_detect);

  if (vbattread <=  512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899) //沒有插USB充電器,LED沒有亮時,USB沒有在放電,  LED電量指示燈關閉, 並開始計時是否睡眠
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);


    if (vbattread >= 513) // USB充電時,讀取充電LED電量
    {
      Charge_ReadVbat ();
    }

    //   if (vbattread >= 513 && analogRead(Vusb_out) >= 900) // USB同時充電與放電時,讀取充電LED 電量
    //   {
    //     Charge_ReadVbat ();
    //   }



    //    if (vbattread <= 512 && brightness_SEL >0 || analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
    if (analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
    {
      ReadVbat ();
    }

  }




  if (digitalRead(buttonPush) == LOW)
  {
    // ----------------------------- Long button detect --------------------------------------------
    if (digitalRead(buttonPush) == LOW)// Read status of tack switch
    {
      ReadVbat ();  // 偵測到LOW 即顯示電量

      startTime = millis();                //  按鈕起始時間計數開始
      while (digitalRead(buttonPush) == LOW)
      {
        if (millis() - startTime > color_SEL_adj && millis() - startTime < color_SEL_adj_timeout && millis() - startTime > button_bounce ) // 按鈕按下時間介於設定起始值與中止值, 並且忽略掉開關彈跳時間, 當開關介於這時間內時,執行BTN_push

        {
          color_SEL++;   // 顏色選擇判斷
          if (color_SEL > 3)
          {
            color_SEL = 1;
          }

          BTN_push ();  // 開關大於2s 後,依照Color sel 的設定執行顏色切換, 若按鈕仍沒有放開,則不會切換顏色,直到按鈕放開後,會跳開 while迴圈

        }


      }//=============================================== ultill button be released
      duration_time = millis() - startTime;   //按鍵總秒數統計

      if (duration_time  > discharge_start )
      {
        digitalWrite (Discharge_detect, LOW);
        delay (300);
        digitalWrite (Discharge_detect, HIGH);
      }




      button_flag = 1;
    }
    //--------------------------------END OF long button detect -------------------------------------






    //===============Button detect for function select====================
    if (button_flag == 1 && duration_time > brightness_level_adj && duration_time < brightness_level_timeout && duration_time > button_bounce)
      // if (button_flag == 1 && duration_time > brightness_level_adj && duration_time > button_bounce)
      // 當上面的回圈離開後,duration_time會統計秒數,如過秒數 250 ~ 1000 ms 之間,則認為要切換亮度,如過按鈕超過1S的話就不會執行亮度切換

    {
      //if (duration_time < brightness_level_adj)
      //{
      brightness_SEL++;

      if (brightness_SEL > 4)
      {
        //RST_ALL ();
        brightness_SEL = 0;
      }
      //}
      BTN_push ();

    } // end of button flag
    button_flag = 0;


  }

  // handle sleep

  if ( ! ( vbattread <= 512  ) )            lastActivityAtMs = millis() ;  // reset timer
  if ( ! ( brightness_SEL == 0 ) )          lastActivityAtMs = millis() ;  // reset timer
  if ( ! ( analogRead(Vusb_out) <= 899 ) )  lastActivityAtMs = millis() ;  // reset timer

  // force sleep mode if the system has been idle for maximumIdleTimeMs
  if ( millis() - lastActivityAtMs > maximumIdleTimeMs ) {
    Serial.println ( "Sleep now");
    delay(100);
    Serial.flush() ;  // force message out before sleep
    energy.PowerDown();
    // sleep here
  }



  //======================================================

}    //loop END mark



//=======================================================

void RST_ALL ()
{
  analogWrite(LEDdimming, brightness_0);
  digitalWrite (whiteLED_ON_OFF, LOW);
  digitalWrite (yellowLED_ON_OFF, LOW);

  brightness_SEL = 0;
}

//==================放電時的電壓指示 Battery voltage detect==================================

void ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val >= Vbat_status_40 )
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }


  if (val <= Vbat_status_39 && val >= Vbat_status_38 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  if (val <= Vbat_status_37 && val >= Vbat_status_36 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  /* if (val <=Vbat_status_37 && val>=Vbat_status_36) // <3.6V >3.5V
    {
    digitalWrite (batval_1,HIGH);
    digitalWrite (batval_2,HIGH);
    digitalWrite (batval_3,HIGH);
    digitalWrite (batval_4,LOW);
    }
  */
  if (val <= Vbat_status_35) //<3.5
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    //digitalWrite (batval_4,LOW);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }



  }


}

//==================充電時的電壓指示 Battery voltage detect==================================
void Charge_ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val  > Vbat_status_43)
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_42 && val >= Vbat_status_40)
  {
    //digitalWrite (batval_1,HIGH);


    if ( BBB == HIGH)
    {
      digitalWrite (batval_1, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_1, HIGH);
      BBB = HIGH;
    }

    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }



  if (val <= Vbat_status_39 && val >= Vbat_status_38)
  {
    digitalWrite (batval_1, HIGH);
    //digitalWrite (batval_2, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_2, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_2, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_37 && val >= Vbat_status_36)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    //digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_3, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_3, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_4, LOW);
  }





  if (val <= Vbat_status_35) //<3.5V    //有插電LED就會亮
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }
  }
}















void BTN_push ()
{

  //=========================WHITE LED ====================================
  if (brightness_SEL == 0)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);
    analogWrite (LEDdimming, brightness_0);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }
  //======================================================
  if (brightness_SEL == 1 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 2 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 3 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 4 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }


  //==========================YELLOW LED ==============================
  if (brightness_SEL == 1 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }



  //========================BOTH White and Yellow=================================================
  if (brightness_SEL == 1 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }
}



void wakeISR()
{
  Serial.println ( "Wake up");
  lastActivityAtMs = millis() ;  // reset timer
}

EDIT

Just to clear this up:

So, for example, if vbattread is 1000 and brightness_SEL is 0, the system is active and should not sleep.
That is, if at least one of those parameters is in the required range, the system is considered active.
Is that correct ?

Have you practiced the examples of putting ATmega328P into sleep and subsequent waking up using Arduino UNO?

... and how do you detect that the 328 goes to sleep and wakes up again?

It doesn't have to detect that it is in sleep mode, it is forced into sleep mode after a period (2 minutes) of "inactivity". At least, that it how I understood the OP's requirements.
A wakeup is forced by the external interrupt on pin 2 through a button press.

Sure. But how does he verify that? If it's not verified, then the whole question is most questionable.

@knee266
1. You want to let your LEDs (at DPin-5, 8, and 3) are active for 2 minutes or "no LED activity (brightness_SEL = 0)" and then you check this condition: if (vbattread <= 512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899){} which if stands true, the MCU will enter into sleep. Is it correct?

2. For how long you want the MCU to be sleeping before you wake up it by pressing the "buttonPress" switch?

3. Can please attach the copy of Enerlib.h File?

4. Are you using Arduino NANO -- you have analog channel A7 in your sketch?

5. The following sketch might help you as to where placing the sleep instruction.

#include<avr/sleep.h>
int brightness_SEL = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  SMCR |= (1 << SM1); //Power-down Mode
  attachInterrupt(digitalPinToInterrupt(2), wakeISR, LOW);  //must be level mode
}

void loop()
{
L1: unsigned long currentMillis = millis();
  while (millis() - currentMillis < 2000)//test interval
  {
    if (brightness_SEL == 0)
    //if(vbattread <= 512 && brightness_SEL==0 && analogRead(Vusb_out) <= 899){}
    {
      sleepMCU();
      bitClear(SMCR, SE);
      Serial.println("Wake up from LED off.");
      brightness_SEL = 1;  //testing
      goto L1;  //my way; trying to get rid of goto statement
    }
  }
  //code to turn of all LED activities
  sleepMCU();
  bitClear(SMCR, SE);
  Serial.println("Wake up from 2-sec delay.");
}

void sleepMCU()
{
  bitSet(SMCR, SE); //sleep enable bit must be HIGH before sleep_cpu() instruction\
  sleep_cpu();  //asm: sleep; the MCU sleeps
}

void wakeISR()
{
}

Good point but his objective is to limit battery consumption so measuring the current is usually a good way of determining whether or not the device is in sleep mode. Switching a led in the loop, as a temporary measure, would also work.

1. You want to let your LEDs (at DPin-5, 8, and 3) are active for 2 minutes or "no LED activity (brightness_SEL = 0)" and then you check this condition: if (vbattread <= 512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899){} which if stands true, the MCU will enter into sleep. Is it correct?
[knee266]Yes, if (vbattread <= 512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899) then go to sleep mode after 2 min.

2. For how long you want the MCU to be sleeping before you wake up it by pressing the "buttonPress" switch?
[knee266] 2 min go to sleep, but press button to wake up.

3. Can please attach the copy of Enerlib.h File?
[knee266] please refer to attached.
Enerlib.cpp (1.2 KB)
Enerlib.h (369 Bytes)

4. Are you using Arduino NANO -- you have analog channel A7 in your sketch?
[knee266] Yes, A7 connecto to USB charger (USb Vo)

thanks for your help

@knee266
Did you try the code in post #11 ? If so, what where the results ?
What about answering the question at the end of post #11 ?

Hello~ 6v6gt

After uploading this sketch. When the button is pressed, nothing happens, and D9,D10,D11,D12 always low.

#define batval_1 9 //always LOW
#define batval_2 10 //always LOW
#define batval_3 11 //always LOW
#define batval_4 12 //always LOW

thanks for your help again.

#include <Wire.h>
#include <Enerlib.h>
Energy energy;

#define whiteLED_ON_OFF 5
#define yellowLED_ON_OFF 8
#define buttonPush 2
#define LEDdimming 3
#define Charge_detect A3 //電池充電
#define Discharge_detect 4 //USB放電按鈕
#define Vusb_out A7 // 偵測power bank 是否有在放電

#define read_Vbat A0
#define batval_1 9    //LED電量
#define batval_2 10   //LED電量
#define batval_3 11  //LED電量
#define batval_4 12  //LED電量


int button_bounce = 10;  // 預防開關彈跳
int brightness_level_adj = 80 ; // 開關按下要大於80ms 才有動作
int brightness_level_timeout = 900 ;
int color_SEL_adj = 2000 ;  // detect press BTN more than 2 second
int color_SEL_adj_timeout = 2100 ;  // 0.5秒
int discharge_start = 3000 ; // 開關按下時間大於3S開始放電
int discharge_timeout = 4000 ; // 開關時間大於4S 不動做
int brightness_SEL = 0;
int color_SEL = 1 ;
int button_flag = 0;
int charge_flag = 0;
int BBB;



// ===========================Brightness adjuset for PWM output
//int brightness_100 =  250;   //98%
int brightness_100 =  255;   //100%

//int brightness_75 = 192 ;    //75%
int brightness_75 = 128 ;    //50%


int brightness_50 = 64 ;    //50%
//int brightness_25 = 64 ;    //25%

int brightness_25 = 32 ;    //12%
int brightness_0 = 0 ;      //0% , LED OFF



//================================Vbat  status  :  5V:1023 = Vbat_status:X
int Vbat_status_43 = 840; //4.3V
int Vbat_status_42 = 825; //4.2V
int Vbat_status_41 = 820; //4.1V
int Vbat_status_40 = 810; //4.0V
int Vbat_status_39 = 790; //3.9V
int Vbat_status_38 = 780; //3.8V
int Vbat_status_37 = 760; //3.7V
int Vbat_status_36 = 740; //3.6V
int Vbat_status_35 = 720; //3.5V
int Vbat_status_34 = 700; //3.4V
int Vbat_status_33 = 680; //3.3V
int Vbat_status_32 = 660; //3.2V
int Vbat_status_31 = 640;  //3.1V




unsigned long startTime = 0;     // 按鈕被按下的起始時間
unsigned long duration_time = 0; // 持續時間
unsigned long previousMillis = 0;
const long interval = 1000;  //每次讀取電池的時間 : 1秒





uint32_t lastActivityAtMs = millis() ;
uint32_t maximumIdleTimeMs = 120000UL ;



void setup()
{
    //CLKPR = 1 << CLKPCE;
    //CLKPR = 8;// 将CPU速度设置为 16MHz / 256
  
  //TCCR2A = 0b00100011;   //62.5KHz
  //TCCR2B = 0b00000001;   //62.5KHz

  //TCCR2A = 0b00100011; //1.92KHz
  //TCCR2B = 0b00000011; //1.92KHz

  TCCR2A = 0b00100011; // 975Hz
  TCCR2B = 0b00000100; // 975Hz
attachInterrupt(0, wakeISR, LOW);


  pinMode(whiteLED_ON_OFF, OUTPUT);
  pinMode(yellowLED_ON_OFF, OUTPUT);
  pinMode(LEDdimming, OUTPUT);
  pinMode(buttonPush, INPUT);
  pinMode(read_Vbat, INPUT);
  pinMode(Charge_detect, INPUT);
  pinMode(Discharge_detect, OUTPUT);
  pinMode(Vusb_out, INPUT);

  // battery voltage detect
  pinMode(batval_1, OUTPUT);
  pinMode(batval_2, OUTPUT);
  pinMode(batval_3, OUTPUT);
  pinMode(batval_4, OUTPUT);

  digitalWrite (whiteLED_ON_OFF, LOW); // default, white LED is off
  digitalWrite (yellowLED_ON_OFF, LOW); // default, yellow LED is off
  digitalWrite (buttonPush, HIGH); // internal pull high
  // digitalWrite (Charge_detect, HIGH); // default ACT2813 BTN = high
  digitalWrite (Discharge_detect, HIGH); // default ACT2813 BTN = high


  digitalWrite (batval_1, HIGH);
  digitalWrite (batval_2, HIGH);
  digitalWrite (batval_3, HIGH);
  digitalWrite (batval_4, HIGH);


  analogWrite(LEDdimming, 0); //default, LED PWM output =0

    Serial.begin(9600);
}



void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)  // 偵測電池電壓間隔時間 1s
  {

    previousMillis = currentMillis;
    int vbattread = analogRead(Charge_detect);
    if (vbattread <=  512 && brightness_SEL == 0 && analogRead(Vusb_out) <= 899) //沒有插USB充電器,LED沒有亮時, LED 電量指示燈關閉
    {
      digitalWrite (batval_1, HIGH);
      digitalWrite (batval_2, HIGH);
      digitalWrite (batval_3, HIGH);
      digitalWrite (batval_4, HIGH);
    }

    if (vbattread >= 513) // USB充電時,讀取充電LED電量
    {
      Charge_ReadVbat ();
    }

 //   if (vbattread >= 513 && analogRead(Vusb_out) >= 900) // USB同時充電與放電時,讀取充電LED 電量
 //   {
 //     Charge_ReadVbat ();
 //   }



//    if (vbattread <= 512 && brightness_SEL >0 || analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
     if (analogRead(Vusb_out) >= 900) // 沒有插USB充電, LED有亮, 或是有在放電 則為放電LED
   {
      ReadVbat ();
   }

  }




   if (digitalRead(buttonPush) == LOW)
 {
    // ----------------------------- Long button detect --------------------------------------------
    if (digitalRead(buttonPush) == LOW)// Read status of tack switch
    {
      ReadVbat ();  // 偵測到LOW 即顯示電量

      startTime = millis();                //  按鈕起始時間計數開始
      while (digitalRead(buttonPush) == LOW)
      {
        if (millis() - startTime > color_SEL_adj && millis() - startTime < color_SEL_adj_timeout && millis() - startTime > button_bounce ) // 按鈕按下時間介於設定起始值與中止值, 並且忽略掉開關彈跳時間, 當開關介於這時間內時,執行BTN_push
         
        {
          color_SEL++;   // 顏色選擇判斷
          if (color_SEL > 3)
          {
            color_SEL = 1;
          }

          BTN_push ();  // 開關大於2s 後,依照Color sel 的設定執行顏色切換, 若按鈕仍沒有放開,則不會切換顏色,直到按鈕放開後,會跳開 while迴圈

        }


      }//=============================================== ultill button be released
      duration_time = millis() - startTime;   //按鍵總秒數統計
  
      if (duration_time  > discharge_start )
      {
      digitalWrite (Discharge_detect, LOW);
      delay (300);
      digitalWrite (Discharge_detect, HIGH);
      }
      
      
      
      
      button_flag = 1;
    }
    //--------------------------------END OF long button detect -------------------------------------






    //===============Button detect for function select====================
    if (button_flag == 1 && duration_time > brightness_level_adj && duration_time < brightness_level_timeout && duration_time > button_bounce)
      // if (button_flag == 1 && duration_time > brightness_level_adj && duration_time > button_bounce)
      // 當上面的回圈離開後,duration_time會統計秒數,如過秒數 250 ~ 1000 ms 之間,則認為要切換亮度,如過按鈕超過1S的話就不會執行亮度切換

    {
      //if (duration_time < brightness_level_adj)
      //{
      brightness_SEL++;

      if (brightness_SEL > 4)
      {
        //RST_ALL ();
        brightness_SEL = 0;
      }
      //}
      BTN_push ();
      
    } // end of button flag
button_flag = 0;


  }

  // handle sleep
int vbattread = analogRead(Charge_detect);
  if ( ! ( vbattread <= 512  ) )            lastActivityAtMs = millis() ;  // reset timer
  if ( ! ( brightness_SEL == 0 ) )          lastActivityAtMs = millis() ;  // reset timer
  if ( ! ( analogRead(Vusb_out) <= 899 ) )  lastActivityAtMs = millis() ;  // reset timer

  // force sleep mode if the system has been idle for maximumIdleTimeMs
  if ( millis() - lastActivityAtMs > maximumIdleTimeMs ) {
    Serial.println ( "Sleep now");
    delay(100);
    Serial.flush() ;  // force message out before sleep
    energy.PowerDown();
    // sleep here
  }
  //======================================================

}    //loop END mark



//=======================================================

void RST_ALL ()
{
  analogWrite(LEDdimming, brightness_0);
  digitalWrite (whiteLED_ON_OFF, LOW);
  digitalWrite (yellowLED_ON_OFF, LOW);

  brightness_SEL = 0;
}

//==================放電時的電壓指示 Battery voltage detect==================================

void ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val >= Vbat_status_40 )
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }


  if (val <= Vbat_status_39 && val >= Vbat_status_38 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  if (val <= Vbat_status_37 && val >= Vbat_status_36 )
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }

  /* if (val <=Vbat_status_37 && val>=Vbat_status_36) // <3.6V >3.5V
   {
   digitalWrite (batval_1,HIGH);
   digitalWrite (batval_2,HIGH);
   digitalWrite (batval_3,HIGH);
   digitalWrite (batval_4,LOW);
   }
   */
  if (val <= Vbat_status_35) //<3.5
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    //digitalWrite (batval_4,LOW);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }



  }


}

//==================充電時的電壓指示 Battery voltage detect==================================
void Charge_ReadVbat ()
{
  int val = analogRead(read_Vbat);

  if (val  > Vbat_status_43)
  {
    digitalWrite (batval_1, LOW);
    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_42 && val >= Vbat_status_40)
  {
    //digitalWrite (batval_1,HIGH);


    if ( BBB == HIGH)
    {
      digitalWrite (batval_1, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_1, HIGH);
      BBB = HIGH;
    }

    digitalWrite (batval_2, LOW);
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }



  if (val <= Vbat_status_39 && val >= Vbat_status_38)
  {
    digitalWrite (batval_1, HIGH);
    //digitalWrite (batval_2, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_2, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_2, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_3, LOW);
    digitalWrite (batval_4, LOW);
  }




  if (val <= Vbat_status_37 && val >= Vbat_status_36)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    //digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_3, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_3, HIGH);
      BBB = HIGH;
    }
    digitalWrite (batval_4, LOW);
  }





  if (val <= Vbat_status_35) //<3.5V    //有插電LED就會亮
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    if ( BBB == HIGH)
    {
      digitalWrite (batval_4, LOW);
      BBB = LOW;
    }
    else
    {
      digitalWrite (batval_4, HIGH);
      BBB = HIGH;
    }
  }
}















void BTN_push ()
{

  //=========================WHITE LED ====================================
  if (brightness_SEL == 0)
  {
    digitalWrite (batval_1, HIGH);
    digitalWrite (batval_2, HIGH);
    digitalWrite (batval_3, HIGH);
    digitalWrite (batval_4, HIGH);
    analogWrite (LEDdimming, brightness_0);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }
  //======================================================
  if (brightness_SEL == 1 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 2 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 3 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }

  if (brightness_SEL == 4 && color_SEL == 1)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, LOW);
  }


  //==========================YELLOW LED ==============================
  if (brightness_SEL == 1 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 2)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, LOW);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }



  //========================BOTH White and Yellow=================================================
  if (brightness_SEL == 1 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_25);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 2 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_50);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 3 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_75);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }

  if (brightness_SEL == 4 && color_SEL == 3)
  {
    analogWrite(LEDdimming, brightness_100);
    digitalWrite (whiteLED_ON_OFF, HIGH);
    digitalWrite (yellowLED_ON_OFF, HIGH);
  }
}





void wakeISR()
{
  Serial.println ( "Wake up");
  lastActivityAtMs = millis() ;  // reset timer
}