Countdown Anzeige

Guten Morgen, da ich noch ein Anfänger mit der Programmierung brauche ich eure Hilfe,
ich habe mit Hilfe des Internets einen Countdown Zähler hinbekommen und verstehe das Programm auch.

Ich möchte jetzt ein “Zukunftsdatum eingeben (d, m, y)”
und ein heutiges Datum ( das ich auch selbst beliebig eingeben möchte ),
dann soll das Zukunftsdatum minus das heutige Datum berechnet werden und
im Code Tage, Stunden, Minuten und Sekunden beschreiben und den Countdown anzeigen.

Wie soll ich am besten vorgehen, ich hab mich mal durch gelesen und man sollte die Tage, Stunden, und Minuten in Sekunden umrechnen, das gleiche mit dem heutigen Datum und die erhalten Sekunden subtrahieren und wiederum umwandeln.

Jetzt habe ich das komische Gefühl das ich mich mit Arrays befassen muss,
damit ich Angeben muss das einige Monate 31, 30, 28 Tage haben, sowie das es Schaltjahre gibt.

Sehe ich das richtig oder bin ich auf dem falschen Wege?
Und Ja,ein Fehler hat das Sketch und zwar, wenn der Countdown ganz bei Null ist geht der weiter auf minus 1 usw. aber das bekomme ich schon hin.

Hier ist der Sketch:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);

int tag=1368, stunde=14, minute=6; //hier die Uhrzeit einstellen
int sekunde_neu, sekunde_alt; 

void setup()
{  
 lcd.clear();       
 lcd.begin(); 
 lcd.setCursor(3,0);
 lcd.print("Countdown");
}


void loop()
{
 lcd.setCursor(1,1); 
 
 sekunde_neu = 59- ((millis()/1000) % 60); // Das %-Zeichen ist der Modulo-Operator
 
   
 // Zeit nur ausgeben, wenn Sekunde sich verändert hat
 if(sekunde_neu != sekunde_alt)
 { 
   
   if (sekunde_neu == 59)
   {
       
     minute--;
     if (minute==-1)
     {
       minute=59;
       stunde--;
       if (stunde==-1) 
        {  
          stunde=23;
           tag--;
      
         }   
           }
               
   }

   if (tag<10) lcd.print("000");// führende Null
   lcd.print(tag);

   lcd.print(":");
 
   if (stunde<10) lcd.print("0"); 
   lcd.print(stunde); 
 
   lcd.print(":"); 
 
   if (minute<10) lcd.print("0"); 
   lcd.print(minute); 
 
   lcd.print(":"); 
   
   if (sekunde_neu<10) lcd.print("0"); 
   lcd.print(sekunde_neu); 
   
   sekunde_alt = sekunde_neu;
 }
 
 
}

Hallo,
die Ide mit der Umrechnung in Sekunden ist schon ganz gut. Ich kenne das unter dem Begriff Unixzeit. Das sind die Sekunden seit einem festen Datum, beispielsweise seit 1.1.1970. Das kannst Du selbst ausrechnen, es gibt aber auch Bibliotheken, die das eingebaut haben. Möglicherweise kannst Du Dir da die Berechnung auch abschauen.

Mit den Feldern ist das so:

Wert0=5; Wert1=6; Wert2=7;

oder eben

Wert[0]=5; Wert[1]=6; Wert[2]=7;

Vorteil:

j=1; NeuerWert=Wert[j];

Bitte setze Deinen Sketch in Code-Tags, das ist der Button </> links oben.

jetzt habe ich das komische Gefühl das ich mich mit Arrays befassen muss

Stimmt, ohne Arrays kommst du wegen der unterschiedlichen Tage je Monat nicht aus, und die Schaltjahre müssen ebenfalls noch ermittelt bzw. berechnet werden. Das ist nicht ganz ohne - so alles zusammen, besonders wenn es über längere Zeiträume gehen soll.

Ich kenne das unter dem Begriff Unixzeit.

Ja, genau das selbe kenne ich auch so.

Und genau aus diesem Grund habe ich mir erst vor wenigen Monaten den Spaß gemacht, für die Umwandlung Zeit/Datum >> UnixTimestamp >> Zeit/Datum eine eigene Class zu schreiben. Nach einigen Versuchen habe ich eine zumindest für UTC m.E. gute Lösung entwickelt. Die “echte” Unixzeit berücksichtigt auf den WebServern noch die Zeitzonen, die auf dem Arduino nur über manuelle Addition/Subtraktion der betreffenden Verschiebungen gewährleistet werden kann.

Beigefügt zwei Beispiele dazu. Einmal zur Kontrolle der in Wikipedia aufgelisteten “besonderen Daten”.

Im zweiten Beispiel eine Umrechnung von “gerade eben”.

LG, Rudi

UnixtimeUTC.zip (3.49 KB)

UnixtimeUTC_2.zip (2.85 KB)

Zuerst möchte ich mich für die schnellen Antworten bedanken.

Da mein Countdown-Zähler flexibel vom Standort sein soll möchte ich anstatt über die Unixzeit die per Internetverbindung sich zusammen setzt besser mit dem DCF77 Modul der über Funk sich verbindet und mit die aktuelle Zeit sowie Datum ausgibt.

So jetzt kommt meine Programmier-Frage, und zwar habe ich mir das Modul über ELV bestellt ( DCF77 ).

Durch ELV erhält man Vier beigefügte Sketche: alarmInterrupt, dcf77Interrupt, periodicInterrupt, und setTime. Durch den Sketch setTime soll man die Uhrzeit sowie Datum auslesen können.

Jedoch wenn ich das Modul am Arduino anklemme und den Sketch drauf spiele, funktioniert es nicht, ich gehe von aus das man eine Adresse über Wire Befehl im Sketch eingeben muss, doch wie bekomme ich die Adresse raus? Oder liegt es nicht daran ?

Hier einmal das setTime Sketch, danke noch vielmals! :slight_smile:

/******************************************************************************
Beispiel:      setTime

Beschreibung:  Dieses Beispiel zeigt das Schreiben und Lesen der Uhrzeit aus
               dem RTC-DCF.
               
Hinweis:       Zur Einstellung des Kommunikationswegs (UART, SPI oder I2C) zum
               RTC-DCF enthält die Library die Datei RTC_DCF_config.h im
               Unterordner \libraries\RTC_DCF\config\. Innerhalb dieser Datei
               kann der Kommunikationsweg umgestellt werden.
******************************************************************************/
#include <stdio.h>
#include "DateTime.h"
#include "RealTimeClock_DCF.h"

/* leider setzt die Arduino-IDE voraus, dass alle in einem Projekt verwendeten
   Klassen auch ins Sketch übernommen werden. Wird dieses nicht berücksichtigt,
   kommt es zu Fehlern beim Linken des Programms. Daher muss an dieser Stelle
   die Headerdatei zu der jeweils verwendeten Kommunikationsklasse eingefügt
   werden. Die beiden jeweils nicht verwendeten Header müssen auskommentiert
   werden. */

/* für die Kommunikation über UART die modSoftwareSerial.h verwenden */
//#include "modSoftwareSerial.h"

/* für die Kommunikation über SPI die SPI.h verwenden */
//#include <SPI.h>

/* für die Kommunikation über Wire die Wire.h verwenden */
#include <Wire.h>

/******************************************************************************
globale Variablen
******************************************************************************/
/* einzustellende Uhrzeit */
DateTime dateTime = DateTime(0, 1, 1, DateTime::SATURDAY, 0, 0, 0);

/******************************************************************************
Funktionen
******************************************************************************/
void setup()
{
  /* der RTC-DCF benötigt ca. 1,5 Sekunden bis er Daten empfangen kann */
  delay(1500); 
  
  /* RTC-DCF initialisieren */  
  RTC_DCF.begin();

  /* Uhrzeit im RTC-DCF setzen */
  RTC_DCF.setDateTime(&dateTime);

  /* die serielle Ausgabe initialisieren */
  Serial.begin(115200);  
}

void loop()
{
  /* ca. jede Sekunde wird die Uhrzeit ausgelesen und über die serielle Schnittstelle 
     ausgegeben. */
  delay(1000);
  
  RTC_DCF.getDateTime(&dateTime);
  
  printClock();
}

void printClock(void)
{
  char clockString[30];
  
  sprintf(clockString, "Es ist %02u:%02u:%02u am %02u.%02u.%02u", dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(), dateTime.getDay(), dateTime.getMonth(), dateTime.getYear());
  
  Serial.println(clockString);   
}

Also im Prinzip müsste doch im Sketch folgendes auftauchen:

#include "Wire.h" // Aktiviert den I2C-Bus
byte DCF77MODUL = 0x70 >> 1; // Die eigentliche Adresse vom Modul

 Wire.beginTransmission(DCF77MODUL);
 Wire.endTransmission();

oder, bin noch ein Anfänger und brauche immer bisschen Zeit um in bestimmte Gebiete einzulesen. Vielen Dank schon mal für die Antworten

user_sv: Da mein Countdown-Zähler flexibel vom Standort sein soll möchte ich anstatt über die Unixzeit ...

Die Unixzeit hat nichts mit dem Standort zu tun und eignet sich zum Vergleich von Zeiten oder zur Errechnung von Differenzen.

user_sv: Jedoch wenn ich das Modul am Arduino anklemme und den Sketch drauf spiele, funktioniert es nicht, ich gehe von aus das man eine Adresse über Wire Befehl im Sketch eingeben muss, doch wie bekomme ich die Adresse raus? Oder liegt es nicht daran ?

Lies mal den Hinweis in Deinem Sketch, da steht die Antwort.

Die Unixzeit hat nichts mit dem Standort zu tun und eignet sich zum Vergleich von Zeiten oder zur Errechnung von Differenzen.

Hi, hab es jetzt kapiert, ich dachte für die Unixzeit benötigt mein Arduino eine Internetverbindung um diese Zeit zu holen um die dann rechnen zu können, aber man kann dann ja mit dem DCF77 Modul die Zeit besorgen und dann gegen eines Zieldatum herunter rechnen. Alles klar, verstanden.

Lies mal den Hinweis in Deinem Sketch, da steht die Antwort.

Du meinst diesen Hinweis ?

Hinweis:       Zur Einstellung des Kommunikationswegs (UART, SPI oder I2C) zum
               RTC-DCF enthält die Library die Datei RTC_DCF_config.h im
               Unterordner \libraries\RTC_DCF\config\. Innerhalb dieser Datei
               kann der Kommunikationsweg umgestellt werden.

moment, ich guck mal eben

Hallo,

wenn du dich hier mal durchwühlst, dann verstehste die Probleme mit der Zeitumrechnung bestimmt und findest Lösungen. jurs hatte in dem Thread was auf die Beine gestellt, auch wenn der Thread dann etwas zerpflückt wurde. Wenn man alle Seiten liest sollte man sich reindenken können. http://forum.arduino.cc/index.php?topic=313047.0

Rudi seine Bsp. Codes kannte ich bis heute noch nicht.

Lies mal den Hinweis in Deinem Sketch, da steht die Antwort.

Danke für diesen Tipp, aber ich kenne das gar nicht ein weiteren Reiter an zu legen. Ich hab also diesen zweiten Reiter "RTC_DCF_config_h" geöffnet, darin ist dieser Code enthalten.

#ifndef RTC_DCF_config_h
#define RTC_DCF_config_h

/******************************************************************************
Definitionen
******************************************************************************/
/* Wahl der Kommunikationsart
   m�gliche Werte:  0x00  UART
                    0x01  SPI
                    Ox02  I2C */
#define RTC_DCF_COMMUNICATION     Ox02    //jeweils Ox02 und 0x02 probiert

/* eingestellte I2C-Adresse des RTC-DCF (wird nur bei I2C-Kommunikation ben�tigt) jeweils Ox02 und 0x02 probiert */
#define RTC_DCF_I2C_ADDRESS       Ox02

/* eingestellte Baudrate des RTC-DCF (wird nur bei UART-Kommunikation ben�tigt) */
//#define RTC_DCF_UART_BAUDRATE     0x02

#endif /* RTC_DCF_config_h */

Wenn ich das so zusammen überprüfe und hochlade, sollte es dann von der Programmierung aus her funktionieren?

Denn ich habe die angegeben Jumper (1&2) gebrückt, Schiebeschalter 2 hoch gestellt, 3.3 V, GND, SCL und SDA entsprechend verbunden, ich habe das Shield nicht aufgesetzt da ich ein neueren Arduino habe und die I2C Anschlüße stimmen so nicht mit dem Shield überein, deswegen die einzel Brücken.

Hallo,

wenn du dich hier mal durchwühlst, dann verstehste die Probleme mit der Zeitumrechnung bestimmt und findest Lösungen. jurs hatte in dem Thread was auf die Beine gestellt, auch wenn der Thread dann etwas zerpflückt wurde. Wenn man alle Seiten liest sollte man sich reindenken können. http://forum.arduino.cc/index.php?topic=313047.0

Rudi seine Bsp. Codes kannte ich bis heute noch nicht.

Vielen Dank für diese Hilfe, auf Anhieb sieht es viel versprechend aus aber ich brauche immer meine Einarbeitungszeit :-)

Da bist Du an der richtigen Stelle.

Leider kann ich Dir nicht weiterhelfen, da ich nicht an meinem eigenen Rechner sitze :(

Doch noch eine Idee: Wenn Du mit I2C arbeiten willst, könnte Dir der i2c_scanner helfen, die Adresse zu finden und ob der Bus richtig arbeitet. Die Adresse Ox02 ist auf jeden Fall falsch.

Doch noch eine Idee: Wenn Du mit I2C arbeiten willst, könnte Dir der i2c_scanner helfen, die Adresse zu finden und ob der Bus richtig arbeitet. Die Adresse Ox02 ist auf jeden Fall falsch.

Also, vorgegeben steht wirklich für I2C - Ox02, durch deinen Test kommt 0x01 raus, wenn ich diesen in der config ändere tut sich trotzdem nichts.

Warum wird eigentlich ein "zweiter Reiter" erstellt und nicht alles auf eine Seite programmiert? Hat das einen Grund?

Danke für die Hilfe

0x02 wird übrigens immer mit Nullen, ohne Ohs, geschrieben.

Ist übrigens auch möglich, einfach

#define RTC_DCF_COMMUNICATION 2 // I2C

zu schreiben.

Die meisten RTC verwenden übrigens die I2C Adresse 0x68. Das kannst du auch mit dem I2C-Scanner-Programm überprüfen.

Falls ja, brauchst du dann die Zeile

#define RTC_DCF_I2C_ADDRESS       0x68