Pages: [1]   Go Down
Author Topic: Eine if Schleife nur alle 5 Minuten durchlaufen  (Read 366 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 117
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo

ich möchte die unten gezeigte Schleife nur alle 5 Minuten 1X abarbeiten. Währen der restlichen Zeit sollte der Sketch aber auch abgearbeitet werden ein Delay scheidet als aus.
Weiß jemand eine Funktion mit der ich das bewerkstellen kann?


Code:

  //Stufe1 wird berechnet
  if ((tempS1 <= TempSpeicher47) && (tempS2 <= TempSpeicher35))
  {
    (Stufe = 1);
  }


  //Stufe2 wird berechnet
  if ((tempS1 > TempSpeicher47) && (tempS2 <= TempSpeicher35))
  {
    (Stufe = 2);
  }

  //Stufe3 wird berechnet
  if (((tempS1 > TempSpeicher47) && (tempS1 <= TempSpeicher50)) && ((tempS2 > TempSpeicher35) && (tempS2 <= TempSpeicher50)))
  {
    (Stufe = 3);
  }

  //Stufe4 wird berechnet
  if (((tempS1 > TempSpeicher50) && (tempS1 <= TempSpeicher75)) && ((tempS2 > TempSpeicher35) && (tempS2 <= TempSpeicher50)))
  {
    (Stufe = 4);
  }

  //Stufe5 wird berechnet
  if (((tempS1 > TempSpeicher50) && (tempS1 <= TempSpeicher75)) && ((tempS2 > TempSpeicher50) && (tempS2 <= TempSpeicher75)))
  {
    (Stufe = 5);
  }

  //Stufe6 wird berechnet
  if ((tempS1 > TempSpeicher75) && ((tempS2 > TempSpeicher50) && (tempS2 <= TempSpeicher75)))
  {
    (Stufe = 6);
  }

  //Stufe7 wird berechnet
  if ((tempS1 > TempSpeicher85) && (tempS2 > TempSpeicher75))
  {
    (Stufe = 7);
  }

den gesammten Code hänge ich noch an

Vielen Dank Rudi

* _27_Mittelwertbildung_der_Messwerte.ino (17.43 KB - downloaded 6 times.)
Logged

Germany S-H
Offline Offline
Edison Member
*
Karma: 117
Posts: 2447
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ich möchte die unten gezeigte Schleife nur alle 5 Minuten 1X abarbeiten. Währen der restlichen Zeit sollte der Sketch aber auch abgearbeitet werden ein Delay scheidet als aus.
Weiß jemand eine Funktion mit der ich das bewerkstellen kann?

Mit millis() aus dem Arduino-Takt, ohne Echtzeit-Uhr?

Code:
unsigned long SecondsRunning()
// Liefert die Sekunden seit Programmstart zurück
// Diese Funktion muss in der loop laufend aufgerufen werden
{ // Sekundenzähler
  static unsigned long secondsCounted=0;
  static unsigned long prevMillis=0;
  while( millis() - prevMillis >= 1000){     
    secondsCounted++;
    prevMillis += 1000;
  }
  return secondsCounted;
}


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

unsigned long lastSeconds, thisSeconds;
int intervall=300; // Intervalldauer in Sekunden
void loop() {
  thisSeconds=SecondsRunning();
  if (thisSeconds>=lastSeconds+intervall)
  {
    lastSeconds+=intervall;
    Serial.print(intervall);Serial.println(" Sekunden sind um!");
  } 
}
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 63
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Rudi!

Also für mich hört sich das nach dem klassischen "blink without delay"-Fall an. Gugg mal das Beispiel hier an, danach sollte es klar sein:

http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Viel Erfolg!
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 234
Posts: 20196
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dei loop() funktion wirst Du nicht alle 5 Minuten aufrufen können ( das würde mit 15 mal dealy(20000) passieren),
Sondern Du kannst wie beim "blink without delay" um loop() immer wieder kontrollieren ob die 5 Minuten vorbei sind und die Funktionen ausführen oder die Funktion aufrufen die Du alle 5 Minuten haben willst. Nebenbei kannst Du im loop() nioch alles mögliche kontrollieren.

grüße Uwe
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 117
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo zusammen

es hat geklappt vielen Dank für die Hilfe.
Einen kleinen Schönheitsfehler har der Sketch noch - nach einem Reset dauert es die 5Min bis die Stufen bildung das erste mal gemacht wird . Dies bedeutet dass nach einer Neuprogramierung oder einem Stromausfall diese 5Min keine Ladung stattfindet.
Was dazuführen kann dass der Solarkollektor in Stagnation (Abschaltung wegen Übertemperatur) geht und dann bis zur Abkühlung (meist erst abends) nicht mehr in Betrieb genommen werden kann.
Eine Lösung währe also nicht schlecht.
Eventuell hat ja jemand eine Lösung.

Nochmals vielen Dank Rudi
Logged

Offline Offline
Faraday Member
**
Karma: 79
Posts: 2733
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lagere den Code den du ausführen willst in eine eigene Funktion aus und Rufe diese Funktion am Ende von setup() auf. Dann wird sie einmal beim Start ausgeführt und danach zeitgesteuert.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gibt es keinen Timer-Interrupt beim Arduino Uno?
Logged

Geht nicht, gibt es nicht!

Offline Offline
Faraday Member
**
Karma: 79
Posts: 2733
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Natürlich, aber eine 5-Minuten Funktion in einem Interrupt auszuführen ist Unsinn. Das macht man eher für ganz schnelle Sachen.

Auf dem Arduino läuft im Hintergrund schon auf Timer0 ein Zähler mit einem Interrupt. Und dessen Stand kann man eben mit millis() abfragen.
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2741
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gibt es keinen Timer-Interrupt beim Arduino Uno?
Beim atmega Controller schon.
Beim "Arduino Uno" werden Timer bei Bedarf von diversen Libraries verwendet, die sich dann in die Quere kommen smiley-wink

Aber was hat das hiermit zu tun ?

Code:
const unsigned long INTERVAL = 1000L*60* 5; // 5 Minuten
unsigned long lastRun = 0 - INTERVAL;  // damit es gleich beim Start losgeht
void loop ()
{
  if ( millis() - lastRun >= INTERVAL )
  {
    Meine5MinutenFunktion();
    lastRun += INTERVAL;
  }
}
Einfacher gehts mit Hardware-Timern nicht.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 27
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...Was wäre aber wenn der Programmcode unter der Funktion zB "void loop ()" relativ lang ist?
Würde es nicht die Gefahr bergen, dass nicht exakt bei der gwünschten Zeit (in diesemBbeispiel zb 5min) die Funktion "Meine5MinutenFunktion()" aufgerufen wird?
Logged

Geht nicht, gibt es nicht!

Offline Offline
Faraday Member
**
Karma: 79
Posts: 2733
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wenn du nicht garantieren kannst, dass loop() alle 5 Minuten durchläuft ist mit deinem Design etwas völlig falsch gelaufen und du solltest den Ablauf generell überdenken.

Dann ist die Frage ob das bei 5 Minuten wirklich auf ein paar ms genau ausgeführt werden muss, oder ob es egal ist ob es vielleicht mal um 100ms schwankt.
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2741
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...Was wäre aber wenn der Programmcode unter der Funktion zB "void loop ()" relativ lang ist?
Würde es nicht die Gefahr bergen, dass nicht exakt bei der gwünschten Zeit (in diesemBbeispiel zb 5min) die Funktion "Meine5MinutenFunktion()" aufgerufen wird?
Vielen Dank für deine Vorlage, Hubert smiley-wink

Wenn du Probleme damit hast, loop innerhalb von sagen wir mal 10 bis 50 ms durchlaufen zu lassen,
dann lass um Himmels willen die Finger von Timer-Interrupts. Die müssen nämlich in nullkommanix fertig werden, und können/dürfen daher viele Arduino-Funktionen gar nicht verwenden. Das wird dir also vermutlich nicht helfen.

Übrigens, selbst wenn sich mal was verzögert:
In meinem vorigen Beispielcode ist sichergestellt, dass Meine5MinutenFunktion() in 24 Stunden 288 Mal drankommt, und dass sich eventuelle Verzögerungen nicht aufsummieren.

Aber: Beim normalen Arduino ist die Zeit übrigens nur auf ca  0.1 %  genau, 5 Minuten können also von daher schonmal hunderte ms daneben liegen.

Logged

Offline Offline
Sr. Member
****
Karma: 4
Posts: 363
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
const unsigned long INTERVAL = 1000L*60* 5; // 5 Minuten
unsigned long lastRun = 0 - INTERVAL;  // damit es gleich beim Start losgeht
Hier wird meiner Meinung nach einer unsigned Variable ein negativer Wert  (-300000) zugewiesen.
Für den Compiler wäre das dann  4294667294   (ULONG_MAX  - INTERVAL+1)
 
Kann aber auch sein, das dies eine C  Schreibweise ist die ich wieder mal nicht verstehe.
Also keine Kritik sondern eher eine Frage  smiley-wink  
Logged

Arduino UNO,MEGA,Pro Mini Ethernet Shield

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 234
Posts: 20196
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bei einem Variablentyp ohne Vorzeichen gibt es keine negativen Werte. Da wird vom max möglichen Wert der wegzuzählende Wert subtrahiert.
Grüße Uwe
« Last Edit: March 10, 2014, 03:21:18 pm by uwefed » Logged

Offline Offline
Faraday Member
**
Karma: 79
Posts: 2733
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Die Variable läuft über. Das aber hier gewollt. Das hat den Effekt dass die Funktion gleich am Anfang ausgeführt wird, da der Wert eben > INTERVAL ist. Danach wird INTERVAL wieder dazu addiert und sie steht wieder auf 0

Logged

Pages: [1]   Go Up
Jump to: