Clock-Shield (RTC und DCF77 auf einem Shield) *Entwicklung*

Hallo zusammen,
oft ließt man im Forum von Projekten in denen eine Uhr benötigt wird.
Viele wollen die Zeit aus dem Arduino entnehmen was doch recht ungenau ist.
Dann kommt die Frage nach eine Real-Time-Clock. Nur wer stellt die?
Dann gibt es die Möglichkeit die Zeit aus dem Netz zu holen. (Ethernet-Shield)
Oder gar per GPS die Zeit erfassen.

Ich hatte das selbe Problem.
Habe es mir dann so zusammen gefrickelt.

Dann habe ich mir überlegt, ich hätte gerne ein Shield oder etwas vergleichbares welches mir einfach eine Zeit liefert.
Möglichst genau und möglichst ohne mich drum kümmern zu müssen.

Deshalb jetzt hier meine Gedanken und meine Planung.
Und natürlich meine Ergebnisse!

Zur Info: Ich bin selber Anfänger. Hab mit uC nicht so viel zu tun gehabt. Basic ist recht gut drinnen aber C ist neu.
Also Nachsicht mit dem kleinen MueThoS

Hier zunächst mal ein Blockschaltbild:

Wir haben also einen uC. Später soll es wenn es möglich ist etwas kleineres sein.
Wir haben ein DCF77-Modul. Von Conrad oder Reichelt! Hab jetzt nur das von Conrad hier. Sollte sich ergeben das die unterschiedlich zu Handeln sind würde ich gerne über einen Jumper auswählen können welches Modul verbaut ist.
Des weiteren die RTC mit einem DS1307. Diese wird genutzt um auch ohne Signal eine recht genau Zeit zu haben und kann uns noch einen Sekundentakt spenden.

Verhalten soll sich das Shield im Grunde wie eine RTC selber.
Mal schauen wie man Zusatzfunktionen dort unter bringt.
Es währe ja auch gut zu wissen ob das DCF-Signal gut war, wann der letzte Sync war und und und.

So, hab es hin bekommen das die DCF-Zeit über den SoftI2C in die RTC geschrieben wird.

Problem war ja das die Variablentypen sich nicht vertragen haben.
Eine Umwandlung mit folgenden Code hat die lösung gebracht (natürlich hier aus dem Forum):

unsigned int BCDencode (unsigned int binval) {
unsigned int bcdval = 0;
for (int i=0; binval && i < sizeof(bcdval) * 8; i+=4) {
   bcdval += (binval % 10) << i;
   binval /= 10;
}
return bcdval;
}

Jetzt sieht meine Ausgabe so aus: (nicht wundern die 20 des Jahres bei der RTC ist hard gecodet Da dort das Jahr nur zweistellig ist.)
Datum Uhrzeit Wochentag und Unix-Time

DCF: 01.01.1970 00:04:03 5 243
RTC: 01.01.2070 00:04:03 05

DCF: 01.01.1970 00:04:04 5 244
RTC: 01.01.2070 00:04:04 05

DCF sync good

DCF: 18.12.2012 17:22:00 3 1355851320
RTC: 18.12.2012 17:22:00 03

DCF: 18.12.2012 17:22:01 3 1355851321
RTC: 18.12.2012 17:22:01 03

DCF: 18.12.2012 17:22:02 3 1355851322
RTC: 18.12.2012 17:22:02 03

Also wenn eh schon soviel Aufwand getrieben werden soll, dann würde ich statt DS1307 eine DS3232 RTC nehmen. Damit könnte man dann eine genauere lokale Uhr haben als den Arduino Quarz. Wie man nächster DCF77 Artikel zum Projekt hier DCF77 Project | Blinkenlight zeigen wird, könnte man dann damit die Empfängerseite noch besser bauen. Also wenn schon soviel Aufwand, dann aber richtig :wink:

Außerdem würde ich die Möglichkeit vorsehen, daß das Shield auch noch wenigstens einen Interrupt Ausgang und einen Enable Eingang hat.

Hmm, erstmal noch mal zur Info :
Ich kleiner Man, der nix kann!

OK DS3232!
Hab son Ding nicht hier.
Ist der Unterschied von der Steuerung her groß?
Hab mir grad mal das Datenblatt angeschaut. Sieht ja schon etwas anders aus. Ob ich damit dann noch klar komme?
Und gibt es den nur als SMD?

Deinen Satz:

Damit könnte man dann eine genauere lokale Uhr haben als den Arduino Quarz.

Verstehe ich nicht.
Wieso genauer als der Arduino-Quarz. Ist doch der auf der DS1307 der hier wichtig ist. Oder sehe ich hier was falsch?
Der DS3232 braucht keinen externen Quarz?

Und wofür den Enable Eingang?
Und wofür der Interrupt Ausgang?

ps: Per Jumper kann ich den Sync-Interval einstellen und das DCF77-Modul wird per Pin nur eingeschaltet wenn es auch gebraucht wird.

DS3232 ist mehr als Faktor 10 genauer da temperaturkompensiert. Das Teil hat einen eingebauten Quarz. Die Ansteuerung ist ähnlich aber nicht genau gleich. Wenn Liefergeschwindigkeit nicht wichtig ist bekommst Du hier http://www.futurlec.com/Mini_DS3232.shtml sehr günstige fertige Module.

MueThoS:
Eine Umwandlung mit folgenden Code hat die lösung gebracht (natürlich hier aus dem Forum):

unsigned int BCDencode (unsigned int binval) {

unsigned int bcdval = 0;
for (int i=0; binval && i < sizeof(bcdval) * 8; i+=4) {
   bcdval += (binval % 10) << i;
   binval /= 10;
}
return bcdval;
}

Code-Künstler mit künstlerisch besonders wertvollem Code am Werk?

unsigned int Dec2BCD (unsigned int dezimal) {
  return((dezimal / 10) * 16) + (dezimal % 10);
}

Irgendwie bin ich ein Code-Kunstbanause, der die ganzen Bitschiebereien gar nicht zu würdigen weiß!
:wink:

wenn du nicht unsigned int geschrieben hättest, sondern uint8_t oder byte, wäre dein Code gut (genug, für 2 BCD Digits ) :wink:
Weil der Compiler dein *16 richtig ( als shift Operation ) versteht.

Ansonsten ist dein Code das Gegenstück zu meinem

   return (ram>>4)*10 + ram&0x0f;

BCDEncode ist auch für Maschinen geeignet, bei denen ein int ein beliebiges Vielfaches von 8 bit groß ist.
In einer RTC Library ist das natürlich "Kunst" ( sonst könnte es weg ).

Aber generell hat MueThoS Recht, ein DCF-Shield braucht (am einfachsten) auch eine RTC, damit man nach Reset keine 2-3 Minuten oder länger warten muss, bis man die Zeit lesen kann.

Würde mich übrigens theoretisch interessieren, wie man einen Sekunden-Puls auf die richtige Millisekunde genau synchronisiert kriegt, und wer (GPS ?) einem das bestätigen kann ?

Ohne solche Anforderung ist die DS1307+DCF Kombi allemal genau genug, schätze ich.

So ich fang dann nochmal von vorne an! :0
Da ist mir zum ersten mal mein MAC mal so richtig abgeschmiert.
Und obwohl ich regelmäßig auf Speichern gedrückt habe ist alles was ich gestern ab 17:30 gemacht habe weg

michael_x:
Würde mich übrigens theoretisch interessieren, wie man einen Sekunden-Puls auf die richtige Millisekunde genau synchronisiert kriegt, und wer (GPS ?) einem das bestätigen kann ?

Ein bisschen was dazu schreibt die PTB dazu hier:

Die handelsüblichen Decoder-Module liefern jedenfalls alle viel zu lange Bit-Impulse. Statt 100 und 200ms wie vorgesehen geben Pollin- und Conrad-Module viel längere Impulse, die oft 10, 20, 30 ms länger sind.

Wie exakt der Anfang des Impulses ist, keine Ahnung, aber wenn die Dauer des Impulses bei den Modulen oft 30 ms neben dem Soll liegt, dann würde ich auch bei der Signalisierung des Anfangs jedes Signals auch nicht von einer höheren Genauigkeit ausgehen.

Wie die PTB schon schreibt: Wer eine viel genauere Zeit per Funk empfangen möchte, der empfängt am besten die Zeit per GPS-Signal statt per DCF.

Wieso genauer als der Arduino-Quarz. Ist doch der auf der DS1307 der hier wichtig ist. Oder sehe ich hier was falsch?

Das hat mit Präzision zu tun. Ein UNO hat nicht einmal einen Quartz, der Resonator ist so ungenau, dass er für Zeitmessungen eigentlich ungeeignet ist. Aber ein DS1307 ist auch nur so genau wie ein Arduino mit Quartz, während ein DS3231 temperaturkompensiert ist und somit deutlich genauer läuft.

Der DS3232 braucht keinen externen Quarz?

Nein, der ist dort eingebaut.

Und wofür den Enable Eingang?

Ich denke, damit soll das Shield vom Strom getrennt werden können (wenn der Arduino sich zwecks Stromsparen schlafen legt), oder zumindest der enthaltene Kontroller soll sich auch schlafen legen.

Und wofür der Interrupt Ausgang?

Der DS3231 hat zwei programmierbare Alarm-Zeiten, die diesen Pin schalten können. Damit kann man z.B. den Arduino schlafen schicken und wird später wieder geweckt. Oder man kann zeitlich sehr genau Aktionen ausführen, indem der Interrupt-Handler damit aufgerufen wird.

OK OK,
ich verstehe was Ihr meint.

Aber ich muss klein Anfangen.
Wenn ich dieses Projekt wieder nicht fertig bekomme dann habe ich demnächst eine Kiste Bastelkram zu verkaufen!
(Jetzt hilft mir wahrscheinlichg keiner mehr weil alle die Kiste günstig kaufen wollen :relaxed: )

Ausserdem reicht der Quarz der RTC aus wenn diese in regelmäßigen abständen neu gestellt wird.
Und dies passiert ja dann automatisch.

Das DCF-Modul wird auf jeden Fall schon mal Stromlos gemacht wenn nicht gesynct wird.

Frage:
Macht es sinn die RTC auch vom Strom zu trennen und nur zu aktivieren wenn man etwas auslesen oder rein schreiben will.
Wird dann die Knopfzelle schneller lehr? Oder macht das keinen Unterschied?

hi, muethos,

Aber ich muss klein Anfangen.

recht hast Du, laß Dich nicht durcheinanderbringen. extrem genau ist ja lustig, wenn man's braucht, aber wie oft braucht man's? ich überleg schon lange wegen einer equinox-uhr, aber wenn die mal um eine sekunde falsch geht, wen kümmert's?
was ich schön finden würde, weil's bei shields immer ein problem ist, wäre die möglichkeit, jeden ausgang des shields mit jedem pin der steckleiste zum arduino verbinden zu können. also eine stiftleist parallel zu den 4 stapelleisten des shields und die jeweils zusammengelötet. dann kann man zb, wenn's 3 anschlüsse sind (und die auch nur zu einer 3-er-stiftleiste führen), mit kleinen drahtbrücken jeden ausgang der uhr mit jedem pin des arduino verbinden.
und falls ich arduino-pins brauche, die es nur einmal auf dem uno gibt, und der von einem anderen shield benutzt wird, nehm ich einen mega, da ist ja alles mehrfach vorhanden, und geh' vom shield mit einer drahtbrücke direkt zum mega.
ich weiß' nicht, ob da jetzt was dagegen spricht, aber platzproblem sollte es bei diesem shield keines sein, die kosten sind lächerlich, und es erweitert Dein projekt um eine schöne komponente.

und gleich zum thema: ich weiß jetzt nicht, ob I²C "bestimmte" pins des uno braucht, aber man könnte in diesem fall mal drüber nachdenken, auch weil Du ja sowieso einen mC im shield verbaust, auch andere protokolle zu verwenden, vielleicht gar auswählbar, die flexibler sind. aber das ist schon viel mehr aufwand als die pin-geschichte vom ersten punkt.

viel spaß jedenfalls bei der sache und
lg stefan

Macht es sinn die RTC auch vom Strom zu trennen und nur zu aktivieren wenn man etwas auslesen oder rein schreiben will.

Nein, eigentlich nicht, aber es könnte Sinn machen, die CPU zumindest schlafen zu legen oder ganz abzuschalten, denn die verbraucht deutlich mehr Saft als die RTC. Deshalb kam der Vorschlag, eine Enable-Leitung vorzusehen.

Wird dann die Knopfzelle schneller lehr? Oder macht das keinen Unterschied?

Die Knopfzelle dürfte deutlich schneller leer sein, aber immer noch für ein Jahr oder so gut sein.

Wie man DCF77 mit einem handelsüblichen billig Modul auf 1/100s hinbekommt mache ich in meinem nächsten Blogpost vor. Das würde auch auf 1/1000 funktionieren wenn man entweder deutlich mehr Speicher hätte oder beim Programmieren noch tiefer in die Trickkiste greift. Ich dokumentier es gerade.

Merke: wenn man es richtig macht sind die breiten Pulse kein Problem.

Aber: man kann nicht einfach so auf 1/1000s genau syncen. Grund: Licht Breitet sich in Luft mit weniger als 300 000 km/s aus. Damit sind die Signallaufzeiten plötzlich relevant. Insbesondere werden diese durch die Lufttemperatur beeinflusst. Um das wegzubügeln bräuchte man eine lokale Uhr die pro Tag deutlich weniger als 1ms abweicht. D.h. deutlich besser als 1ppm. Sowas ist nicht billig, dann nimmt man besser gleich einen teuren Empfänger oder ein gebrauchtes Trimble Thunderbolt Zeitnormal.

Hallo zusammen,
ich bin jetzt soweit das der uC des "Shields"

  1. Die DCF77 auswertet
  2. die RTC beschreibt und wieder ausließt
  3. in Power Down geht (wacht alle 8 Sekunden auf)
  4. Mit Jumper einstellbar jede Stunde oder ein mal am Tag neu synct.
  5. Das DCF77-Modul stromlos macht.
  6. Nach 300 Sekunden bricht der Syncversuch ab und spart wieder Strom
  7. Per Pin geweckt werden kann

Jetzt bin ich am I2C.
Er empfängt auf Adresse 24. tuts auch!
Ich glaube er sendet auch nur leider noch nicht so wie ich will.

Ich habe folgendes was ich übertragen will:
time_t rtcNow : Die Aktuelle Zeit in Unix-Style
time_t lastSync : Wann wurde zuletzt erfolgreich gesynct in Unix-Style

Eventuell:
time_t nextSync : Wann findet der nächste Sync statt in Unix...
time_t syncInterval : Interval der Syncversuche in Sekunden

Ich brauche jetzt aber mal Tips wie ich das mit der Umsetzung am besten mache!
Wenn ich einfach

Wire.requestFrom(24, 10);

mache weiß mein Shield nicht was du für Infos haben willst also müsste ich alles übertragen.
Dann weiß der Master aber nicht wievielt er zurück bekommt.

Ich brauche mal Anregungen wonach ich suchen muss!

Ich habe jetzt mal ein DCF77 Modul von Reichelt bestellt. Sobald das da ist habe ich dann eins von Reichelt, eins von Pollin und eins von Conrad. Ich werde die dann mal genau vergleichen und berichten welches die Beste Empfangsleistung bringt.

Ich komme einfach nicht weiter!

Ich habe tmElements_t tm
Hiermit kann ich mir z.B. tm.Year anzeigen lassen.
Soweit ich das verstanden hab muss ich jetzt mit Wire.write die Daten senden.
Ich wollte sie so senden das ein Sketch mit Standart RTC.Lib diese lesen kann.
Sowas in der Art?

 payload[0] = tm.Second;
  payload[1] = tm.Minute;
  payload[2] = tm.Hour;
  payload[3] = '0';
  payload[4] = tm.Day;
  payload[5] = tm.Month;
  payload[6] = tm.Year;
  
  

  // send data to the DS1307
  for (uint8_t i = 0; i < 7; i++) {
    if (Wire.write(payload[i])) ;
  }

Aber es kommt an:

2165/165/165 165:165:0

2165/165/165 165:165:0

Ich brauche echt Hilfe!
:roll_eyes:

Hallo zusammen,
wer versteht sich denn mit Eagle und kann mir mal bei dem Platinenlayout helfen?
Ich bekomme es einfach nicht hin.
Ich habe ein UNO-Board als Vorlage genommen.
Habe alles gelöscht was ich nicht brauche (hoffentlich nicht zu viel)
Und versucht meine Komponenten hinzu zu fügen.
Aber ich weiß nicht was ich für die Wiederstände auswählen muss (Bauform)
Und wie kann ich ihm sagen er soll eine Drahtbrücke zur not nehmen?

Platine.jpg

Hallo,
willst du ein Shield entwickeln oder einen stand-alone Arduino?
Bei ersterem: installiert dir mal das Adafruit Eagle Lib GitHub - adafruit/Adafruit-Eagle-Library: Slowly building up a collection of parts we use here ... This file includes some library parts from microbuilder.eu Most of 'em are either Eagle parts that I've changed a little to make them easier to solder, some are 'handmade' and a few are from microbuilder.eu Its released into the Public Domain - that means you can do whatever you want. We'd like it if you kept the author email/url in the part description, just so we can be alerted if there are errors. Enjoy!.
Darin sind Arduino Shields als Bauteile definiert.
Wenn du später eine Drahtbrücke einsetzen willst, wechsel mit der Leiterbahn doch einfach auf die Oberseite. Du solltest nur die Durchkontaktierungen dann später größer machen. Die Bauform der Widerstände hängt davon ab, ich setze immer 0207/10 (10mm Rastermass). Das passt für die 1/4W Kohleschichtwiderstände, die ich einsetze.
Gruß
Reinhard

Es soll ein Shield sein!
Allerdings mit einem mC drauf.
Ich weiß nicht ob es auch ein kleinerer tun würde, hab damit noch keine Erfahrungen.

Die lib werde ich mir mal anschauen.