Hands on Extra: OCXO-horloge

Opmerking: dit bericht is oorspronkelijk gepubliceerd in de Github-repository van de auteur voor dit project.

Zoals beschreven in het begeleidende Hands On-artikel is dit project een digitale klok die een zeer stabiele 10 megahertz-oscillator als tijdreferentie gebruikt. De oscillator is een Oven Controlled Crystal Oscillator of OCXO, een technologie die de afgelopen jaren aanzienlijke verbeteringen heeft ondergaan en veel minder stroom verbruikt tegen veel lagere kosten.

Het basisplatform hier is een OCXO gecombineerd met een Arduino Nano. De Nano biedt veel meer verwerkingskracht dan nodig is om een ​​eenvoudig uur-minuten-secondenhorloge te laten werken, maar hij is goedkoop en gemakkelijk te gebruiken. Het ruwe 10 MHz kloksignaal van de OCXO kan echter niet worden gebruikt om de Nano rechtstreeks aan te sturen. De Nano gebruikt een keramische resonator van 16 MHz voor zijn systeemklok en het is niet eenvoudig om de frequentie hiervan te veranderen naar bijvoorbeeld 10 MHz zonder significante wijzigingen aan de firmware van de Nano, aangezien het 16 MHz kloksignaal wordt gebruikt om het timingsignaal voor de USB af te leiden. verbinding die nodig is om het programma naar de microcontroller te laden. Een fysieke schakelaar om te schakelen tussen 16 MHz en 10 MHz na het laden van een programma was een optie, maar niet erg praktisch.

In plaats daarvan was de aanpak om interrupts te gebruiken. Zoals bij alle microprocessors ondersteunt de Nano interrupts, die, indien geactiveerd, de momenteel lopende programmacode kunnen pauzeren, CPU-registers naar een geheugenlocatie kunnen verplaatsen, een interrupt-serviceroutine kunnen uitvoeren en vervolgens de controller weer normaal kunnen laten werken door het register te herstellen. Interrupts kunnen doorgaans worden geactiveerd door een klokgestuurde timer of door een ingang op een speciale externe pin. De Nano bevat drie interrupttimers, en Timer0 en Timer1 kunnen ook worden aangestuurd door een externe klokbron via de T0- en T1-pinnen. Timers werken doordat ze worden geladen met een binair getal, dat vervolgens wordt verlaagd elke keer dat er een puls wordt gedetecteerd op de overeenkomstige pin. Wanneer de timer nul bereikt, wordt een interrupt geactiveerd. Als u het nummer wijzigt dat in de timer is geladen, verandert het interval tussen interrupts. Timer0 is 8-bits, terwijl Timer1 16-bits is.

Het was echter nog steeds niet mogelijk om de timers direct te starten met het 10 MHz signaal van de OCXO. Bij gebruik met een externe klok op T0 of T1 wordt het signaal op de pin bemonsterd ten opzichte van de 16 MHz systeemklok. Het gebruik van een maximale Nyquist-bemonsteringsfactor van 2,5 resulteert in een realistische maximale externe ingangsfrequentie van 6,4 MHz – alle hogere en inkomende pulsen op de pin worden gemist. Het toevoegen van een 4-bits binaire teller na de OCXO-uitvoer resulteert erin dat de teller één puls uitzendt voor elke 16 ontvangen pulsen, aangezien de teller telt vanaf 0000 Dat 1111. Wanneer de OCXO op 10 MHz werkt, is de frequentie van het telleruitgangssignaal dan 625 kHz. Daarom zal een timer die aftelt vanaf 62500 resulteren in een onderbreking elke tiende van een seconde. De seconden, minuten en uren worden vervolgens dienovereenkomstig bijgewerkt.

Componenten

Ik heb voor de Arduino Nano als klokmicrocontroller gekozen omdat deze dezelfde mogelijkheden biedt als de grotere Arduino-controllers, maar dan in een compactere vormfactor en erg goedkoop is. Het bevat met name algemene SPI- en I2C-interfaces die het eenvoudig maken om verbinding te maken met moderne beeldschermen met hun ingebouwde stuurprogramma’s. De OCXO is een Raltron Electronics OX4120A-D3-5-10.000-3.3. Elke geschikte OCXO kan worden gebruikt, zelfs een met een verschilfrequentie door de delerverhouding te veranderen. Het wordt ook geleverd in een standaard 14-pins dual-inline-package (DIP)-configuratie, hoewel er feitelijk slechts 4 pinnen worden gebruikt. De OCXO is een onderdeel van 3,3 volt, dus de LD1117V33C lineaire spanningsregelaar met lage uitval (LDO) ontleent deze spanning aan de 5 volt systeemspanning die wordt geleverd via de USB-C-aansluiting die wordt gebruikt om de klok van stroom te voorzien. Een andere, identieke, regelaar geeft 3,3V op het display weer. Het type regelaar is niet kritisch, er kunnen alternatieve LDO- of schakelaartypes worden gebruikt. De 4-bits teller is een 74HC191. Hoewel de teller wordt gevoed door een systeemspanning van 5 V, is de ingang compatibel met het logische OCXO-niveau van 3,3 V, zodat een spanningsomvormer niet nodig is.

De display bestaat uit zes Adafruit CharliePlex FeatherWings. Elke CharliePlex bestaat uit een reeks LED’s van 7×15 pixels die afzonderlijk kunnen worden aangestuurd in de grafische modus of met behulp van lettertypen die zijn ingebouwd in de Adafruit_IS31FL3731-bibliotheek. Ze worden gecommuniceerd via een I2C-verbinding. Het adres van elke CharliePlex kan op een van de twee waarden worden ingesteld: standaard 0x74, maar u kunt dit wijzigen in 0x77 door de soldeerverbinding te overbruggen. Om meerdere beeldschermen aan te sturen heb ik een breakout-bord gebruikt met een TCA9548A I2C-expanderchip, waarmee ik meerdere CharliePlexes kan aansluiten en elk op een afzonderlijke I2C-bus kan adresseren, waardoor adresbotsingen worden vermeden.

Als gebruikersinterface wordt een enkele roterende encoder met een momentane drukschakelaar gebruikt. Dit geeft het horloge een moderne, minimalistische uitstraling. Uiteraard kunnen losse schakelaars worden gebruikt met minimale hardware- en/of softwarewijzigingen.

Alle componenten die in dit project worden gebruikt, hebben een doorlopende verpakking voor eenvoudige constructie. Een overzicht van Digikey-productreferentienummers is beschikbaar in mijn Github-repository.

Printplaat

De printplaat is ontworpen in KiCad. PCB-ontwerpen zijn beschikbaar in de repository als KiCad-bestanden en in Gerber-formaat, zodat anderen deze kunnen produceren of wijzigen onder een Creative Commons-licentie.

Het eindbord is niet complex en is ontworpen als een dubbelzijdig bord dat gemakkelijk te solderen is. Het kan gemakkelijk in tweeën worden gebroken langs twee uitsparingen, hetzij met een zaag, hetzij door inkepingen en klikken. Als ze in secties worden opgedeeld, worden er pads meegeleverd, zodat headers kunnen worden gesoldeerd zodat ze op het ene bord achter het andere passen, waardoor een compactere vorm ontstaat die geschikt is voor een bureauklok. In deze vorm bevat de “bovenste” plaat het display en de roterende encoder, en al het andere op de achterplaat. De roterende encoder wordt in het midden van het bord geplaatst, maar kan naar een andere locatie worden verplaatst en via losse kabels worden bevestigd. Het prototype van de PCB werd besteld via JCL in China, maar elk PCB-huis zou het kunnen doen. Het onderste deel van het bord bevat de Arduino, I2C-expander, OCXO, breakout-keten en spanningsregelaars. De spanningsregelaars zijn gemonteerd met de lipjes naar buiten gericht, zodat indien nodig koellichamen kunnen worden gemonteerd. In het prototype was dit niet nodig, maar als de displays bijvoorbeeld een hoge algehele helderheid hebben, kan dit wel nodig zijn. Als de panelen rug aan rug worden geplaatst, moeten ze naast elkaar worden geplaatst, zodat alle componenten toegankelijk zijn vanaf de achterkant van de klok. Dit maakt het gemakkelijker om het horloge later te hacken als dat nodig is. Er zijn M3-gaten in de plaat ingebouwd voor eenvoudige montage en ze zijn uitgelijnd met de boven- en onderkant van de plaat als ze rug aan rug worden gemonteerd. Er kunnen metalen afstandhouders worden geïnstalleerd om de juiste afstand en mechanische stabiliteit te garanderen. Ook zijn er twee montagegaten boven en onder de OCXO geplaatst. Dit is om de mechanische stabiliteit te garanderen. De OCXO is een relatief zwaar onderdeel en wordt eenvoudig op het bord vastgehouden door vier pinnen in een DIP-socket. Deze wordt ook verticaal gemonteerd, dus niet bijzonder stabiel. Door de twee gaten kan een stuk draad worden gevoerd, waarbij de uiteinden in elkaar zijn gedraaid om de OCXO op zijn plaats te houden. Indien aanwezig kunnen ook kabelbinders of een klem worden gebruikt. Er zijn twee sets schema’s, PCB- en gerbers-bestanden. Dit komt omdat TCA9548A-modules in twee typen verkrijgbaar zijn. Adafruit heeft een rijafstand van 0,6 inch (de “N”-versie), terwijl sommige op eBay beschikbare modules een afstand van 0,7 inch hebben. Controleer nogmaals welke u gebruikt voordat u de PCB gaat vervaardigen.

Software

De software is ook beschikbaar in mijn Github-repository. De broncode is afhankelijk van slechts twee extra bibliotheken, de reeds genoemde Adafruit_IS31FL3731 en de gemeenschappelijke Wire-bibliotheek die seriële communicatie mogelijk maakt, essentieel voor de I2C-verbinding met het display. Het besturen van de displays vereist een individuele programmering van elk van de 105 LED’s op elke CharliePlex. Dit wordt gedaan met behulp van een set opzoektabellen (LUT’s) die onmiddellijk worden gedefinieerd nadat de bibliotheek in de broncode is opgenomen. Er is één LUT per nummer. Als je ernaar kijkt, wordt het duidelijk welk nummer in welke LUT is opgeslagen, en het is gemakkelijk om de LUT’s te vervangen door een nieuwe set die een ander lettertype vertegenwoordigt. Vervolgens controleert de installatiecode of alle CharliePlexen correct functioneren en stuurt als dat niet het geval is een foutopsporingsbericht naar elke aangesloten computer via de seriële USB-interface. Next Timer1 is geconfigureerd om pulsen van de externe klok te accepteren en af ​​te tellen vanaf 62499. Dit is 62499, niet 62500 om rekening te houden met de tijd die nodig is om de teller elke keer opnieuw in te stellen als deze nul bereikt en een onderbreking in de hoofdprogrammalus te activeren. De primaire functie van de hoofdlus is het oproepen van de subroutine die de roterende encoder leest. De encoder-subroutine probeert het stuiteren van schakelaars te elimineren en kan ook eenvoudig worden aangepast. De hoofdlus werkt ook de weergave bij, maar alleen wanneer de vlag is ingesteld door de interrupttimer. Er is hier ook een door de gebruiker instelbare helderheidsvariabele, evenals een variabele om de helderheid van het cijfer tijdelijk te verhogen wanneer deze wordt ingesteld. De code voor de interruptserviceroutine Timer1 volgt de hoofdlus. Dit wordt tien keer per seconde opgeroepen en zorgt ervoor dat de seconden, minuten en uren indien nodig worden verhoogd. Een paar LED’s tussen de seconden en minuten en nog een paar LED’s tussen de minuten en uren knipperen hier ook, en gaan elke halve seconde aan en uit. Hun functie kan eenvoudig naar wens worden gewijzigd. De laatste subroutine verzorgt de overdracht van updates naar het display via de TCA9548A I2C expander-chip.

Precisie

De OX4120A-D3-5-10.000-3.3 die in dit project wordt gebruikt, is een vaste OCXO; de frequentie ervan kan niet worden aangepast. Bij andere OCXO’s is afstemming mogelijk door een stuurspanning op een van de pinnen aan te leggen, maar ik heb gekozen voor een eenvoudigere oscillator waarvan werd aangenomen dat de stabiliteit zo hoog was dat voor dit project geen afstemming nodig was. Om de nauwkeurigheid van het horloge te controleren, is een referentiehorloge met een nog hogere nauwkeurigheid nodig. Het beste dat de auteur in zijn laboratorium had, was een HP 53150A-frequentieteller met zijn eigen OCXO-referentie. De laatste kalibratie vond plaats in 2013. Bij het meten van de OCXO-referentie schommelde de frequentie op de teller tussen 10.000.000 en 9.999.999. Dit suggereert overeenstemming, en dus nauwkeurigheid, beter dan 1 deel op 10.000.000. Omdat hij nieuwer is, is de kans groot dat de OCXO in deze klok beter is dan de HP-teller!