Ein
DCF77-Zeitzeichen-Funkempfänger mit USB-Anschluss.
Früher war deren Anschluss an COM-Ports oder Parallelports üblich.
Diese für Bastler so bequemen Schnittstellen sind an heutigen Notebooks praktisch ausgestorben.
Ein kleiner, billiger, weitverbreiteter 8-poliger Mikrocontroller genügt für diese Aufgabe.
Für Bastler so praktisch:
Es gibt ihn im DIL-Gehäuse.
Passend für Steckboards.
Aber auch im SMD-Gehäuse, der locker in einen USB-Stecker passt.
Emuliert eine serielle Schnittstelle (COMx) per
CDC
und funktioniert unter Windows 2000 bis 7, 32 oder (schwierig) 64 bit, sowie unter Linux.
Sollte auch unter Windows 98, Me sowie auf dem Mac zum Laufen zu bringen sein.
Mittlerweile gibt es auch eine
überarbeitete Firmware-Version, die einen Joystick emuliert.
Ansonsten sieht alles genauso aus.
Übliche Funkuhr-Module
benötigen eine serielle Schnittstelle.
Bei den heute üblichen schnittstellen-verarmten PCs und Laptops
behilft man sich üblicherweise mit einem USB-Seriell-Konverter,
die preiswert zu haben sind und zumeist sogar funktionieren.
Nun fallen aus defekten Funkuhren und Funkweckern gelegentlich
funktionierende Funkuhr-Module an; ich musste also keins bei
Conrad kaufen.
Doch warum dann eine übliche Anpassschaltung fürs serielle Port
anschalten, wenn's auch gleich mit USB geht?
Dafür reicht ein 8poliger ATtiny45, gefüllt mit schlauer Software namens
V-USB und
AVR-CDC.
Damit erscheint der Funkempfänger wie gehabt an einem (neuen)
seriellen Anschluss, und man benötigt keinerlei Software-Anpassung.
Das Empfangssignal wird an alle Pins der (emulierten) seriellen
Schnittstelle angelegt, somit ist es für Empfangssoftware egal,
welche Leitung abgefragt wird.
Mit „Funkuhr.exe“ funktionieren
DCD,
DSRRI und
RxD;
das Signal
CTS funktioniert nicht.
Mit RxD erfolgt die Pulslängenmessung im Mikrocontroller,
sodass deren Auswertung nicht von der Rechnerlast abhängt,
also sicherer ist. Dabei ist die richtige Signalpolarität wichtig;
bei allen anderen Anschlüssen kann „Funkuhr.exe“ die Polarität
automatisch feststellen und ggf. automatisch negieren.
Mit der Auswahlmöglichkeit in Funkuhr.exe „Stromversorgung“
wird das Funkuhr-Modul aktiviert.
Dabei funktionieren
TxD und
DTR;
RTS funktioniert nicht.
Die Beschreibung der Software-Installation unten bezieht sich
auf Windows (2k, XP, Vista+).
Ich gehe davon aus, dass Linux- und Mac-Anwender wissen,
was sie tun müssen.
(Bei Linux ist m.W. als erstes ein Patch einzuspielen, um
eigentlich verbotene Bulk-Transfers bei Low-Speed zu erlauben.)
Die Schaltung versorgt den Mikrocontroller und den Funkempfänger
mit stabilisierten 3,3 V.
Die Taktversorgung erfolgt intern mit 16,5 MHz, synchronisiert
mithilfe der
SOF-Impulse des PCs.
SIG liefert das Empfangssignal, LOW bei DCF77-Trägerabsenkung.
ENA steuert den Funkempfänger, LOW = aktiv.
ENA wird (nur) für den USB-konformen Schlafmodus benötigt.
Die ungewohnte Stromversorgung mit dem Energie sparenden
Längsregler TPS71533 (kostenloses Muster von Texas Instruments)
ist notwendig, um für den Funkempfänger eine saubere 3,3 V
bereitzustellen.
Der Querstrom des Reglers beträgt lt. Datenblatt nur 3,2 µA
und ist deshalb kein Hindernis für den USB-konformen Schlafmodus.
Im Muster war die 5-V-Speisespannung nicht stabil genug,
um mit den üblichen zwei in Reihe geschalteten Siliziumdioden
eine hinreichend saubere 3,3-V-Betriebsspannung bereitzustellen,
damit der Funkempfänger ordentlich arbeitet.
Diskrete Längsregler mit Z-Dioden sind schwierig auszulegen,
weil für die geforderten geringen Querströme (max. 200 µA)
die handelsüblichen Z-Dioden nicht steil genug sind.
Querregler allein (TL431) beißen sich mit dem USB-Schlafmodus.
Der Aufbau erfolge naheliegenderweise auf einer Lochrasterplatte.
Diese ist in ihren Abmessungen passend für das preiswerte und trittfeste
Reichelt-Gehäuse
„GEH KS 21“
(etwa 0,72 €).
Das Funkempfängermodul wurde mit kleinen Schrauben des toten
Funkweckers locker (wichtig: ohne Verzug der Platine!)
befestigt.
Für die raumsparende Befestigung der Antenne wurde ein Loch
in die Platine gesägt und der Ferritstab mit Draht gesichert.
Fotos vom Versuchsmuster
Extrem Strom sparende Längsregler scheint es nur im SMD-Gehäuse zu geben;
dieser wurde auf die Leiterseite gelötet.
NC-Pins wurden kurzerhand mit auf Masse gelegt, der Lötkolben
war zu groß.
So wurde der winzige TPS71533 verlötet
Das Einschreiben der Firmware erfolgte im Muster mit einem
extra Steckboard, welches als
STK200-kompatibles Programmiergerät
hergerichtet wurde.
Das Programmieren im eingelöteten Zustand (in-system)
ist hier nicht vorgesehen. Deshalb die IC-Fassung.
Die Firmware kann frei verwendet werden
(FunkUsb.c: Public Domain; der V-USB-Teil: GNU LGPL).
Sie enthält einige Neuerungen, die einerseits die Synchronisation
des Oszillators betrifft, als auch erhebliche Änderungen an AVR-CDC
zur Unterstützung virtueller Statusleitungen.
Wie für alle AVR-CDC-Projekte wird kein Treiber benötigt,
Windows bringt den Treiber „usbser.sys“ mit.
Allerdings wird eine .INF-Datei benötigt, die beim ersten
Anstecken des Gerätes FunkUsb dem Hardware-Assistenten
mitgegeben wird.
Damit wird eine serielle Schnittstelle eingebunden, die von
gängigen Funkuhrempfangsprogrammen verwendet werden kann.
Hinweis: Mit dem Anstecken und Installieren wird noch keine
Zeit empfangen oder die PC-Uhr gestellt!
Das macht beispielsweise das nächste Programm.
Die LED leuchtet normalerweise halbhell.
[Nicht implementiert: Bei USB-Datenpaketen der Busaufzählung
wird sie dunkel getastet.]
Bei Funksignal (Trägerabsenkung) leuchtet sie hell.
Dazu muss eine Empfangssoftware laufen, die mindestens eine der
Leitungen TxD oder DTR aktiviert.
Im USB-Schlafmodus ist die LED aus.
… Ich habe mir letztes Wochenende ein SMD-Layout dafür erstellt.
Es funktioniert wunderbar!
Wenn Sie Interesse an dem Layout haben, schicke ich es Ihnen gerne zu.
Eine unbestückte Platine habe ich auch noch übrig.
Die Installation eines COM-Port-Treibers für das obige Modell ist mittlerweile
ziemlich kompliziert geworden. Einfach ist es nur unter Windows 2000 und Windows XP.
Die Probleme im einzelnen:
Kein Treiber auffindbar für Windows 98 / Me;
jedenfalls habe ich noch nichts brauchbares gefunden,
angeblich soll es aber etwas von Microchip geben
Windows Vista / 7 / 8 / 10 / Linux gleichermaßen verbieten das Starten
jenes USB-Gerätes, da es die USB-Spezifikation verletzt.
Demnach sind BULK-Pipes für Low-Speed-USB-Geräte verboten.
Dafür ist ein Zwischentreiber namens
lowcdc erforderlich.
Bei Linux sind andere bestimmte Maßnahmen erforderlich,
je nach Distribution.
→ Eine gesonderte INF-Datei (in der ZIP-Datei enthalten) erledigt das Problem für Windows.
Windows Vista / 7 / 8 / 10 in ihrer 64-Bit-Edition verweigern das Laden
unzertifizierter Treiber.
Dabei genügt nicht irgendein vertrauenswürdiges Zertifikat,
sondern es muss unbedingt ein bestimmtes von Microsoft ausgestelltes,
über 100 € (im Sonderangebot!) teures Zertifikat sein.
→ Da ich mir derartigen Spaß nicht leiste, bleibt nur, beim Booten F8
zu drücken und „Treiberzertifizierungszwang deaktivieren“ auszuwählen.
Es gibt auch entsprechende „Driver Signature Enforcement Disabler“-Programme,
aber diese sind keine sonderlich schöne Lösung.
Unter anderem deshalb, weil zumindest eins davon Windows in den
„Testmodus“ versetzt, was stets am Desktop ersichtlich ist
(der Schriftzug steht in den 4 Ecken).
Die neue Firmware
emuliert einen Joystick mit 1 Knopf und – seit April 2013 – 1 Hebel.
Das bietet folgende Vorteile:
Kein Treiber-Problem; jedes USB-fähige System unterstützt Joysticks
ohne extra Treiber, möglicherweise sogar Windows 95c
Prüfmöglichkeit der Funktion im der Systemsteuerung unter
Gamecontroller; keine weitere Software erforderlich.
Siehe animierter Screenshot rechts.
(So sieht's im Windows 8 aus.)
Anmerkung: Unter Windows 98 funktioniert die entsprechende
Systemsteuerungsanwendung nicht, weil diese – so auch die Funktion
joySetCapture()
– zwingend einen Joystick mit 2 Hebeln erwartet.
FunkUsb.exe funktioniert trotzdem, via
joyGetPosEx().
Die Zeitmessung erfolgt im Mikrocontroller — damit in einem echtzeitfähigen System —
die PC-seitige Telegramm-Dekodierung funktioniert auch bei hoher Rechenlast.
Die Hebel-Stellung ist ein 16-Bit-Wert, der den Zeitpunkt der letzten Flanke,
in ms seit USB-Reset, wiedergibt.
Voraussetzung ist natürlich, dass die PC-Software die Hebelstellung zur Zeitmessung heranzieht.
Der Zähler läuft in einer reichlichen Minute über,
aber Anwendungssoftware berechnet ohnehin nur Differenzen im Sekundenbereich.
Mikrocontroller darf kleiner ausfallen (ATtiny25 statt ATtiny45)
und ist in der Beschaffung auch billiger
Nachteil:
Verlust der Kompatibilität zu Software, die ein COM-Port erwartet;
für diesen Fall kann man ja auch noch die obige Firmware nutzen
Im übrigen muss man nichts an der Hardware ändern.
Einfach den Mikrocontroller tauschen oder neu flashen, das ist alles.
Klar, dass zumindest mein Programm
„Funkuhr.exe“
um dieses Interface erweitert wurde. Wie sollte ich's sonst testen …
Hinweis: Die Kombination beider USB-Interfaces in einer Firmware
ist zwar technisch möglich, bereitet aber noch mehr Komplikationen
in der Anwendung des Gerätes als nur ein Interface.
Außerdem: Der Firmware-Quelltext ist seit April 2013
mit einstellbaren Portpins
sowie für gcc4 geeignet umgestrickt.
Somit ist dieser besser auf eigene Bastelprojekte anpassbar.
Ein ATtiny25 ist nun fast voll.
In der Zeitschrift CQ-DL Oktober 2013 Seite 709 ff.
ist in etwa dieses Ding vorgestellt.
Der mechanische Aufbau … kein Kommentar.
Zum Nachbau habe ich die folgende Bemerkung:
Die Nachbausicherheit ist durch die Verwendung des (in der Tat exotischen) TPS71533
arg erschwert.
Schon dessen Beschaffung ist für den Normalverbraucher hinderlich.
(Ich hatte diesen gerade in der Bastelkiste herumliegen.)
Ganz zu schweigen von der Löterei.
Ich würde hier die Verwendung des
LP2950ACZ-3.3
im bequemen TO-92-Gehäuse empfehlen.
Dessen Querstrom ist zwar höher, aber:
Immer noch zulässig für USB, nämlich ≤ 200 µA bei 300 µA.
Hinfällig wenn man ENA oder ENA nicht beschaltet!
Auch das etwas höhere minimale Spannungsgefälle (Drop) stört hier nicht.
Ich habe die Schaltung auf Steckbrett getestet, und es funktioniert auch mit diesem Regler.
Das angegebene käufliche Funkuhr-Modul hat einen HIGH-aktiven ENA-Eingang.
Für USB-konformen Schlafmodus muss die Firmware für High-aktives ENA kompiliert werden.
Dazu ist in Zeile 36 der Datei FunkUsb.c
das Symbol ENA_INV auf 0 zu setzen.
Für den Bastler mag es OK sein, auf ENA oder ENA zu verzichten.
Dann zieht der Funkempfänger permanent 1..2 mA aus dem USB-Anschluss.
Muss man halt wissen, bevor man sich beschwert, wenn der Laptop-Akku unerwartet leer sein sollte.
Beim akkulosen Vorlaufempfänger unten ist das prinzipbedingt.
Eigentlich habe ich gerade für Funkamateure im Windows-Programm
die Empfangsmöglichkeit per Soundkarte eingebaut.
Fertige Empfangsmodule, noch dazu gekaufte, sind für Bastler geradezu unsportlich.
Die angegebene Ausrichtung der Antenne quer nach Frankfurt
am Main ist zwar theoretisch richtig,
praktisch sollte man die Antenne längs zum nächsten Störer
(Fernsehempfänger, Röhrenmonitor) ausrichten.
Der Zeitserver ntpd unterstützt mit seiner DCF77-Synchronisation
ausschließlich das serielle Port am RxD-Eingang.
Dieser lässt die einfache Messung der Pulslänge in 20-ms-Stückelung zu.
Den (ziemlich unübersichtlichen und antiquierten) Quelltext
auf einen Joystick zu ändern übersteigt meine Möglichkeiten.
Pardon!
Zumindest zum Stellen der Systemuhr habe ich ein Programm geschrieben
namens dcf77-js.c.
Der Quelltext benötigt keine zusätzlichen Bibliotheken
und kann somit recht zweckmäßig die Uhr eines autonomen
Raspberry Pi
stellen.
Dieser hat bekanntlich keine
Echtzeituhr.
Auf Grund der Knappheit der USB-Anschlüsse sowie der Verfügbarkeit
eines RS232-Anschlusses mit TTL-Pegeln ist jedoch dieser FunkUsb
für diesen Anwendungsfall Overkill,
es geht auch einfacher.
Standardmäßig benutzt es /dev/input/js0.
Der einzig mögliche Kommandozeilenschalter gibt einen
alternativen Joystick an.
Das Programm hat zwei Betriebsmodi:
Als Normalbenutzer empfängt es permanent und zeigt
die empfangenen Bits und die Uhrzeit mit farbig hervorgehobenen
Zeichen an. Sonst nichts. Siehe Bild rechts.
Als root läuft das Programm so lange, bis 2x hintereinander
eine korrekte Zeit empfangen wurde und die beiden Telegramme
um 1 Minute differieren.
Dann setzt es die Systemzeit und beendet sich.
Beim Beenden (mittels Strg+C) wird ein Histogramm
der empfangenen Bitlängen angezeigt.
Die Eimerbreite beträgt 20 ms.
Im Archiv befindet sich
zz. ein Kompilat für x86-64.
Das neueste Update fügt dem Joystick einen Slider (Schiebesteller) hinzu.
Dieser kodiert, in Millisekunden, die Zeit zwischen der Flanke (= Ereignis)
und dem Abholen des Reports.
Damit kann die begrenzte Auflösung bedingt durch den Zeitverzug von
GetReport (lt. USB-Standard bei Low-Speed: 10 ms, Windows: 8 ms)
auf 1 ms minimiert werden.
Es mag etwas Spielerei sein, die Auflösung der Vorderflanke eines
100-ms-Impulses so genau detektieren zu wollen,
der ntpd macht aber um diesen Umstand ziemlich viel
Federnlesen.
Mein Windows-Programm macht davon keinen Gebrauch.
Alle üblichen Funkuhr-Module haben den Nachteil,
dass die Dekodierung durch den PC vorgenommen werden muss und die Uhrzeit
nicht bereits beim Booten des Rechners bereitsteht.
Da die oben genannten Dinger einen Mikrocontroller enthalten,
kann er diese Aufgabe ohnehin übernehmen.
Nur ein geeignetes Protokoll ist noch auszudenken.
Natürlich fällt da die Wahl auf HID!
Nun muss ein derartiger Empfänger möglichst ein paar Minuten vor
dem Einschalten des Rechners laufen.
Da dieser Zeitpunkt sehr schwer vorherbestimmbar ist,
läuft die Funkuhr einfach akkubetrieben durch.
Die Alternative wäre die Speisung durch das PC-Netzteil im Standby-Modus.
Nur wenige USB-Buchsen eignen sich hierfür (typischerweise in der Nähe
oder an Stelle der PS/2-Buchsen
für Tastatur und Maus).
Und man muss auf dem Board passende Jumper umstecken oder
BIOS-Einstellungen
vornehmen.
Nicht sonderlich universell. Deshalb die Entscheidung für Akkus.
Primärbatterien
würden nur wenige Tage durchhalten, sofern an den Wetterdaten Interesse besteht.
Natürlich sollte der Controller auch das Nachladen des Akkus überwachen!
Dazu wird der Strom aus der USB-Buchse benutzt.
Auch ein USB-Ladegerät wird unterstützt und dazu die
Brücke zwischen DATA+ und DATA– von der Firmware detektiert.
Das Laden erfolgt mit Konstantstrom oder mit gelücktem Konstantstrom,
und die Spannung wird überwacht.
In der Firmware einstellbar ist der angeschlossene Akkutyp
(siehe Tabelle im Schaltplan).
Diese erste Schaltung kommt mit einigermaßen
konventionellen Bauelementen aus.
Mikrocontroller und Uhrenchip hängen fest an dem Akku.
Dieser muss durch seinen geringen Innenwiderstand etwaige Brummstörungen
aus dem PC unterdrücken.
Einfacher Schaltplan
Von T2 wird der Ladevorgang gesteuert.
Dessen Basiswiderstand R1 mal Stromverstärkung bestimmt den Ladestrom.
Er arbeitet so als Vorwiderstand und Konstantstromquelle für den Akku.
Die LED D1 zeigt den Ladevorgang an.
Aufgrund der Halbleiterstrukturen eines Bipolartransistors kann es hierbei
nicht zur „Rückspeisung“ eines angeschlossenen PCs kommen.
Die LED D2 dient zur Anzeige des Funkempfangs,
sinnfälligerweise nur dann,
wenn USB-Speisung (etwa ein Laptop, auch im Standby) vorliegt.
Mit dem Spannungsteiler aus R4 und R5 wird die
Betriebsspannung des Mikrocontrollers und damit die Akkuspannung überwacht.
Schade, dass es nicht ohne das Umprogrammieren des
RESET-Anschlusses geht.
Der Spannungsteiler wird bei Erreichen der Entladeschlussspannung
mitsamt dem Funkempfänger IC2 vom Portpin B4 abgeschaltet.
Der verbleibende Power-Down-Entladestrom von 0,5 µA liegt in der Größenordnung
jeder Akku-Selbstentladung.
Mit Primärbatterien kann diese Schaltung so nicht gespeist werden,
da der USB nicht die Speisung übernehmen kann, ohne die Batterien zu gefährden.
Dann müsste eine Schottky-Entkopplungsdiode in die Batterieleitung
eingefügt werden.
Die zweckfreie Ladeschaltung kann dabei durch 2 in Serie geschaltete
Dioden ersetzt werden, und 1 Mikrocontroller-Ausgang wird frei.
Wie oben beschrieben ist Batteriebetrieb trotz alledem nicht sinnvoll!
Am besten funktioniert diese Schaltung mit 2-3 NiMH-Akkus
wegen ihres geringen Innenwiderstandes.
Die Stützzeit bei 2000-mAh-Akkus
dürfte bei 1-2 Wochen (150 .. 300 h) liegen.
Diese NiMH-Variante lässt sich gut in einen
Funkwecker einbauen!
Man sollte aber darauf achten, dass dieser ein Batteriefach mit zwei
Rundzellen hat.
Das Enable-Signal vom eingebauten Funkwecker-Dekoder wird einfach ignoriert.
Der Funkwecker bekommt äußerlich einfach eine USB-Buchse eingebaut, und fertig.
Hier werden Controller und Funkuhr-Chip mit sauberen
(maximal) 3,3 V betrieben.
Dafür fehlt die direkte Anbindung des Akkus an den Controller.
Weiterhin kann — bei angeschlossenem Ladegerät — nicht die Leerlauf-Akkuspannung
gemessen werden, sondern nur die beim Laden.
Etwas komplexerer Schaltplan
Von T1 wird der Ladevorgang gesteuert.
Es muss ein moderner Logik-Level-Typ mit geringem Einschalt-Bahnwiderstand sein.
Dessen Drain-Source-Diode sorgt dafür,
dass die Schaltung auch ohne externe Speisung anläuft.
Der Ladestrom wird durch den Widerstand R1 festgelegt.
D1 verhindert die „Rückspeisung“ des angeschlossenen PCs vom Akku.
T1 wird leistungslos durchgesteuert, wenn Entladebetrieb vorliegt,
um dann die Drain-Source-Diode zu überbrücken.
Daher ist es bei dieser Schaltung nicht sinnvoll, den Ladevorgang
mit einer roten LED anzuzeigen;
stattdessen kann man den Ladeschluss mit der LED D3 anzeigen.
Die LED D2 dient zur Anzeige des Funkempfangs, aber nur dann,
wenn USB-Speisung vorliegt.
Mit dem Spannungsteiler aus R4 und R5 wird die
Akkuspannung überwacht.
Dieser muss so hochohmig wie möglich sein, da dieser nicht vom Akku
abgetrennt werden kann.
Bei Erreichen der Entladeschlussspannung wird der Controller in PowerDown
versetzt und der Funkempfänger IC2 vom Portpin B4 abgeschaltet.
Der verbleibende Entladestrom wird vor allem durch den Querstrom von IC3
von 2 µA bestimmt. R4 und R5 machen 0,2 µA aus.
Am besten funktioniert diese Schaltung mit einem Li-Ionen-Akku.
Aber auch NiMH und Primärbatterien funktionieren; man muss es dann
in einer erweiterten Version von Funkuhr.exe
richtig einstellen.
Der Innenwiderstand der Speisung ist wegen der nachfolgenden Stabilisierung
unkritisch.
Hinweis: Bei allen beiden o.a. Schaltungen gilt als „Funkempfänger“
eine Schaltung mit 3,3 V Betriebsspannung,
HIGH-aktivem Ausgang (d.h. HIGH bei Trägerabsenkung)
und HIGH-aktivem Enable (d.h. LOW = ausgeschaltet und Stromaufnahme < 1 µA).
Typischerweise aus Funkuhren oder Funkweckern ausgeschlachtet.
Nicht geeignet ist das
Conrad-Funkuhrmodul,
weil die Zener-Diode (als Überspannungsbegrenzung und Verpolschutz)
einen nicht abschaltbaren Querstrom schluckt, ggf. nachmessen, ggf. ausbauen!
Diese Schaltung ist die USB-Umsetzung des
SDR-Geradeausempfängers,
vorgestellt 2021/2022 bei mikrocontroller.net.
Da die Stromaufnahme bei gefräßigen 10 mA liegt,
lohnt sich Akkubetrieb nicht so recht.
Allenfalls ist ein „Smart-LiIon-Akku“mit eingebautem Überlade- und Tiefentladeschutz einzubauen.
Die Diode D1 verhindert das Entladen in Richtung USB.
Ohne Akkustütze können D1 und R8 gebrückt werden.
Als Quarz wurde der Wert von 15 MHz gewählt, weil dieser
den Betrieb von Timer0 mit Vorteiler 1 (statt 8 bei 16-MHz-Quarz) und
genauerer
(= weniger Phasenfehler) ADC-Triggerung zulässt
den Betrieb des ADC mit einem (zulässigen) Takt unter 1 MHz ermöglicht
(ADC-Taktteiler 16 statt 8 bei 12-MHz-Quarz, was zu 1,5 MHz ADC-Takt führt)
V-USB diese Frequenz unterstützt — inwieweit sich die Interrupts in die Quere kommen
muss noch untersucht werden.
Kein Funkempfänger-Modul sondern Software-Filter
Als Vorlaufempfänger sollte diese Schaltung von einem Hilfsnetzteil gespeist werden,
weil die Stromaufnahme deutlich über den zulässigen 500 µA liegt.
Der Vorteil dieser Schaltung liegt in der sehr guten Frequenzselektivität,
der Möglichkeit des Phasenempfangs und des Empfangs anderer Zeitzeichensender
sowie der Anpassungsmöglichkeit der Verstärkerschaltung für größere Reichweiten.
Auf der USB-Seite liefert diese Schaltung nicht nur das Funksignal
als Joystick-Feuerknopf-Signal, sondern in einem gesonderten HID-Report
alle 100 ms die Signalstärke, den Signal-Rauschabstand
und die Abweichung der Quarzfrequenz vom DCF77-Träger, der atomuhrgenau ist.
Die Abweichung der Quarzfrequenz vom Nennwert kann per HID-Feature-Report
eingestellt, um das Software-Quarzfilter
auf exakte 77,5 kHz Mittenfrequenz zu ziehen.
(Die Selektionsbandbreite liegt bei 30 Hz,
und wie bei allen Digitalfiltern ist die Nebenselektion
spaltfunktionsförmig.)
Die Antenne selbst und/oder eine weitere Vorselektion muss
Spiegelfrequenzen
von 15,5 kHz, 46,5 kHz und 108,5 kHz unterdrücken.
Die Firmware funktioniert soweit,
aber der Verstärker schwingt und lässt sich durch nichts davon abbringen.
Im Gegensatz zum Schaltplan ist am Antenneneingang ein FET-Spannungsfolger mit BF245,
und die Speisung jeder Transistorstufe ist mit RC-Glied 470 Ω / 100 nF geblockt.
Die Antenne benötigte tatsächlich 100 pF
(= 1 m RG174-Kabel)
Zusatzkapazität, um die Resonanzfrequenz von 78,xx kHz auf 77,5 kHz zu ziehen.
Das Programmieren des Mikrocontrollers erfolgt nun (2025) mit dem
soweit lauffähigen aber noch unfertigen avrpp-usb.
Er generiert selbständig eine einstellbare (für PIC16F1454: 8 V) Programmierspannung.
Es wird verdammt eng im Flash-Speicher, wenn da die Wetterdekodierung noch mit hineinsoll.
Ein halbes Kilobyte Deskriptoren und Konstantentabellen können in den EEPROM ausgelagert werden.
Zurzeit V-USB: 1660 Byte, Empfänger+Prüfer: 1540 Byte.
Zusätzlich zum vorher gehenden 1-Tasten-Joystick (zum Funkempfang wie bisher)
gibt es ein HID-Gerät, welches das Abfragen der momentanen Uhrzeit
und der empfangegen Wetterdaten der letzten 24 h erlaubt.
Es sind also 2 HID-Geräte drin.
Der Brown-Out-Detektor und der Watchdog wird hier nicht verwendet,
da diese zu viel Strom fressen, wenn der Akku einmal leer geworden ist.
Folgende Zustände können nahezu unabhängig voneinander eintreten:
Akku:
ladend (verboten für Primärbatterie)
Ladeschluss (nicht für Primärbatterie)
entladend
Entladeschluss (unwichtig für Primärbatterie)
nicht angeschlossen (offen)
kaputt (Kurzschluss)
USB:
nicht angeschlossen
5 V, speisend, D+ offen (alte Ladegeräte)
5 V, speisend, D+ mit D– verbunden (marktübliche Ladegeräte)
0 V, D+ mit D– verbunden (Ladegerät vom Netz getrennt)
5 V, nicht speisend, D+ mit 15 kΩ gegen Masse (USB-Standby, 500 µA erlaubt)
5 V, speisend, D+ mit 15 kΩ gegen Masse (USB-Standby, nur Notversorgung bei fehlendem oder kaputtem Akku)
5 V, speisend, Aktivität auf D– durch SOF alle 1 ms (normaler Betrieb am Computer)
0 V, D+ und D– ziehen nach Masse (Computer aus)
Firmware:
Hochlauf nach Reset
Funkempfang ohne USB-Aktivität
Funkempfang mit USB-Aktivität
Kein Funkempfang im PowerDown-Modus, mit oder ohne angeschlossenem USB-Kabel
Zustandsübergänge: TODO
Akku-Entlade-Betrieb ohne USB:
B0=H, B1=h (L), B2=z, B4=H, normaler Funkempfang.
Keine LED leuchtet oder blinkt wegen fehlender Speisung. Überwachungen:
B1=h = L bei USB-Anschluss
B2=z =B1 beim Anstecken eines konformen Ladegerätes
B5=z=ADC0 zum Erkennen vom Entladeschluss
Entladeschluss ohne USB:
B0=H, B1=h, B2=z, B4=L, Low-Power-Standby.
Stromentnahme am Akku messen! Überwachungen:
Integriert. Das Abspeichern der Daten erfolgt im Flash.
Um Wetterdaten für alle 90 Regionen aufzuzeichnen
muss der Empfänger rund um die Uhr laufen.
Alle 3 Minuten fällt ein 24-Bit-Wert an,
der mit einem 8-Bit-Datumsstempel versehen auf 32 Bit anwächst.
Pro Tag fallen so 20×24 = 480 DWORDs an,
was einen Speicherbedarf von knapp 2 KByte bedeutet.
RAM und EEPROM sind dafür viel zu klein.
Da dieser Flash-Bereich 1× pro Tag beschrieben wird,
entspricht die Haltbarkeit von 104 Schreibzyklen
einer garantierten Funktionszeit von 27 Jahren.
Genügt die LED-Ausgabe, passt es in einen ATtiny25.
So wie's jetzt ist passt es bequem in einen ATtiny45.
Ansonsten müsste alles in Assembler umgeschrieben werden,
dass es in einen ATtiny25 passt.
Alles ist jetzt C++ mit einem C++14-Feature:
Generierung der Logarithmentafel zur Compilezeit.
Implementiert sind Klassen mit Memberfunktionen,
was das Herumhampeln mit Strukturzeigern erspart.
Die printf()-Funktion ist weitestgehend in Assembler
und bietet weitere Möglichkeiten der Festkomma-Ausgabe: Komma statt Punkt,
String mit Längenbegrenzung, von-neumannisierte String-Zeiger.
Die Zeitdekodierung erspart sich elende 32-Bit-Register
und verwendet eine ausgefuchste Bitverteilungsroutine in Bytes.
Alle Prüfroutinen (Parität, Grenzen, BCD, Wochentag) sind eingebaut geblieben
und dabei eingedampft. Für Wetterdatendekodierung vorbereitet.
Der Programmaufbau ist an eine idle()-Prozedur gebunden,
die nach maximal 4 ms aufgerufen werden muss (also in jeder Warteschleife)
und die den einen DPC abarbeitet sowie sleep_cpu() aufruft.
So gibt es keine „Dummy-Interruptroutine“ wie bisher, was Flash und Stack spart.
Die serielle Schnittstelle kann jetzt jitterfrei mit 230400 Baud senden.
Ich habe die Baudrate auf 115200 festgelegt.
Möglich ist das durch Einsatz der USI; es ginge aber auch mittels Output Compare.
Sämtliche FIR-Filter sind durch IIR-Filter ersetzt.
Sowie die unübersichtliche Schwellwert- und Flankenfindung neu geschrieben.
Damit sinkt der RAM-Bedarf auf 58 Byte.
Sechs Register sind für die ISRs reserviert sowie GPIOR0, GPIOR1 und GPIOR2 verwendet.
Möglicherweise funktionieren meine Routinen etwas schlechter.
Die Dezibel-Angaben stimmen jetzt nicht mehr so ganz.
Den vielen Kleinkram und das Makefile, was nie mehr mit HEX-Dateien herumopert,
erwähne ich mal gar nicht erst…
Eigene Überlegungen
und Untersuchung der Eingangsbandbreite eines AVR-ADC
mit erfreulichem Ergebnis im Gegensatz zum Datenblatt,
ohne das kein SDR-Geradeausempfänger laufen würde
SDR-Geradeausempfänger mit ATtiny85 als Weihnachtsgeschenk 2021,
habe ich 2024 auf Steckbrett sklavisch
nachgebaut und funktioniert — genial einfach und nachbausicher.
Benötigt viel RAM, deshalb geht's nicht in einen ATtiny45.
Unschön ist die Lösung mit dem Software-Interrupt.
Das verbrät Flash-Bytes, Rechenleistung und Übersicht.
Richtig ist die Lösung mittels
DPC
und einer entsprechenden zentralen idle()-Funktion.
IMHO ist auch der RAM-Bedarf zu hoch.
Flash-Bedarfnur Empfängerteil, ohne DCF-Telegrammdekodierung,
ohne serielle Schnittstelle: 2400 Byte.
Letzter Stand: Auf 2884 Byte gepresst mit Telegrammdekodierung
und serieller Schnittstelle 38400 Baud und Quarzfrequenz 4 MHz.
Bei 8 oder 16 MHz 115200 Baud problemlos.
Komplett überarbeitete Programmstruktur ohne Software-Interrupt,
IIR- statt
FIR-Filter zur drastischen Senkung des RAM-Bedarfs,
viel Assembler bspw. für 24-Bit-Arithmetik,
neuer Pulslängen- und Lückendetektor, u.a. an IIR angepasst.
Passt in ATtiny45.
Stromaufnahme insgesamt ≈ 4 mA.
Funktionsprinzip:Unterabtastung!
Dasselbe als Phasenempfänger.
Damit ist der Mikrocontroller ATtiny85 zum Brechen voll.
Hinweis: Wetterdaten können damit nicht empfangen werden!
Sie werden schlichtweg nicht phasenkodiert gesendet. Letzter Stand: Unbedeutend kosmetisch modifiziert,
weil mangels Wetterdatenempfang uninteressant.
Schaltungswettbewerb: DCF77-Empfänger mit 4007 (ohne Amplitudenregelung)
hat bei mir nicht funktioniert!