Hallo, zum neuen Jahr eine neue DCF77-Uhr. Ok - nicht der absolute Innovationsschub, aber einige Features habe ich noch an die Uhr drangebastelt (bis der Flash voll war): - Die Uhr führt eine Plausibilätsprüfung durch und arbeitet auch ohne DCF-Signal (nachdem mindestens 1x erfolgreich synchronisiert wurde). - Die Uhr steuert ein 4-Zeilen-LCD. Man kann aufs LCD aber auch verzichten und den Chip in eine finstre Box einsperren. Dann bleibt sogar wieder Platz für neue Ideen. (Die Antwort auf die Frage "Wie liest man dann die Zeit ab?" folgt gleich.) - Die Uhr berechnet den aktuellen Sonnenstand sowie Sonnenauf-/untergang. - Es sind zeitgesteuerte Schaltfunktionen eingebaut: zu definierbaren Uhrzeiten können Portpins ein-/ausgeschaltet oder getoggled werden. - Verwendet wird ein mega8, aber sein SRAM ist für diese Aufgabe weit überdimensioniert. Daher stellt die Uhr als TWI-Slave 768 SRAM Byte zur freien Verwendung von aussen bereit. - Alle relevanten Daten (uncodiertes DCF-Signal, Uhrzeit, UTC-Zeit, Sonnenstandsdaten) können via TWI ausgelesen werden. Schreiben geht auch - erscheint aber nicht sinnvoll. Die Alarm-/Schaltfunktionen können per TWI gesetzt und ausgelesen werden. Gelesen werden kann hoffentlich auch der Quellcode, ich habe mich um eine Dokumentation bemüht. Vielleicht interessiert's ja doch ? mfg Michael S.
@Michael, ist ne sehr interessante Sache. Zu den Schaltzeiten wäre eine Ausnahmeregelung an Feiertagen und/oder Wochenenden wünschenswert. Sehr effiziente Codeschnipsel zu diesem Thema könnte ich beisteuern, aber nicht implementieren, da ich nur in BASIC programmiere. Falls Du Interesse hast, melde Dich einfach mal. Am besten direkt per Email über den Link (p-e-t-e-r) oben hinter dem Namen. Gruß, Peter
Hallo Peter, stell doch einfach mal hier rein. Michael S.
Hi Michael, ich habe die Sache noch in Arbeit, ist aber fast fertig. Außerdem habe ich alles in einem BASIC-Dialekt geschrieben der eigentlich nicht recht hier ins Forum passt. Ich habe bisher nur mit C-Control von Conrad gearbeitet, erwäge aber einen einstieg in AVR. Der Code ( C-Basic ) lässt sich also erst nach Anpassung in BASCom bzw. in C oder ASM verwenden, daher dachte ich wir sollten das erst mal unter uns direkt abhandeln. Später können wir das dann auch hier veröffentlichen. Zu klären wäre u.A. noch mit wievielen Stellen das Jahr verrechnet werden kann. Bei zwei Stellen kann ja nur von 2000 bis 2099 rechnen. Vierstellig würde mein Code jedoch 1900 - 2199 abdecken. ( Natürlich mit allen Schaltjahren und Ausnahmen ) Das DCF-Protokoll liefert aber nur Zwei Stellen, oder ? Für die Berechnung der Feiertage werden übrigens in BASIC NUR DREI 8-Bit Variablen an Speicher gebraucht. Gruß, Peter
Hallo Peter, > Außerdem habe ich alles in einem BASIC-Dialekt geschrieben der > eigentlich nicht recht hier ins Forum passt. Nicht ohne Grund. Wer mal mit einem AVR und Bascom oder AVR-gcc oder Assembler gearbeitet hat, der wird eine C-Control und sein/ihr Basic nicht vermissen. Aus Unkenntnis habe ich leider vor einigen Jahren auch diesen Umweg gemacht. > Zu klären wäre u.A. noch mit wievielen Stellen das Jahr verrechnet > werden kann. Nun, ein Byte = 0 .. 255. Das DCF-Signal transportiert 80 + 40 + 20 + 10 + 8 + 4 + 2 + 1 = ? Aber ob es diesen Veteranen noch so lange geben wird, das wage ich zu bezweifeln. > Für die Berechnung der Feiertage werden übrigens in BASIC NUR > DREI 8-Bit Variablen an Speicher gebraucht. 3 x 8Bit = 3 Byte ? Das ist o.k. Aber an Speicher mangelt es ja nicht wirklich. Eine Frage habe ich auch. Welche praktische Anwendung schwebt dir vor, wenn du Schaltzeiten an Feiertagen definieren willst ? Was mir dazu nur einfällt: Alljährlich am Karfreitag um 12.00h die Kirchturmglocken läuten lassen. Dass man Wochentage bereits definieren kann, das hast du sicherlich gesehen? mfg Michael S.
> Welche praktische Anwendung schwebt dir vor, wenn du Schaltzeiten an > Feiertagen definieren willst ? Ich denke umgekehrt wird ein Schuh draus: Schalte an Wochentagen wenn Werktag, also ausser an Feiertagen
Hallo Karl heinz,
> Schalte an Wochentagen wenn Werktag, also ausser an Feiertagen
Diese Problem zu lösen wäre sicherlich ungleich einfacher, als
bewegliche Feiertage zu bestimmen.
Wie war das da noch mit Ostern ?
Irgendwann vor einem Vollmond - oder danach ...
Und an Ostern koppeln sich dann doch die übrigen Feiertage.
Aber wie ermittelt man den Zeitpunkt des Vollmondes ?
Das ist vermutlich ähnlich aufwändig wie die Ermittlung des
Sonnenstandes.
Die Formel zur Berechnung des Heiligabend und Tages der Arbeit kommt
möglicherweise ohne Kenntnis der Mondphase aus.
mfg
Michael S.
Hi Michael > Aus Unkenntnis habe ich leider vor einigen Jahren auch diesen Umweg gemacht. OK, dann kennst Du das Ding ja wenigstens > Nun, ein Byte = 0 .. 255. Das ist nicht so gut, aber ich denke mal die ersten zwei Stellen wird man berechnen können. Muss ich mal drüber nachdenken. Sonst ist der Kalenderbereich ja doch etwas eingeengt. ( Nur noch gut 90 Jahre, naja, mir würde es ja reichen ) Ich müsste halt den Code dann noch mal auf Jahr = Zweistellig umstellen. Sollte aber keine Problem sein. > Aber an Speicher mangelt es ja nicht wirklich. Nicht bei AVR, aber bei der C-Control. Ich habe noch die alte 1.1er, bei der muss man mit 24 Bytes ( = 12 Words ) auskommen. Außerdem gibt es da glaube ich auch Unterschiede bei den Datentypen. Bei mir gibt es keinen Typ "Integer". Zwei Bytes sind bei mir schon ein WORD. Allerdings kann ich auf ein Word auch Byteweise und Bitweise zugreifen. Deshalb habe ich es so "umständlich" ausgedrückt. > Eine Frage habe ich auch. Bei mir geht es um die Steuerung von Rollläden. Die sollen an Feiertagen (Optional) erst mit einem Offset hochfahren. Auch sollte "Nicht öffnen vor" und "Spätesten schließen um" Anwählbar sein. Die Sonnenzeiten haben ja doch eine erhebliche Schwankungsbreite. Eventuell auch noch Option morgens "Spalt ziehen" vor dem öffnen. Damit ist auch die Frage von Karl-Heinz beantwortet. Im Moment denke ich die Uhr und die Steuerung sollten auf zwei Geräte verteilt werden, aber das steht noch nicht ganz fest. Das Hauptproblem ist eigentlich das Rechnen mit Float-Werten, Winkelfunktionen usw. für die Astro-Zeiten. Das kann die C-Control halt nicht. Gruß, Peter
Hallo Peter, > OK, dann kennst Du das Ding ja wenigstens Deswegen empfehle ich dir auch aus voller Überzeugung, über den C-Control-Tellerrand hinaus mal andere Welten anzusehen. Es zahlt sich aus (im wahrsten Sinne des Wortes). Ich selbst kenne "leider" auch nur die AVR's, aber es ist schon ganz beachtlich, was man bereits mit einem kleinen Tiny25 anstellen kann. Und der kostet ca. schlappe 1.50 Eur (natürlich nicht in der Apotheke). > Das Hauptproblem ist eigentlich das Rechnen mit Float-Werten, > Winkelfunktionen usw. für die Astro-Zeiten. > Das kann die C-Control halt nicht. Diese Probleme wirst du mit anderen Controllern auch haben. Da muss dann - wenn möglich - ein wenig getrickst werden. Oder du arbeitest in einer Umgebung, in der Bibliotheken diese Berechnungen notfalls bereitstellen (das kostet aber natürlich richtig Speicherplatz ...). Mit dem C++ Basic bist du aber schon wieder gekniffen. Kopf hoch und durch ... Michael S.
MoinMoin, > Aber wie ermittelt man den Zeitpunkt des Vollmondes ? > Das ist vermutlich ähnlich aufwändig wie die Ermittlung des > Sonnenstandes. > nein, ganz einfach! Sämtliche (kirchliche) Feiertage werden relativ von Ostersonntag berechnet. Problem ist also Ostersonntag zu ermitteln. Und da hat sich Herr Gauß was einfallen lassen: die Gaußsche Osterformel, die relativ einfach zu implementieren ist... http://de.wikipedia.org/wiki/Gau%C3%9Fsche_Osterformel Grüße Uwe
Hallo Uwe Berger, danke für den Tipp. Manche Probleme lösen sich ja doch deutlich einfacher als man denkt. Wenn man denkt - bzw. goggelt. mfg Michael S.
Hallo Peter und Karl heinz, schönen Dank für eure Anregungen, hier meine skizzenhaften Lösungen: zum Vorschlag von Karl heinz (Wochentage/Wochenende zu unterscheiden): Ist sicherlich sehr nützlich - und einfach zu implementieren. Anstatt den 'day of week' mit einer Ziffer 1..7 zu kodieren, wird einfach für jeden Wochentag ein Bit spendiert: Montag = Bit.0 .. Sonntag = Bit.6 Durch glückliche Fügung bleibt das 7.Bit frei (das wird ja verwendet, um anzuzeigen, dass dieses Datum als Filter herangezogen werden soll). Für diejenigen Tage, für die der Filter TRUE liefern soll, wird in der Maske ein Bit gesetzt: 0x60 liefert TRUE am Wochenende (+ Bit.7 versteht sich) 0x1F liefert TRUE an Wochentagen (dito). 0x10 zeigt an, das nach spätestens 24 Stunden Wochende ist ... Um Peters Idee mit den Feiertagen umzusetzen: Im 'day of month' (1..31) sind noch zwei Bit unbenutzt (Bit.5 , Bit.6). Wenn man zum Programmstart und von da an jeweils täglich um 00:00 berechnet, ob dieser Tag ein Feiertag ist - und dann das Ergebnis in Bit.5 (wenn Feiertag) und Bit.6 (wenn nicht Feiertag) schreibt, dann könnte man diese beiden Bits als Filterbedingung heranziehen: Als Tagesdatum 0x20 liefert der Filter an jedem Feiertag TRUE. Als Tagesdatum 0x2F liefert der Filter TRUE an jedem Feiertag, der das Datum 15 hat. Als Tagesdatum 0x30 liefert der Filter TRUE an einem Nicht-Feiertag. Und wenn wir schon dabei sind für die Abergläubischen: Wenn Tagesdatum 0x0D und DOW 0x10, dann liefert der Filter TRUE am Freitag, den 13. eines Monats. Jetzt höre ich von Peter den Einwand: Wenn meine Rolläden aber am Wochenende ODER an Feiertagen erst später aufgehen sollen. Da gibts zunächst ein Problem, weil alle Filter einer Alarmdefinition über ein logisches UND verknüpft sind. Aber die Lösung ist auch nicht weit: Es werden zwei unterschiedliche Alarmdefinitionen für den selben Schaltausgang definiert, und schon funktioniert alles wie gewünscht: 1. Alarm: Schalter 1 einschalten, wenn Feiertag und 08.00h 2. Alarm: Schalter 1 einschalten, wenn Wochenden und 08.00h Jetzt müsste Peter nur noch seinen Rechenweg für die Feiertage ins Netz stellen ... Und irgendwer alles zusammenfügen. Aber interessiert das hier überhaupt jemanden ? mfg Michael S. PS. an Peter: $SIM in Bascom könnte den lahmen Debugger auf Trab bringen.
Jetzt braucht man nur noch eine Formel welche die Feiertagsregelungen der einzelnen Bundesländer berücksichtigt. In Bayern (und Sachsen ?) muss natürlich auch nach "überwiegend katholische / überwiegend evangelische Bevölkerung" anhand der GPS-Koodinaten unterschieden werden. Schade dass Herr Gauss schon nicht mehr unter uns weilt :-(( ;-) Werner
Hallo Peter > Warum für jeden Tag ein Bit spendieren, ein Bit für "Wochenende" und > eins "Feiertag" reicht doch völlig aus. Da die Bits bezahlt sind, kann man sie ja auch benutzen. Und eine Selektion nach Wochentagen ist ja nicht schädlich. Wäre ich z.B. Friseur, dann hätte ich am Montag noch Wochenende ... > Einmal am Tag testest Du, wie Du auch schon sagtest, jeweils auf > Wochenende und Feiertag. Die Wochentage (und damit das Wochenden) sind der Uhr immer bekannt. > Idealer Weise spendiert man noch zwei Schalter mit denen man die Option > für Wochenende und/oder Feiertag unabhängig ein- und ausschalten kann. Richtig. Denn Feiertage fallen glücklicherweise nicht immer auf ein Wochenende. Den Rest schaue ich mir später an. Leider ist mein Wochenende nämlich vorüber. mfg Michael S.
Hi Michael > Die Wochentage (und damit das Wochende) sind der Uhr immer bekannt. Das ist auch mir bekannt. Ist sogar bei C-Control so ;-). ( Unglaublich aber wahr ist aber das die C-Control den DOW von 0 .. 7 zählt. Die hat also eine 8-Tage Woche ) Aber der Controller weiß nicht das es sich um ein Wochenende handelt wenn er der DOW = 0 vorliegen hat. Also muss der DOW von heute mit einer "Maske" verglichen werden. ( Ist DOW von heute 6 oder 0, dann ist Wochenende ) Nichts anderes mache ich ja in meinem Code. Ich frage den von System bereitgestellten DOW ab und prüfe auf Null oder Sechs. Hast Du vermutlich in der kürze der Zeit nicht gesehen. Die Idee mit dem Friseurwochenende von So.- Mo. hat allerdings was für sich. Es gibt sicher noch mehr Berufsgruppen die kein "normales" Wochenende haben. > Da die Bits bezahlt sind, kann man sie ja auch benutzen. Klar, solange man noch genug davon hat ist das OK. Ich, als geplagter C-Controller, muss da leider anders denken. Meine bezahlten Bytes beschränken sich auf nur 24 Stück. ( Den Stückpreis trau ich mich erst gar nicht zu nennen ) Daher muss ab und an auch "unsauber" programmiert werden. ( Siehe Variablenüberschneidung. Das ist bei mir leider Alltag ) Auch das einzeilige "IF" kann einen manchmal zur Verzweiflung bringen. Ist halt so. Also dann bis zum nächsten mal. Gruß, Peter
Hallo, im dcf_77.c steht folgendes: // PD.2/3 INT0, INT1 // hier wird die Uhr angeschlossen Pin-Belegung meines DCF77-Moduls. VDD Betriebsspannung GND Masse DATA DCF-Ausgang PON Power On/Down Mir ist nicht ganz klar, was ich an INT0 und INT1 anschließen soll. Kann mir jemand auf die Sprünge helfen? Danke und Grüße, wborck
Hallo ebenfalls, beide INT's werden genutzt, der eine reagiert auf eine rising edge, der andere auf eine falling edge. Daher müssen beide INT's mit dem Signalausgang des DCF-Moduls verbunden werden. Oder anders formuliert: INT0 und INT1 werden kurzgeschlossen - und einer von beidem mit dem DCF-Modul verbunden. Michael S.
Hallo Michael, hab´ mir schon gedacht, dass das so hingehört aber sicher ist sicher... Das DCF77 habe ich an mein STK500 angeschlossen. Leider kommt die Verarbeitung an folgender Abfrage nicht vorbei: ------------------------------------------ while (!(flag & (1<<DCF_MINUTE))); // solange warten, bis das Minutenflag gesetzt ist ------------------------------------------ Vor der Abfrage setze ich eine LED auf on und danach auf off. LED bleibt an, so dass die Verarbeitung in der While-Schleife hängt. Laut dcf_77.c wird ein Quarz benötigt: // PB.6/7 XTAL // der Quarz benötigt zwei Pin Leider habe ich keinen zur Hand, geht´s denn nicht ohne bzw. mit dem internen? Grüße, wborck
Hallo wborck, wenn die Uhr auch ohne DCF-Signal einigermaßen korrekt mitlaufen soll, dann ist ein XTAL schon notwendig. Man kann zwar an der OSCCAL-Schraube drehen und den RC-Oszillator versuchen zu kalibrieren ... Aber eine zuverlässige Uhr wird das dann eher nicht werden. Michael S.
Hallo Michael, ja, das ist mir schon bewusst, wundere mich aber, dass bei mir gar nichts geht. Ich werde erstmal ein wenig rumexpimentieren und hoffe, ich finde den Weg... :-) Grüße, wborck
Hallo allerseits, nachfolgend einige Überarbeitungen der DCF77-Uhr, die entstanden sind, nachdem ich das Programm für eine eigene Anwendung praktisch einsetzen wollte (die Version aus der Weihnachtszeit war ‘just for fun’ entstanden). - Die grundlegende Funktionalität der DCF-77 Uhr und der Sonnenstands- berechnung ist unverändert. - Es werden nun 63 Definitionen für Schaltzeitpunkte berücksichtigt. - Diese Definitionen können im Eeprom resetfest abgelegt werden. - Zusätzliche Definitionen können leicht nachgerüstet (aber nicht im Eeprom gesichert) werden. - Das TWI-Modul kann als Slave oder als Master agieren. - Es sind 70 "Schalt-"Pins adressierbar (davon 6 am Controller, der Rest auf bis zu 8 TWI-Portexpandern). - Anstelle von Schaltaktionen können zeitgesteuert Kommandos an TWI-Slaves versendet werden. - Die globalen Daten sind nun komplett in einem 2-dimensionalen Array abgelegt und per Pointer/Index adressierbar. - Alle relevanten globalen Programmdaten (Zeiten und Schaltdefinitionen) können via TWI gelesen und geschrieben werden. Zusätzliche Schnörkel: alle 15 Minuten wird ein Zeitsignal an einen Slave geschickt, der dann wie eine klassiche Uhr akustische Signale aussenden kann. Bei Sonnenuntergang/Sonnenaufgang wird ein Portpin gesetzt/gelöscht. Eine ausführlichere Beschreibung findet sich in der beigefügten Readme. Und der Programmcode ist auch dokumentiert. Michael S.
Hallo, ich habe mal in sun.c sun_calc(void){} eingesetzt (das rechnet natürlich nichts und führt wohl zu einer Endlos-Schleife bei der Sonnenaufganngsbestimmung) und schon wurden aus 9706 Byte Flash 7700 und völlig ohne die Sonnenberechnung 5300. Was mich so verwundert ist die Tatsache, dass dies soviel ausmacht (sin/cos/atan/asin Rechnereien) von sun_calc, denn der Quelltext ist am Ende nur 1276 Byte durch sun.c -> sun.lst belegt, der Rest von 3130 Byte wohl durch die Fliesskomma-Bibliotheken. Könnte man nicht eine Tabelle für den jeweiligen Standort berechnen, die Jahre wiederholen sich ja, sodass man mit einer Abweichungstabelle und ohne die Winkelfunktionen auskäme? Gruß Horst P.S. Man kommt in sun_calc auch mit 5 statt 20 double Variablen aus, wenn man nur die zur Zeit nötigen nutzt das spart zusammen mit dem direkten Einsetzen von julian_day() und dezimal_day() 222 Byte, aber eben nicht mehr :-(
Ebenfalls hallo, auch wenn der Quelltext schlank aussieht, die trigonometrischen Funktionen sind natürlich nicht das, was ein 8-Bit-Controller am liebsten rechnet. Versuch doch mal, nur mittels Addition und Subtraktion einen Sinus zu berechnen. Das wird ein langer Rechenweg. Und die kostet entsprechend viel Speicher. Aber auf einem mega168 ist ausreichend davon vorhanden. Tabellen sind unflexibel, weil sie immer nur für einen Standort korrekt sind. Und Speicher kosten sie auch. Noch eine Anmerkung zum letzten Quellcode. Bevor ich den ins Netz gestellt habe - hatte noch mal eben schnell einen Watchdog eingebaut. In der Annahme, dass er nur nützlich sein kann. Leider bereitet er aber Probleme, die Uhr hängt sich manchmal auf und reagiert nicht einmal mehr auf einen RESET. Den Fehler habe ich bislang nicht gefunden (aber auch nicht ernsthaft gesucht) - ich habe den Wachhund einfach entlassen. Michael S.
Hallo, ich finde die Verwendung einer ortsbezogenen Tabelle nicht schlecht, da ich nicht mit dem Kollektor auf Reisen gehe ;-) und die Genauigkleit der von Dir verwendeten Formel mit 0.01 Grad für die nächsten 40 Jahre http://de.wikipedia.org/wiki/Sonnenstand muss ich ja nicht unbedingt einhalten. Bei Verwendung als Reisewecker müßte man ja auch die Koordinaten per GPS einlesen können. Ich habe eine Frage bezüglcig togglen. Wenn ich einen Modus 3 (umschalten) -Alarm setze, beim dem die Minute durch setzen des Bit7 nicht berücksichtigt werden, dann schaltet der entsprechend Ausgang nun jede Minute um, oder wie oder was? Ich dachte zuerst klasse, für eine Stunde einschalten und schaltet sich selber aus, aber dem ist nicht so und ist auch viel zu unflexibel. Also muss ich zwei Plätze belegen, einer der einschaltet und einen der diesen später wieder ausschaltet. Eine dumme Frage, wozu brauchen Alarmzeiten das Jahr, man kann doch am 1.1 eines Jahres ( oh ein Feiertag ) alle beweglichen Feiertage neu berechnen, oder will jemand seine Silberhochzeit nicht verpassen (Hochzeitstag ist jedes Jahr...) eine gespartes Byte bringt doch was. Ich denke immer noch an sowas wie 03:17 Uhr Waschmaschine ein, 155 min Laufzeit. Dann wäre die 155 im jetzigem Jahr-Byte eine Laufzeit in Minuten. In dem einfach dieser Alarm den Schaltbefehl sendet, sich selbst auf die die neue Alarm Zeit (+155 min) einstellt und nach Ablauf von dieser , wieder 155 vorstellt und den Ausgang abschaltet. Gruß Horst
Hallo Horst, bei konstantem geographischen Standort reicht eine Tabelle sicherlich aus. Auch die Genauigkeit mit 2 Nachkommastellen ist übertrieben, aber sie fällt ohne Mehrkosten mit ab. Der Vorteil der Nachkommastellen ist, dass man bei jedem Minutenwechsel an der Veränderung der Anzeige erkennen kann, dass das Programm arbeitet. Und der Vorteil der Berechnung in einer Funktion ist, das nicht jeder Anwender (sofern es mehr als einen gibt) eine Tabelle für seinen Standort erstellen muss. Der Nachteil ist der Speicherbedarf. Was willst du bei Verwendung als Reisewecker mit die GPS-Koordinaten anfangen, wenn du sie (die Koordinaten) nicht an eine Funktion zur Berechnung des Sonnenstandes weitergeben kannst ? Zur Logik des Schaltens: Wenn mindestens EINE der gesetzten Bedingungen erfüllt ist, dann wird ein Schaltvorgang (ein/aus/toggle) ausgelöst. Wenn du als einzige Bedingung "alle Wochentage" definierst, dann ist diese Bedingung zu jeder Minute erfüllt und es wird zu jedem Minutenanfang geschaltet. Wenn du stündlich zu einer bestimmten Zeit umschalten willst, dann legst die NUR die gewünschte Minute fest - und als Modus "toogle". Nun wird genau dann getoggelt, wenn die angegebene Minute mit der Uhrzeit übereinstimmt, also jede Stunde einmal. Ob man das Jahr als Schaltbedingung benötigt, das ist in der Tat unwahrscheinlich. Da die im Hintergrund stehende Funktion in einer Schleife arbeitet, ist es aber völlig egal, ob sie 7 oder 8 Bedingungen abfragt. Im Zweifelsfall wähle ich in solchen Fällen die flexiblere Lösung. Vielleicht will ja wirklich jemand an seine Goldenen Hochzeit erinnert werden. mfg Michael S.
Hallo! Bastel gerade mit deinem Programm ein wenig rum. Was muss ich hier vertauschen damit ich ein Invertiertes Signal auswerten Kann?
1 | #ifdef M168
|
2 | EICRA = (1<<ISC11 | 1<< ISC10 | 1<< ISC01);// Rising INT1, Falling INT0 |
3 | EIMSK = (1<<INT1 | 1<< INT0); // INT0 / INT1_isr enablen |
4 | #endif
|
Danke Denny
Hallo Horst, ein Lapsus meinerseits: Zur Logik des Schaltens: > Wenn mindestens EINE der gesetzten Bedingungen erfüllt ist, dann wird > ein Schaltvorgang (ein/aus/toggle) ausgelöst. Das ist natürlich Käse! Wenn JEDE der GESETZTEN Bedingungen erfüllt ist, dann wird ein Schaltvorgang ausgelöst. Beispiel: gesetzt: 12h 30min Geschaltet wird wenn GENAU 12h UND 30Minuten! Hallo Denis S. weiß ich nicht auswendig, habe kein Handbuch zur Hand, aber vermutlich: EICRA = (1<<ISC01 | 1<< ISC11 | 1<< ISC11); (ohne Gewähr) mfg Michael S.
Hallo, Nur bei einem Reisewecker wäre der Standort variabel und viele Alarmzeiten machen dann für mich weniger Sinn. Mir ist schon klar, dan man die Tabelle auch für jeden Standort auch erzeugen lassen muss, was umständlicher ist.Man könnte ja ein javascript mit document.write als Text in ein Fenster schreiben.... Ist ja nicht wichtig. Wenn schon soviel seriell genutzt wird, reicht es doch bestimmt noch für ein Eeprom mit z.B. 8k-Byte per TWI oder SPI. Denn 70 Ausgänge mit 63 Schaltzeiten passt nicht wirklich zusammen ;-) Auf dem ausgelagertem Eeprom könnten ja bis zu 1000 Schaltzeiten gespeichert sein, aber man kann es auch noch anders nutzen. Mir schwebte dann etwas wie in http://www.mikrocontroller.net/articles/Soft-PWM vor. Also eine Liste für die 70 Schaltausgänge und wann diese das nächste Mal und im welchem Modus (Byte 7) geschaltet werden sollen, wie Du auch beschrieben hast, der letzte, der sich auf diesen Kanal und Schaltzeit bezieht gewinnt. Eigentlich braucht man eine Liste die nach Schaltzeiten aufwärts sortiert den Schaltkanal/Modus angibt, aber ich will jeden Kanal ja nur einmal vorkommen haben.Dafür reicht ein Bitfeld. Innerhalb einer Minute kann man sicher aus 1000 Einträgen, den nächsten Eintrag für den/die gerade abgearbeiteten Schaltka nal/äle finden. Damit müsste die CPU auch länger schlafen zu legen sein können. Die braucht ja jede Sekunde nur einmal die Zeit korrigieren und LCD ansteuern und Sonnenstand berechnen und jede Minute, falls nötig,den/die jeweiligen Kan-al/äle schalten und nur dann die Tabelle der Einträge nach diesen durchsuchen, die zeitlich dahinterliegen. Das wäre eine üppige Schaltzentrale.Die das eigene Eeprom freilässt.Externe Eeprom sind doch datensicherer.Da kann 1,9 Jahre jeden Minute einen Speicherplatz ändern statt nur 69 Tage lang. Gruß Horst
Hallo! Benutze das DCF-Modul von Conrad und bekomme irgendwie keine Verbindung. Habe beide Ausgänge probiert und im Display bleibt immer "wait for sync" stehen. Hat einer eine Idee von euch? Gruß Denny
Hallo, kannst Du denn Spannungen an DCF / *DCF messen, die sich ab und an ändern. In einer Minute sollten schon ein paar Änderungen sichtbar sein. Ist die Antenne quer (orthoganal) zur Richtung Frankfurt/Main ausgerichtet?.Ist die Antenne mindestens 1 m weg von jeder elektromagnetischen Störung (Computernetzteil,Monitor (Zeilenfrequenz 50-85 khz), Fernseher ...) Hast Du 20 min Geduld gehabt? Man kann scheinbar viel Spass mit DCF 77,5 khz haben. Gruß Horst
Hallo, und überhaupt, passt es nicht hierher.. Suchen: http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=DCF+77
Hallo Michael (Gast), habe Deinen Beitrag mit gr0ßem Interesse gelesen. Die Idee und die Software ist auch gut. Ich habe mich mit Deinem Source intensiv beschäftigt und wollte auch mal die Hardwareseite kennenlernen. Hast Du die Schaltung passend zum Source? Habe versucht den Source passend umzu- stricken. Sehr Zeitintensiv und bisher gesamt noch nicht gelungen. Ich habe auch schon DCF77 auf ATMEGA8/16/32 umgesetzt. Dein Source im Original einzusetzten und zu testen würde mich reizen. Melde Dich doch mal - wäre nett. Gruß Adrian
Hallo Adrian, eine (aus)gedruckte Schaltung habe ich nicht (nur im Kopf). Die Schaltung ist aber relativ trivial: - DCF-Signal an INTO und INT1, - XTAL wie üblich, - das LCD wie in lcd.h beschrieben. Da das Programm mehr als 8Kb benötigt, habe ich zuletzt einen Mega168 einsetzten müssen. Zur Software: Da ich selbst wissen wollte, ob das Programm fehlerfrei schaltet und auch Fehler im DCF-Signal gutmütig wegbügelt, habe ich mir im Sommer eine Debug-Ausgabe über die RS232-Schnittstelle auf einen USB-Logger eingebaut. Und logge jede Minute die ausgebenene Zeit, das DCF-Signal, ggf. die Fehlercodes und die Schaltvorgänge. Dadurch habe ich noch einige Fehler finden können. Im Moment laboriere ich am DCF-Empfangsteil. Versehentlich hatte ich das Gerät zu nahe am Fernseher stehen. In der Log-Datei konnte ich dann sehen, wie der Empfänger mit Fehler zugemüllt wurde - und am Ende die Uhr teilweise aus dem Tritt gerät. Was nicht sein sollte. Die Logik des Empfangs und der Neusynchronisation auf das DCF-Signal habe ich mehrfach umgestellt - aber zufriedenstellend ist das Ergebnis noch nicht. Ich befürchte fast, hier muss ein komplettes Neudesign her. Da die Resonanz auf meinen Beitrag verhalten war, habe ich die Gemeinde mit meinen Programmierübungen nicht weiter belästigen wollen. mfg Michael S.
Hallo Michael, da ich noch Anfänger bei C, WINAVR und Studio 4 bin, habe ich noch ein paar Fragen: 1. Es sind *.c Dateien vorhanden (DCF77, Sun, etc.) 2. Es sind *.h Dateien vorhanden (sun.h, etc.) Wenn ich studio4 BUILD angebe, dann kommt im Ablauf die Fehlermeldung 304: undefined reference to "Sun_display" Build failed with 57 errors and 0 Warnings Die Hauptdatei ist DCF77.c Ich weiß nicht mehr weiter. Kannst Du mir helfen? Gruß Adrian
Hallo Adrian, sun_display() wird in main() aus dcf_77.c aufgerufen. Offensichtlich ist die Funktion sun_display() in main() unbekannt. Sie steht in sun.c. Es muss also in main() - bzw. in dcf_77.c darauf hingewiesen werden, dass die Funktion extern ist. Indem man sun_display() in der Liste der Prototypen nennt oder indem man dasselbe letztlich über das Einbinden einer Headerdatei macht. Was bei dir genau schiefläuft, das kann ich nicht sagen, da ich aus dem Studio nur in Assembler programmiere. Alles in C mache ich über WINAVR. Vielleicht versuchst du es auf diesem Weg ? Da ich gerade einige Dinge im Programm geändert habe: - Logdateien zur Fehlersuche - geänderte Empfangslogik wegen Fehler bei gestörtem Empfang füge ich den aktuellenm Stand einfach mal bei. Unter WINAVR kompiliert der Code (zumindest heute Vormittag noch) ohne Murren. Es ist auch eine Log-Datei vom Sonnabend-Sonntag beigefügt. Der Wechsel der Sommer- auf die Winterzeit. Ob dieser Wechsel funktioniert, das interesssierte mich. Ab 18.00h beginnt das Loggen. Ab 22.00 bis 00:15 ist die Glotze eingeschaltet - Empfang fast zu 100% gestört. Danach wird um 02.00h das A1-Signal (Ankündigung der Sommerzeit) empfangen. Und die Uhrzeit springt nach 02.59 wieder auf 02.00h. Wie es sein sollte. Die übrigen Einträge zeigen das Protokoll der Schaltvorgänge. mfg Michael S.
Hallo Michael, für die Synchronisiation von RTC's habe ich Teile deiner Software genutzt. Die Funktion ist ok. Bei Störsignalen kam es bei mir zu folgendem Phänomen: Es wurden mehr DCF-Impulse empfangen als vorhanden sein dürften. Dabei wird in der Routine "DCF_save_bit" über das vorgesehene Array hinaus der Speicher beschrieben und führte zu Programmfehlern. Vielleicht hilft Dir der Hinweis. MfG Henry K
Hallo henry, das Problem hatte ich noch nicht. Im Zweifelsfall sollte man den Index der dcf_bits mit 63 UNDIEREN, dann kann er nie über die Arraygrenzen hinauslaufen. Und fehlerhaft ist das Signal ja eh schon. mfg Michael S.
Hallo Michael, in der Zwischenzeit habe ich einige Änderungen durchgeführt und das Ergebnis ist durchweg positiv. 1. Zwischen Empfangsmodul und MC habe ich einen OP als Komperator mit TP geschaltet. 2. Umstellung von Flankenerkennung auf Abtastung des IO-Pins, Abtastrate alle 10ms. Die Erkennung der Impulse und deren Länge erfolgt in einem 1ms Timer, der auch die Systemzeiten erzeugt. Gruß Henry
hallo henry..du hast also den code so verändert dass die ignal leitung des dcf-moduls nicht mehr an into/int1 liegt sondern einfach ein beliebiger Einagng des µC auf seinen Pegel abgefragt wird? könntest du den veränderten Code posten? mfg
Hallo allerseits, eigentlich ist ein DCF-Empfanger/Decodierer ja keine wirklich schwierige Aufgabe. Sofern das DCF-Signal schulbuchmäßig empfangen wird. Beim Loggen der Uhrzeit musste ich feststellen, dass immer wieder absonderliche Fehler im Signal auftraten - immer dann, wenn der Emfänger in der Nähe eines eingeschalteten Fernsehers (Röhrengerät) plaziert war. Das teilweise fehlerhaft Signal ist manchmal sogar mit blossem Auge an der Kontroll-LED des Empfängers wahrnehmbar. Meine ersten Versuche, das Problem in den Griff zu bekommen, waren leider nicht von nachhaltigem Erfolg gekrönt. Henry hatte den Hinweis gegeben, dass ein Array (in ungünstigen Fällen) überlaufen kann. Auch seinen Hinweis auf einen zwischen Empfänger und mc geschalteten Tiefpass habe ich umgesetzt. Aber erst die Umstellung auf völlig unabhängige Zeitzählung für DCF-Signal und interne XTAL-Uhr haben die Probleme beseitigt. Eine Synchronisation zwischen beiden Signalen findet nur dann noch statt, wenn mindestens 3 Minuten lang das DCF-Signal fehlerfrei ist (so in der Testphase). Im Normalbetrieb kann man die Synchronisationsabstände nach Belieben erweitern, das ändert aber nichts an der Tatsache, dass die Synchronisation im Grundsatz funktionieren muss. Durch Loggen des DCF-Signals und der Uhrzeiten habe ich das Programm getestet, es sind am Ende trotz mehrstündiger TV-Betriebes und ständiger Synchronisationsversuche keine Fehler mehr in der ausgegebenen Zeit aufgetreten. Im beigefügten Programmcode habe ich die vermutlich weniger interessierenden (aber dafür irritierenden) Schnörkel wie Sonnenstandsberechnung und Schaltfunktionen rausgelassen und die Funktionalität auf die reine DCF-Uhr beschränkt. Durch Auskommentieren von #define LCD sollte die Uhr zum Testen auch ohne LCD nur mit Debug-Ausgabe über die serielle Schnittstelle laufen. Sollten sich immer noch Fehler ereignen, dann wäre ein Hinweis hilfreich. mfg Michael S.
Hallo nocheinmal, in der letzten Programmversion hatte ich alle Tests mit dem Wert 0 in der Konstanten SYNCH_TIME durchgeführt. Leider hatte ich längere Synchronisationsintervalle nicht ausprobiert - und so kommt es, wie es kommen muss ... Daher als Anlage noch die geänderte dcf.c und dcf.h, damit sind auch längere Intervalle einstellbar. mfg Michael S.
Hallo Michel, Bei der letzten Version hast du vergessen die Datei Global.h mit anzuhängen. da ich nicht so fit bin in WinAVR schaffe ich es nicht sie passend zu ändern. Wäre incht schlecht wenn du das gesamte Paket noch einmal reinstellst. Mfg Kalle.
Hallo Karl-Heinz, die global.h habe ich tatsächlich vergessen. Peinlich. Ich liefere sie hier nach. Allerdings als Kopie aus meinem vollständigen Projekt. Hofftenlich gibt damit keine Probleme. Ansonsten läuft die Uhr jetzt ohne dass in den Logdateien Fehler erkennbar sind. mfg Michael S.
Hallo Michael, Danke für die Global.h, aber jetzt sind neue Probleme aufgetaucht. Das Makefile paßt nicht. Ein haufen Syntax Error und unbekannter Befehle. Kannst du nicht noch einmal das ganze Paket reinsetzen. Mit welcher Version von WinAvr arbeitest du? Datum? MfG Kalle.
Hallo Karl-Heinz, hier stelle ich dir den aktuellen Stand meines Programmes rein. Das ist allerdings das komplette Projekt mit allem Tüdel dran. Wenn dich nur die DCF-Uhr interessiert, dann musst du allen Schnörkel rauswerfen - oder mir einen Hinweis geben. Michael S.
Hallo Michael, ich bin gerade dabei Deine Uhr nachzubauen. Die Hardware mit dem DCF77-Modul, das LCD und der Mega88 spielt bereits. Aus Deiner S/W habe ich alles bis auf das LCD rausgeworfen. Ein Error ist geblieben: ../lcd.c:27:20: global.h: No such file or directory Wenn ich die Zeile auskommentiere, findet der Compiler einige LCD Prozeduren nicht mehr: ../DCF_77.c:777: undefined reference to `lcd_goto_xy' Dies allerdings nur im unteren Teil des Quellcodes. Hast Du eine Idee? Gruß Clemens
Hallo Clemens, eine spontane Lösung habe ich nicht. Du wirst an irgendeiner Stelle zu viel gelöscht haben ... Die global.h vermutlich nicht, denn dann kämen vermutlich mehr Fehlermeldungen ? Wenn ich am Wochenende etwas Zeit habe, werden ich mich mal ransetzen und bis auf die LCD-Routinen alles abspecken. mfg Michael S.
Hallo Clemens, als Anhang die reduzierte Version der DCF-Uhr. Ausser der LCD-Ausgabe sind alle anderen Option entfernt. Das Programm benötigt nun noch ca. 3700 Byte Flash und 80 Byte Daten. Läuft also ab einem mega48. Wenn Debugging-Information zugeschaltet werden (Anzeige von Fehlern auf dem LCD, Protokollierung der Daten via RS232), dann kommt man auf 4000 bzw. ca. 5000 Byte. Ich habe das Programm kurz auf einen mega168 gespielt - es läuft. Weitergehende Tests habe ich allerdings nicht durchgeführt. Viel Spaß - heute Nacht wird's spannend (wenn die Uhr auf Sommerzeit umschalten soll). Man wird sehen ... Michael S.
Hallo Michael, ich verwende ein MK3 von myAVR mit einem mega2560. Meinst du es ist möglich deine reduzierte Version so umzuschreiben das sie auch auf dem 2560 läuft? Bin Anfänger, würde mich also über Tipps sehr freuen... Gruss Fabian
Hallo Fabian, möglich ist das sicherlich. Aber es würde bedeuten, mit Kanonen auf Spatzen zu schießen. Denn wie ich oben geschrieben habe, das Programm benötigt in dieser abgespeckten Variante mal gerade 4kb an Speicher. Und wieviel davon hat der mega2560 ? Aber machbar ist es. Anzupassen sind lediglich die verwendeten Pins für das LCD und den DCF-Empfänger. Und vielleicht noch einige Registernamen. Da ich selbst noch nie einen mega2650 eingesetzt habe, wird wohl die Lektüre der Manuals notwendig. Übrigens ist der "größte" Controller, den ich bislang verwendet habe, der mega168 im Zusammenhang mit diesem DCF-Programm. Als ich mit den AVR's angefangen habe, habe ich mir als erstes 2 mega32 beschafft: die habe ich bis heute noch nicht benutzt. mfg Michael S.
Hallo Michael, du hast absolut recht damit das der mega2560 ein bißchen übertrieben ist. Ich habe mich für diesen Controller entschieden, weil er mir genügend Reserven bietet. Die Auswertung des DCF Signals ist nicht alles, es sollen noch Motoren und Sensoren gesteuert werden. Wenn am ende klar ist wieviel Speicher bzw. Pins benötigt werden, wollte ich mir einen passenden Controller suchen. Der mega2560 ist also nur zum experimentieren gedacht. Ist es richtig das es sich bei den von dir erwähnten Registernamen um die Register der Timer handelt? mfg Fabian
Hallo Michael, vielen Dank für die Modifikation des Source Codes. Ich habe es leider noch nicht durch den Compiler. Ich werde heute Abend noch einmal auf die Fehlersuche gehen. Gruß Clemens
Hallo Fabian, da ich den mega2560 nicht kenne, ist mir auch nicht klar, welche Fallgruben da lauern. Aber sicher sind alle Einstellung im Bereich des Timers und der Interrupts für INT0 / INT1 zu prüfen. (Ich habe gerade mal einen kurzen Blick ins Datenblatt des mega2560 geworfen, der hat ja Interrupts via INT0 bis INT7 ... Und die müssen alle irgendwie konfiguriert werden.) Der Timer muss halt am Ende wieder den gleichen Takt erzeugen, wie auf dem mega48/88/168. Alternativ könnte man natürlich das Programm entsprechend ändern ... Im Zweifelsfalle einfach mal den Compiler anwerfen und schauen, worüber er meckert. Und wenn er schweigt, dann schauen, ob das Programm funktioniert. Und wenn nicht, dann muss man überlegen, was die Ursache sein könnte. Ist halt manchmal ein mühseliges und zeitraubendes Geschäft. mfg Michael S.
Hallo Michael, nachdem ich einige kleine Hürden beim Compilieren nehmen musste, ließ sich der Controller schießen. Anbei zwei Fotos. Danke noch einmal. Gruß Clemens
Hallo Michael, Finde dein Program gut, Läuft auch ohne Problme solange ich kein Alarmzeit eingebe. Gebe ich eine Alarmzeit ein kommt die Uhr mit ERE:07. Hier mal der Ausdruck über RS232: 000000.0000000!.000000!.000000.000.00000.00000000! XTL: x 20 11:50-s-28.04.10 # 18 code: 0x7, err: timeout, bit_cnt, parity 11:50-s-28.04.10 slot: 01, rule: ---.---.127.---.---.---.070.003. -> switch: 70, action: toggle. Vieleicht hast du einen Tip. MFG Karl-Heinz
Hallo Karl-Heinz, > Läuft auch ohne Problme solange ich kein Alarmzeit eingebe Das ist schlecht. > 000000.0000000!.000000!.000000.000.00000.00000000! XTL: x 20 > 11:50-s-28.04.10 # 18 code: 0x7, err: timeout, bit_cnt, parity es wird kein DCF-Signal decodiert, die Bit-Zeiten werden nicht eingehalten, deswegen err:timeout. Deswegen gibts es auch die Paritätsfehler. Und die Uhr läuft (wenn sie denn überhaupt noch läuft) nach der XTAL-Zeit. Die Anzeige 'ERE:07' läßt vermuten, dass hier Speicherbereiche überlaufen, auf falsche Speicherbereiche zugegriffen wird. Ich nehme an, dass die Ursache in 'switch 70' steckt. Denn damit müßte ein Port 7 (63 + 7 = 70) am Controller angesprochen werden - den hatte ICH zumindest nicht definiert. Möglicherweise wird hier ein fehlerhaft (zu großer) Wert nicht korrekt abgefangen. Setze einmal den switch auf 64 anstelle von 70. Damit sollte dann auch ein real existierender Port am Controller geschaltet werden. mfg Michael S.
Hallo Michael, Danke für die schnelle Antwort. Das mit switch 70 war ein versehen von mir. 64 u. 65 ist Rs232. Habe jetzt mal 69 (PD.5) eingegeben. 001001.1110010!.110010!.000101.110.00100.00001000! XTL: x 20 13:27-s-28.04.10 # 1 code: 0x7, err: timeout, bit_cnt, parity 13:27-s-28.04.10 slot: 01, rule: ---.---.127.---.---.---.069.003. -> switch: 68, action: toggle. Das gleiche ergebnis. MfG Karl-Heinz
Hallo Karl-Heinz, ich habe mal in meinem Kommentar im Quellcode nachgesehen: Da habe ich geschrieben, dass z.Z. nur der switch #64 an PD.7 aktiviert ist !! Das Problem ist, dass kein "ganzer" Port mehr für Schaltaktionen frei ist. Somit muss man (ich) mühsam die switches auf die wenigen freie Portpins mappen. Da ich aber in der Regel einen Portexpander via TWI nutze (also mit den switches 0 .. 63 arbeite), habe ich nur einen Portpin zum Testen (und für einen lokalen Schalter) aktiviert. Wenn ich es recht erinnere, dann ist auch nur noch ein weiterer Portpin frei. Also noch mal ein Versuch mit #64 an PD.7. Wenn's nicht hilft, dann musst du das entstehende Problem etwas ausführlicher beschreiben. Denn an der Debugging-Ausgabe erkenne ich nur, dass kein gültiges DCF-Signal empfangen wird. mfg Michael S.
Hallo Michael, mit #64 wird PD.7 getoogelt.ist ok. Aber trotzdem, sobalt ich die schaltfunktion zum 168 sende geht er auf error. Selbst wenn ich dann die Schlatzeiten lösche(0x08, 0xFC) bleibt der Fehler. MfG karl-Heinz
Hallo Michael, habe vergessen zu schreiben, die Schaltzeiten werden auch gelöscht. MfG Karl-Heinz
Hallo Michael, Habe noch etwas festgestellt. Beim ersten Durchlauf Steht in der Debugging Ausgabe DCF, 001001.1000001!.101010!.000101.110.00100.00001000! DCF: d 61 15:41-s-28.04.10 resynch Beim 2. Durchlauf XTL 001001.0100001!.101010!.000101.110.00100.00001000! XTL: x 20 15:42-s-28.04.10 MfG Karl-Heinz
Hallo Karl-Heinz, grundsätzlich gibt es zwei Baustellen: 1.) die DCF-Uhr mit der Synchronisation auf das DCF-77-Signal 2.) die Alarmzeiten und das Schalten der Portpins/Senden von TWI-Daten Das hier betrifft 1.) > 001001.1000001!.101010!.000101.110.00100.00001000! DCF: d 61 > 15:41-s-28.04.10 resynch Die Uhr hat sich von einer fehlerhaften Zeitanzeige wieder auf die Zeit des DCF-77 (re)sychronisiert. Bleibt nur die Frage, warum die Zeit vorher fehlerhaft war. Dazu muss man sich das Protokoll der vorausgehenden Zeit ansehen. Während der Testphase habe ich über viele Tage die Protokolle geloggt und anschließend versucht, die Ursachen für aufgetretene Fehlermeldungen zu erklären. Viele Fehler sind mir nur in den Log-Dateien aufgefallen. Die richtige Umsetzung der Alarmzeiten ist das andere Thema. Dort scheint ja der Auslöser für deine Probleme zu stecken. Interessant sind hier im Protokoll die Ausgaben wie > slot: 01, rule: ---.---.127.---.---.---.069.003. -> switch: 68, action: toggle. (vermutlich liegt hier ein Tipfehler vor: 069.003 sollte zur Erlätuerung "switch: 69, action: toggle" führen) An dieser Ausgabe läßt sich erkennen, ob die Schaltzeiten und Schaltvorgänge so erkannt wurden, wie sie gemeint waren. Anschließend muss geprüft werden, ob auch die Umsetzung auf die Portpins bzw. den TWI-Bus korrekt erfolgt. Wenn ein Fehler auftritt (wie das vermutete Überschreiten von Arraygrenzen), dann hat das nicht vorhersehbare Auswirkungen und kann z.B. nur zu falschen Zeitangaben oder aber sogar zum Absturz führen. Theoretisch kannst du auch im Programm eine klitzekleine 'Verbesserung' vorgenommen haben ... Wie du siehst, ohne systematische Tests ist für mich das Problem schwer eingrenzbar. Ich will aber mein laufendes System mit deinen Daten füttern und schauen, ob es schlapp macht. Wenn nicht, dann schicke ich dir den aktuellen (eigentlich seit 4 Monaten unveränderten) Programmcode. Dauert aber etwas. Denn das kann ich im Büro nicht machen. mfg Michael S.
Hallo Michael, Hab noch einmal deine Zip ausgepackt und geladen. Dabei bleibt die Uhr stehen sobald die neue Sekunde kommt(DCF). Dann habe ich, da für die Uhr kein Slave vorhanden ist in der Global.h TWI_ADR_Zeitzeichen und Zeitzeichen abgeklemmt. Dann erkennt die Uhr die neue Minute und läuft. sonst habe ich keine anderen änderungen gemacht. Vielleicht mal ein Tipp wo ich sonst den Slave für die Uhr abklemmen kann. Bis wieder eine Alarmzeit geladen wird. habe mal 5 Zeilen mitgeschrieben. Logging on RS232 001001.0001100!.000110!.000101.110.00100.00001000! DCF: d 61 18:18-s-28.04.10 resynch 001001.1001100!.000110!.000101.110.00100.00001000! XTL: x 20 18:19-s-28.04.10 001001.0000010!.000110!.000101.110.00100.00001000! XTL: d 20 18:20-s-28.04.10 001001.1000010!.000110!.000101.110.00100.00001000! XTL: d 20 18:21-s-28.04.10 Hier habe ich dann die Alarmzeit geladen 001001.0100010!.000110!.000101.110.00100.00001000! XTL: x 20 18:22-s-28.04.10 # 1 code: 0x7, err: timeout, bit_cnt, parity 18:22-s-28.04.10 slot: 01, rule: ---.---.127.---.---.---.064.003. -> switch: 64, action: toggle MfG Karl-Heinz
Hallo Michae, Der Feher mit der Alarmzeit tritt auch auf wenn ich nur Zeit_Zeichen abklemme. Mfg Karl-Heinz
Hallo Michael, hängt alles am Slave von der Uhr aus gesehen. ein paar Fragen hierzu. PCF8574 oder PCF8574A, Hex adr vom Slave ist 0x10, ist das richtig? Habe einen Logic Analyzer dran hängen. Bei mir wird von der Uhr kein Telegram an den Slave gesendet. deshalb bleibt er auch hängen bei erkannter minute. Hab noch keine Lösung. Gruß karl-Heinz
Hallo Michael, Ich ruder wieder etwas zurück. Habe jetzt einen Slave drangehängt, hatte vorher die Alarmzeit ins Eprom geschrieben und siehe da die Uhr läuft ohne Fehler. Muß dann wohl mal meinen Master überprüfen. MfG Karl-Heinz
Hallo Karl-Heinz, am gestrigen Abend habe ich meine Uhr mit deinen Daten gefüttert: und ich konnte auch Fehlermeldungen erkennen. Allerdings war mir nicht klar, ob nicht eine Störung des DCF-Signals die Fehlermeldung erzeugt. Daher habe ich zwei Schaltzeitpunkte definiert und die Nacht über die Ausgabe aufgezeichnet. Einen typischen Ausschnitt habe ich als Anhang beigefügt. Wenn deine Fehleranalyse lauten würde: Nach Schaltvorgängen werden (meistens, nicht immer) Fehlermeldungen ausgegeben, aber das System hat keine erkennbare Funktionsstörung, nach 2 Minuten verschwindet die Fehlermeldung (das klappt natürlich nicht bei togglen im Minutentakt) dann kann ich einen korresponierenden Hinweis im Protokoll finden. Unerwartet sind hier (das habe ich bislang ignoriert) die Ausgaben wie in Zeile 29 und Zeile 43. Hier fehlt die Ausgabe der DCF-Bits !! Komischerweise gibt es auch keine Fehlermeldung. Und in der nachfolgenden Minute mißlingt der Vergleich des DCF-Signals mit der vorangegangenen Minute. Erst nach 2 Minuten fasst das System wieder tritt. Beruhigend ist, dass die Uhrzeit fehlerfrei weiterläuft und dass auch die Schaltvorgänge offensichtlich korrekt ausgeführt werden. Bleibt also als Ansatzpunkt der Programmteil, in dem die DCF-Bits ausgegeben werden (oder auch nicht). Von da aus kann man sich weiterhangeln. Im Augenblick habe ich dafür aber Zeit. mfg Michael S.
ich wollte im letzten Satz schreiben: im Augenblick habe ich dafür aber KEINE Zeit. mfg Michael S.
Hallo Karl-Heinz, wenn ich dich richtig verstanden habe, dann treten bei dir keine Fehler mehr auf ?? Allerdings habe ich inzwischen die Ungereimtheiten in der Protokollausgabe eingekreist: Wenn weniger als 58 Bit empfangen werden, dann erfolgt keine Ausgabe der DCF-Bits in der Log-Datei. Daher habe ich direkt vor dem Löschen der DCF-Bits (der letzten Minute) noch eine Abfrage auf Vollständigkeit der DCF-Bits eingefügt und setzte ggf. ein Fehlerflag. Nun erscheint die Fehlermeldung auch im Protokoll. Beim Sichten der nächtlichen Protokollierung fällt mir auf, dass der Fehler häufig (d.h. nicht immer !!!) bei Schaltvorgängen auftritt. Was die Fehlerfindung nicht gerade vereinfacht. Allerdings als Trost: die Uhrzeit läuft korrekt weiter und auch die Schaltvorgänge funktionieren (soweit ich es getestet habe). Trotzdem werde ich wohl über die Ursachen des Problems nachdenken müssen. mfg Michael S.
Hallo Michael, Bin wieder bei der Uhr. Die Uhr läuft prima solange ich nicht mit einem Master drauf zugreife. Sobald ich die Uhr jede Minute auslese und auch die richtige Zeit zurück bekomme, geht die Uhr auf error 07. Ich programmiere mit MikroPascal. Habe noch eine Frage: Habe einen PCF8574 drangehängt. Welche Hardwareadr. muß eingestellt werden. MfG Karl-Heinz
Hallo Karl-Heinz, der Error 0x07 bedeutet, dass Bits 0,1,2 im flag 'error' gesetzt sind. In der dcf.h kannst du nachsehen, welches die Fehlerursachen sind (ich weiss es nicht auswendig, aber ich glaube das sind Fehler aus der Prüfung der 58 DCF-Bits.) Allerdings greife ich häufig mit einem Master auf die Uhr zu, etwa um Alarmzeiten zu programmieren oder um sie ins Eeprom zu schreiben - das gibt keine grundsätzlichen Probleme. Arbeitet dein Master korrekt ? Kann es sein, dass dein Bus 'klemmt' ? (sind SDA oder SCL nach der Sendung ständig low - mal mit einer LED prüfen) Kannst du denn mit dem PCF8574 erfolgreich kommunizieren ? Was meinst du mit minütlichem Auslesen ? Um die Uhrzeit auszulesen, musste du die Uhr mit einer bestimmten Adresse (siehe read.me) ansprechen und 8 Byte auslesen. Dann wird dir die Uhrzeit geliefert. Also 0x08 und die Adresse senden, dann mit 0x09 8 Byte abholen. Die andere Frage: Die Adresse der TWI-Slaves ist frei einstellbar. Dazu gibt es #define TWI1 64 .... TWI8 0 78 xin alarm.c (?). Die Schalter mit der Nr. 0.. 7 werden an TWI1, die Schalter mit der Nr. 8..15 werden an TWI2 usw. gesendet. Wenn du den PCF8574 mit seiner Standardadresse 0x40 = 64 senden willst und meine Definitionen nicht verändert hast, dann sollten die Schalter 0..7 auf Adresse 0x40 = 64 ausgegeben werden. mfg Michael S.
Hallo Michael, Danke für deine ausführliche Hilfe, bei mir läuft jetzt alles. Nur noch ein Problem. wenn ich mit dem Master einmal pro Minute die Zeit auslese, geht die Uhr auf Störung.(Er:07). Hör ich mit dem Auslasen auf, fängt sich die Uhr wieder. Habe jetzt mal alle 10 min ausgelesen kommt die Error- meldung und wird dann nach einer minute wieder zurückgenommen. Kann ich mit leben. Tolles Projekt. MfG Karl-Heinz
Hallo Karl-Heinz, dein Problem, dass die Uhr nach dem Auslesen von Speicherbereichen (genaugenommen der Uhrzeit) in der Folgeminute Fehlermeldungen wirft, deutet darauf hin, dass bei Lesen Veränderungen in den Daten vorgenommen werden. Ich werde am Abend testen, ob das ein Problem des Programmes ist - oder eine "falsche" Abfrage. Ansonsten haben deine Fragen meine Nase auf ein kleines Problem gestossen. Was mir keine Ruhe gelassen hat - aber ich habe die Ursache gefunden. Das Problem war: durch eine unvollständige Plausibilitätsprüfung wurde in den Fehlermeldung bislang nicht angezeigt, wenn weniger als 58 DCF-Bits empfangen wurde. Dieser Fehler tauchte immer dann auf, wenn: - die rechenintensive Sonnenstandberechnung eingeschaltet war, - Alarmzeitpunkte erreicht waren und - die Protokollierung über die RS232-Schnittstelle aktiv war. Dann wurde länger als 1 Sekunde gerechnet bzw. Daten ausgegeben. Mit dem Erfolg, dass der DCF-MInutenbeginn, der zwar per Interrupt empfangen wird und ein Flag setzt, nicht rechtzeitig bearbeitet wurde und der Index für die DCF-Bits erst in der Sekunde 1 zurückgesetzt wurde. Dann fehlte in der Folgeminute ein DCF-Bit. Da es bislang keine Fehlermeldung bei einem unvollständigen DCF-Bit-Datensatz gab, war mir das Problem nicht aufgefallen. Lediglich die Tatsache, dass im Protokoll an manchen Stellen keine DCF-Bits ausgegeben wurden, hat mich auf die Fährte geführt. Das Problem ist nun durch eine Aufteilung der Arbeit zu Beginn einer neuen Minute gelöst: - Am Beginn der Minute wird das Display neu aufgebaut - am Beginn der 1. Sekunde werden die Alarmzeit getestet und ggf. geschaltet. - am Beginn der 2. Sekunde werden die Sonnenstandsberechnung ausgeführt. - am Beginn der 59. Sekunde wird geprüft, ob die DCF-Bits vollständig sind. Da mir zu Beginn der Fehlersuche die Logik der DCF-Synchronisation nicht mehr wirklich präsent war, habe ich - nach der Motto, 1 Bild sagt mehr als 1000 Worte - zuerst einmal ein Ablaufschema der Hauptprogrammschleife aufgetragen. Das Diagramm ist als DCF_Logik.pdf angehängt. Es zeigt den Ablauf des akuellen Programmes ! In den bisherigen Versionen wurde die Arbeit aus Sekunde 1 und Sekunde 2 zusätzlich zum Neuaufbau des Display am Minutenbeginn ausgeführt. Neu ist auch die Prüfung der Anzahl der DCF-Bits in der 59. Sekunde. Vielleicht hilft das Schema auch anderen beim Verständnis der DCF-Synchronisation. Beigefügt im zip.file ist auch noch eine Logdatei, die ein Protokoll von etwas mehr als 1 Stunde mit vielen Schaltvorgängen widergibt. Die Störungen entstehen vermutlich durch ein eingeschaltetes TV. mfg Michael S.
Hallo Karl-Heinz, folgender genereller Hinweis zur Abfrage der Zeit via TWI fällt mir gerade noch ein: Das Abholen der Daten erfolgt innerhalb einer ISR, das ist zunächst das Problem. Aber nicht nur theoretisch kann diese Abfrage genau dann erfolgen, wenn das Programm gerade dabei ist, die Zeit fortzuschreiben. Und dann bekommst du Daten geliefert, die zum einen Teil aus der alten und anderen Teil aus der neuen Minute bzw. Sekunde stammen. Beispiel: alte Zeit: 23:59:59 03.05.10 neue Zeit: 00:00:00 04.05.10 Angenommen, der TWI-Interrupt schlägt z.B. genau zwischen Minute und Datum zu. Dann liest du als Datum 00:00:00 03.05.10 Das ist genau um 24 Stunden daneben. Wenn du also (nicht nur zum Debuggen) die Zeit per TWI auslesen willst, dann müssen diejenigen Routinen, in denen die Daten geändert werden, durch Sperren / Freigeben der Interrupts atomar gemacht werden. mfg Michael S.
Hallo Karl-Heinz, als Hilfe zur Selbsthilfe zu deinem Ausleseproblem für die Uhrzeit hier die Frage, ob du richtig vorgegangen bist. Dazu eine kurze Erläuterung des TWI-Slave-Moduls. Es ist so eine Art trojanischen Pferd, das der Uhr implantiert ist. Die DCF-Uhr weiss nichts vom TWI-Slave - und verwendet ihn auch nicht. Das Modul arbeitet ausschließlich in der TWI-Interrupt-Routine. Wenn der Slave mit einem "write" angesprochen wird, dann interpretiert er das erste Datenbyte als Speicheradresse. Auf diese Stelle wird ein Pointer gesetzt. Wenn weitere Bytes folgen, dann werden sie lang weg sequenziell in den Speicher geschrieben, egal ob's Sinn macht oder nicht. Alarmzeiten und Uhrzeiten werden programmtechnisch nicht unterschieden, es sind jeweils Arrays der Länge 8 Byte. Genaugenommen handelt es sich um ein 2-dimensionales Array, wobei der erste Index der "slot" ist, der zweite die Byte-Nr. Diese Methode ermöglicht, beliebige Speicherbereiche der Uhr von aussen zu beschreiben und zu lesen. Das war wunderbar zum Debuggen. Etwa um den Übergang von Sommer- auf Winterzeit zu testen. Da habe ich der Uhr einfach geeignete Daten untergejubelt und geschaut, ob richtig reagiert wird. Aber es ist auch gefährlich, wenn das Prinzip nicht verstanden ist und man die Methode falsch einsetzt. Etwa, indem man mehr Daten schreibt, als ein "slot" lang ist. Dann überschreibt man nämlich den folgenden slot - die Folgen sind vorhersehbar. Der richtige Weg zum Auslesen der Uhrzeit ist: Zum Auslesen von Daten schreibt man zunächst genau 2 Byte: - das 1.Byte ist die TWI-Adresse des slave + ("write") - das 2. Byte ist die Speicheradresse des arrays, in dem die gesuchten Daten (etwa die Uhrzeit) steht. Nun steht der Pointer auf dem ersten Byte dieses Arrays. Achtung: Jedes weitere Byte, das du hier schreibst, überschreibt Daten der Uhrzeit !!!! Dann gibt es konsequenterweise Fehler in der Folgeminute. Zum Auslesen der Daten muss man nun lesend auf den Slave zugreifen - die Slave-Adr + ("read") senden und 8 Byte oder mehr einlesen. Beginnend von der Stelle, auf die der Pointer zeigt, werden nun die Daten eingelesen und via TWI an den Master abgeschickt. In den ersten 8 gelesenen Byte steht dann z.B. die Uhrzeit. An dieser Stelle ist es unschädlich, wenn mehr Bytes gelesen werden - es werden ja keine Daten verändert. Alles klar ? Alles richtig gemacht ? Wenn ja, dann suche ich nach Fehlern im Programmcode. mfg Michael S.
Hallo Karl-Heinz, deine Beobachtung war richtig. Es wird bei allen Zugriffen auf ein Zeitarray ein Fehler 0x07 ausgegeben. Hier steckt noch eine Zeile aus der Testphase im Programmcode, der darauf hinweisen sollte, dass die Uhrzeit via TWI geändert wurde. Und leider steckt darin auch noch ein kleiner Bug - der zu einer falschen Fehlermeldung führt. Das lockte natürlich auf eine falsche Fährte. file: TWI_master_slave.c ab Zeile 213 else if ((TWI_SLA_cmd > 0xEF) && (TWI_SLA_cmd < (0xF0 + CLK_ARRAYS))) { TWI_SLA_cmd -= 0xF0; ptr = &time[TWI_SLA_cmd][0]; // error |= ERR_TWI; // diese Zeile auskommentieren // richtig wäre die Zeile so gewesen: // error |= (1<<ERR_TWI); } Jetzt sollte die Uhr nach dem Auslesen der Zeit ohne Fehlermeldung weiterlaufen. mfg Michael S.
Hallo Michael, Habe die Änderung durchgeführt und läuft alles super. Falls ich noch etwas bemerke, melde ich mich dann wieder. MfG Karl-Heinz
hallo michael, läuft dein programm auf einem atmega8 + lcd 2x16. ich will nur uhr + datum aus dem dcf signal anzeigen lassen. das sollte doch problemlos möglich sein?! mfg benny
Hallo benny, am 27.03. hatte einen abgespeckten Programmcode eingestellt, der sollte auf den atmega8 passen. Es sind möglicherweise noch Register umzubenennen. Dazu einfach kompilieren - die Fehlermeldung stossen dich mit der Nase darauf. Und natürlich sind ggf. die Einstellungen für das LCD anzupassen. mfg Michael S.
hallo Michael S., ich hab den Beitrag hier mit interesse gelesen, nu hab ich zwei Fragen an dich, könntest du den Quellecode nochmal komplett als zip.File einstellen wie die letzte Version ist(LCD 4stellig) und hast du auch einen Schaltplan für das ganze zum nachbauen? Danke für deine Mühe Gruß Hein
Hallo hein, den (fast) aktuellen Programmcode (für eine 4-zeilige LCD-Anzeige) habe ich am 04.05. bereits bereitgestellt. Die einzige Änderung habe ich am 05.05. beschrieben: - es muss eine Zeile im TWI-Modul gelöscht werden. Einen Schaltplan gibt es nicht - aber in der readme habe ich in Worten beschreiben, wer mit wem zu verbinden ist. Es ist eigentlich auch ganz einfach: - das LCD wird so angeschlossen, wie in der lcd.h definiert, - TWI, RS232, Quarz und Power hat der Hersteller festgelegt, - das DCF-Signal wird an INT0 und (!) INT1 angeschlossen. mfg Michael S.
Hallo Michael, ich weiß garnicht ob du hier überhaupt noch reinschaust, aber ich versuch es trotzdem mal. Also ich hab da mit großer Interresse deine DCF-Uhr gelesen, nun hab ich deinen Code vom 05.05 geladen und versucht zu compalieren. bei mir kommen zwei error's im bezug auf TWI_master_slave.c - `F_CPU` undeclared (first use in this funktion) - (Each undeclared identifier is reported only once for each function it appears in.) kannst du mir oder vieleicht ja jemand anders hier einen Tip geben was ich da falsch mache. Warscheinlich mach ich hier nur ein dofer Fehler aber ich komm nicht drauf. Vielen Dank schonmal im voraus mfg Paul
ist definiert im Makefile: # F_CPU = 2000000 F_CPU = 3686400 # F_CPU = 4000000 mit C kenne ich mich aber auch nicht aus. Viel Glück.
Hallo allerseits, gelegentlich benötigt man in einem Projekt lediglich eine Zeitbasis, ohne all die zusätzlichen Funktionen, die in der bisher vorliegenden DCF-Uhr implementiert sind. Daraus ist der Gedanke entstanden, die Uhr auf die wesentlichen, zeitfortschreibenden Funktionen zu reduzieren, alles komplett in einem Modul zu kapseln und über definierte Funktionen auf das Modul zuzugreifen. Der Vorteil: man muß das Modul lediglich ins eigene Projekt einbinden und schon stehen Uhrzeit und Datum zur Verfügung. In der Readme.pdf sind weitere Details beschrieben, im Programmcode (in main.c) ist die Anwendung demonstriert. Michael S.
Hallo allerseits Hier gibt es noch einmal eine Überarbeitung des Uhrmoduls mit folgenden Veränderungen: - Es wird nur noch ein einziger Interrupt und damit auch nur noch ein einziger Eingangspin für das DCF-Signal verwendet. - Die Funktion DCF_New_Second() liefert nur dann ein TRUE zurück, wenn die Zeit wirklich fortgeschrieben werden muss (bislang konnten zum Minutenbeginn zwei Aufrufe erfolgen). - Bei Empfangsproblemen kann eine neue Funktion dabei helfen, Probleme im Timing des DCF-Signals zu erkennen, so dass die Programmparameter an das Signal angepasst werden können. Weitere Hinweise stehen in der Readme.pdf. Michael S.
Hallo Michel, Ich bin's mal wieder. Uhr läuft super. Wollte jetzt aber mal was mit Sonnenauf- und untergang machen. Nur die Zeiten sind sehr ungenau. bei sonnenaufgang -26 min und bei SU +44 min. Meine Koordinaten, wo ich wohne (52,23 10,42), sind deinen ähnlich. Geht es nicht besser oder ist noch ein Fehler vorhanden. Gruß Karl-Heinz.
Hallo Karl-heinz, zum Thema Sonnenstand bzw. Sonnenaufgang/untergang fallen mir zwei Anmerkungen ein: 1. Es gibt verschiedene Definitionen für den Zeitpunkt des Sonnenuntergangs, die sich in der Definition des Winkels (Elevation) unterscheiden, den die Sonne unter dem Horizont stehen muss. Den Winkel kann man im Programm beliebig definieren. Vergleiche der Programmausgabe mit anderen Angaben setzen immer voraus, das unter derselben Definition (Elevation) gerechnet wird. 2. Die Berechnung des Sonnenstandes fordert den ATMega ordentlich heraus. Platz für einen eigenständigen Algorithmus, der den Zeitpunkt von Sonnenuntergang/Aufgang berechnen kann, ist nicht mehr vorhanden. Daher habe ich den vorhandenen Rechenweg für den Sonnenstand genutzt und versuche, durch "Ausprobieren" verschiedener Uhrzeiten den Zeitpunkt zu finden, an dem der für Sonnenuntergang/Aufgang definierte Winkel gerade über/unterschritten wird. Die Berechnung wird übrigens nur 1x am Tag ausgeführt - und natürlich beim Programmstart . Im Laufe der Zeit habe ich feststellen müssen, dass manchmal Fehler in den Zeitangaben erkennbar sind (um bis zu 1h). Bei der Berechnung von Elevation und Azimuth sind mir keine Fehler aufgefallen. Resetet man die Uhr, dann werden plausible Werte für Sonnenaufgang/Untergang berechnet. Vor einigen Jahren hat einmal der Chefentwickler eines CAD-Programmmes zu mir gesagt: "Ein Fehler, der nur gelegentlich auftritt, ist kein Fehler". In seinem Sinne ist das Programm also fehlerfrei. Naja - Scherz beiseite. Irgendwo steckt da noch ein Bug, aber ich habe ihn nicht gefunden - und suche auch nicht weiter danach. Das ganze Programm war schließlich nur als Fingerübung über den Jahreswechsel entstanden ... Michael S.
Hallo Michael, schönes Programm hast Du geschrieben. Mich interessiert, ob ich das Programm als Schaltuhr mit 3 Kanälen zu gebrauchen ist. Also am liebsten direkt mit den freien Portpins z.b. Relais schalten ohne die TWI Bausteine..(PCF8574?). Kannst Du mir eine Tip geben, wie ich das einflechten kann in dein Programm. Bischen Erfahrung in der Programmierung habe ich schon. Ich möchte als Ergebnis eine Schaltuhr haben, die meine "dumme Schaltuhr aus der Heizungsanlage ersetzt. Dort ist eine 2 Kanal Uhr eingebaut,mit der man am Tag glaube 3 Schaltzeiten für jeden Kanal nutzen kann. Es wird wohl reichen, wenn man für 3 Kanaäle, 7 Tage 3 Ein-Aus Schaltungen programmieren kann. Ich hoffe ich bin nicht zu lästig mit meiner Frage. Gruß Bernd
Hallo Bernd Bömer, natürlich kannst Du Dein Problem mit dem Programm lösen. Schau dir in der Readme die Beschreibung zu den Slots an. Oder - wenn das zu kompliziert klingt - geh' doch einfach an die Stelle im Programm, an der eine neue Minute beginnt. Hier dann fragst Du ab, ob dies der Zeitpunkt ist, an dem Du etwas schalten willst. Wenn ja, dann schaltest Du einen oder mehrere (der freien) Pins am Controller. Das wars schon. mfg Michael S.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.