DS3231 RTC SQWpin

Ich werde aus der Verwendung des RTC-SQWpin nicht ganz schlau.:thinking:

Kann ich den Pin verwenden um bei Eintreten des RTC-Alarms einen ESP8266 über seinen RSTpin einmalig zu resetten?

Wenn ja - wie?

Aus dem DaBla heisst es:

(Seite 12 - Alarms)
Also ein wenig Register setzen nach Tabelle 2

Setz Dich mit https://github.com/JChristensen/DS3232RTC/blob/master/alarm-primer.md auseinander und Du findest in den Examples die Codezeile, die Du für Dich anpassen musst :wink:

Welche ist Deine Lieblingsbibliothek?

Ich habe die Adafruit verwendet.

Dann wäre doch das Beispiel DS3231_alarm.ino für Dich geeignet, oder?

Ja, sollte passen.

Ich kapier den Code aber noch nicht.

Was mache ich denn mit: ?

DateTime alarm1 = rtc.getAlarm1();
    Ds3231Alarm1Mode alarm1mode = rtc.getAlarm1Mode();

Vermutlich nichts, das dient nur der Kontrolle von Alarmzeit und -Modus.

Gar nix.
Im Kommentar steht:

    // the stored alarm value + mode

Und dann kommt nur noch die serielle Ausgabe der Inhalte.
Der Teil ist nur eine Kontrollfunktion, was in getAlarm1() und getAlarm1Mode wiedergibt.

Der Interrupt wird jetzt ausgegeben!

Am Testpin D6 kann ich die Reaktion über die interne LED sichtbar machen.

Schliesse ich den SQWpin an den RSTpin vom ESP an erfolgt zwar ein Stopp des Codes aber ein Reset erst nach abziehen des RST Kontaktes. SQW muss ihn wohl auf L halten.

#include <ESP8266WiFi.h>
#include <SSD1306Wire.h>            // für OLED` 128x64
#include <RTClib.h>
#include "ezTime.h"

RTC_DS3231 rtc;

char myIpString[24];                //um IP Adresse in String umzuwandeln und anzuzeigen

char *ssid = "Speexxxxxxx";
char *password = "yyyyyyyyyy";

// Initialize the OLED display using Wire library
SSD1306Wire  display(0x3c, D1, D2);  //D2=SDK  D1=SCK  I2C As per labeling on NodeMCU

int h=0;                            //Variable Stunde
int m=0;                            //Variable Minute
int s=0;                            //Variable Sekunde
int Monat=0;                        //Variable Monat
int Jahr=0;                         //Variable Jahr
int Tag=0;                          //Variable Tag

const int RTCinput = 12;            //D6 als Input
const int LED = 2;                  //interne LED

int InputState = 0;                 //Input Status






//Unterprogramm wird ausgeführt wenn Interrupt kommt
void IRAM_ATTR isr() {
  digitalWrite(LED, HIGH);                                            //interne LED ausschalten
}





void setup() {
  display.init();
  //display.flipScreenVertically();                                   //Display 180° drehen
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.setFont(ArialMT_Plain_16);
  WiFiStart();                                                        //Unterprogramm verbindet ESP mit Router
  //Zeit aus Internet holen und in Variablen speichern
  waitForSync();                                                      //Zeit wird synchronisiert
  Timezone myTZ;
  myTZ.setLocation(F("Europe/Berlin"));                               //Zeitzone Berlin
  String sh = String(myTZ.dateTime("H"));h = sh.toInt();              //Stunde ezTime zu Zahl in Variable umwandeln
  String sm = String(myTZ.dateTime("i"));m = sm.toInt();              //Minute ezTime zu Zahl in Variable umwandeln
  String ss = String(myTZ.dateTime("s"));s = ss.toInt();              //Sekunde ezTime zu Zahl in Variable umwandeln
  String sTag = String(myTZ.dateTime("d"));Tag = sTag.toInt();        //Tag ezTime zu Zahl in Variable umwandeln
  String sMonat = String(myTZ.dateTime("m"));Monat = sMonat.toInt();  //Monat ezTime zu Zahl in Variable umwandeln
  String sJahr = String(myTZ.dateTime("Y"));Jahr = sJahr.toInt();     //Jahr ezTime zu Zahl in Variable umwandeln
        display.setFont(ArialMT_Plain_10);
        display.clear();
        display.drawString(0, 0, String(Jahr) + "," + String(Monat) + "," + String(Tag) + "," + String(h) + ":" + String(m) + ":" + String(s));
        display.display();
        delay(6000);
  // initializing the rtc
    if(!rtc.begin()) {
        display.clear();
        display.drawString(0, 0, "Couldn't find RTC!");
        display.display();
        delay(2000);
    }
    else {
        display.clear();
        display.drawString(0, 0, "RTC gefunden!");
        display.display();
        delay(2000);
    }
    if(rtc.lostPower()) {
        rtc.adjust(DateTime(Jahr, Monat, Tag, h, m, s));              //RTC mit Zeit aus Internet stellen
        //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));             //RTC mit Zeit vom PC stellen
    }
    rtc.disable32K();                                                 //we don't need the 32K Pin, so disable it
    pinMode(RTCinput, INPUT_PULLUP);                                  //Eingangspin als Input definieren und auf H heben
    attachInterrupt(RTCinput, isr, FALLING);
    pinMode(LED, OUTPUT);                                             //Ausgangspin (interne LED) als Ausgang definieren
    rtc.clearAlarm(1);                                                //alte Alarme löschen
    rtc.clearAlarm(2);
    rtc.writeSqwPinMode(DS3231_OFF);                                  // stop oscillating signals at SQW Pin -otherwise setAlarm1 will fail
    rtc.disableAlarm(2);
    // Plane den alarm 10 seconds in the future
    if(!rtc.setAlarm1(
            rtc.now() + TimeSpan(30),
            DS3231_A1_Second                                          // this mode triggers the alarm when the seconds match. See Doxygen for other options
    )) {
        display.drawString(0, 20, "Error, alarm wasn't set!");
        display.display();
    }
    else {
        display.drawString(0, 20, "Alarm will happen in 30 seconds!");
        display.display();
    }
    digitalWrite(LED, LOW);
  delay(3000);
}








void loop() {
  DateTime now = rtc.now();                                     //aktuelle Zeit holen
  DateTime alarm1 = rtc.getAlarm1();                            //für Alarm notwendig
  Ds3231Alarm1Mode alarm1mode = rtc.getAlarm1Mode();            //für Alarm notwendig
  if (rtc.alarmFired(1)) {                                      // resetting SQW and alarm 1 flag (using setAlarm1, the next alarm could now be configurated)
        rtc.clearAlarm(1);
        display.drawString(0, 30, "Alarm cleared");
        display.display();
  }
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 0, String(now.hour()) + ":");
  display.drawString(15, 0, String(now.minute()) + ":");
  display.drawString(30, 0, String(now.second()) + " / ");
  display.drawString(65, 0, String(now.month()));
  InputState = digitalRead(RTCinput);                           //Input Pin lesen
  if (InputState == HIGH) {
    //digitalWrite(LED, LOW);
    display.drawString(0, 10, "HIGH");
  }
  else {
    //digitalWrite(LED, HIGH);
    display.drawString(0, 10, "LOW");
  }
  display.display();
  delay(100);
}




void WiFiStart()                              // Unterprogramm um WiFi am Router anzumelden
{
  // Connect to WiFi network
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 0, "Call to " + String(ssid));
  display.display();
  WiFi.begin(ssid, password);
  int i = 0;
  while (WiFi.status() != WL_CONNECTED)
  {
    display.drawString(i, 9, ".");
    display.display();
    delay(500);
    i = i + 3;
  }
  // Print the IP address
  IPAddress myIp = WiFi.localIP();
  sprintf(myIpString, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]);   //IP muss in String umgewandelt werden
  display.clear();
  display.setFont(ArialMT_Plain_16);
  display.drawString(0, 0, "IP Adresse:");
  display.drawString(0, 20, myIpString);
  display.display();
  WiFi.setAutoReconnect(true);                    //automatisches wiederverbinden
  WiFi.persistent(true);                          //automatisches wiederverbinden
  delay(2000);                                    
}

Das Beispiel nutzt eigentlich einen Interrupt anstelle Reset, warum Du nicht?

Ich möchte den ESP in den deepSleep setzten und mit der RTC per Reset aufwecken.

Für den ESP32 gibt es ein IDE-Beispiel ExternalWakeUp.ino mit einem normalen Pin1) als Aufwach-Trigger. Schau bitte auch mal in des Thema ESP32 deep sleep with DS3231. Sowas sollte es auch für den ESP8266 geben. Den habe ich aber nicht, daher kann ich da nicht helfen.


Anm.:

  1. Er sollte einen internen PullUp-Widerstand haben oder Du benötigst einen externen PullUp-Widerstand.

Hätte ich bloss gleich den ESP32 genommen....:thinking:

Ich habe aber etwas gefunden::hugs:

Aufwecken mit SQWpin an RSTpin vom ESP8266 aber mit Elko 1-10yF dazwischen (Minus an RST). Jetzt klappt es auch mit dem vollständigen Reset - Langzeittest steht noch aus... ob er aus dem deepSleep geholt wird muss ich auch noch testen.

Da möchte ich Dir jetzt mal nicht widersprechen :blush:

Wird schon werden!