Atmega328PU wake up with a long button press

OP #4672024
Rate this post
useful
not useful
Hello there,

I'm working on a new project. One important topic is to save power in 
standalone Atmega 328PU. The microcontroller is into a deep sleep mode 
and should only wake up after the button was pressed for over 3 seconds. 
I wrote the following two codes.


1
#define LED_PIN 13
2
void setup() {
3
// put your setup code here, to run once:
4
pinMode(LED_PIN, OUTPUT);
5
//Save Power by writing all Digital I0 LOW 
6
for(int i=0; i<20; i++){
7
  if(i != 2)//just because the button is hooked up to digital pin 2
8
    pinMode(i, OUTPUT);
9
  }
10

11
  attachInterrupt(0, digitalInterrupt, FALLING); //interrupt for waking up
12
}
13

14
void loop() {
15
  // put your main code here, to run repeatedly:
16
digitalWrite(LED_PIN, HIGH);
17
delay(1000);
18
digitalWrite(LED_PIN, LOW);
19

20
//DISABLE ADC
21
ADCSRA &= ~(1<<7);
22
//ENABLE SLEEP
23
SMCR |= (1<<2); //power down mode
24
SMCR |= 1; //enable sleep
25

26
//BOD DISABLE
27
MCUCR |=(3 << 5); //set both BODS and BODSE at the same time
28
MCUCR = (MCUCR & ~(1 << 5)) | (1<< 6); //then set the BODS bit and clear the BODS bit at the same time
29
__asm__ __volatile__("sleep");
30
}
31

32
void digitalInterrupt(){
33
  //needed for the digital input interrupt
34
}



1
int inPin = 2;  // the pin number for input (for me a push button)
2
int ledPin = 13; 
3

4
int current;         // Current state of the button
5
                     // (LOW is pressed b/c i'm using the pullup resistors)
6
long millis_held;    // How long the button was held (milliseconds)
7
long secs_held;      // How long the button was held (seconds)
8
byte previous = HIGH;
9
unsigned long firstTime; // how long since the button was first pressed 
10

11

12
void setup() {
13
  pinMode(ledPin, OUTPUT);
14
  digitalWrite(inPin, HIGH);  // Turn on 20k pullup resistors to simplify switch input
15
}
16

17
void loop() {
18
  current = digitalRead(inPin);
19

20
  // if the button state changes to pressed, remember the start time 
21
  if (current == LOW && previous == HIGH) {
22
    firstTime = millis();
23
  }
24

25
  millis_held = (millis() - firstTime);
26
  secs_held = millis_held / 1000;
27

28
    if (current == LOW && previous == LOW) {
29

30
      // If the button was held for more then 3 seconds blink LED 1 time
31
      if (secs_held >= 3) {
32
        ledblink(1,4000,ledPin); 
33
      }
34

35
    }
36
  
37

38
  previous = current;
39

40
}
41

42
// Just a simple helper function to blink an led in various patterns
43
void ledblink(int times, int lengthms, int pinnum){
44
  for (int x=0; x<times;x++) {
45
    digitalWrite(pinnum, HIGH);
46
    delay (lengthms);
47
    digitalWrite(pinnum, LOW);
48
    delay(lengthms);
49
  }
50
}


The first code is for the deep sleep mode and wakes the Atmega 328PU up 
after an external interrupt.
The second code is a normal code (without any power saving option) and 
reads the digital input and sets a timer if the button was pressed. If 
the timer is over 3 seconds and the button is still pressed something 
will happen (for example a LED will flash).

So now my question is how to combine them? Is there any way to do that?
I hope somebody can help me :) I'm looking forward to your replies.

Best regards

Maurice W.

Reply

Please log in before posting.

or

Log in with Google account

Registration is free and takes only a minute.

Register now