Sketch für Atmega328p will nicht

Hallo an alle.

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

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

Aus Gründen der Platine muss der Taster auf PIN 11 (Physisch 15 physisch 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 und 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 und USB Status = 0 ist, geht er in sleep. Und er geht auch in den Sleep Mode was ich daran erkenne, dass 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 erkannt dass / wenn der USB Status HIGH ist.

Ich möchte nur wissen warum es nicht geht und keine optimierenden Anpassungen die nicht zwingend notwendig sind sondern nur verstehen wo der Fehler liegt

Ablauf.
-Hauptlicht geht für 5h o. 6h an wenn USB Status 0 ist.
-Wenn nichts passiert - Sleep aktiviert
-Timer unterbricht den Sleep Mode Loop läuft durch.
-Taster geht auf HIGH und löst Interrupt ausund startet Void Starter
-Wenn USB Status 1 ist, Hauptlicht aus (an geht er im Void Zeit)

#include <avr/sleep.h>
#include <TimerOne.h>  // Bibliothek für Timer1

int USBvcc = 16;
int Taster = 11; // Taster an Pin 11 (physischer Pin 15)
int Rot = 6;
int Weiß = 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 der 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);  
    }
}

Ich hoffe man versteht um was es mir geht.
Bin für Hilfe dankbar.

Verstehe ich nicht.
Beim Atmega328p ist PB4 "physisch" der Pin 18, OC2A/MOSI ist PCINT3 "physisch" Pin17
Der physische Pin15 ist PB1/PCInt 1 ( DIP). Bei den anderen Bauformen ist PB4 auch nicht auf dem physischen Pin 15 ... also was ist da jetzt wirklich Sache?
Das sieht mir danach aus, dass Du mit den Pins etwas durcheinander gekommen bist.

Bei der Nummer mit dem Timer1 wüsste ich nicht wie das funktionieren soll. Wie kommst Du auf diese Konstruktion? Verwende den Watchdog-Timer des Controllers und konfiguriere diesen auf 4 Sekunden.

// watchdog ISR
ISR(WDT_vect) {
  // nothing to do here, just wake up
}

void enableWatchdog() {
  cli();
  wdt_reset();
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = (1 << WDIE) | (0 << WDE) | (1 << WDP3);   // 4s / interrupt, no system reset
  sei();
}

void setup() {
  enableWatchdog();
}

Ich habe mich vertan mit PCINT4 und PB4.
Der PIN 15 am IC (Atmega328p) hat die Belegung: OC2A - OC - MOSI - D11 - PCINT3 - PB3.
Der PIN 18 hat AVCC. PDF
Also ich sollte nur mit der Beschreibung durcheinander gekommen sein definitiv nicht aber mit dem PIN 15 (Arduino D11)

Der Timer1 wird mithilfe der Bibliothek TimerOne.h verwendet und ist wie folgt eingebunden:

Initialisierung des Timers:

Timer1.initialize(4000000); // 4 Sekunden
Timer1.attachInterrupt(timerInterrupt); // Funktion "timerInterrupt" zuweisen

initialize(4000000): Konfiguriert Timer1 so, dass er alle 4 Sekunden einen Interrupt auslöst.
attachInterrupt(timerInterrupt): Verknüpft eine benutzerdefinierte Funktion (timerInterrupt), die beim Ablauf des Timers ausgeführt wird.

Funktion des Timers:

Der Timer läuft unabhängig von der Hauptprogrammschleife (loop()) im Hintergrund.
Nach Ablauf der eingestellten Zeit (4 Sekunden) löst der Timer einen Interrupt aus, der die Funktion timerInterrupt aufruft.
Diese Funktion wird verwendet, um den Schlafmodus zu unterbrechen und den Mikrocontroller aufzuwecken.

Zusammenarbeit mit dem Sleep-Modus:

Der Mikrocontroller wird in den Power-Down-Schlafmodus versetzt:

set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();

Währenddessen bleibt Timer1 aktiv. Sobald der Timer abläuft, löst er den definierten Interrupt aus, der den Mikrocontroller wieder aufweckt:

void timerInterrupt() {
// Hier kann man Aktionen definieren, z. B. Flags setzen oder andere Aufgaben
}

Nach dem Aufwachen wird der Schlafmodus deaktiviert, und das Programm läuft normal weiter:

sleep_disable();

Das hatte ich schon aber der Controller hat dann nach den max 8 Sekunden resetet weil während des SleepMode das WDT-Reset nicht ausgeführt werden kann. Deswegen hat mir KI die Nummer mit dem Timer vorgeschlagen der den Interrupt ausführen und Sleep beenden soll.

EDIT:
Ich habe den Timer1 rausgeschmissen, der hat sich eh nicht mit PWM auf Arduino Pin 9 vertragen. Der Tasten-Interrupt geht an Pin 11 (15) jetzt richtig und danach SleepMode. Vorläufig habe ich es tatsächlich mit Watchdog doch zum laufen bekommen. :grin:
Na Hauptsache ich poste was und komme dann selber drauf. :person_facepalming:

#include <avr/sleep.h>
#include <avr/wdt.h> // WDT-Bibliothek für den Watchdog-Timer

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

int StarterStatus = 0;
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);

  // 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

  // Watchdog Timer konfigurieren, um ein Interrupt auszulösen, anstatt den MCU zurückzusetzen
  wdt_reset();             // WDT zurücksetzen
  WDTCSR |= (1 << WDIE);   // WDT Interrupt aktivieren (kein Reset)
  WDTCSR |= (1 << WDP2) | (1 << WDP1); // WDT-Timer auf 8s setzen (optional anpassen)
}

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

  Zeit();  // Zeitfunktionen aufrufen

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

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

  // 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 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 WDT-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();
  }
}

ISR(WDT_vect) {
  // ISR für WDT-Interrupt (keine Reset-Funktion, sondern Wake-Up)
  tasterInterrupt = true;  // Setze das Flag für den Taster-Interrupt
}

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

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);  
  }
  StarterStatus = 0;  // Gehört zu Starter
  goToSleep();
}

Ich habe den Code mit dem Timer1 schon begriffen. Der ruft alle 4 Sekunden eine Callback Funktion auf, in der nichts passiert. Es wird jedoch kein Interruptvektor des Controllers aufgerufen.

Da hat Dir die KI Tinnef erzählt. So ein bisschen NI einzusetzen schadet manchmal nicht.

Hast Du den von mir geposteten Codeschnipsel ausprobiert? Es wird kein Reset ausgeführt wenn der Watchdog in den Interruptmode gesetzt wird (siehe Seite 63/64 im Datenblatt).

Außerdem schau Dir folgende Tabelle mit den „Wakeup Sources“ an:

Du erwähntest, dass der Controller 2mA im Deepslep Modus verbraucht? Das ist viel zuviel. Normal ist ein einstelliger μA Wert. Schalte mal den ADC aus.

Da hast du ganz sicher Recht. Ich habe ohne sleep 18mA mit 2mA bis 3mA. ADC brauch ich nicht sollte ich also unter Setup so deaktivieren.

void setup() {
ADCSRA &= ~(1 << ADEN);
PRR |= (1 << PRADC);
}

Stimmt das? Hatte es vorhin schon mal versucht aber der bleib bei 3 mA.

Davon ab stimmt da immer noch was nicht im Sketch. Aber eins nach dem anderem.

Kommt halt auch auf die Gesamtschaltung an. Spannungswandler? Sonstige Bausteine, Sensoren in der Schaltung? Den ADC abzuschalten macht so grob um die 100 bis 150μA aus

Das ist etwas doppelt gemoppelt.
Du kannst entweder die erste oder die zweite Anweisung anwenden.

Includierst Du <avr/power.h> kannst Du auch das Makro power_adc_disable() verwenden,
was letzten Endes dem zweiten Ausdruck entspricht.

Ich habe hier ein kleines Beispielprogramm geschrieben, das zeigt, das KEIN Systemreset stattfindet.

Wäre das der Fall, müsste alle vier Sekunden "Start..." auf der seriellen Konsole angezeigt.
Das ist aber nicht der Fall. Stattdessen sieht man anhand des + Zeichens, wann der Controller "aufwacht" und die eingebaute LED leuchten lässt (Nano Clone Devboard) und ein "*" wenn der Controller aufwacht, aber gleich wieder schlafen gelegt wird, weil nur alle 20 Sekunden die LED für zwei Sekunden leuchten soll.

Wenn nur vier Sekunden "geschlafen" werden soll, setzt man entweder die Konstante SLEEP_ZEIT auf 4 oder man entfernt die For-Schleife und setzt nur eine enterSleep() Anweisung dafür ein.

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

constexpr byte WATCHDOG_TIME {4};       // in Sekunden
constexpr uint32_t SLEEP_ZEIT {20};     // zur Zählerberechnung notwendig
constexpr uint32_t BLINK_ZEIT {2000};   // in Millisekunden

// watchdog ISR
ISR(WDT_vect) {}   // Nichts tun, wird aber für das Aufwachen benötigt

void enableWatchdog() {
  cli();
  wdt_reset();
  WDTCSR |= _BV(WDCE) | _BV(WDE);   // Setze WDCE um WDE setzen/ändern zu können
  WDTCSR = _BV(WDIE) | _BV(WDP3);   // 4s / interrupt, kein System Reset
  sei();
}

// Lege den Microcontroller schlafen
void enterSleep(void) {
  wdt_reset();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // EDIT: SLEEP_MODE_PWR_DOWN - niedrigster Stromverbrauch.
  sleep_enable();
  sleep_mode();                          // Starte Schlafmodus
  // Nach dem Aufwachen, wird das Programm genau hier weiterlaufen
  sleep_disable();   // Erste Aktion muss das Ausschalten des Schlafmodus sein.
}

void setup() {
  Serial.begin(115200);
  enableWatchdog();
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("Start...");
}

void loop() {
  Serial.print("+ ");
  digitalWrite(LED_BUILTIN, HIGH);
  delay(BLINK_ZEIT);
  digitalWrite(LED_BUILTIN, LOW);
  // In den Schlafmodus wechseln
  // 20 / 4 = 5 mal aufwachen und gleich wieder schlafen -> 20 Sekunden Schlafzeit
  for (size_t i = 0; i < (SLEEP_ZEIT / WATCHDOG_TIME); ++i) {
    Serial.print("* ");
    delay(10);
    enterSleep();
  }
}

Es hängt nichts weiter als Verbraucher am Arduino was Energie zieht. Habe zum Test 10K auf Masse entfernt, bzw. ohne Wandler direkt mit Netzteil versorgt. Habe zusätzlich einen ganz neuen unbenutzten Nano genommen. Also keine LEDs keine Sensoren nur der externe Quarz der für nano üblich ist.

Ohne ADC Abschaltung 3,04 mA
mit PRR |= (1 << PRADC); 2,87mA
mit PRR |= (1 << PRADC); und ADCSRA &= ~(1 << ADEN); 2,78mA

power_adc_disable() kollidiert mit Pin Change Interrupt Aktivierung für Taster

error: expression cannot be used as a function
   PCICR |= (1 << PCIE0);    // Aktiviert PCINTs für Port B

Weiter runter komme ich nicht.

Der wdt macht erst mal keinen Neustart. Ich musste meinen Kommentar über dir 3 mal anpassen. Es scheint zu laufen aber es gibt noch Fehler. Jetzt will ich schauen was mit dem Eneriesparen los ist, ob das so stimmt.

Du schreibst eigenartige, nicht nachvollziehbare Dinge. Das ist macht power_adc_disable():

#if defined(__AVR_HAVE_PRR_PRADC)
#define power_adc_enable()      (PRR &= (uint8_t)~(1 << PRADC))
#define power_adc_disable()     (PRR |= (uint8_t)(1 << PRADC))
#endif

Was sonst noch Strom spart: BOD ausschalten, nicht genutzte Pins auf INPUT_PULLUP setzen.

Ich kann damit auch nichts anfangen bzw. wie es anzuwenden ist.:stuck_out_tongue:

Ich schrieb das kein Verbraucher (LEDs keine 10K Widerstände die auf Masse gezogen werden, keine Sensoren, kein Spannungswander die die 2-3mA verursachen. Auch das ich einen neuen Nano ohne LEDs und Taster usw. zum Testen verwendet habe.

Ich schrieb
:das ohne ADC Abschaltung der Verbrauch 3,04 mA ist,
:das er nur mit PRR |= (1 << PRADC); auf 2,87mA gefallen ist
:das er mit PRR |= (1 << PRADC); und ADCSRA &= ~(1 << ADEN); bei 2,78mA ist.

Du hast den Sketch geschrieben und demonstriert dass der wdt keinen Rest auslöst und das hatte ich in meinem Kommentar darüber schon erwähnt das der funktioniert.

Und das mit power_adc_disable() das Kompilieren den Fehler verursacht.

error: expression cannot be used as a function
   PCICR |= (1 << PCIE0);    // Aktiviert PCINTs für Port B

Also ich weiß grade nicht wie ich die Sache weiter angehen sollte.

Du brauchst nicht zu wiederholen was Du geschrieben hast. So begriffsstutzig bin ich nicht, um das nicht schon beim ersten mal zu verstehen.

Hi,

pogrammierst Du einen ATmega328P auf einer eigenen PCB, oder den auf einem NANO? Auf letzterem ist ja noch der CH340 für USB drauf, zumindest auf einem China-Clone.

Gruß André

Hi,

ich programmiere den ATmega328P separat für eine eigene Platine und ja da ist kein CH340 drauf das stimmt. Aber zum Testen verwende ich einen Nano weil ich damals bei der Erstellung der Platine vergessen habe zum Programmieren entsprechende Verbindungen vorzusehen. An den CH340 habe ich noch gar nicht gedacht.

Habe jetzt vom Nano den CH340 und Spannungswandler entnommen und der Verbrauch liegt bei 3μA ! :+1: :+1: :+1:

Danke für den Hinweis.

Jetzt hab ich grade nur noch ein Problem, durch die Änderung werden die Millis wohl nicht mehr gezählt wenn der Sleep ausgelöst ist. Wie bekomm ich ohne Externe Uhr das noch zum Laufen?
Wenn ich den set_sleep_mode(SLEEP_MODE_IDLE); nehme hab ich ja wieder locker 6-7 mA.

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
  }
}

Im Ganzen

#include <avr/sleep.h>
#include <avr/wdt.h> // WDT-Bibliothek für den Watchdog-Timer


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

int StarterStatus = 0;
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);

  ADCSRA &= ~(1 << ADEN);
  PRR |= (1 << PRADC);
 

  // 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

  // Watchdog Timer konfigurieren, um ein Interrupt auszulösen, anstatt den MCU zurückzusetzen
  wdt_reset();             // WDT zurücksetzen
  WDTCSR |= (1 << WDIE);   // WDT Interrupt aktivieren (kein Reset)
  WDTCSR |= (1 << WDP2) | (1 << WDP1); // WDT-Timer auf 8s setzen (optional anpassen)
}

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

  Zeit();  // Zeitfunktionen aufrufen

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

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

  // 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 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 WDT-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();
  }
}

ISR(WDT_vect) {
  // ISR für WDT-Interrupt (keine Reset-Funktion, sondern Wake-Up)
  tasterInterrupt = true;  // Setze das Flag für den Taster-Interrupt
}

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

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);  
  }
  StarterStatus = 0;  // Gehört zu Starter
  goToSleep();
}

Du hast doch einen 8 Sekunden Takt durch den Watchdog . Zähle doch einfach, wie oft der aufwacht.

86400000 / 8000 = 10800
18000000 / 8000 = 2250

Davon abgesehen lässt sich der Code einwandfrei mit power_adc_disable() compilieren. Das nur nebenbei...

Daran hatte ich auch gedacht. Wollte mir aber erstmals ausgeben lassen, wann der WDT durchgelaufen ist und jedes Mal zählen wenn der Sleep beendet wird. Normalerweise müsste der aller 8 Sekunden +1 Zählen aber der rauscht in der Seriellen Ausgabe einfach durch. Warum?

#include <avr/sleep.h>
#include <avr/wdt.h> // WDT-Bibliothek für den Watchdog-Timer

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

int StarterStatus = 0;
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

// Zähler für die WDT-Interrupts
unsigned int wakeUpCounter = 0;  

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

  ADCSRA &= ~(1 << ADEN);
  PRR |= (1 << PRADC);
 
  // 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

  // Watchdog Timer konfigurieren, um ein Interrupt auszulösen, anstatt den MCU zurückzusetzen
  wdt_reset();             // WDT zurücksetzen
  WDTCSR |= (1 << WDIE);   // WDT Interrupt aktivieren (kein Reset)
  WDTCSR |= (1 << WDP3) | (1 << WDP0); // WDT-Timer auf 8s setzen (optional anpassen)

  Serial.begin(9600); // Seriellen Monitor starten
}

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

  Zeit();  // Zeitfunktionen aufrufen

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

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

  // 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 goToSleep() {
  // Interrupt für den Taster aktivieren (Wake-Up)
  //set_sleep_mode(SLEEP_MODE_IDLE);
  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 WDT-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();
  }
}

ISR(WDT_vect) {
  // ISR für WDT-Interrupt (keine Reset-Funktion, sondern Wake-Up)
  tasterInterrupt = true;  // Setze das Flag für den Taster-Interrupt
  wakeUpCounter++;         // Zähler um 1 erhöhen
  Serial.print("Wake-up count: ");
  Serial.println(wakeUpCounter); // Zählerstand ausgeben
}

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

void Zeit() {
  if (millis() - currentMillis >= 86400000) {
    currentMillis = millis();  // 24h abgelaufen -> Zeitspeicher neu setzen
  } else if ((millis() - currentMillis < 2000) && (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);  
  }
  StarterStatus = 0;  // Gehört zu Starter
  goToSleep();
}

vielleicht, weil Du kein wdt_reset(); in deiner gotoSleep() Funktion hast?

Auch wenn ich wdt_reset(); einfüge rauscht er durch.

Nö...

Es ist mir zu mühselig Deinen Code nachzuvollziehen, aber möglicherweise funkt dir dein Tasterinterrupt dazwischen.

An welche Stelle muss wdt_reset(); in void goToSleep()?

Ich habe Dir einen Beispielcode gepostet. Guck doch einfach nach. Da "rauscht" jedenfalls nix durch.