Arduino RTC Timer Licht steuern

Guten Tag,

ich versuche einen Timer, mit einem RTC Modul (Real Time Clock), mit dem Arduino Nano zu bauen.

Der Timer soll nach einer Betätigung eines Tasters starten, X Sekunden (im Code bsp. 10 Sek) das Licht brennen lassen, und nach Ablauf der Zeit das Licht ausschalten. Ich habe in der Vergangenheit dies mit der millis() Funktion versucht, doch nach längerem Betrieb fällt eine Ungenauigkeit auf.

Ich habe versucht einen Code zu schreiben. Dieser funktioniert nicht nach Plan. Die LED leuchtet, nach Betätigung des Tasters, ohne Ende.

//DS3231 zu Arduino Nano: SDA -> A4
//                        SCl -> A5
//                        VCC -> 5V
//                        GND -> GND

#include <Wire.h>
#include <DS3231.h>

RTClib myRTC;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    pinMode(2, INPUT_PULLUP);  //Pull-up Taster Pin 2
    pinMode(5, OUTPUT);        //LED Pin 5

    delay(500);
    Serial.println("Ready!");
}

void loop () {
    
    delay(1000);                                 //kurze Pause     
    DateTime now = myRTC.now();
        
    Serial.print(now.unixtime());                 
    Serial.println();

    int button1 = digitalRead(2);                 //Position des Tasters lesen

    if (button1 == LOW) {                         //Wenn der Taster gedrückt ist
      digitalWrite(5, HIGH);                      //Schalte LED ein
      static long alteZeit = now.unixtime();      //Merken der Zeit, an der angeschaltet
      
      if (now.unixtime() >= alteZeit + 10) {      //Wenn aktuelle Zeit >/= als alte Zeit + 10Sec
        digitalWrite(5, LOW);                     //Schalte LED aus
        

      }
    }

}

Was könnte das Problem sein und wie kann man es lösen?

Mit freundlichen Grüßen

Der Zeitablauf wird nie festgestellt, denn dazu müsste die Taste gedrückt sein. Aber die stellt ja die Zeit wieder neu ein.

Du musst also die Einstellung der Zeit mit dem taster und die Auswertung voneinander trennen.

ungefähr so

//DS3231 zu Arduino Nano: SDA -> A4
//                        SCl -> A5
//                        VCC -> 5V
//                        GND -> GND

#include <Wire.h>
#include <DS3231.h>

RTClib myRTC;

unsigned long alteZeit;
const byte tasterPin = 2;
const byte ledPin = 5;
void setup ()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(tasterPin, INPUT_PULLUP);  //Pull-up Taster Pin 2
  pinMode(ledPin, OUTPUT);        //LED Pin 5
  digitalWrite(ledPin, LOW);
  delay(500);
  Serial.println("Ready!");
}
uint32_t oldTime = 0;

void loop ()
{
  DateTime now = myRTC.now();
  if (now.unixtime() != oldTime)
  {
    Serial.println(now.unixtime());
    oldTime = now.unixTime()
  }
  bool button1 = digitalRead(tasterPin);                 //Position des Tasters lesen
  if (button1 == LOW)                           //Wenn der Taster gedrückt ist
  {
    digitalWrite(ledPin, HIGH);                      //Schalte LED ein
    alteZeit = now.unixtime();                  //Merken der Zeit, an der angeschaltet
  }
  if (now.unixtime() - alteZeit > 10)           //Wenn aktuelle Zeit >/= als alte Zeit + 10Sec
  {
    digitalWrite(ledPin, LOW);                       //Schalte LED aus
  }
}

Ja?
Wie?

Danke für deine schnelle Antwort. :grinning:
Das von Dir vorgeschlagene Sketch funktioniert. Danke.

Könnte man das auch auf mehrere Taster und LEDs übertragen? Also sodass jeder Taster eine eigene LED steuert.

MfG

Die Ungenauigkeit von millis() zeigt sich nach längerem Betrieb, in dem die angegebenen 10 Sekunden, bei dem Arduino, früher eintreffen, als 10 Sekunden in Wirklichkeit währen.

//DS3231 zu Arduino Nano: SDA -> A4
//                        SCl -> A5
//                        VCC -> 5V
//                        GND -> GND

#include <Wire.h>
#include <DS3231.h>

RTClib myRTC;

const byte zeitKreise = 3; // Anzahl Uhren/LED Kombi

unsigned long alteZeit[zeitKreise] = {0};
const byte tasterPin[zeitKreise] = {2, 3, 4};
const byte ledPin[zeitkreise] = {5, 6, 7};
void setup ()
{
  Serial.begin(9600);
  Wire.begin();
  for (byte b = 0; b < zeitKreise; b++)
  {
    pinMode(tasterPin[b], INPUT_PULLUP);
    pinMode(ledPin[b], OUTPUT);
    digitalWrite(ledPin[b], LOW);
  }
  delay(500);
  Serial.println("Ready!");
}
uint32_t oldTime = 0;

void loop ()
{
  DateTime now = myRTC.now();
  if (now.unixtime() != oldTime)
  {
    Serial.println(now.unixtime());
    oldTime = now.unixTime()
  }
  for (byte b = 0; b < zeitKreise; b++)
  {
    bool button = digitalRead(tasterPin[b]);                 //Position des Tasters lesen
    if (button == LOW)                                       //Wenn der Taster gedrückt ist
    {
      digitalWrite(ledPin[b], HIGH);                         //Schalte LED ein
      alteZeit[b] = now.unixtime();                          //Merken der Zeit, an der angeschaltet
    }
    if (now.unixtime() - alteZeit[b] > 10)                   //Wenn aktuelle Zeit >/= als alte Zeit + 10Sec
    {
      digitalWrite(ledPin[b], LOW);                          //Schalte LED aus
    }
  }
}

Funktioniert. Vielen Dank :+1:

Nichts anderes erwartet. Wenn Du jedem Timer auch noch eine andere Ablaufzeit geben möchtest, musst Du für die 10 ebenso eine Konstante benutzen, wie für den Zeitmerker die Variable gesetzt ist.
Markier den Sketch oben als Lösung - dann findet man das auch mit der Suchfunktion unter gelösten Fragen.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.