RTC DS3231 macht Probleme..

Hallo!

Vorweg: Ich bin neu im Programmieren (ok bis auf ein paar einfachste Spiele in Scratch), bei MicroControllern und bei Elektrizität allgemein.

Momentan bin ich dabei, einen selbst gebauten Wecker zu programmieren:

  • Über ein Keypad wird die Weckzeit eingegeben und umgerechnet (funktioniert bereits)
  • Diese Zeiten werden alle 3 sekunden mit den Zeiten des DS3231 verglichen, wenn Stunde und Minute übereinstimmt, geht der Alarm los.
    Und an dieser Stelle liegt das Problem: Der Wecker macht kein Alarm, auch wenn die Zeiten übereinstimmen. Durch ein paar Tests habe ich herausgefunden, das das Problem an der Uhrzeit des RTCs liegt: Wenn ich mit zB. Serial.print(now.minute()) die aktuelle Minute lesen möchte, wird mir die Minute angezeigt, zu der der Sketch das letzte mal gestartet wurde. Das ist nicht nur bei der Minute, sondern auch bei der Stunde.

Das Testprogramm der Library (was die aktuelle Uhrzeit anzeigt) funktioniert mit dem selbem RTC richtig.

Wisst ihr, was ich falsch mache? :cry:

Hier ist mein Code:

#include <Keypad.h>
const byte ROWS = 4; //vier Zeilen
const byte COLS = 4; //vier Spalten
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; //verbindet Zeilenpins
byte colPins[COLS] = {5, 4, 3, 2}; //verbindet Spaltenpins

Keypad pad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);  //Erstellung Objekt "pad"

#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
//RTC einbinden

//Variable für:
int Minute = 0; //eingegebene Minute
int Hour = 0;  //eingegebene Stunde
int a = 0; //eingegebene Zahl

const int Piezo = 10;

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

  if (! rtc.begin()) {
    Serial.println("RTC konnte nicht gefunden werden");
    while (1);
  }
  Serial.println("Wecker");
  Serial.println("Bitte Uhrzeit eingeben (z.B. 1223 fuer 12:23)");
}

void loop() {
  unsigned int key = pad.getKey(); //Variable zum erkennen der Tasten
  DateTime now = rtc.now(); //Objekt zur Abfrage der momentanen Zeit

  if ((key) && (key != '*'))
  {
    a = a * 10 + (key - 48);
  }

  if (key == '*')
  {

    Hour = a / 100;
    Minute = a % 100;
    Serial.println("Uhrzeit: ");

    if (Hour < 10)
    {
      Serial.print("0");
    }

    Serial.print(Hour);
    Serial.print(":");
    if (Minute < 10)
    {
      Serial.print("0");
    }
    Serial.print(Minute);
    
    while (Hour != now.hour()) //Hier beginnt der Vergleich mit der eingegebenen Zeit:
    {
    }
    while (Minute != now.minute())
    {
    }
    while (key != '#')
    {
      for (int i = 0; i <= 100; i++)
      {
        digitalWrite(Piezo, HIGH);
        delay(500);
        digitalWrite(Piezo, LOW);
        delay(500);
      }
    }
  }


}

TheBigPekka:
Wisst ihr, was ich falsch mache? :cry:

Ja, nicht den gesamten Code posten. Sollen wir das Setup und die Variablen würfeln?

Gruß Tommy

ich hab jetzt den gesamten Code gepostet

Stelle mal bitte einen Link zur RTC-Lib ein. Da gibt es mehrere.

Du blockierst Dich selbst.

while (Hour != now.hour()) {...} blockiert den ganzen Prozessor, bis die Stunden passen. Bei Minute das Gleiche.

Ich würde sagen, Du kannst gerade mal 1 Zeichen eingeben, wenn Du es nicht genau um 00:00 Uhr machst.

Schau Dir mal BlinkWithoutDelay und die Nachtwächtererklärung (kein Witz) an.

Du hast schon eine große Schleife: loop(). Diese sollte man nicht blockieren.

Gruß Tommy

PS: Wie stellst Du die Uhrzeit der RTC?

Edit: Ohne explizites Stellen der Uhr z.B. mit
void RTC_DS3231::adjust(const DateTime& dt);
Wird immer die Compilezeit genommen.

Meine RTC-Library find ich nicht mehr, da gibt's echt viele (oder kann man in der Arduino - Software irgendwo die Links sehen?)
Ist das nicht das Ziel, das der Sketch blockiert wird, bis die eingegebene Zeit mit er echten Zeit zutrifft? (Ich bin neu, wie schon gesagt)

Nach dem erstem mal einstellen der Zeit ist das doch nicht mehr nötig (außer wenn die Batterie leer ist/entfernt wurde) und mit dem Testsketch der Lib wurde sie bereits eingestellt.

Anfängerfehler:

while (Hour != now.hour()) //Hier beginnt der Vergleich mit der eingegebenen Zeit:
{
}

tut genau das, was da steht: NICHTS.
Wird aber immer und immer wieder aufgerufen, weil sich now.hour() niemals ändern kann- denn dadurch, dass das Programm in dieser while()-Schleife fest hängt, wird die Uhr auch nie erneut abgelesen!
Sinnvoll wäre das schon eher so:

while (Hour != now.hour()) //Hier beginnt der Vergleich mit der eingegebenen Zeit:
{
guckeWieSpätEsIst();
}

Hallo,

solche einmaligen Sachen zum einstellen nach Reset oder Batteriewechsel kannste auch am Ende von setup erledigen. Dann ist das aus der loop raus.

TheBigPekka:
Ist das nicht das Ziel, das der Sketch blockiert wird, bis die eingegebene Zeit mit er echten Zeit zutrifft? (Ich bin neu, wie schon gesagt)

Jein,
Der Arduino soll keine Aktion machen aber die Zeit mit der Sollzeit vergleichen sollte er schon dauernd machen.

Grüße Uwe