Go Down

Topic: Mega 2560 - Power Saving - Strom sparen (Read 17161 times) previous topic - next topic

Doc_Arduino

Hallo,

habe mich nach langer Zeit wieder mit dem Thema Strom sparen beschäftigt und haben den Bsp. Code vom Arduino Playground probiert. Im Vergleich zum Code und zur lesenswerten Seite vom Nick Gammon gibts jedoch keinen Unterschied. Vielleicht weil er für beides verantwortlich zeichnet. Gehört ja zur Arduino Truppe soweit ich das verstanden habe.

Also der Code funktioniert soweit, dass er vom normalen Idle Zustand mit 62mA in den Power Down Modus geht mit 27mA. Es leuchtet nur noch die Power LED auf dem Arduino Board. Mit einem Taster an Pin 2 kann man ihn wieder aufwecken, bevor er nach erneuten 10sec Wartezeit wieder in den Power Down Modus wechselt.

Ich speise von einem Netzteil 5V direkt ein an den 5V Pin und GND Pin und messe dabei den Strom.

Jetzt möchte ich fragen. Ist das auf dem Mega2560 wirklich das maximale an Strom sparen was per Code möglich ist?
Die 27mA wird vom Rest auf dem Board verschluckt? Es ist ja nur der USB-RS232 Wandler und der Spannungsregler zusätzlich vorhanden. Der Spannungsregler sollte außen vor sein, wenn ich extern hinter seinem Rücken einspeise. Und der USB-RS232 IC kann doch keine mA ziehen? Hat sich jemand damit schon näher beschäftigt? Wenn er PowerDown ist, ist es doch egal ob der sonst mit 16 oder 8 oder 1MHz taktet? (von 5V auf 3,3V kann ich nicht runtergehen, wegen externer Beschaltung)

Ich müßte mir erst einen 2. Mega2560 kaufen bevor ich weitermachen kann und darauf rum löte bzw. Teile auslöte.

Die einzelnen power .... disable()  Funktionen werden nur benötigt um gezielt einzelne Funktionen abzuschalten? Richtig?

Statt dem Taster zum aufwecken möchte ich die RTC DS3231 verwenden. Könnte doch funktionieren? Wenn die den AVR aller einer Sekunde aufweckt. Laufen die millis() im PowerDown Modus weiter oder bleibt der Zähler stehen? Eigentlich müßte der stehen bleiben, laut meiner Überlegung. Das heißt ich müßte meine Warteschleifen mit millis() komplett umschreiben auf Zähler die von der RTC im Sekundentakt dann letztlich gezählt werden?



Code: [Select]

/* Sleep Demo Serial
* -----------------
* Example code to demonstrate the sleep functions in a Arduino. Arduino will wake up
* when new data is received in the serial port USART
* Based on Sleep Demo Serial from http://www.arduino.cc/playground/Learning/ArduinoSleepCode
*
* Copyright (C) 2006 MacSimski 2006-12-30
* Copyright (C) 2007 D. Cuartielles 2007-07-08 - Mexico DF
*
*  With modifications from Ruben Laguna  2008-10-15
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

//  27mA mit direkter 5V Einspeisung an 5V Pin / GND

#include <avr/sleep.h>

int sleepStatus = 0;        // variable to store a request for sleep
int count = 0;              // counter

int ledPin = 13;            // LED connected to digital pin 13
//int interruptPin = 10;      // LED to show the action of a interrupt
int wakePin = 2;            // active LOW, ground this pin momentary to wake up
//int sleepPin = 12;          // active LOW, ground this pin momentary to sleep


void wakeUpNow()        // here the interrupt is handled after wakeup
{
  // execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
  // digitalWrite(interruptPin, HIGH);  // LED an Pin 10 ein
}


void sleepNow()
{
    /* Now is the time to set the sleep mode. In the Atmega8 datasheet
     * http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
     * there is a list of sleep modes which explains which clocks and
     * wake up sources are available in which sleep modus.
     *
     * In the avr/sleep.h file, the call names of these sleep modus are to be found:
     *
     * The 5 different modes are:
     *     SLEEP_MODE_IDLE         -the least power savings
     *     SLEEP_MODE_ADC
     *     SLEEP_MODE_PWR_SAVE
     *     SLEEP_MODE_STANDBY
     *     SLEEP_MODE_PWR_DOWN     -the most power savings
     *
     *  the power reduction management <avr/power.h>  is described in
     *  http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html
     */ 
       
  //set_sleep_mode(SLEEP_MODE_IDLE);   // sleep mode is set here
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here

  sleep_enable();          // enables the sleep bit in the mcucr register
                           // so sleep is possible. just a safety pin
 
    /* Now it is time to enable an interrupt. We do it here so an
     * accidentally pushed interrupt button doesn't interrupt
     * our running program. if you want to be able to run
     * interrupt code besides the sleep function, place it in
     * setup() for example.
     *
     * In the function call attachInterrupt(A, B, C)
     * A   can be either 0 or 1 for interrupts on pin 2 or 3. 
     *
     * B   Name of a function you want to execute at interrupt for A.
     *
     * C   Trigger mode of the interrupt pin. can be:
     *             LOW        a low level triggers
     *             CHANGE     a change in level triggers
     *             RISING     a rising edge of a level triggers
     *             FALLING    a falling edge of a level triggers
     *
     * In all but the IDLE sleep modes only LOW can be used.
     */

  attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
                                     // wakeUpNow when pin 2 gets LOW
 
  /*                                   
  power_adc_disable();     // dafür wird die   #include <avr/power.h>  benötigt
  power_spi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
  power_timer3_disable();
  power_timer4_disable();
  power_timer5_disable();
  power_twi_disable();       // I2C Interface
  power_usart0_disable();    // RS232 Interfaces
  power_usart1_disable();
  power_usart2_disable();
  power_usart3_disable();
  */
   
  sleep_mode();            // here the device is actually put to sleep!!

                           // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
  sleep_disable();         // first thing after waking from sleep:
                           // disable sleep...
 
  detachInterrupt(0);      // disables interrupt 0 on pin 2 so the
                           // wakeUpNow code will not be executed
                           // during normal running time.
   
}


void setup()
{
  // Serial.begin(57600);
 
  pinMode(ledPin, OUTPUT);         // LED connected to digital pin 13
  //pinMode(interruptPin, OUTPUT);   // LED to show the action of a interrupt pin 10
 
  pinMode(wakePin, INPUT);         // active LOW, ground this pin momentary to wake up
  digitalWrite(wakePin, HIGH);     // Pullup aktiv
  //pinMode(sleepPin, INPUT);        // active LOW, ground this pin momentary to sleep
  //digitalWrite(sleepPin, HIGH);    // Pullup aktiv
 
  attachInterrupt(0,wakeUpNow, LOW);   // use interrupt 0 (pin 2) and run function
                                       // wakeUpNow when pin 2 gets LOW
}



void loop()
{
 
  count++;
  delay(1000);                           // waits for a second

  // check if it should go asleep because of time
  if (count >= 10) {
    count = 0;
    digitalWrite(ledPin, LOW);   
    sleepNow();     // sleep function called here
  }
 
  digitalWrite(ledPin, HIGH);   
 
}
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Serenifly

Du kannst die Power-LED auslöten oder die Leiterbahn auftrennen. Aber das war es dann.

Der USB-seriell Wandler ist ja auch ein Mikrokontroller. Und dessen Verbrauch ist in der Größenordnung wie es für dessen Klasse üblich ist.

Quote

Laufen die millis() im PowerDown Modus weiter oder bleibt der Zähler stehen?

Wenn Timer0 abgeschaltet ist, ist auch der millis() Zähler gestoppt. Es gibt auch Modi wo der weiterläuft. Dann wacht der Prozessor aber alle 1ms auf und der Stromverbrauch steigt entsprechend.

combie

Quote
Statt dem Taster zum aufwecken möchte ich die RTC DS3231 verwenden. Könnte doch funktionieren? Wenn die den AVR aller einer Sekunde aufweckt. Laufen die millis() im PowerDown Modus weiter oder bleibt der Zähler stehen? Eigentlich müßte der stehen bleiben, laut meiner Überlegung. Das heißt ich müßte meine Warteschleifen mit millis() komplett umschreiben auf Zähler die von der RTC im Sekundentakt dann letztlich gezählt werden?

Du kannst die Millis Variable bei jedem aufwachen einfach "AlterStand" +1000 rechnen.
Dann stimmt sie wieder.

Oder den Watchdog nutzen und aus der RTC Zeit den neuen Millistand setzen


Und ca 20 mA für den USB Prozessor scheint mir plausibel.
Auch den kannst du in den Sleep schicken.
Gefährlich, was Theorien aus Menschen machen können.
Schlimmer, was Menschen aus Theorien machen.

Doc_Arduino

Hallo,

okay, soweit sind die Hinweise verstanden. Nur wie kann man den USB-RS232 µC schlafen legen? Ausbauen wollte ich den nicht. Der muß noch funktionieren wenn ich später ggf. ein Update vom Sketch einspielen muß.


Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

uwefed

Indem Du den Atmega16U2 neu programmierst.
Du mußt aber in den Code die Sleepfunktion einfügen und zwar so daß es die Bootload-Funktion und die Serial-USB Funtion noch funktioniert.
In einfachen Worten: sehr schwierig.
Grüße Uwe

Doc_Arduino

Hallo,

das würde mir sehr schwer fallen, den neu zu programmieren. Bin froh das ich mein Anliegen so programmieren konnte. Mit Eurer Hilfe natürlich.   ;)

Was würde denn passieren, wenn ich den AVR 16U2 komplett runternehme von der Platine und dann mittels USB<>RS232 Adapterkabel oder Miniadapter mit FTDI-232 an Pin 0/1 direkt rangehe und den Rest der Änderungen flashen möchte. Klappt das dann noch mit der IDE so wie jetzt oder hat der 16U2 noch irgendwelche Sonderaufgaben? Was hat der mit dem Bootloader zu tun. Der Code sitzt doch im großen µC drin? Könnte mir denken man muß den µC zum flashen dann erstmal mit Jumper in den Programmiermodus bringen.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

uwefed


Was würde denn passieren, wenn ich den AVR 16U2 komplett runternehme von der Platine und dann mittels USB<>RS232 Adapterkabel oder Miniadapter mit FTDI-232 an Pin 0/1 direkt rangehe und den Rest der Änderungen flashen möchte. Klappt das dann noch mit der IDE so wie jetzt ...


Das funktioniert.
Das einzige Problem ist den Atmega auszulöten weil er so winzig ist. Dann kannst Du auch den Operationsverstärket LM358, Den Transistor, den Spannungsstabilisator ( 5V und 3,3V) und die LED auslöten, um allen nicht notwendigen Strom zu sparen.
Ich würde einen Adapter mit dem ATmega16U2 nehmen wie Arduino ihn anbietet statt einen mit FT232.

Grüße Uwe

jurs


Was würde denn passieren, wenn ich den AVR 16U2 komplett runternehme von der Platine und dann mittels USB<>RS232 Adapterkabel oder Miniadapter mit FTDI-232 an Pin 0/1 direkt rangehe und den Rest der Änderungen flashen möchte.


Halte Deinen 16U2 doch einfach im Reset, dann taktet er nicht!

Dein MEGA Board hat einen zweiten ICSP-Header, der für den 16U2 ist. Dort ist unter anderem der Reset-Pin des 16U2 herausgeführt. Verbinde Reset des 16U2 mit GND, dann ist er stillgelegt. Zum Programmieren öffnest Du diese Dauer-Reset Leitung dann wieder.

Allerdings dürfte das nicht die Masse der 27mA im PowerDown ausmachen, die der 16U2 verbraucht, sondern im wesentlichen wird dieser Verbrauch durch den falsch beschalteten Spannungsregler auf dem Board verursacht. Der ist nämlich verboten falsch beschaltet, wenn er am Ausgang mit einer höheren Ausgangsspannung als am Eingang betrieben wird. Und die wenigsten Spannungsreglertypen haben gegen diese Falschbeschaltung eine interne Schutzschaltung, die diesen Fehlerfall erkennt und den Spannungsregler dann gegen Rückwärts-Stromfluss schützt.

Also den Spannungsregler und Power-On LED wirst Du wohl auslöten müssen. Den 16U2 würde ich einfach durch Dauer-Reset stilllegen, so dass er zum Programmieren des Boards leicht wieder aktiviert werden kann.

Serenifly

Vielleicht willst du eher das hier statt ein komplettes Mega Board:
http://www.ebay.de/itm/Mikrocontroller-Atmel-ATMega2560-ATMega-SMD-Adapter-/271224130246?pt=Bauteile&hash=item3f2637cac6

Das ist nur ein Atmega2560 auf einem SMD Adapter. Damit kommst du sogar an Pins, die auf dem normalen Arduino Board gar nicht drauf sind

SkobyMobil

Hallo,
das ist ja mal ein nützlicher Link. Bekomme ich den aud dem selben Wege programmiert wie einen 328P?

Also Arduino Mega 2560 -> 328P das sollte ja "keine" Probleme bereiten.
aber Arduino Mega 2560 -> 2560 (Dein Link) geht das dort genau so?

Dann könnte man auf dem Arduino Mega ohne SpeicherPlatzProbleme etwas entwickeln, das dann auf dieses Board schieben-
und klitzekleine Gehäuse verwenden.
Gruß und Dank
Andreas
die zweite Maus bekommt den Speck...

Serenifly

#10
Aug 01, 2014, 12:32 pm Last Edit: Aug 01, 2014, 01:21 pm by Serenifly Reason: 1
Hier ist eine Anleitung wo man sich dafür die Platine für die grundlegende Peripherie bauen kann:
http://www.instructables.com/id/DIY-Arduino-Mega-2560/?ALLSTEPS (ab Schritt 7)
oder hier:
http://tsjwang.blogspot.de/2013/08/diy-arduino-mega-2560.html

Man muss erst mal den Bootloader per ISP installieren. Wenn man das geschafft hat, lässt er sich ganz normal programmieren.

Den Teil wo er sagt, dass es für den Atmega1280 geht, aber nicht mit dem Atmega2560 verstehe ich aber nicht. Wieso soll man den 2560 Bootloader nicht über die IDE installieren könnnen? In den Kommentaren deutet er an dass es irgendwas damit zu tun, dass er den UART geschrottet hat aber das ist nicht richtig erklärt.

SkobyMobil

#11
Aug 01, 2014, 01:03 pm Last Edit: Aug 01, 2014, 01:19 pm by SkobyMobil Reason: 1
Hallo,
so verstehe ich das auch. Der hat seine UART verbastelt. Wenn man sich die Kommentare der beiden Beiträge durchliest, dann sollte es also
genau so funktionieren wie mit dem 328P. Den Eindruck habe ich jedenfalls. Mal sehen, ob hier noch jemand etwas dazu sagen kann...
Gruß und Spaß
Andreas
P.S.
könnte das der Grund dafür sein:
"The reason for this is because there is a bug in the Arduino MEGA 2560/ADK firmware that does not allow flash write commands to start at anywhere but the beginning of flash memory (0x000000). See the bottom of this page for more technical details. "

http://www.robotc.net/wiki/ARDUINO_MEGA_Update_Bootloader
die zweite Maus bekommt den Speck...

Serenifly

Der 2560 Bootloader hatte früher noch mehr Bugs (drei Ausrufezeichen, die Sache mit dem Watchdog Reset und irgendwas mit dem EEPROM).

Allerdings muss das laut dem hier auch mit dem Mega gehen:
http://www.gammon.com.au/forum/?id=11635

Hier wird es auch gemacht:
http://androm12.blogspot.de/2013/10/arduino-bootloader-atmega.html
http://cisana.net/burning-the-bootloader-onto-the-arduino-mega-2560/


Wenn ich mir das nochmal anschaue, dann bezieht sich das mit UART auch auf das originale Mega Board, das er kaputt gemacht hat. Nicht auf das Breakout Board.

SkobyMobil

Hallo,
wenn man das so liest, dann ist es eigentlich "ganz einfach" Ich werde das einmal probieren.
20€ Lehrgeld habe ich in der Kasse.
Gruß und Dank
Andreas
die zweite Maus bekommt den Speck...

Doc_Arduino

#14
Aug 01, 2014, 05:18 pm Last Edit: Aug 01, 2014, 05:57 pm by Doc_Arduino Reason: 1
Hallo,

den 16U2 im Dauer-Reset zu halten war ein sehr guter Hinweis. Das senkt die Stromaufnahme im PowerDown von 27mA auf 15mA für das gesamte nackte Board. Das ist ordentlich. Beim Spannungsregler habe ich die "Schutzdiode" zwischen 5V und VIN extern nachgerüstet, so wie es üblich wäre. Das bringt aber keine Änderung, auch in der Kommastelle, mit sich.

Jetzt stellt sich die Frage, ob das mit dem Dauerreset vom 16U2 alles ist was möglich ist. Wenn ich den Arduino Reset Taster drücke messe ich 36mA. Mit 16U2 Resetjumper. Wenn man sagt der Mega verbraucht im PowerDown quasi nichts, wären das dann die 15mA Differenz die der 16U2 auch noch beitragen könnte, wenn er ordentlich im PowerDown oder ganz runter vom Board wäre. Das würde bedeuten, Reset ist ungleich PowerDown. Sehe ich das richtig?

Ich habe mal einen LM2940 5V aus der Bastelkiste geholt Da fließt völlig unbeschalten ein Strom von 11mA, egal ob ich 5V an OUT-GND oder IN-GND anschließe. Dann habe ich noch einen 7805 rausgeholt, hier fließen, wieder völlig unbeschalten, nur 2mA richtig beschalten und 18mA falsch beschalten. Das widerlegt meine Theorie.

Die Miniplatine mit dem Mega2560 klingt auch verlockend. Nur fängt man dann wieder bei Null an. Mal sehen ob meine Zusatzschaltung in das Format eines Mega-Shields paßt. Sonst ergeben sich neue Freiheiten.

Ich glaube ich muß erstmal gucken wie groß meine externe Zuschaltung wird, die nimmt z.Z. 11mA. Vielleicht kann ich da nochwas optimieren. Das BT-Modul HC-06 habe ich schon "optimiert" Das wird per Transistorbeschaltung PNP/NPN, quasi ein High-Side Switch Nachbau, und Taster am Arduino und etwas Code ein- und ausgeschalten. Denn wenn das nichts macht, nimmt das durch die ständige suche pulsend bis 80mA auf, hat es einen Connect sind es immer noch stabile 40mA. Das ist zu viel für einen Akkubetrieb. Je tzt kann es mittels Taster nur bei Bedarf eingeschalten werden.  ;)

Was wäre der Vorteil einen 16U2 Adapters im Gegensatz zum FTDI? Machen doch beide das gleiche?

Edit:
ich messe noch einen Unterschied von 2mA, wenn ich den 16U2 gejumpert lasse und dann 5V anschließe oder erst 5V ran und dann jumper.
Also, 5V ran, 16U2 jumpern, warten bis PowerDown, messe 15mA.
Jumper gesteckt lassen. 5V weg nehmen, warten, wieder ran, warten bis PowerDown, messe 17mA.
Jetzt den Jumper ziehen und wieder stecken macht keinen Unterschied, sind immer 17mA.
Erst das Jumper ziehen und 5V wegnehmen und dann wieder alles ran, macht 15mA.
Hab noch keine Erklärung für den Effekt.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Go Up