Forum: Mikrocontroller und Digitale Elektronik WordClock mit DCF77, Photodiode und ATMega8


von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

ich habe vor eine WordClock wie man sie ja schon kennt nachzubauen. Ich 
habe mir dabei ein paar Anforderungen aufgeschrieben die ich gerne mit 
dem Aufbau erreichen würde.

- Jede LED einzeln ansteuerbar (gemuxt) mit Software PWM
- Zeitsynchronisation mit Hilfe von DCF77
- Helligkeitsgesteuert über die Photodiode mit Software PWM

Als LEDs hab ich mir diese Strawhat LEDs ausgesucht welche ich nicht 
übersteuern will, da ich denke, dass die Leistung von denen so 
ausreichend ist, sprich mit 1,9V und 20mA fahren.
http://www.leds24.com/LED/StrawHat-LEDs-led/50-x-gelbe-Strawhat-LEDs-120--600mcd---LED-gelb-orange.html

Da ich die Spalten Multiplexe muss der ATMega8 bis zu 200mA ausspucken 
nur für die LEDs, was ich denke aber OK ist, da er ja pro IO Pin 40mA 
und insgesamt bis zu 300mA liefert.

Mit Hilfe einiger Leute aus dem IRC (besonders mcfloppy) habe ich nun 
dieses Schaltbild erstellt und brauche ein paar Leute die Ahnung haben 
und mal was zu meinem Entwurf sagen. Da für mich die Software-Seite die 
interessante ist, habe ich von der Hardware entsprechend leider nicht so 
viel KnowHow.

Besonders die TransistorArrays sind mir nicht ganz klar.

Es würde mich sehr freuen wenn mir dabei jemand ein bisschen zur Seite 
stehen könnte, der davon mehr Ahnung hat als ich, und mal etwas zu dem 
Entwurf sagen könnte.

Schöne Grüße
Oli

von Joachim .. (joachim_01)


Lesenswert?

Ich tät' anstatt den 20mA-LEDs welche mit 2mA nehmen.

von Oli (Gast)


Lesenswert?

Die müsste ich dann ja übersteuern, was dann im Endeffekt auch wieder 
20mA wären. Dabei wären dann aber die Gefahr nur größer, dass die 
Durchbrennen.

Auch die Helligkeit erscheint mir nicht genug von den Low-Current LEDs, 
deswegen hab ich mich wie gesagt für die obigen entschieden.

von Knut (Gast)


Lesenswert?

Moin,

wo kommt deine Versogungsspannung für den 7805 her und wie hoch ist sie?
Evtl. musst den dem 7805 einen Kühlkörper spendieren!

Die DCF Versorgung muss jedenfalls absolut sauber sein, die Module sind 
sehr sehr empfindlich. Hier mit dem Layout und Filter C´s nicht geizen!


Knut

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Das DCF-Modul sollte ohnehin vom Rest der Schaltung abgesetzt werden.

von Oli (Gast)


Lesenswert?

Ich wollte das DCF77 Modul von Conrad nehmen, den Dateneingang an den 
INT0 mit Pull-Up legen, GND und VCC wollte ich eigentlich ganz normal 
über die geglätteten Vcc und GND nutzen die ich auch überall sonst 
verwende.

Was ist denn mit den Transistor Arrays unten? Bin mir nicht sicher ob 
das so korrekt funktionieren würde.

LG, Oli

von Matthias (Gast)


Lesenswert?

Also ich würde dem Teil noch 2 zusätzliche Schieberegister spendieren 
und
die Schieberegister an den SPI anschließen. Damit sollte man dann das
ganze Bitgeschaufel ein wenig "stromlinienförmiger" gestalten können.

An die zusätzlichen Schieberegister noch ein HighSide-Transistor-Array
(zu dem ULN sollte es doch ein passendes gegenstück geben?) oder ein
paar P-Fets anschließen. Die Versorgung der LEDs von der Versorgung
des uC trennen (ggf. separaten Regler) und ein paar Dioden und Elkos 
spendieren.

von Falk B. (falk)


Lesenswert?

@  Oli (Gast)

>Ich wollte das DCF77 Modul von Conrad nehmen, den Dateneingang an den
>INT0 mit Pull-Up legen,

Den INT0 brauchst du nicht. Ein DCF77 Modul wertet man per Polling aus, 
sprich alle ca. 100ms per Timer den Pegel einlesen und verarbeiten. 
Damit kann man besser Störungen filtern.

> GND und VCC wollte ich eigentlich ganz normal
>über die geglätteten Vcc und GND nutzen die ich auch überall sonst
>verwende.

Kann funktionieren, muss aber nicht.

http://www.mikrocontroller.net/articles/DCF77-Funkwecker_mit_AVR#DCF77-Modul_von_Reichelt

MfG
Falk

von Rene B. (themason) Benutzerseite


Lesenswert?

@Oli

Ich würde es zwar vllt nicht so machen das der AVR die 20mA pro LED 
Treiben muß, da der AVR doch sehr viel Strom ziehen würde bzw müsste. 
Und die 40mA sind ja Absolute Maximum Rating. Vllt lieber noch nen 
Treiber für die Zeilen nehmen. Aber das ist wohl Geschmackssache.

Was mir allerdings auffällt und das sollte man vllt anders machen.
Du Steuerst die Spalten ja über ein Schieberegister an.
Allerdings ist das Strobe dauerhaft auf 1. Ich würde an der Stelle 
lieber noch nen Port-Pin spendieren damit du die Spalten erst dann 
aktivierst wenn  der Strobe gesetzt wurde. Ansonsten würdest du beim 
erneuten Schreiben des SPI-Wortes alle Spaltensignale durchgehen bis das 
letzte Bit eingetaktet wurde. Je nach SPI-Frequenz und Haltezeit kann es 
sein das es nicht auffällt, aber falls doch sieht es etwas unschön aus. 
Du müsstes ansonsten vor jedem Eintakten in das Schiebetrgister die 
Zeilen-LED-Signale zurücknehmen (Dunkeltasten) und erst wenn das 
Spaltensignal vollständig in den Schieberegistern vorliegt die 
Zeilen-Bits setzen.
Bei LEDs mag man sich da evtl noch helfen können, aber wenn die Signale 
was anderes steuern würden hätte man u.u. fiese bzw unerklärbare 
"Seiteneffekte".
Daher vllt lieber das Strobe-Signal noch an einen Port-Pin anschließen.
Nur mal so als Tip.

von Volkmar D. (volkmar)


Lesenswert?

Oli schrieb:
> was ich denke aber OK ist, da er ja pro IO Pin 40mA

Das klappt aber in Deiner Schaltung nicht. Die AVRs können den Strom 
'nur' gegen Masse liefern, aber nicht gegen Vcc. Hier brauchst Du also 
noch sowas wie ein HighSide-Transistor-Array, wie schon weiter oben 
angesprochen.

von Volkmar D. (volkmar)


Lesenswert?

Oli schrieb:
> Die müsste ich dann ja übersteuern, was dann im Endeffekt auch wieder
> 20mA wären. Dabei wären dann aber die Gefahr nur größer, dass die
> Durchbrennen.
>
> Auch die Helligkeit erscheint mir nicht genug von den Low-Current LEDs,
> deswegen hab ich mich wie gesagt für die obigen entschieden.

Wenn Du eine Matrix-Ansteuerung machst, dann mußt Du 'übersteuern' um 
auf eine ähnliche Helligkeit im Vergleich zu einem kontinuierlichen 
Strom zu kommen. Mit dieser Matrix hast Du ein Taktverhältnis von max. 
1:10, damit werden die LEDs nur 10% der Zeit angesteuert und 
entsprechend dunkel.

von Oli (Gast)


Lesenswert?

Volkmar Dierkes schrieb:
> Wenn Du eine Matrix-Ansteuerung machst, dann mußt Du 'übersteuern' um
> auf eine ähnliche Helligkeit im Vergleich zu einem kontinuierlichen
> Strom zu kommen. Mit dieser Matrix hast Du ein Taktverhältnis von max.
> 1:10, damit werden die LEDs nur 10% der Zeit angesteuert und
> entsprechend dunkel.

Das dachte ich ist bei den LEDs die ich gewählt habe nicht wichtig, weil 
die ausreichend helligkeit liefern, auch wenn ich sie nicht übersteuer. 
Das ist aber nur eine Vermutung und ich kann da tatsächlich nicht viel 
zu sagen. Ich glaube halt, dass die 20mA normal bei den besser sind als 
eine übersteuerte 2mA LowCurrent LED.

Volkmar Dierkes schrieb:
> Das klappt aber in Deiner Schaltung nicht. Die AVRs können den Strom
> 'nur' gegen Masse liefern, aber nicht gegen Vcc. Hier brauchst Du also
> noch sowas wie ein HighSide-Transistor-Array, wie schon weiter oben
> angesprochen.

Ich dachte dafür sind die Darlington Transistor Arrays. Die hat mir 
mcfloppy empfohlen.

Rene B. schrieb:
> Was mir allerdings auffällt und das sollte man vllt anders machen.
> Du Steuerst die Spalten ja über ein Schieberegister an.
> Allerdings ist das Strobe dauerhaft auf 1. Ich würde an der Stelle
> lieber noch nen Port-Pin spendieren damit du die Spalten erst dann
> aktivierst wenn  der Strobe gesetzt wurde.

Evtl. hab ich das mit dem Strobe nicht ganz korrekt verstanden, aber ich 
Schieb ja immer nur eine 1 weiter, und schieb da nicht auf einmal 11 Bit 
rein und mach dann erst wieder an.

Schöne Grüße
Oli

von Volkmar D. (volkmar)


Lesenswert?

Oli schrieb:
>> Das klappt aber in Deiner Schaltung nicht. Die AVRs können den Strom
>> 'nur' gegen Masse liefern, aber nicht gegen Vcc. Hier brauchst Du also
>> noch sowas wie ein HighSide-Transistor-Array, wie schon weiter oben
>> angesprochen.
>
> Ich dachte dafür sind die Darlington Transistor Arrays. Die hat mir
> mcfloppy empfohlen.

Der Strom muß durch beide Bausteine fließen. Die ULN2803 sind nötig, da 
der 4094 den nötigen Strom nicht liefern kann.
Auf der anderen Seite muß der Strom durch den ATmega8 fließen (der 
Stromfluß muß ja geschlossen sein), und der ATmega8 macht das sehr 
ähnlich zum ULN2803 und hat einen Transistor gegen Masse durch den auch 
ein etwas höherer Strom fließen kann. Im Gegensatz dazu hat der Atmel zu 
VCC hin keinen derartigen Transistor und kann hier nur sehr kleine 
Ströme durchlassen.

Was ich mich hier frage, wozu benötigst Du die freie Ansteuerung aller 
LEDs, am Ende wird es doch auf einige wenige Muster hinauslaufen. Hast 
Du Dir mal den Word Clock-Artikel 
(http://www.mikrocontroller.net/articles/Word_Clock) angesehen?

Oli schrieb:
> Evtl. hab ich das mit dem Strobe nicht ganz korrekt verstanden, aber ich
> Schieb ja immer nur eine 1 weiter, und schieb da nicht auf einmal 11 Bit
> rein und mach dann erst wieder an.

Mit dieser Matrix-Ansteuerung mußt Du immer ganze Zeilen (also 11 Bit) 
reinschieben, dann eine Zeile einschalten und für 1/10 der Zeit an 
lassen. Dann schaltest Du die Zeile wieder aus, schiebst die 11 Bit der 
nächsten Zeile rein und schaltest dann diese nächste Zeile wieder für 
1/10 der Zeit an. Und so weiter und so fort.
Du kannst das Abschalten der Zeilen auf 2 Wege durchführen:
- Abschalten der Zeilenausgänge (wie eben beschrieben)
- Abschalten der Schieberegister (dazu dann den Portpin anschließen, 
würde ich aber sowieso machen um mir alle Optionen aufrechtzuerhalten)

von Oli (Gast)


Lesenswert?

Volkmar Dierkes schrieb:
> Mit dieser Matrix-Ansteuerung mußt Du immer ganze Zeilen (also 11 Bit)
> reinschieben, dann eine Zeile einschalten und für 1/10 der Zeit an
> lassen. Dann schaltest Du die Zeile wieder aus, schiebst die 11 Bit der
> nächsten Zeile rein und schaltest dann diese nächste Zeile wieder für
> 1/10 der Zeit an. Und so weiter und so fort.
> Du kannst das Abschalten der Zeilen auf 2 Wege durchführen:
> - Abschalten der Zeilenausgänge (wie eben beschrieben)
> - Abschalten der Schieberegister (dazu dann den Portpin anschließen,
> würde ich aber sowieso machen um mir alle Optionen aufrechtzuerhalten)

Ich glaube du hast mein Layout missverstanden. Ich muxe die Spalten, 
nicht die Zeilen. D.h. es ist immer nur eine Spalte an aber alle Zeilen. 
Die Zeilen steuer ich dabei direkt über den ATMega welcher Vcc 
bereitstellt für die LEDs und über das Schieberegister mach ich immer 
nur eine Spalte an, weshalb ich eigentlich auch immer nur 1 
weiterschieben müsste.

Volkmar Dierkes schrieb:
> Der Strom muß durch beide Bausteine fließen. Die ULN2803 sind nötig, da
> der 4094 den nötigen Strom nicht liefern kann.

Den Strom liefer doch der ATMega, er fließt durch die LEDs zum 
Darlington Array, welches gegen GND schaltet wenn im Schieberegister an 
dem Pin eben eine 1 anliegt. Demnach sollte auch nur wenn im 
Schieberegister dort eine 1 anliegt Strom fließen.

Volkmar Dierkes schrieb:
> Was ich mich hier frage, wozu benötigst Du die freie Ansteuerung aller
> LEDs, am Ende wird es doch auf einige wenige Muster hinauslaufen. Hast
> Du Dir mal den Word Clock-Artikel
> (http://www.mikrocontroller.net/articles/Word_Clock) angesehen?

Ja hab ich, ich wollte aber noch andere Muster auf der Anzeige nutzen. 
Spielerei halt :D

Schöne Grüße
Oli

von Volkmar D. (volkmar)


Lesenswert?

Oli schrieb:
> Ich glaube du hast mein Layout missverstanden. Ich muxe die Spalten,
> nicht die Zeilen. D.h. es ist immer nur eine Spalte an aber alle Zeilen.

OK, sorum geht es auch. Dann hast Du halt nur einen Duty-Cycle von 1:11 
und nicht 1:10.

Oli schrieb:
> Den Strom liefer doch der ATMega, er fließt durch die LEDs zum
> Darlington Array, welches gegen GND schaltet wenn im Schieberegister an
> dem Pin eben eine 1 anliegt. Demnach sollte auch nur wenn im
> Schieberegister dort eine 1 anliegt Strom fließen.

Sorry, ich muß meine Aussage zurückziehen. Ich habe nochmal im 
Datenblatt des ATmega8 nachgeschaut und dort gibt es keinen derartigen 
Unterschied zwischen Low und High-Pegeln an den Ports. Hatte ich wohl 
mit etwas anderem verwechselt.

Eng wird es mit der Stromaufnahme dennoch:
Laut Datenblatt:
1
2] The sum of all IOH, for port C0 - C5, should not exceed 100 mA.
2
3] The sum of all IOH, for ports B0 - B7, C6, D0 - D7 and XTAL2, should not exceed 100 mA.

von Oli (Gast)


Lesenswert?

Volkmar Dierkes schrieb:
> Eng wird es mit der Stromaufnahme dennoch:
> Laut Datenblatt:2] The sum of all IOH, for port C0 - C5, should not exceed 100 
mA.
> 3] The sum of all IOH, for ports B0 - B7, C6, D0 - D7 and XTAL2, should not 
exceed 100 mA.

Oh, das hab ich nicht gesehen. Ich hatte was von max. 40mA pro Port und 
insgesamt 300mA im Kopf. Auf welcher Seite steht das im Datenblatt?

Schöne Grüße
Oli

von Volkmar D. (volkmar)


Lesenswert?

Diese Einschränkung steht auf Seite 236 im aktuellen Datenblatt, wobei 
ich hier noch ein Altes hatte und mir noch mal das Aktuelle geladen 
habe. Es ist leicht korrigiert seit dem:
1
1] The sum of all IOH, for all ports, should not exceed 300mA.
2
2] The sum of all IOH, for port C0 - C5, should not exceed 100mA.
3
3] The sum of all IOH, for ports B0 - B7, C6, D0 - D7 and XTAL2, should not exceed 200mA

Vielleicht kannst Du ja noch die ein oder andere Leitung von PortC auf 
PortB oder PortD verlegen.

von Michael (Gast)


Lesenswert?

Willst du die Helligkeit jeder LED unabhängig von der der anderen 
steuern? Das wird eng, denke ich :S

von Oli (Gast)


Lesenswert?

Volkmar Dierkes schrieb:
> Diese Einschränkung steht auf Seite 236 im aktuellen Datenblatt, wobei
> ich hier noch ein Altes hatte und mir noch mal das Aktuelle geladen
> habe. Es ist leicht korrigiert seit dem:1] The sum of all IOH, for all ports, 
should not exceed 300mA.
> 2] The sum of all IOH, for port C0 - C5, should not exceed 100mA.
> 3] The sum of all IOH, for ports B0 - B7, C6, D0 - D7 and XTAL2, should not 
exceed 200mA
> Vielleicht kannst Du ja noch die ein oder andere Leitung von PortC auf
> PortB oder PortD verlegen.

Ich denke ich werde die LEDs einfach mit weniger als 20mA betreiben. Ich 
werde ein paar Testläufe machen wie hell sie dann sind und den 
Vorwiderstand entsprechend anpassen.

Michael schrieb:
> Willst du die Helligkeit jeder LED unabhängig von der der anderen
> steuern? Das wird eng, denke ich :S

Hatte ich ursprünglich nicht vor, sollte aber über die Software PWM doch 
recht einfach möglich sein.

Schöne Grüße
Oli

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Volkmar Dierkes schrieb:
> Das klappt aber in Deiner Schaltung nicht. Die AVRs können den Strom
> 'nur' gegen Masse liefern, aber nicht gegen Vcc.

Volkmar Dierkes schrieb:
> und der ATmega8 macht das sehr
> ähnlich zum ULN2803 und hat einen Transistor gegen Masse durch den auch
> ein etwas höherer Strom fließen kann. Im Gegensatz dazu hat der Atmel zu
> VCC hin keinen derartigen Transistor und kann hier nur sehr kleine
> Ströme durchlassen.

Woher habt ihr denn diese information? Alle AVRs haben an allen Ports 
(bis auf ganz wenige Ausnahmen) vollwertige Push-Pull Endstufen und 
können pro Pin nach Masse und Vcc ableiten. Bei den XMEGAs sind es 
maximal 20mA.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Volkmar Dierkes schrieb:
> Sorry, ich muß meine Aussage zurückziehen. Ich habe nochmal im
> Datenblatt des ATmega8 nachgeschaut und dort gibt es keinen derartigen
> Unterschied zwischen Low und High-Pegeln an den Ports.

Genau.

Volkmar Dierkes schrieb:
> Hatte ich wohl
> mit etwas anderem verwechselt.

80C51 vielleicht?

von Oli (Gast)


Lesenswert?

Ich würde gerne noch vier weitere LEDs gemäß der QLOCKTWO einbauen, um 
die Minuten Korrektur anzuzeigen. Da mir allerdings langsam die IO Ports 
ausgehen, dachte ich mir ich klemme die an das Ende vom 4094 
Schieberegister.

Nun meine Frage, wird der Strobe dazu genutzt, um alle Register des IC 
zu füllen und dann alle auf einmal auf den Ausgang zulegen wenn auch 
alle Register gefüllt sind, sprich der alte Zustand komplett erhalten 
wird, bis ich alle neuen Zustände drauf habe?

Wie lange dauert es so zwei Schieberegister komplett zu füllen? Um 
Gescheit zu Multiplexen mit PWM dachte ich an eine Frequenz von 100 Hz * 
10 * 100 = 100.000 Hz für jeden PWM Schritt, wobei die Schieberegister 
nur mit 1000 Hz befüllt werden müssten.
Reicht die Zeit 1/1000Hz aus um die 15Bit in die Schieberegister zu 
kriegen?

Schöne Grüße
Oli

von Michael (Gast)


Lesenswert?

Oli schrieb:
> Michael schrieb:
>> Willst du die Helligkeit jeder LED unabhängig von der der anderen
>> steuern? Das wird eng, denke ich :S
>
> Hatte ich ursprünglich nicht vor, sollte aber über die Software PWM doch
> recht einfach möglich sein.

Ich mache einmal folgende Annahmen:
- 150 Frames/s
- 11 Spalten
- 10 Zeilen
- 8 bit PWM, also 256 Schritte
- AVR mit 4MHz, laut Schaltplan

Dann hast Du
 pro Spalte zu jeweils 10 Zeilen. Das ist doch etwas eng ;)

Ich arbeite momentan an einer Helligkeitsansteuerung für eine 8x8-Matrix 
mit BAM, der sehr ungünstig benannten Bit Angle Modulation, Google weiss 
mehr darüber. Mein ATMega168 läuft da mit 8MHz und das gibt nicht extrem 
viel Luft. Falls Du nur die Gesamthelligkeit der Matrix kontrollieren 
wirst, das ist einfacher.

Damit will ich dich nicht demotivieren oder blosstellen, ich fand es 
einfach interessant, dass gerade jetzt jemand auf ein Problem stösst, 
das sich mir eben als erstaunlich schwierig herausgestellt hat.

von Oli (Gast)


Lesenswert?

Michael schrieb:
> Damit will ich dich nicht demotivieren oder blosstellen, ich fand es
> einfach interessant, dass gerade jetzt jemand auf ein Problem stösst,
> das sich mir eben als erstaunlich schwierig herausgestellt hat.

Hab ich auch nicht böse aufgefasst, ich hatte das ja ursprünglich auch 
nicht vor. Mein Ziel war nur eine Clock die im gesamtem Dimmbar ist, 
abhängig von der Umgebungshelligkeit. Auf die Idee die Teile einzeln zu 
Dimmen, hast du mich gebracht, was man später als Spielerei mal testen 
könnte.

Schöne grüße
Oli

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

So,

ich hab das ganze nun um 4 weitere LEDs für die Minutenanzeige 
erweitert, einfach über Vcc mit ULN2803 gegen GND und dann mit den 4094s 
gesteurt.

Damit es nicht flackert hab ich dann wie vorher schon angeraten wurde, 
den Strobe-Pin auch noch auf einen Port gelegt, damit ich dann die 
ganzen 15 Bit am Stück in das Register schieben kann.

Weiterhin hab ich den Anschluss des DCF77 mal etwas genauer gezeichnet.

Wäre nett wenn da mal wieder jemand drüber gucken könnte. :)

Schöne Grüße
Oli

von Oli (Gast)


Lesenswert?

Hey,

brauch wieder mal Hilfe. :D
Da ich das erste mal mit Eagle arbeite hab ich ein bisschen Probleme 
beim Layouten des Boards. Der Autorouter will und will einfach nicht 
alles Verbinden, ich nehme an einfach zu viele Bahnen die sich Kreuzen.

Nun meine Idee, einfach Gewisse Teile durch pinheader ersetzen und dann 
den Anschluss der Teile einfach über Kabel machen. So eine Art 
Stecksystem für Module.

Schöne Grüße
Oli

von Volkmar D. (volkmar)


Lesenswert?

Ich hatte mir noch mal die ULN2803 angeschaut, und wenn ich nicht falsch 
liege, dann ist der Pin 10 falsch angeschlossen. Der sollte offen oder 
gegen VCC angeschlossen sein.

(Ich hoffe nur, daß ich nicht wieder so daneben liege wie weiter 
oben...)

Volkmar

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

nach langer Zeit mal wieder eine Meldung.

Volkmar Dierkes schrieb:
> Ich hatte mir noch mal die ULN2803 angeschaut, und wenn ich nicht falsch
> liege, dann ist der Pin 10 falsch angeschlossen. Der sollte offen oder
> gegen VCC angeschlossen sein.
Ja, du hast rest, der ist nun gegen VCC gelegt.

Hab nun alle Teile beisammen und die ersten Tests der Teilkomponenten
sehen vielversprechend aus.

- Helligkeitssensor liefert gute Spannungswerte einfach zum abgreifen 
per ADC.
- Schön helle weiße LEDs 20CD bei 3V 20mA mit 120° Abstrahlwinkel
- DCF Modul von Conrad tut einwandfrei, direkt nach 2 Minuten ein super 
Signal

Nun gehts ans Routen. Da hab ich auch schon soweit fast alles fertig,
hoffentlich schaff ich das diese Woche und kann die Platine dann auch
nächste Woche direkt fräsen.

Hier mal der Code des DCF Empfängers zum Anschauen wenn es jemanden
interessiert.
1
#include "dcf77.h"
2
3
#include <stdio.h>
4
#include <math.h>
5
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
9
typedef struct {
10
    unsigned start_minute : 1;
11
    unsigned weather : 14;
12
    unsigned call : 1;
13
    unsigned summer_time : 1;
14
    unsigned cest : 1;
15
    unsigned cet : 1;
16
    unsigned leap_second : 1;
17
    unsigned start_time : 1;
18
    unsigned minute : 7;
19
    unsigned minute_parity : 1;
20
    unsigned hour : 6;
21
    unsigned hour_parity : 1;
22
    unsigned day : 6;
23
    unsigned weekday : 3;
24
    unsigned month : 5;
25
    unsigned year : 8;
26
    unsigned date_parity : 1;
27
} bitmap_t;
28
29
static uint64_t bitmap_buffer = 0;
30
static uint8_t bitmap_counter = 0;
31
static bitmap_t *bitmap = (bitmap_t *) &bitmap_buffer;
32
33
static uint8_t parity_minute = 0;
34
static uint8_t parity_hour = 0;
35
static uint8_t parity_date = 0;
36
37
static uint16_t timer1_50ms = (float) F_CPU / 1024 / 1000 * 50;
38
static uint16_t timer1_150ms = (float) F_CPU / 1024 / 1000 * 125;
39
static uint16_t timer1_250ms = (float) F_CPU / 1024 / 1000 * 250;
40
41
static uint8_t timer2_overflows = lroundf((float) F_CPU / 128 / 255);
42
static uint8_t timer2_counter = 0;
43
44
/* the global variables we alter */
45
dcf77_time_t dcf77_time_last;
46
dcf77_time_t dcf77_time;
47
uint32_t dcf77_seconds_since_last;
48
49
extern void dcf77_init(void)
50
{
51
    /* enable INT0 and trigger on any edge change */
52
    GICR = _BV(INT0);
53
    MCUCR = _BV(ISC00);
54
55
    /* enable 16bit timer1 with 1024-prescaler in CTC mode with OCR1A as TOP
56
       value */
57
    TIMSK |= _BV(TOIE1);
58
    TCCR1A = _BV(WGM11);
59
    TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12) | _BV(CS10);
60
61
    /* overflow every 1.75 seconds */
62
    ICR1 = (F_CPU / 1024) * 1.75;
63
64
    /* usage 8bit timer2 with 128-prescaler in normal mode to increase the
65
       dcf timestamp every second by one second */
66
    TIMSK |= _BV(TOIE2);
67
    TCCR2 = _BV(CS22) | _BV(CS20);
68
    TCNT2 = 0;
69
}
70
71
/* trigger on falling and rising edge */
72
ISR(INT0_vect)
73
{
74
    /* get current counter to calculate pulse width */
75
    uint16_t counter = TCNT1;
76
    uint8_t bit = 2;
77
78
    /* do we got a low level? */
79
    if ((PIND & _BV(PD2)) == 0) {
80
        /* we got a 1 */
81
        if (counter > timer1_150ms && counter < timer1_250ms) {
82
            bitmap_buffer |= ((uint64_t) 1 << bitmap_counter);
83
            bit = 1;
84
        /* we got a 0 */
85
        } else if (counter > timer1_50ms && counter < timer1_150ms) {
86
            bit = 0;
87
        /* we got crap */
88
        } else {
89
            bit = 2;
90
        }
91
92
        /* in case we got no crap */
93
        if (bit != 2) {
94
            /* calculate the parity bits */
95
            if (bitmap_counter > 20 && bitmap_counter < 28) {
96
                parity_minute ^= bit;
97
            } else if (bitmap_counter > 28 && bitmap_counter < 35) {
98
                parity_hour ^= bit;
99
            } else if (bitmap_counter > 35 && bitmap_counter < 58) {
100
                parity_date ^= bit;
101
            }
102
103
            bitmap_counter += 1;
104
        }
105
    } else {
106
        /* on a rising edge we reset the counter */
107
        TCNT1 = 0;
108
    }
109
}
110
111
/* triggered if no edge change in about 1.75sec since last change */
112
ISR(TIMER1_OVF_vect)
113
{
114
    /* do all possible deterministic checks */
115
    if (bitmap_counter == 59 && bitmap->start_minute == 0 &&
116
        bitmap->start_time == 1 && bitmap->minute_parity == parity_minute &&
117
        bitmap->hour_parity == parity_hour &&
118
        bitmap->date_parity == parity_date)
119
    {
120
        dcf77_time_t time;
121
122
        /* bcd code to decimal */
123
        time.hour = bitmap->hour - ((bitmap->hour / 16) * 6);
124
        time.minute = bitmap->minute - ((bitmap->minute / 16) * 6);
125
        time.second = 0;
126
127
        uint8_t day = bitmap->day - ((bitmap->day / 16) * 6),
128
            month = bitmap->month - ((bitmap->month / 16) * 6),
129
            year = bitmap->year - ((bitmap->year / 16) * 6);
130
131
        /* logical checks */
132
        if (time.hour < 25 && time.minute < 60 && day > 0 && day < 32 &&
133
            month > 0 && month < 13 && year < 100)
134
        {
135
            /* we got a valid timestamp */
136
            printf("new time %i:%i:0 %i.%i.20%i\n", time.hour, time.minute,
137
                day, month, year);
138
            printf("blubs time %i:%i:%i\n", dcf77_time.hour, dcf77_time.minute,
139
            dcf77_time.second);
140
141
            /* save new timestamp information */
142
            dcf77_time_last = dcf77_time = time;
143
            dcf77_seconds_since_last = 0;
144
145
            /* reset seconds timer */
146
            timer2_counter = 0;
147
            TCNT2 = 0;
148
        }
149
    }
150
151
    /* reset everything */
152
    bitmap_buffer = 0;
153
    bitmap_counter = 0;
154
    parity_minute = 0;
155
    parity_hour = 0;
156
    parity_date = 0;
157
}
158
159
/* used to add every second a second to the dcf timestamp */
160
ISR(TIMER2_OVF_vect)
161
{
162
    if (timer2_counter == timer2_overflows) {
163
        /* add one second to the timestamp */
164
        if (dcf77_time.second == 59) {
165
            if (dcf77_time.minute == 59) {
166
                dcf77_time.hour = (dcf77_time.hour == 23) ? 0 :
167
                    dcf77_time.hour + 1;
168
                dcf77_time.minute = 0;
169
170
            } else {
171
                dcf77_time.minute += 1;
172
            }
173
            dcf77_time.second = 0;
174
        } else {
175
            dcf77_time.second += 1;
176
        }
177
178
        dcf77_seconds_since_last += 1;
179
180
        timer2_counter = 0;
181
    } else {
182
        timer2_counter += 1;
183
    }
184
}

Schöne Grüße
Oli

von Mike J. (emjey)


Lesenswert?

@ Oli (Gast)
So wie du das machen möchtest kann es funktionieren, muss aber nicht.

Bei deiner Variante mussst du ein paar dicke Keramikkondensatoren (10µF 
, 100nF) direkt an VCC/GND legen und kurz dahinter min. 200µF (oder 
mehr) um den Spannungseinbruch abzufangen.

Wenn du den Chip besser schützen möchtest kannst du die Zeilen zu einem 
P-Kanal MosFET oder Bipolaren PNP-Transiastor gehen lassen, dann 
funktioniert das dauerhaft und ohne warm zu werden.

Der kleine MosFET im Chip hat einen recht hohen RdsOn und erwärmt den 
Chip, das führt bei erhöhter Umgebungstemperatur zu dessen Ausfall.

Du sagst dass du nicht genug freie I/O-Pins hast, aber MOSI und SCK 
werden nicht zum ansteuern des 4094 genutzt, da hängt nur der 
ISP-Stecker dran.

von Oli (Gast)


Lesenswert?

Mike J. schrieb:
> Bei deiner Variante mussst du ein paar dicke Keramikkondensatoren (10µF
> , 100nF) direkt an VCC/GND legen und kurz dahinter min. 200µF (oder
> mehr) um den Spannungseinbruch abzufangen.
Sprich meine Spannungsversorgung ist nicht korrekt dimensioniert?
Wie komm ich denn an die korrekten Werte?

Mike J. schrieb:
> Wenn du den Chip besser schützen möchtest kannst du die Zeilen zu einem
> P-Kanal MosFET oder Bipolaren PNP-Transiastor gehen lassen, dann
> funktioniert das dauerhaft und ohne warm zu werden.
>
> Der kleine MosFET im Chip hat einen recht hohen RdsOn und erwärmt den
> Chip, das führt bei erhöhter Umgebungstemperatur zu dessen Ausfall.
Sind das Erfahrungswerte deinerseits? Ich lasse den ATMega8 gerade mit 
10 LEDs dauerhaft leuchten und habe bislang keine Probleme feststellen 
können.

Schöne Grüße
Oli

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Mal ein kleines Update.

Die Platine ist fertig und bestützt. Für die Spannungsversorgung hab ich 
nen einfaches 5V Schaltznetzteil genommen, also kein 7805 mehr.

Der Empfang vom Conrad Modul ist gut, das Multiplexn geht bei 32 PWM 
Stufen auch gut, allerdings gibt der Helligkeitssensor keine guten Werte 
raus.

Wenn ich fertig bin gibts noch ein abschließendes Foto.

Grüße Oli

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

bin nun endlich durch!
Läuft 1A und sieht einfach toll aus.

Grüße
Oli

von Humpawumpa (Gast)


Lesenswert?

Nette Arbeit, bin darauf gestossen weil ich grad selber an einer bin.
Kannst du mal Aussagen zum mechanischen Aufbau und zu den Gesamtkosten 
machen?

von Peter D. (peda)


Lesenswert?

Oli schrieb:
> allerdings gibt der Helligkeitssensor keine guten Werte
> raus.

Du mußt die LEDs während der Messung ausschalten, sind ja nur wenige µs.


Peter

von Oli (Gast)


Lesenswert?

Humpawumpa schrieb:
> Nette Arbeit, bin darauf gestossen weil ich grad selber an einer bin.
> Kannst du mal Aussagen zum mechanischen Aufbau und zu den Gesamtkosten
> machen?

Gesamtkosten ca. 50 Euro, also preislich durch aus überschaubar, wobei 
allein für das DCF Modul und den Rahmen 20€ drauf gehen und nochmal nen 
größerer Betrag für die LEDs sowie ca. 15€ für die Folie aus der die 
Buchstaben geschnitten wurden. Die Platine konnte ich kostenfrei 
fertigen lassen, wie teuer sowas wäre weiß ich nicht, aber eine 
Lochrasterplatine wäre wahrcheinlich günstiger :D

Zum mechanischen Aufbau:
Platine fertig bestückt und auf den Boden des schwarzen quadratischen 
IKEA Bilderrahmenes geschraubt. Dann auf die Platine Holzplatte 
geschraubt die die einzelnen LEDs entkoppelt und für Abstand zwischen 
den LEDs und der Glasplatte bringt, damit sich das Licht entsprechend 
entfalten kann. Von außen auf die Glasplatte eine schwarze Folie 
geklebt, aus der ich die Buchstaben hab schneiden lassen. Von der 
anderen Seite hab ich noch schwarzes Transparentpapier geklebt, zum 
einen als Diffusor und zum anderen damit die nicht beleuchteten LEDs von 
außen nicht so "hell" erscheinen.

Peter Dannegger schrieb:
> Du mußt die LEDs während der Messung ausschalten, sind ja nur wenige µs.

War mein Fehler, hab das Datenblatt falsch interpretiert, mittlerweile 
läuft das auch sehr gut, trotz laufender LEDs. :)

Grüße Oli

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.