Mega 2560 - Energie sparen - Schlafmodus - Wie?

Hallo,

der Thread kann als Sammelthread betrachtet werden für alle Fragen zum Schlafmodus + sonstige Energiesparmöglichkeiten zum Mega 2560.

Man findet zwar so einiges an Librarys und Code Schnipsel, die aber letztenendes alle nur für den UNO gedacht sind. Deshalb frage ich mal in die Runde, gibt es eine “Schlafmodus Library” oder ähnliches auch für den Mega 2560? Und wie sage ich dem µC das er mit 8MHz takten soll damit ich ihn sicher mit 3,3V betreiben könnte - zur Not? Wenn er mit dann mit 8MHz taktet, passen sich dann die vorhanden Librarys wie Wire, SPI, I2C automatisch mit den Timings an? Was sind hier für Probleme zu erwarten?

Mit 3,3V gehe ich dann direkt an den 5V Pin oder mit 4V (Diode) an den Vin Pin? Irgendwie muß ich ja den Spannungsregler umgehen.

Zur Zeit messe ich, dass das Board alleine, ohne externe Beschaltung, ca. 60mA zieht. Der µC selbst wird nicht viel nehmen. Bleiben nur der Spannungsregler und der 2. µC der als USB<>RS232 Übersetzer dient. Die Power LED wird nur ca. 3mA nehmen. Ich muß irgendwie auf die Hälfte kommen oder darunter. Wenn ein Schlafmodus funktionieren würde, könnte ich ihn durch einen externen Interrupt vom RTC 3231 aufwecken lassen.

Der Atmega2560 funktioniert in den meisten Bereichen auch nicht anders als der Atmega328. Er hat mehr Funktionen, aber die Grundlagen sind identisch. Ich nehme an das von Nick Gammon hast du gesehen? Das sollte auch für den Mega funktionieren.

Aber wie die sagst, ist die Zusatzbeschaltung auf dem Board der größte Stromfresser. Deshalb sind die Anleitung eher für blanke Prozessoren gedacht. Nicht für die Entwicklungsboards.

Also ich verwende meistens die "Low Power Library" von Rocket Scream, die müsste auch mit dem Mega 2560 funktionieren. Link hierzu: http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

Ob man den Spannungsregler umgehen kann und direkt 3,3V einspeisen, weiß ich auch nicht. Sauberer wäre es aber vermutlich, direkt einen anderen Spannungsregler einzubauen. Der dürfte vermutlich auch den Hauptverbrauch ausmachen, d.h. anstatt einem Linearregler einen Schaltregler verwenden...

Hallo,

Du meinst www.gammon.com.au/forum/?id=11497 ? Das ist laut meiner Meinung zu sehr auf den 328P gemünzt.

Die Library ist wohl, wenn man die Kommentare genauer liest, wohl doch schon für den Mega2560 geeignet. Hab nur etwas Angst was falsch zumachen und ihn dann nie mehr flashen zu können, weil er sich im Dauertiefschlaf befindet. Was gibt es zu beachten?

Wenn ich die Library verwende mit dem Bsp. idleWakePeriodic, dann geht der immer für 8 Sekunden schlafen, macht was und geht wieder 8 Sekunden schlafen? Die Loop wird nur einmal durchlaufen zwischen den Schlafpausen?

Flashen getraue ich mich noch nicht. Nur wenn ich statt 8sec auf 10 ändere, bekomme ich einen Kompilierfehler. LowPower.idle(SLEEP_10S ...

idleWakePeriodic.ino: In function 'void loop()': idleWakePeriodic:24: error: 'SLEEP_7S' was not declared in this scope

SLEEP_7S

Ohne mir die Lib angesehen zu haben, behaupte ich, dass der Watchdog timer verwendet wird. Und dieser hat nur ein paar Teilerstufen. Deswegen wurden wohl nur die Verfügbaren als Konstanten definiert.

Eine Taktfrequensänderung hat übrigens keine Auswirkungen auf den WDT

Hallo,

okay, war mal mutig und hab das geflasht. Nur bekomme ich im seriellen Monitor keine Ausgaben. Ich dachte aller 8sec. bekomme ich den millis Wert angezeigt zum testen. UART 0 und 1 sind ON.

// **** INCLUDES *****
#include "LowPower.h"

void setup()
{
  // No setup is required for this library

}

void loop() 
{
  // Enter idle state for 8 s with the rest of peripherals turned off
  // Each microcontroller comes with different number of peripherals
  // Comment off line of code where necessary


  // ATmega2560
  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF, 
         TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART3_OFF, 
         USART2_OFF, USART1_ON, USART0_ON, TWI_OFF);

  // Do something here
  // Example: Read sensor, data logging, data transmission.
  Serial.println(millis()/1000);
  
}

Doc_Arduino: Du meinst www.gammon.com.au/forum/?id=11497 ? Das ist laut meiner Meinung zu sehr auf den 328P gemünzt.

Vergleich mal die Datenblätter. So viel Unterschied ist da nicht. Der Atmega2560 hat mehr Timer, mehr UARTs, mehr I/Os, mehr Interrupts. Aber das Prinzip ist das gleiche. Das ist eine evolutionäre Entwicklung. Nichts völlig anderes.

Prozessoren wie der ATtiny sind was anderes. Da gibt es tatsächlich große Unterschiede.

Hier siehst du was an Watchdog Konstanten gibt: http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html

8 Sekunden ist wie gesagt das Maximum. Das ist aber ein einfacher Teiler. Also geht es darunter immer geteilt durch zwei. Also 4s, 2s, 1s, 500ms, etc.

Zu deinem Problem: Du hast Timer0 abgeschaltet. Damit geht natürlich millis() nicht mehr. Wenn Timer0 aber an ist, wacht der Prozessor glaube ich alle 1ms auf. Deshalb auch der hohe Stromverbrauch in diesem Fall.

Er sollte aber theoretisch trotzdem was ausgeben. Halt immer den gleichen Wert.

Hallo,

Danke für die Hinweise. Vorallendingen mit dem Timer0. Die serielle Ausgabe konnte nicht funktionieren, wenn man unter setup die serielle Schnittstelle nicht aktiviert. XD Hatte zwischenzeitlich eine Variable hochzählen lassen, was auch nicht funktionierte. XD Jetzt bekomme ich millis ausgegeben, jedoch überraschenderweise bekomme ich jede Sekunde ausgegebe. Ich dachte ich bekomme aller 8sec. eine Ausgabe?

// **** INCLUDES *****
#include "LowPower.h"

void setup()
{
  Serial.begin(57600);
}

void loop() 
{
  // Enter idle state for 8 s with the rest of peripherals turned off
  // Each microcontroller comes with different number of peripherals
  // Comment off line of code where necessary

  // ATmega2560
  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF, 
         TIMER2_OFF, TIMER1_OFF, TIMER0_ON, SPI_OFF, USART3_OFF, 
         USART2_ON, USART1_ON, USART0_ON, TWI_OFF);

  // Do something here
  // Example: Read sensor, data logging, data transmission.
  Serial.println(millis()/1000);
 }

Hmm ja komisch, funktioniert teilweise nicht je nachdem was auf ON oder OFF gestellt wird. Folgendes Beispiel geht aber:

#include "LowPower.h"
int counter;

void setup()
{
  Serial.begin(115200);
}

void loop() 
{
  Serial.println(counter);
  Serial.flush();  // serielle Ausgabe beenden, bevor der µC wieder schlafen gelegt wird
  counter++;

  // ATmega2560
  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF, 
  TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART3_OFF, 
  USART2_OFF, USART1_OFF, USART0_OFF, TWI_OFF);
}

Oder direkt der "PowerDown"-Modus mit folgendem Befehl:

LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

Folgende "Schlafzeiten" sind möglich: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms, 500 ms, 1 s, 2 s, 4 s und 8 s. Wenn du mehr wie 8 Sekunden möchtest, musst du eben nochmal eine Schleife mit einem Zähler einbauen...

Hallo,

okay, eine Variable aller 8sec ums eins hochzählen funktioniert. Das könnte ich durch einen externen Interrupt auf meine gewünschten 5min ändern.

Nur mit millis geht er nicht schlafen. Der serielle Monitor wirft ohne Pause ständig die "Zeit" raus. Im Projekt-Hauptprogramm wird jedoch millis verwendet, der Timer0 dafür muß weiterlaufen. Dennoch sollte sich der µC sich für eine gewisse Zeit sich zur Ruhe legen.