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.