If-Anweisung wird mehr als einmal ausgeführt

Hallo zusammen ich bin mittlerweile am verzweifeln…
Folgendes: Ich habe eine Realtime Clock und einen Temperatursensor. Umsetzen will ich dass der Sensor beispielsweise alle 5s eine Messung macht. Daher möchte ich die Zeit der RTC nutzen. Nun zu meinem großen Problem, dass hier vereinfacht dargestellt ist:

#include <DS3231.h>
DS3231  rtc(SDA, SCL);
void setup() {
  Serial.begin(9600);
  rtc.begin();
}

void loop() {
  //Variablen
  String Uhrzeit=rtc.getTimeStr();
  int sekunde=Uhrzeit.substring(6,8).toInt();
  static bool Flankenmerker, Hilfsmerker;

  //Abfrage positive Flanke
  Flankenmerker= sekunde%5==0 && !Hilfsmerker;

  if(Flankenmerker)
  {
    // später für Temperatursensor gedacht
    Serial.println(sekunde);
    Hilfsmerker=true;
    }
    else
    {
      Hilfsmerker=false;
    }
}

Ich zerlege die Zeit der RTC in die Sekunden und übergebe sie eine Integer Variablen. Die if-Abfragen soll alle 5s ausgeführt werden. Problem ist, dass die if-Anweisung 1s lang true ist. Was bedeutet dass sie mehrfach satt nur ein einzges mal durchlaufen wird. Ich habe versucht etwas wie eine postive Flankenauswertung zu machen. Muss aber sagen dass ich kläglich gescheitert bin ;(.
Bitte Bitte um Hilfe.
(Ein delay möchte ich nach möglichkeit nicht verwenden=

Viele Grüße

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Es gibt keine if-Schleifen, nur if-Abfragen.

Gruß Tommy

  • bitte ändere den Thread-Titel und lösche das Schleife

  • bitte lösche die * in deinen Code-Tags

  • zur Sache: arbeite nach Muster BlinkWithoutDelay. Wenns umbedingt sein muss halt mit deinem Zeitstempel aus der Uhr.

ungeprüft:

static uint32_t previousTimestamp = 0;
uint32_t timestamp = rtc.unixtime();

if (timestamp - previousTimestamp >5)
{
  // doIt
  previousTimestamp = timestamp;
}

Hallo,

deine Flankenmerker und Hilfsmerker sind lokal nicht initialisiert. Die können Zufallsstartwerte annehmen.
static local in der loop können auch global gemacht werden. Macht keinen Unterschied.
Außer das globale Variablen ohne weitere Initialisierung immer mit 0 initialisiert werden.

Hier steckt dein Problem. Wo ist die Abfrage? Du hast alle Operatoren gemischt die möglich sind. :slight_smile:

//Abfrage positive Flanke
  Flankenmerker = sekunde % 5 == 0 && !Hilfsmerker;

Was soll es wirklich werden?

Für eine aller 5s Messung benötigst du millis.

Theseus erklärt millis()

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung

Doc_Arduino:
deine Flankenmerker und Hilfsmerker sind lokal nicht initialisiert. Die können Zufallsstartwerte annehmen.

Durch das static sind sie Null. Verhalten sich in dem Zusammenhang wie globale Variablen

Serenifly:
Durch das static sind sie Null. Verhalten sich in dem Zusammenhang wie globale Variablen

Aha, okay, gut zu wissen, Danke.
Ich werde wohl dennoch weiterhin lokale Variablen mit einem Wert initialiseren, dann kann man das nicht ausversehen vergessen ohne auf static achten zu müssen. :wink:

Dann mal aus meinem Nähkasten kopiert…

Achtung: unorthodox und mit einer lib.
Man könnte weglassen, aber dann wäre der Vergleich nicht zu 100% sicher.

#include "RTClib.h"   // 

/*
  name=RTClib
  version=1.2.1
  author=Adafruit
  maintainer=Adafruit <info@adafruit.com>
  sentence=A fork of Jeelab's fantastic RTC library
  paragraph=A fork of Jeelab's fantastic RTC library
  category=Timing
  url=https://github.com/adafruit/RTClib
*/
RTC_DS3231 rtc;

//#include <DS3231.h>
// DS3231  rtc(SDA, SCL);

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

void loop()
  {
  //Variablen
  static int lastsecond = 61;
  DateTime now = rtc.now();
  int second = now.second();
  if (second % 5 == 0)
    {
    if (lastsecond != second)
      {
      Serial.print("Ausgabe Sekunde: ");
      Serial.println(second);
      lastsecond = second;
      }
    }
// HIer ist Schluss mit der Aufgabe



  //  String Uhrzeit = rtc.getTimeStr();  // Hilfsfunktion
  //  int sekunde = Uhrzeit.substring(6, 8).toInt();  // sekunde wird weiter verwertet
  /*
    static bool Flankenmerker, Hilfsmerker;
    //Abfrage positive Flanke
    Flankenmerker = sekunde % 5 == 0 && !Hilfsmerker;
    if (Flankenmerker)
    {
    // später für Temperatursensor gedacht
    Serial.println(sekunde);
    Hilfsmerker = true;
    }
    else
    {
    Hilfsmerker = false;
    }
  */
  }

Dein Flankenmerker wird bereits im zweiten Durchlauf der Sekunde false, (wegen des gesetzten Hilfsmerkers) und setzt also den Hilfsmerker sofort zurück.
Im 3. Durchlauf ist dann wieder eine kommende Flanke.

Problem ist, dass die if-Anweisung 1s lang true ist

Wenn es so wäre, hättest du gewonnen :slight_smile:

Flankenerkennung ist machbar, nur Mut.
Noch bist du nicht kläglich gescheitert, du bist nur noch nicht am Ziel.

Also wie michael_x erlährt:
Den hilfsmerker nicht in else zurücksetzen sonder eine eigene If bedingung zB wenn
((sekunde % 5 != 0) && Hilfsmerker)

Grüße Uwe

Funktioniert - Vielen vielen Dank!

uwefed:
Den hilfsmerker nicht in else zurücksetzen sonder eine eigene If bedingung zB wenn
((sekunde % 5 != 0) && Hilfsmerker)