- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 4 von 4

Thema: Arduino/Atmega328PU wake up with a long button press

  1. #1

    Arduino/Atmega328PU wake up with a long button press

    Anzeige

    E-Bike
    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.

    Code:
    #define LED_PIN 13
    void setup() {
    // put your setup code here, to run once:
    pinMode(LED_PIN, OUTPUT);
    //Save Power by writing all Digital I0 LOW 
    for(int i=0; i<20; i++){
      if(i != 2)//just because the button is hooked up to digital pin 2
        pinMode(i, OUTPUT);
      }
    
      attachInterrupt(0, digitalInterrupt, FALLING); //interrupt for waking up
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    digitalWrite(LED_PIN, HIGH);
    delay(1000);
    digitalWrite(LED_PIN, LOW);
    
    //DISABLE ADC
    ADCSRA &= ~(1<<7);
    //ENABLE SLEEP
    SMCR |= (1<<2); //power down mode
    SMCR |= 1; //enable sleep
    
    //BOD DISABLE
    MCUCR |=(3 << 5); //set both BODS and BODSE at the same time
    MCUCR = (MCUCR & ~(1 << 5)) | (1<< 6); //then set the BODS bit and clear the BODS bit at the same time
    __asm__ __volatile__("sleep");
    }
    
    void digitalInterrupt(){
      //needed for the digital input interrupt
    }

    Code:
    int inPin = 2;  // the pin number for input (for me a push button)
    int ledPin = 13; 
    
    int current;         // Current state of the button
                         // (LOW is pressed b/c i'm using the pullup resistors)
    long millis_held;    // How long the button was held (milliseconds)
    long secs_held;      // How long the button was held (seconds)
    byte previous = HIGH;
    unsigned long firstTime; // how long since the button was first pressed 
    
    
    void setup() {
      pinMode(ledPin, OUTPUT);
      digitalWrite(inPin, HIGH);  // Turn on 20k pullup resistors to simplify switch input
    }
    
    void loop() {
      current = digitalRead(inPin);
    
      // if the button state changes to pressed, remember the start time 
      if (current == LOW && previous == HIGH) {
        firstTime = millis();
      }
    
      millis_held = (millis() - firstTime);
      secs_held = millis_held / 1000;
    
        if (current == LOW && previous == LOW) {
    
          // If the button was held for more then 3 seconds blink LED 1 time
          if (secs_held >= 3) {
            ledblink(1,4000,ledPin); 
          }
    
        }
      
    
      previous = current;
    
    }
    
    // Just a simple helper function to blink an led in various patterns
    void ledblink(int times, int lengthms, int pinnum){
      for (int x=0; x<times;x++) {
        digitalWrite(pinnum, HIGH);
        delay (lengthms);
        digitalWrite(pinnum, LOW);
        delay(lengthms);
      }
    }

    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.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    your main problem here is, making the timer in software makes your sleep mode useless, the moment the interrupt is called, the controller leaves it's sleep mode immediately to execute your Interrupt Service Routine (ISR)

    you need to make it a bit more complicated to achive this with maximum efficiency
    Code:
    loop_code(){
       if(buttonisreleased())
          prepare_deep_sleep();
          sleeping = TRUE;
          //enter sleep, store the sleep status to some variable like sleeping = TRUE (important!!!)
          while(sleeping){
             execute_sleep();
          }
       }
    }
    ISR(external_interrupt)
    {
       if(buttonhasbeenpressed()){
          start_timer();
          prepare_low_power_sleep_with_timer();
       else if(buttonhasbeenreleased()){
          stop_timer();
          prepare_deep_sleep();
          sleeping = TRUE;
       }
    }
    ISR{timer_reached_3s)
    {
       sleeping = FALSE;
    }
    when the button is not pressed, the cpui enters deep sleep until you press the button

    whenever an ISR is returning, it re-enters the normal execution, the call after your sleep(), so when the button is pressed but sleep remains true(because your time dod not run out yet), you automatically returns to lo power mode, waiting for either the timer to execute an interrupt or the button to be released

    when you release the button too early, the timer is stopped and deep sleep is re-entered
    when the timer runs up, the sleeping variable is set to false and the sleep loop is left until you again release the button!
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von HeXPloreR
    Registriert seit
    08.07.2008
    Ort
    Bad Bramstedt
    Alter
    45
    Beiträge
    1.369
    Mein lieber (Funk-)freund,

    was stimmt mit Dir nicht?

    Nein, du bist hier nicht richtig! Findest du es nicht ziemlich unhöflich in diese Unterhaltung hereinzuplatzen??

    Bitte kann ein Moderator, oder höher, den Thread selbstständig machen. Dieser Beitrag hier darf/kann/soll dann bitte entfernt werden.

    Viele Grüße
    Jörg

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    @HeXPloreR unter dem Beitrag, links neben "Blog-Eintrag" kannst du auf dieses Dreieck mit Ausrufezeichen klicken und den Post melden (hab ich auch gerade gemacht). Ich mag solche Dreistigkeit ebenfalls überhaupt nicht!
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

Ähnliche Themen

  1. AtMega328PU mit Arduino-Bootloader beschreiben - aber wie?
    Von Cysign im Forum AVR Hardwarethemen
    Antworten: 13
    Letzter Beitrag: 03.04.2013, 14:12
  2. Button Arduino Processing (GUI)
    Von paper im Forum Open Source Software Projekte
    Antworten: 0
    Letzter Beitrag: 22.11.2012, 19:38
  3. c: press key to continue
    Von toxi im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 30.10.2005, 15:01
  4. test Programm T/C2-wake up funktionieren nicht richtig
    Von janboejle im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 24.06.2005, 12:35
  5. Begriffe bei Press-Verbindungen
    Von Hellmut im Forum Mechanik
    Antworten: 2
    Letzter Beitrag: 08.02.2005, 20:07

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test