Arduino UNO Relais Steuern mit RTC Modul DS3231

Hi ihr lieben,

ich möchte einen Lampe und eine Wasserpumpe mit meinem Arduino mit Hilfe von Relais steuern. Das ganze soll zeitbasiert sein, also Lampe an um 8:00 etc. Dafür will ich den das RTC Modul DS3231 benutzen. Mittlerweile bin ich soweit, dass ich die Uhr eingestellt habe und die Uhrzeit auf einem LCD angezeigt wird. Jetzt wollte ich mich daran machen die zwei Relais anzuschließen, aber ich versteh die Programmierung einfach nicht. Kann mir evtl. jemand erklären worauf ich genau achten muss, bzw. wie das ganze überhaupt funktioniert!
Danke

#include <TimeAlarms.h>

#include <LiquidCrystal_I2C.h>

#include <Wire.h>

#include <DS3231.h>

DS3231  rtc(A4, A5);

#define I2C_ADDR    0x3F  // Define I2C Address for controller
#define BACKLIGHT_PIN  7
#define En_pin  4
#define Rw_pin  5
#define Rs_pin  6
#define D4_pin  0
#define D5_pin  1
#define D6_pin  2
#define D7_pin  3

#define  LED_OFF  0
#define  LED_ON  1
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);



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

  

  rtc.begin();
  
  lcd.begin(16, 2);
}

void loop()
{
  lcd.setCursor(4, 0);
  lcd.print(rtc.getTimeStr());

  //lcd.setCursor(0, 1);
  //lcd.print(rtc.getDOWStr(FORMAT_SHORT));

  //lcd.setCursor(6, 1);
  //lcd.print(rtc.getDateStr());
  
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  

  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");


  Serial.println(rtc.getTimeStr());
  
  
  delay (1000);
}

Da du die Library "TimeAlarms" verwenden willst, kannst du doch da in den Beispielen nachsehen, wie das eingestellt werden kann.

Im übrigen benötigst du die Definitionen

#define I2C_ADDR    0x3F  // Define I2C Address for controller
#define BACKLIGHT_PIN  7
#define En_pin  4
#define Rw_pin  5
#define Rs_pin  6
#define D4_pin  0
#define D5_pin  1
#define D6_pin  2
#define D7_pin  3

nicht, da diese in der Zeile

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

fest eingestellt sind.
Deine Darstellung der Urzeit kommt mir auch etwas seltsam vor.
Das solltest du ebenso in den Beispielen der Library überprüfen.
Wenn du uns den Link der verwendeten "LiquidCrystal_I2C.h" postest, können wir das gegenchecken.

Schaue Dir mal die Bibliothek jursRTCtimeEasy an, die sollte mit den switchTimes sein, was Du suchst. Eine automatische Sommer-/Winterzeitumstellung ist auch dabei.

Danke für die schnelle Antwort!
Okay, der falsche Code ist gelöscht!

https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home und diese Bibliothek habe ich benutzt.

Okay ich hab mir Bibliothek angeschaut, versteh aber noch nicht so ganz wie ich sie integriere?

Sorry ich glaube es ist sehr offensichtlich, dass ich NOCH nicht sehr viel verstehe! :slight_smile:

Edit:

ich bin gerade auf diesen Post gestoßen
https://forum.arduino.cc/index.php?topic=345410.0
blöde Frage, aber kann ich auch einfach die RTClib benutzen anstatt die DS3231?

Du kannst sicher auch eine andere Library einsetzen, aber nimm eine aktuellere.

Ich verwende z.B. diese, die spielt auch mit der RTC DS3231 und arbeitet bei mir sehr gut.
Die hat auch gute Beispiele zum Üben dabei.

Okay, ich hab das Gefühl, dass ich mich noch etwas mehr reinarbeiten muss um das alles richtig zu verstehen.
Hatte gedacht das es ja nicht so schwer sein kann zwei Relais um eine bestimmte Zeit an und aus zu stellen :slight_smile:

brunowindt:
Okay, ich hab das Gefühl, dass ich mich noch etwas mehr reinarbeiten muss um das alles richtig zu verstehen.
Hatte gedacht das es ja nicht so schwer sein kann zwei Relais um eine bestimmte Zeit an und aus zu stellen :slight_smile:

Wenn du das mit der verlinkten Library aufbaust , kannst du doch mit den Beispielen testen.
Und wenn Fragen sind, einfach hier fragen.

Bin jetzt dabei, hat auch alles soweit geklappt, bis ich versucht habe TimeAlarms einzurichten.
ich bekomme folgenden Fehler

/Users/louisbindernagel/Documents/Arduino/TEst_LCD/Fertig1/Fertig1.ino: In function 'void setup()':
Fertig1:25: error: 'RelayOn' was not declared in this scope
Alarm.alarmRepeat(20,30,0, RelayOn);
^
Fertig1:26: error: 'RelayOff' was not declared in this scope
Alarm.alarmRepeat(20,35,0, RelayOff);
^
/Users/louisbindernagel/Documents/Arduino/TEst_LCD/Fertig1/Fertig1.ino: In function 'void digitalClockDisplay()':
Fertig1:67: error: variable or field 'RelayOn' declared void
void RelayOn(RELAY1, LOW) {
^
exit status 1
'RelayOn' was not declared in this scope

bei diesem Code

#include <TimeAlarms.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS3232RTC.h>    
#include <Wire.h>         
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

AlarmId id;

#define RELAY1 7

void setup(void)
{
    Serial.begin(9600);
    setSyncProvider(RTC.get);   // the function to get the time from the RTC
    if(timeStatus() != timeSet) 
        Serial.println("Unable to sync with the RTC");
    else
        Serial.println("RTC has set the system time");      

    lcd.begin(16, 2);

    Alarm.alarmRepeat(20,30,0, RelayOn);  
    Alarm.alarmRepeat(20,35,0, RelayOff);

    

    pinMode (RELAY1, OUTPUT);
}

void loop(void)
{
    digitalClockDisplay();  
    delay(1000);
    Alarm.delay(1000);
}



void digitalClockDisplay(void)
{
    // digital clock display of the time
    Serial.print(hour());
    printDigits(minute());
    printDigits(second());
    Serial.print(' ');
    Serial.print(day());
    Serial.print(' ');
    Serial.print(month());
    Serial.print(' ');
    Serial.print(year()); 
    Serial.println(); 


    lcd.setCursor(0,0);
    lcd.print(hour(), DEC);
    lcd.setCursor(2,0);
    lcd.print(':');
    lcd.setCursor(3,0);
    lcd.print(minute(), DEC);

    delay(1000);


  void RelayOn(RELAY1, LOW) {
  Serial.println("Alarm: - turn lights off");
}
    
}

void printDigits(int digits)
{
    // utility function for digital clock display: prints preceding colon and leading 0
    Serial.print(':');
    if(digits < 10)
        Serial.print('0');
    Serial.print(digits);
}

Den Code habe ich versucht aus dem Beispiel der TimeAlarms Library abzuleiten:

/*
 * TimeAlarmExample.pde
 *
 * This example calls alarm functions at 8:30 am and at 5:45 pm (17:45)
 * and simulates turning lights on at night and off in the morning
 * A weekly timer is set for Saturdays at 8:30:30
 *
 * A timer is called every 15 seconds
 * Another timer is called once only after 10 seconds
 *
 * At startup the time is set to Jan 1 2011  8:29 am
 */

// Questions?  Ask them here:d
// http://forum.arduino.cc/index.php?topic=66054.0

#include <TimeLib.h>
#include <TimeAlarms.h>

AlarmId id;

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor

  setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011

  // create the alarms, to trigger at specific times
  Alarm.alarmRepeat(8,30,0, Relay);  // 8:30am every day
  Alarm.alarmRepeat(17,45,0,EveningAlarm);  // 5:45pm every day
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);  // 8:30:30 every Saturday

  // create timers, to trigger relative to when they're created
  Alarm.timerRepeat(15, Repeats);           // timer for every 15 seconds
  id = Alarm.timerRepeat(2, Repeats2);      // timer for every 2 seconds
  Alarm.timerOnce(10, OnceOnly);            // called once after 10 seconds
}

void loop() {
  digitalClockDisplay();
  Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:
void Relay() {
  Serial.println("Alarm: - turn lights off");
}

void EveningAlarm() {
  Serial.println("Alarm: - turn lights on");
}

void WeeklyAlarm() {
  Serial.println("Alarm: - its Monday Morning");
}

void ExplicitAlarm() {
  Serial.println("Alarm: - this triggers only at the given date and time");
}

void Repeats() {
  Serial.println("15 second timer");
}

void Repeats2() {
  Serial.println("2 second timer");
}

void OnceOnly() {
  Serial.println("This timer only triggers once, stop the 2 second timer");
  // use Alarm.free() to disable a timer and recycle its memory.
  Alarm.free(id);
  // optional, but safest to "forget" the ID after memory recycled
  id = dtINVALID_ALARM_ID;
  // you can also use Alarm.disable() to turn the timer off, but keep
  // it in memory, to turn back on later with Alarm.enable().
}

void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Was übersehe ich und wie und wo genau schreibe ich den Befehl um das Relais zu aktivieren?

Verschiebe mal die angemeckerten Funktionen vor den Loop. Manches Mal hat die IDE da ein Problem.

Gruß Tommy

Du kannst jetzt auch ohne die "TimeAlarms" Library einfach deine Schaltzeiten festlegen und damit die Relais ansteuern.

Beispiel für die Relaiszeiten:

if (hour()== EinschaltStunden && minute() == EinschaltMinuten) {   // Einschaltzeit
digitalWrite(RelaisPin1, HIGH);
}

if (hour()== AusschaltStunden && minute() == AusschaltMinuten) {   // Ausschaltzeit
digitalWrite(RelaisPin1, LOW);
}

In Schaltstunden und Schaltminuten da trägst du deine Wunschzeiten ein.
Das baust du in deine Loop.

Davon kannst du theoretisch beliebig viele Anweisungen einbauen.

Es funktioniert!
Vielen Dank ich freu mich sehr!
Ich werd jetzt morgen meine Bauteile alle aufbauen und evtl. noch ein paar Funktionen hinzufügen!

brunowindt:
Es funktioniert!
Vielen Dank ich freu mich sehr!
Ich werd jetzt morgen meine Bauteile alle aufbauen und evtl. noch ein paar Funktionen hinzufügen!

Ok, wie hast du es jetzt aufgebaut ?
Mit Library oder "einfach" ?

Einfach mit den if Befehlen, experimentiere gerade noch ein bisschen damit was auf meinem LCD steht. In dem Code gerade z.B. verschwindet der Text "Pumpe an" nicht mehr, muss man das wieder "löschen"?

#include <Time.h>
#include <TimeLib.h>
#include <DS3232RTC.h>    
#include <Wire.h>         
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);



#define RELAY1 7

void setup(void)
{
    Serial.begin(9600);
    setSyncProvider(RTC.get);   // the function to get the time from the RTC
    if(timeStatus() != timeSet) 
        Serial.println("Unable to sync with the RTC");
    else
        Serial.println("RTC has set the system time");      

    lcd.begin(16, 2);
    

   

    

    pinMode (RELAY1, OUTPUT);
}

void loop(void)
{
    digitalClockDisplay();  
    delay(1000);
 
}



void digitalClockDisplay(void)
{
    // digital clock display of the time
    Serial.print(hour());
  Serial.print(minute());
    Serial.print(second());
    Serial.print(' ');
    Serial.print(day());
    Serial.print(' ');
    Serial.print(month());
    Serial.print(' ');
    Serial.print(year()); 
    Serial.println(); 


    lcd.setCursor(0,0);
    lcd.print(hour(), DEC);
    lcd.setCursor(2,0);
    lcd.print(':');
    lcd.setCursor(3,0);
    lcd.print(minute(), DEC);

    delay(1000);

    if (hour()== 23 && minute() == 23) {   // Einschaltzeit
digitalWrite(RELAY1, HIGH);
}

if (hour()== 23 && minute() == 25) {   // Ausschaltzeit
digitalWrite(RELAY1, LOW);
}

if (RELAY1, HIGH) {
 lcd.setCursor(0,1);
lcd.print("Pumpe an");
}


   

}
    

void printDigits(int digits)
{
    // utility function for digital clock display: prints preceding colon and leading 0
    Serial.print(':');
    if(digits < 10)
        Serial.print('0');
    Serial.print(digits);
}

brunowindt:
Einfach mit den if Befehlen, experimentiere gerade noch ein bisschen damit was auf meinem LCD steht. In dem Code gerade z.B. verschwindet der Text "Pumpe an" nicht mehr, muss man das wieder "löschen"?

Ok, prima.

Ja, den Text kannst du mit Leerzeichen wieder überschreiben, oder neuem Text.

Edit:
Die Library "TimeLib.h" brauchst du hier nicht.

Wenn ich TimeLib deaktiviere bekomme ich Fehlermeldungen.
Das mit dem Text auf dem LCD funktioniert leider immer noch, nicht im Moment ist der Text immer da.

Arduino: 1.6.12 (Mac OS X), Board: "Arduino/Genuino Uno"

In file included from /Users/louisbindernagel/Documents/Arduino/TEst_LCD/Fertig1/Fertig1.ino:4:0:
/Users/louisbindernagel/Documents/Arduino/libraries/DS3232RTC-master/DS3232RTC.h:136:26: error: 'tmElements_t' has not been declared
static byte read(tmElements_t &tm);
^
/Users/louisbindernagel/Documents/Arduino/libraries/DS3232RTC-master/DS3232RTC.h:137:20: error: 'tmElements_t' has not been declared
byte write(tmElements_t &tm);
^
/Users/louisbindernagel/Documents/Arduino/TEst_LCD/Fertig1/Fertig1.ino: In function 'void setup()':
Fertig1:17: error: 'setSyncProvider' was not declared in this scope
setSyncProvider(RTC.get); // the function to get the time from the RTC
^
Fertig1:18: error: 'timeStatus' was not declared in this scope
if(timeStatus() != timeSet)
^
Fertig1:18: error: 'timeSet' was not declared in this scope
if(timeStatus() != timeSet)
^
/Users/louisbindernagel/Documents/Arduino/TEst_LCD/Fertig1/Fertig1.ino: In function 'void digitalClockDisplay()':
Fertig1:43: error: 'hour' was not declared in this scope
Serial.print(hour());
^
Fertig1:44: error: 'minute' was not declared in this scope
Serial.print(minute());
^
Fertig1:45: error: 'second' was not declared in this scope
Serial.print(second());
^
Fertig1:47: error: 'day' was not declared in this scope
Serial.print(day());
^
Fertig1:49: error: 'month' was not declared in this scope
Serial.print(month());
^
Fertig1:51: error: 'year' was not declared in this scope
Serial.print(year());
^
exit status 1
'setSyncProvider' was not declared in this scope

Dieser Bericht wäre detaillierter, wenn die Option
"Ausführliche Ausgabe während der Kompilierung"
in Datei -> Voreinstellungen aktiviert wäre.

#include <Time.h>
#include <TimeLib.h>
#include <DS3232RTC.h>    
#include <Wire.h>         
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

#define PUMPE 7
#define LICHT 8


void setup(void)
{
    Serial.begin(9600);
    setSyncProvider(RTC.get);   // the function to get the time from the RTC
    if(timeStatus() != timeSet) 
        Serial.println("Unable to sync with the RTC");
    else
        Serial.println("RTC has set the system time");      

    lcd.begin(16, 2);
    
    pinMode (PUMPE, OUTPUT);
    pinMode (LICHT, OUTPUT);
}

void loop(void)

//DISPLAY
{
    digitalClockDisplay();  
    
 
}



void digitalClockDisplay(void)
{
   
    Serial.print(hour());
    Serial.print(minute());
    Serial.print(second());
    Serial.print(' ');
    Serial.print(day());
    Serial.print(' ');
    Serial.print(month());
    Serial.print(' ');
    Serial.print(year()); 
    Serial.println(); 


    lcd.setCursor(0,0);
    lcd.print(hour(), DEC);
    lcd.setCursor(2,0);
    lcd.print(':');
    lcd.setCursor(3,0);
    lcd.print(minute(), DEC);

   if (PUMPE, HIGH) {
    lcd.setCursor(0,1);
    lcd.print("Pumpe an");
    
}

  if (PUMPE, LOW) {
    lcd.setCursor(0,1);
    lcd.print(" ");
}

    delay(1000);


//LICHT

        if (hour()== 8 && minute() == 00) {   // Einschaltzeit
digitalWrite(LICHT, HIGH);
}

if (hour()== 20 && minute() == 00) {   // Ausschaltzeit
digitalWrite(LICHT, LOW);
}

//PUMPE

    if (hour()== 8 && minute() == 00) {   // Einschaltzeit
digitalWrite(PUMPE, HIGH);
}

if (hour()== 8 && minute() == 20) {   // Ausschaltzeit 
digitalWrite(PUMPE, LOW);
}

  if (hour()== 16 && minute() == 00) {   // Einschaltzeit
digitalWrite(PUMPE, HIGH);
}

if (hour()== 16 && minute() == 20) {   // Ausschaltzeit
digitalWrite(PUMPE, LOW);
}

  if (hour()== 24 && minute() == 00) {   // Einschaltzeit
digitalWrite(PUMPE, HIGH);
}

if (hour()== 24 && minute() == 20) {   // Ausschaltzeit
digitalWrite(PUMPE, LOW);
}



   

}
    

void printDigits(int digits)
{
    // utility function for digital clock display: prints preceding colon and leading 0
    Serial.print(':');
    if(digits < 10)
        Serial.print('0');
    Serial.print(digits);
}
1 Like

Was hast du deaktiviert ?

TimeLib.h oder Time.h ?

Die Time.h wird benötigt, die TimeLib.h meines erachtens nicht.

Und ohne die TimeLib.h kompiliert er bei mir fehlerfrei.

Wenn Dich die Timer-Bibliotheken irritieren, dann schaue Dir mal eine ganz einfache Abfrage der Zeit an: Tutorial – Using DS1307 and DS3231 Real-time Clock Modules with Arduino. Mir hat es geholfen :slight_smile:

TimeLib.h hatte ich deaktiviert und dann kompiliert er nicht und gibt die Fehlermeldung von meinem letzten Post.
Aber is ja auch so okay, es funktioniert ja alles.

LCD Text habe ich hin bekommen

statt:

   if (PUMPE, HIGH) {
    lcd.setCursor(0,1);
    lcd.print("Pumpe an");

das hier:

   if (PUMPE == HIGH) {
    lcd.setCursor(0,1);
    lcd.print("Pumpe an");

brunowindt:
LCD Text habe ich hin bekommen

statt:

   if (PUMPE, HIGH) {

lcd.setCursor(0,1);
    lcd.print("Pumpe an");




das hier:


if (PUMPE == HIGH) {
    lcd.setCursor(0,1);
    lcd.print("Pumpe an");

Ah, ok...da war ein Fehler drin. :wink: