Go Down

Topic: Stromversorgung (Read 777 times) previous topic - next topic

nckwdt

Wenn ich die Kiste jetzt in den Tiefschlaf befördere, wer weckt sie dann wieder auf? Es ist nur eine RTC an Bord. De läuft ja weiter, auch wenn alles ausgeschaltet ist. Aber die Ausführung des Code wird doch auch unterbrochen

noiasca

Der Microprozessor ("die Kiste") soll sich selber wieder aufwecken. Wenn du sagst du brauchst nur eine Messung alle 60 Minuten, ist das eigentlich ideal, das können einige Mikroprozessoren. Ja prinzipiell wird "alles unterbrochen" aber kann es ja. Hauptsache der Microprozessor kommt nach dem Schlafen wieder hoch, verrichtet seine Arbeit und geht wieder schlafen. Selbst Varianten, dass er dennoch früher wieder hochkommt (Trigger, ADC unter/überschreitungen etc) sind bei einigen Prozessoren möglich.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

postmaster-ino

Hi

Die RTC kann Dir mindestens einen Sekunden-Impuls generieren.
Externe Pegeländerungen kann man an einem PC-INT-fähigem Pin (PinChange-Interrupt) benutzen, um damit den µC aufzuwecken.
Alternativ geht auch der interne Timer, jeder Interrupt weckt den Käfer aus Seinem Tiefschlaf - danach musst Der erst Mal schauen, Wer Ihn nun stört - wenn Du nur EINEN Interrupt scharf hast, wird's Der gewesen sein - wenn Du aber z.B. mehrere PC-INTs benutzt oder andere Interrupts ebenfalls, obliegt Es an Dir, herauszufinden, 'Wer Dass denn jetzt war'.

Alternativ lässt Du den Arduino pennen und weckst Diesen alle 9 Sekunden (las ich in einem anderen Thread, hätte selber 8 Sekunden im Kopf gehabt, darum soll's jetzt aber nicht gehen), zählst diese 9er Blöcke mit und bei >60 wird Deine Minute um sein.
Wenn die Minute noch nicht vorbei ist, wieder ab ins Bettchen und auf den nächsten Interrupt warten.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

nckwdt

Hi

Die RTC kann Dir mindestens einen Sekunden-Impuls generieren.
Externe Pegeländerungen kann man an einem PC-INT-fähigem Pin (PinChange-Interrupt) benutzen, um damit den µC aufzuwecken.
Alternativ geht auch der interne Timer, jeder Interrupt weckt den Käfer aus Seinem Tiefschlaf - danach musst Der erst Mal schauen, Wer Ihn nun stört - wenn Du nur EINEN Interrupt scharf hast, wird's Der gewesen sein - wenn Du aber z.B. mehrere PC-INTs benutzt oder andere Interrupts ebenfalls, obliegt Es an Dir, herauszufinden, 'Wer Dass denn jetzt war'.

Alternativ lässt Du den Arduino pennen und weckst Diesen alle 9 Sekunden (las ich in einem anderen Thread, hätte selber 8 Sekunden im Kopf gehabt, darum soll's jetzt aber nicht gehen), zählst diese 9er Blöcke mit und bei >60 wird Deine Minute um sein.
Wenn die Minute noch nicht vorbei ist, wieder ab ins Bettchen und auf den nächsten Interrupt warten.

MfG
Also wenn ich ihn alle 9 Sekunden wecke, dann sind das pro Stunde (das ist mein Meß-Intervall) genau 400 Vorgänge. Ich kann mir nicht vorstellen, daß das stromsparend sein kann. Oder irre ich da?

Und der interne Timer? Das ist nicht das Delay? Ich weiß, das sind jetzt ganz dumme Fragen, ich bitte um Nachsicht. Der Umgang mit der Hardware ist totales Neuland für mich. Der Sender, um den es ja hier geht, besteht (zur Zeit) aus einem Arduino Uno, einem RFM69HCW-Modul, einer recht lausigen RTC und einem BME280-Sensor. Das ist alles.

Rentner

Hallo,

ich hab für sowas ähnliches einen Wemos D1 verwendet. Sleepzeit geht bis über eine Stunde. Stromaufnahme im Deep-sleep aus dem Aku vor dem Step-up 0,5mA. Im Heimnetz anmelden NTP Zeit holen , messen mit BME280 und mit TCP versenden dauert 6s. Aktive Stromaufnahme 40-60 mA mit ein paar Spitzen beim senden von 300 mA. Kann man auch ohne WIFI machen und mittels 433Mhz versenden.

Heinz

postmaster-ino

Hi

Das Wach werden, feststellen, daß Nichts zu tun ist und wieder schlafen legen sind nur wenige hundert/tausend Takte - bei 16MHz wären 16.000.000 Takte die Sekunde 'drin' - beim alle 9 Sekunden kurz wach werden mit 1000 Takte zu 144'000'000 Takte (sofern ich korrekt gerechnet habe) - ich sehe hier doch schon Einiges an Sparpotential.

Ob die RTC oder der WDT den µC wach bekommen, spielt Da keine kaum eine Rolle.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

uwefed

Alle 1 Sec oder alle 9 Sekunden bringt sehr viel. Da bei jedem Wecken nur geschaut werden muß ob es schon zeit ist (eine Variable kontrollieren und hochzählen) ist die ON/OFF Zeit sehr zur OFF-Zeit hin verschoben Darum ist der Stromverbrauch nahe am Dauerschlaf.

Grüße Uwe

nckwdt

#37
Jun 05, 2019, 08:38 am Last Edit: Jun 05, 2019, 10:29 am by nckwdt
Alle 1 Sec oder alle 9 Sekunden bringt sehr viel. Da bei jedem Wecken nur geschaut werden muß ob es schon zeit ist (eine Variable kontrollieren und hochzählen) ist die ON/OFF Zeit sehr zur OFF-Zeit hin verschoben Darum ist der Stromverbrauch nahe am Dauerschlaf.

Grüße Uwe
Ich denke, du meinst den link
http://www.netzmafia.de/skripten/hardware/Arduino/Sleep/index.html
"Aufwecken mit Watchdog
Eine Möglichkeit, einen etwas längere Timer zu nutzen, ist das Aufwecken durch den Watchdog, dieser ist in der Lage den Controller nach 8 s wieder zu wecken..."

Und wenn ich das richtig verstehe, dann soll das einstündige delay drin bleiben? Und nur der Wachhund bellt alle 8 Sekunden?

Ich teste....... und werde mich wieder melden

Grüße
Nick

ElEspanol

Delay ist so gut wie immer Mist. Mach das mit millis()

uwefed

Weiß jetzt nicht auf was sich meine Vorredner bezogen haben.


Wenn Du Strom sparen willst muß die Elektronik entweder ausgeschaltet erden oder in Standby gehen. delay() läßt den Kontroller nur für eine bestimmte Zeit nichts anderes tun als zu arbeiten und keine anderen Funktionen des Sketches ausführen.

Grüße Uwe

nckwdt

#40
Jun 05, 2019, 11:14 am Last Edit: Jun 05, 2019, 11:22 am by nckwdt
Weiß jetzt nicht auf was sich meine Vorredner bezogen haben.


Wenn Du Strom sparen willst muß die Elektronik entweder ausgeschaltet erden oder in Standby gehen. delay() läßt den Kontroller nur für eine bestimmte Zeit nichts anderes tun als zu arbeiten und keine anderen Funktionen des Sketches ausführen.

Grüße Uwe
das ist jetzt der Code: (ISR(WDT_vect) ganz am Anfang... ist das korrekt?)

Code: [Select]


# verschiedene includes

verschiedene Klassen

#define LED_PIN (13)

volatile int toggle = 1;       // watchdog
ISR(WDT_vect)                      // watchdog
  /* Watchdog imer Interrupt Service Routine */
  {
  if(toggle == 0)
    { toggle = 1; }
  else
    { Serial.println("WDT Overrun Error!"); }
  }


//#define debug

//////////////////////////////////// setup Serial /////////////////////////////////////
void setup ()
{
  Serial.begin(9600);
//////////////////////////////////// setup Funk ///////////////////////////////////////

  if (!radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
    { // undsoweiter


////////////////////////////////// setup  Uhr und Sensor //////////////////////////////
   
   clock.begin(); 
//   clock.fillByYMD(2019, 5, 28); clock.fillByHMS(8, 16, 0); //clock.fillDayOfWeek(SAT); 
//   clock.setTime();     
 
  if(!bme280.init()) {  Serial.println(F("Sensor-Fehler!")); }
////////////////////////////////////// setup  SD Karte ////////////////////////////////
//pinMode(10, OUTPUT);
 
  Serial.print(F("\n"));

/////////////////////////////////// Setup watchdog ////////////////////////////////////

delay(100);
  pinMode(LED_PIN,OUTPUT);

  /* Setup des Watchdog Timers */
  MCUSR &= ~(1<<WDRF);             /* WDT reset flag loeschen */
  WDTCSR |= (1<<WDCE) | (1<<WDE);  /* WDCE setzen, Zugriff auf Presclaler etc. */
  WDTCSR = 1<<WDP0 | 1<<WDP3;      /* Prescaler auf 8.0 s */
  WDTCSR |= 1<<WDIE;               /* WDT Interrupt freigeben */
 
  Serial.println(F("Init erfolgt"));
  delay(100);
 
////////////////////////////////// setup Ende /////////////////////////////////////////
}

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

void loop()
{
// undsoweiter
delay(900000);
////////////////////////////////////// loop watchdog //////////////////////////////////

if(toggle)
    {
    /* LED umschalten und wieder schlafen */
    toggle = 0;
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    enter_sleep();
    }

// weiterer Code


michael_x

Quote
ganz am Anfang... ist das korrekt?
Das ist egal. Irgendwo außerhalb anderer Funktionen, und nach der Definition der verwendeten Variablen
(die eigentlich kein int sein muss).

Aber Serial.print in einer ISR geht nicht. (Jedenfalls nicht, wenn Gefahr besteht, dass gleichzeitig von woanders die 64 Zeichen Ausgabepuffer benutzt werden)

combie

#42
Jun 05, 2019, 11:31 am Last Edit: Jun 05, 2019, 11:31 am by combie
Quote
Aber Serial.print in einer ISR geht nicht. (Jedenfalls nicht, wenn Gefahr besteht, dass gleichzeitig von woanders die 64 Zeichen Ausgabepuffer benutzt werden)
Das Problem ist ein anderes.

Serial benötigt seinerseits Interrupts um die Zeichen raus zu bringen.
Srial.print() blockiert, wenn sein Buffer voll ist.
In ISR sind die Interrupts gesperrt.
Also kommt Serial dann nie aus der Blockade raus.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

nckwdt

#43
Jun 05, 2019, 11:32 am Last Edit: Jun 05, 2019, 11:40 am by nckwdt
Das ist egal. Irgendwo außerhalb anderer Funktionen, und nach der Definition der verwendeten Variablen
(die eigentlich kein int sein muss).

Aber Serial.print in einer ISR geht nicht. (Jedenfalls nicht, wenn Gefahr besteht, dass gleichzeitig von woanders die 64 Zeichen Ausgabepuffer benutzt werden)
gut, das leuchtet ein. Sie serial prints kann ich beim Sender ja auch überhaupt nicht gebrauchen

die serial prints habe ich so ausgeschlossen.

Code: [Select]

#ifdef debug     
    Serial.print(F("received from node "));
    Serial.print(radio.SENDERID, DEC);
    Serial.print(", message [");
#endif   
    for (byte i = 0; i < radio.DATALEN; i++){;}
#ifdef debug
    Serial.print((char)radio.DATA[i]);
    Serial.print("], RSSI ");
    Serial.println(radio.RSSI);
#endif


Und am Ende vom loop lasse ich ein Delay von 3600000 (eine Stunde) drin. Zum Testen nehme ich erst mal ein Viertel davon, also 15 Minuten, und später dann mache ich die Messungen alle Stunde. Ich teste das jetzt mit einem 12 Volt Block...

michael_x

Quote
Das Problem ist ein anderes.
...
Serial.print() blockiert, wenn sein Buffer voll ist.
Genau das meine ich auch:
Wenn der Puffer nicht voll ist, schreibt Serial.write (und damit print) nur in den Puffer. Das geht eigentlich auch unter geschlossenem Interrupt in der ISR. Aber wenn er voll ist oder durch die neue Ausgabe voll wird, wartet Serial.write. In diesem Fall ewig. 

Go Up