Programmieren & Softwareentwicklung

Wenn Du nicht nur Anwender sein willst, sondern auch aktiv programmierst oder mit dem Gedanken spielst, dann warten hier die passenden Fragen und Antworten auf Dich.

26.777 Beiträge

Sketch atmega328p sleep und Interrupt?

Hallo an alle.

Ich möchte diesen Sketch zum laufen bekommen aber er klemmt im Sleep u. einiges andere funktioniert noch nicht.

Ich programmiere direkt den atmega328p u. nutze den Nano als Programmer. Das funktioniert alles super.

Aus Gründen der Platine muss der Taster auf PIN 11 (Physisch 15 OC2A OC2 MOSI PCINT4 PB4) bleiben.Daher muss ich bin change für den Interrupt auf PCint4 legen.

Also soll es einen Taster geben der den Interrupt auslöst u.den Sleep-Modus unterbricht so dass Void Starter aufgerufen wird. Außerdem soll der Timer alle vier Sekunden auch einen Interrupt auslösen, so das der loop durchläuft.

Wenn kein Taster gedrückt ist && USB Status = 0 ist, geht er in sleep. Er geht auch in den Sleep Mode weil nur 2 mA gezogen werden.

Der timer unterbricht den sleep nicht und der Interrupt vom Taster geht auch nicht. Sieht man auch gut weil loop nicht mehr durchlaufen wird, sonst würde wenn der USB Status 1 ist.

-Hauptlicht geht für 5h an wenn USB Status 0 ist

-Wenn nichts passiert - Sleep aktiviert

-Timer unterbricht Sleep Mode, Loop läuft durch

-Taster geht auf 1 u. löst Interrupt aus u. startet Void Starter

-Wenn USB Status 1 ist, Hauptlicht aus

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

int USBvcc     = 16;
int Taster     = 11; // (physischer Pin 15)
int Rot        = 6;
int Weis       = 5;
int Sound      = 10;
int Hauptlicht = 9;

int Status; 
int Tasterzustand; 
int R;
int W;
int H = 255;

int USBStatus;

unsigned long currentMillis = millis(); // Zeitspeicher

volatile bool tasterInterrupt = false;  // Flag für Interrupt

void setup() {
  pinMode(Hauptlicht, OUTPUT); // LED-Ausgang
  pinMode(Rot, OUTPUT);
  pinMode(Weis, OUTPUT);
  pinMode(Sound, OUTPUT);
  pinMode(Taster, INPUT); 
  pinMode(USBvcc, INPUT);

  // Timer-Interrupt einrichten (alle 4 Sekunden)
  Timer1.initialize(4000000); // 4 Sekunden
  Timer1.attachInterrupt(timerInterrupt); // Timer-Interrupt-Funktion zuweisen

  // Pin Change Interrupt aktivieren für Taster (PB4 = PCINT4)
  PCICR |= (1 << PCIE0);    // Aktiviert PCINTs für Port B
  PCMSK0 |= (1 << PCINT4);  // Aktiviert PCINT für PB4 (Pin 11)
  sei();                    // Globale Interrupts aktivieren
}

void loop() {
  USBStatus = digitalRead(USBvcc);
  Tasterzustand = digitalRead(Taster);
  Zeit();

  // Wenn Taster-Interrupt ausgelöst wird und der USB-Status 0 ist, dann Starter ausführen
  if (tasterInterrupt && USBStatus == 0) {
    Starter();  // Starter-Funktion ausführen
  }

  // Wenn der USB-Status 1 ist, Hauptlicht ausschalten
  if (USBStatus == 1) {
    digitalWrite(Hauptlicht, 0); 
  }

  // Wenn der Taster-Interrupt nicht ausgelöst wurde und der USB-Status 0 ist
  if (!tasterInterrupt && USBStatus == 0) {
    // Den Schlafmodus aktivieren
    goToSleep();  // in den Schlafmodus gehen
  }
}

void timerInterrupt() {
  // Funktion, die bei jedem Timer-Interrupt ausgelöst wird
  // Wird verwendet, um den Sleep-Modus zu unterbrechen
}

void goToSleep() {
  // Interrupt für den Taster aktivieren (Wake-Up)
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Power-Down-Modus wählen
  sleep_enable(); // Schlafmodus aktivieren
  sleep_mode(); // In den Schlafmodus gehen

  // Der Mikrocontroller wird hier durch den Timer-Interrupt oder den Taster-Interrupt geweckt
  sleep_disable(); // Schlafmodus deaktivieren nach dem Aufwachen
  tasterInterrupt = false; // Interrupt-Flag zurücksetzen
}

ISR(PCINT0_vect) {
  // ISR für Pin Change Interrupt auf Port B (PB4 = Pin 11)
  if (digitalRead(Taster) == HIGH) { // Prüfen, ob der Taster gedrückt wurde
    wakeUp();
  }
}

void wakeUp() {
  // Taster Interrupt, um den Mikrocontroller aufzuwecken
  tasterInterrupt = true;
}

void Zeit() {
  if (millis() - currentMillis >= 86400000) {
    currentMillis = millis();  // 24h abgelaufen -> Zeitspeicher neu setzen
  } else if ((millis() - currentMillis < 18000000) && (USBStatus == 0)) { 
    analogWrite(Hauptlicht, 255);  // Licht für die ersten 6h
  } else {
    analogWrite(Hauptlicht, 0);  // Licht ausschalten, wenn keine Bedingung erfüllt ist
  }
}

void Starter() {
    delay(1000);
    digitalWrite(Sound, HIGH);
    delay(100);
    digitalWrite(Sound, LOW);

    for (int D = 0; D <= 254;) {
      analogWrite(Rot, R = R + 5);
      D = D + 5;
      delay(50); 
    }

    for (int D = 0; D <= 34;) {
      for (int X = 0; X <= 254;) {
        analogWrite(Rot, R = R - 5);
        analogWrite(Weis, W = W + 5);
        analogWrite(Hauptlicht, H = H - 5);
        X = X + 5; 
        delay(10); 
      }

      for (int X = 0; X <= 254;) {
        analogWrite(Rot, R = R + 5);
        analogWrite(Weis, W = W - 5);
        analogWrite(Hauptlicht, H = H + 5);
        X = X + 5; 
        delay(10); 
      } 
      D = D + 1;
    }

    for (int X = 0; X <= 254;) {
      analogWrite(Hauptlicht, H = H - 5);
      X = X + 5; 
      delay(5);  
    }

    for (int D = 0; D <= 254;) {
      analogWrite(Rot, R = R - 5);
      analogWrite(Hauptlicht, H = H + 5);
      D = D + 5;
      delay(40);  
    }
}
Ask Me Anything: Themenspecials