Forum: Projekte & Code DCF77-TWI(I2C)-Slave


von Uwe B. (boerge) Benutzerseite


Angehängte Dateien:

Lesenswert?

MoinMoin,

ich habe für mein BLIT2008-Board (http://bralug.de/wiki/BLIT2008-Board) 
einen DCF77-Decoder auf Basis eines ATtiny zusammengebaut und 
entsprechende Software geschrieben.

Ich weis, DCF77 zum x-ten Mal... Mein Anspruch war es aber, dass das 
Ding ein TWI-Slave wird und via eines TWI-Masters Datum/Zeit decodiert 
preisgibt. Als ich mit der Geschichte anfing, hatte ich nichts 
vergleichbares gefunden...

Als Controller wurde ein ATtiny45 (sollte auch auf ATtiny25/85 
laufen...) verwendet, der bekanntlich kein Hardware-TWI hat. Deshalb 
wurde Application Note 312 von Atmel adaptiert und TWI via USI 
realisiert.

Alles weiter ist in README.txt bzw. obiger Webseite (ff.) zu finden....

Grüße Uwe

von D. S. (Gast)


Lesenswert?

Nabend,

baust du die Sachen eigentlich immer auf Arbeit in deinem Büro oben?

Feine Sache deine Schaltungen!!!

Gruß

von Uwe B. (boerge) Benutzerseite


Angehängte Dateien:

Lesenswert?

MoinMoin,

beim Einschlafen ist mir noch ein Fehler aufgefallen, der zwar 
theoretisch nur bei einem Jahreswechsel zum Tragen kommt, aber es ist ja 
bald wieder soweit. Im Anhang die korrigierte Version...

Uwe

von Michael S. (Gast)


Lesenswert?

Hallo Uwe,

dein Beispiel interessierte mich insofern, als ich verschiedene Sensoren 
in gleicher Weise auslese und einen ähnlichen DCF77-Slave
gedanklich auch schon konzipiert hatte.

In deiner read.me steht:

> Auf eine eigenstaendig mitlaufende Uhr wurde
> im Programm verzichtet, da die Baugruppe als TWI-Slave ausgelegt ist
> und damit relativ einfach ein RTC-Baustein (z.B. PCF8583) an den
> TWI-Bus angeschlossen werden und mitlaufen kann.

Klar, kann man machen.
Aber dann muss der Master immer die Uhrzeit vom DCF77-Modul auf
die Uhr übertragen.
Ich würde mir aber wünschen, dass der Master den Uhrenbaustein als
Blackbox betrachten kann und nur wissen muss, wo und wie er die 
(garantiert
gültige) Zeit abfragt.

> Auf die
> Ueberpruefung der einzenen Werte mittels den mitgesendeten Paritaet-
> Bits wurde verzichtet, laesst sich aber sicher einfach einbauen.

Eine Paritäts- und Plausibilätsprüfung würde ich schon nahelegen,
Empfangsstörungen kommen nun mal vor.
Die Paritätsprüfung allein reicht sicher noch nicht aus.
Eine Plausibiliätsprüfung (eine neue Zeit muss genau 1 Minute nach der
vorausgegangenen Zeit liegen) halte ich für wichtig.

Und was machst du, wenn mal ein Fehler auftritt ??

Dann wäre es doch schön, die Zeit ohne externes DCF-Signal
fortschreiben zu können (mit einem internen Quarz-Takt).
Und wie erkennst du, dass das DCF77-Signal dann irgendwann wieder 
korrekt ist?


>      * der TWI-Master spricht den DCF77-TWI-Slave in folgender
>        Reihenfolge an:
>      * TWI-Start (schreiben)
>      * TWI-Schreiben (1 Byte, Inhalt egal)
>      * TWI-Stopp
>      * Programmpause von ca. 50ms, da der Tiny nicht schnell
>        genug ist
Anmerkung: das halte ich für ein Gerücht der Konkurrenz ...
in 50ms werden (4.000.000 / 1000) * 50 = 200.000 Befehle abgearbeitet!
>      * TWI-Start (lesen)
>      * 8x TWI-Lesen mit Ack (Datenreihenfolge ss, mm, hh,
>        dd, mt, yy, wd, mez)
>      * 1x TWI-Lesen mit NAck (es kommt noch mesz)
>      * TWI-Stopp

Ob das auch einfacher geht ?

Der Ringbuffer im Beispiel der AVR312 ist für deine Anwendung nicht 
prädestiniert (wie man an deiner Beschreibung sieht).

Was wäre, wenn du den Ringpuffer gegen einen linearen Puffer von 9 Byte 
ersetzen würdest (spart sogar 7 Byte)?
Den rx_buffer benötigst du eigentlich gar nicht (spart noch mal 16 
Byte).
Den tx_buffer machst du public, schreibst dort aus main() wohlgeordnet 
die Zeit hinein.
Regelmäßig, jede Sekunde neu.

Die gesamte TWI-Kommunikation läuft Interrupt-gesteuert.
In main() wird lediglich die Zeit berechnet und in den tx_buffer 
geschrieben.

Wenn nun der Master die Zeit anfordern will, dann liest er einfach 9 
(oder weniger) Byte vom Slave.
In der USI_OVL_isr setzt du den Index auf tx_buffer[] auf 0 in dem
Moment, in dem du erkennst, das jemand lesend auf den Slave zugreifen 
will
(wennn das zuerst empfangene Byte == TWI_SLAVE_ADR).
Nach jedem gelesenen Byte aus tx_buffer incrementierst du den Index.

Weiterer Vorteil: der Master kann selbst entscheiden, wieviele Bytes er 
lesen möchte, vielleicht braucht er ja nur die Uhrzeit ohne Datum ?

Und noch eine Anmerkung:
Der Code der AVR312 ein Beispiel dafür ist, wie man mit Macros die 
Funktionsweise eines Programmes (zumindest beim Einstieg) auch richtig
gut verschleiern kann.
Ausserdem hat der Code auch noch andere Problemchen, z.B. kann er kein 
USI-Stop erkennen.
Und ein Ringbuffer war bei meine Anwendungen (fast) immer ungeeignet 
(siehe ja auch hier).

Vielleicht helfen diese Gedanken etwas bei deiner weiteren Optimierung 
...

Michael S.

von Uwe B. (boerge) Benutzerseite


Angehängte Dateien:

Lesenswert?

MoinMoin

Michael S. wrote:
> Hallo Uwe,
>
> dein Beispiel interessierte mich insofern, als ich verschiedene Sensoren
> in gleicher Weise auslese und einen ähnlichen DCF77-Slave
> gedanklich auch schon konzipiert hatte.
>
na wenigsten jemand, der sich den Code genauer angesehen hat....


>> Auf eine eigenstaendig mitlaufende Uhr wurde
>> im Programm verzichtet, da die Baugruppe als TWI-Slave ausgelegt ist
>> und damit relativ einfach ein RTC-Baustein (z.B. PCF8583) an den
>> TWI-Bus angeschlossen werden und mitlaufen kann.
>
> Klar, kann man machen.  Aber dann muss der Master immer die Uhrzeit
> vom DCF77-Modul auf die Uhr übertragen.
> Ich würde mir aber wünschen, dass der Master den Uhrenbaustein als
> Blackbox betrachten kann und nur wissen muss, wo und wie er die
> (garantiert gültige) Zeit abfragt.
>
...klar kann man machen ;-), war aber nicht mein Anspruch. In dem 
Zusammenhang (Blackbox und garantiert gültige Zeit...) stellt sich auch 
die umgekehrte Frage: Was gibt das Modul zurück, wenn von Anfang na 
überhaupt kein DCF77-Signal empfangen wurde, also man in einem 
Empfangsloch ist?

> Eine Paritäts- und Plausibilätsprüfung würde ich schon nahelegen,
> Empfangsstörungen kommen nun mal vor.
>
nun denn, im Anhang ist eine Version mit Paritätsüberprüfung enthalten.

> Die Paritätsprüfung allein reicht sicher noch nicht aus.
> Eine Plausibiliätsprüfung (eine neue Zeit muss genau 1 Minute nach der
> vorausgegangenen Zeit liegen) halte ich für wichtig.
>
Doch es reicht aus, die Toleranzen der jeweiligen Impulsbreiten/-pausen 
und die die Parität zu überprüfen. Alles andere würde dann aber schon 
bedeuten, dass ein inhaltlich falsches DCF77-Signal ausgestrahlt wurde!

> Und was machst du, wenn mal ein Fehler auftritt ??
>
> Dann wäre es doch schön, die Zeit ohne externes DCF-Signal
> fortschreiben zu können (mit einem internen Quarz-Takt).
> Und wie erkennst du, dass das DCF77-Signal dann irgendwann wieder
> korrekt ist?
>
Im Fehlerfall, ist dem Quelltext zu entnehmen, setze ich ein paar Merker 
zurück und gebe als Datum eine Null aus... Die empfangene Zeit ist dann 
wieder korrekt, wenn zwischen 2 erkannten 59-Sekunden-Pausen auch 
wirklich 58 Impulse lagen, diese den Toleranzen entsprechen und nunmehr 
auch die Paritäten stimmen.

>
>>      * der TWI-Master spricht den DCF77-TWI-Slave in folgender
>>        Reihenfolge an:
>>      * TWI-Start (schreiben)
>>      * TWI-Schreiben (1 Byte, Inhalt egal)
>>      * TWI-Stopp
>>      * Programmpause von ca. 50ms, da der Tiny nicht schnell
>>        genug ist
> Anmerkung: das halte ich für ein Gerücht der Konkurrenz ...
> in 50ms werden (4.000.000 / 1000) * 50 = 200.000 Befehle abgearbeitet!
>
naja, die Rechnung stimmt auch nicht ganz, der Tiny arbeitet mit 1MHz... 
Der angegebene Pausenwert war nach "Gefühl"... Wenn man es genau 
berechnen möchte, sollte der Tiny nach Empfang eines Bytes genug Zeit 
haben, 9 Werte in den Schreib-Puffer zu legen, bevor der Master anfängt 
auszulesen...


> Ob das auch einfacher geht ?
>
> Der Ringbuffer im Beispiel der AVR312 ist für deine Anwendung nicht
> prädestiniert (wie man an deiner Beschreibung sieht).
>
mag sein und bezweifle ich auch nicht. Die Puffergrößen könnte man 
wirklich anpassen, um RAM zu sparen. Den Algorithmus mit dem Ringbuffer 
wollte ich mit Bedacht nicht speziell für dieses Beispiel anpassen, 
denn:
* es funktioniert ja "trotzdem"
* das Beispiel ist so nicht spezialisiert und könnte für andere Dinge 
einfach übernommen werden

Aber stimmt schon, hier würde Optimierungspotential sein.

Uwe

von Michael S. (Gast)


Lesenswert?

Hallo Uwe,

> Doch es reicht aus, die Toleranzen der jeweiligen Impulsbreiten/-pausen
> und die die Parität zu überprüfen. Alles andere würde dann aber schon
> bedeuten, dass ein inhaltlich falsches DCF77-Signal ausgestrahlt wurde!

Nicht ausgestrahlt - sondern lediglich empfangen wurde!
Wegen Störungen.

Michael S.

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

>> Doch es reicht aus, die Toleranzen der jeweiligen Impulsbreiten/-pausen
>> und die die Parität zu überprüfen. Alles andere würde dann aber schon
>> bedeuten, dass ein inhaltlich falsches DCF77-Signal ausgestrahlt wurde!
>
> Nicht ausgestrahlt - sondern lediglich empfangen wurde!
> Wegen Störungen.
>
ich meine schon "ausgestrahlt". Ich könnte mir jetzt mal keine 
Konstellation vorstellen, in der obige Prüfungen nicht greifen würden 
(ausser einer, die die ist reichlich hirnrissig...)

Grüße Uwe

von Michael S. (Gast)


Lesenswert?

Hallo Uwe

> ich meine schon "ausgestrahlt". Ich könnte mir jetzt mal keine
> Konstellation vorstellen, in der obige Prüfungen nicht greifen würden
> (ausser einer, die die ist reichlich hirnrissig...)

Naja - wenn du meinst.
Dann mach doch gleich den Vorschlag an die PTB, auf die Paritätsbits zu 
verzichten.
Sind ja nach deiner Theorie überflüssing, weil sich ja nur hinrissige 
Fehler ereignen können.

Ich schließe mich deiner Theorie übrigens nicht an.
Und behaupte, dass selbst die Paritätsprüfung nicht ausreicht.

Aber das kann je jeder für sich entscheiden.

Michael S.

von Michael F. (fury)


Lesenswert?

Hallo,
ich habe selbst vor einiger Zeit ähnliches 
(Beitrag "DCF77 über IIC") programmiert, bin aber am 
Hardware-IIC gescheitert.

Jetzt muss ich mir bei Gelegeheit mal deinen Code anschauen und meinen 
verbessern.

Gruss
Michael

von Uwe B. (boerge) Benutzerseite


Lesenswert?

MoinMoin,

Michael S. wrote:
>> ich meine schon "ausgestrahlt". Ich könnte mir jetzt mal keine
>> Konstellation vorstellen, in der obige Prüfungen nicht greifen würden
>> (ausser einer, die die ist reichlich hirnrissig...)
>
> Naja - wenn du meinst.
> Dann mach doch gleich den Vorschlag an die PTB, auf die Paritätsbits zu
> verzichten.
>
...ganz so absolut habe ich es nicht gemeint und mittlerweile prüfe ich 
ja auch die Parität (siehe Codeversion vom 15.12. 11:14 Uhr), weil in 
diesem Punkt dein Einwand schon berechtigt war (letztendlich war es auch 
nur ein zusätzlicher 3-Zeiler...).

> Ich schließe mich deiner Theorie übrigens nicht an.
> Und behaupte, dass selbst die Paritätsprüfung nicht ausreicht.
>
Wie könnte die Konstellation aussehen, in der eine Impulsbreiten- und 
Paritäts-Prüfung nicht ausreicht? Oben hast du geschrieben, dass 
überprüft werden sollte, ob die aktuell empfangene Minute um 1 grösser 
als die letzte Minute ist. Meiner Meinung kann dies nur der Fall sein, 
wenn PTB dies so sendet oder ein anderer Sender das Signal bewußt 
verfälscht..., dass meinte ich mit "hirnrissiger" Konstellation.

Dazu müssten mindestens 2 Bits von Minute, Stunde oder Datum falsch 
erkannt werden und dann genau so, dass es immer jeweils noch mit der 
Parität zusammenpasst. Die statistische Wahrscheinlichkeit für einen 
solchen systematischen Fehler halte ich für relativ gering, lasse mich 
aber gern eines besseren belehren....

Grüße Uwe

von Michael S. (Gast)


Lesenswert?

Hallo Uwe,

eine Paritätsprüfung ist eine äußerst simple Form der Verifizierung.
Du hast ja selbst richig erkannt, wenn 2 Bits "verkehrt" sind, dann 
passt die Prüfsumme schon wieder.

Ein Beispiel aus der Praxis: Bei einem kommerziellen Hausbussystem 
tauchten in den Protokolldaten unsinnige Zeiteinträge auf:
Die Ursache war das DCF-77 Modul.

Seitdem fordere ich (für mich) den relativ geringfügigen Aufwand für 
eine Plausibilätsprüfung UND einen "Reservetakt" bei fehlendem 
DCF-Signal.

Das wird erst dann etwas aufwändiger, wenn man auch den Wechsel von 
Sommer- zu Winterzeit (ohne DCF-Signal) bewältigen will.
Ist aber eine ganz nette Fingerübung, da man sich mit den Problemen von 
Schaltjahren, Sommerzeitumstellung etc. beschäftigen darf.
Wenn man sich quälen will, dann werden auch noch die Ankündigungsbits 
berücksichtigt ..

Der erlangte Vorteil ist: Wenn das Modul einmal auf das DCF-Signal 
synchronsiert hat, dann wird es mit großer Wahrscheinlichkeit jederzeit 
gültige Daten liefern.

Und noch eine Fingerübung:
Wie könnte man das Modul aufbauen, dass es (ungestörter Empfang 
vorausgesetzt) SPÄTESTENS nach 60 Sekunden den gesamten Datensatz 
decodiert hat ?
(Natürlich ohne Wetterdaten !)

Viel Spaß

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
Noch kein Account? Hier anmelden.