Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

DCF77 Analyzer/Clock v2.0

Componenten en benodigdheden

Arduino Mega 2560
× 1
Arduino UNO
× 1

Over dit project

Nadat ik het Arduino-platform had ontdekt, was ik verbaasd en mijn droom om ooit mijn eigen elektronica te ontwikkelen, werd werkelijkheid.

Zoals iedereen zal doen, begon ik met de basisschetsen, maar al snel wilde ik iets bruikbaars maken. Omdat ik altijd van radioklokken hield (in mijn geval synchroniseren ze met het DCF77-signaal uit Duitsland), besloot ik een klok te maken die niet alleen de tijd weergeeft, maar ook een klok die me laat zien wat er aan de hand is.

Na honderden uren sleutelen, ontelbare fouten maken, had ik eindelijk een werkende klok met mijn eigen code en printplaatontwerpen.

Foto's en video's van DCF77 Analyzer/Clock v1.0:

Maar later ontdekte ik het DCF77-superfilter van Udo Klein dat een schoon signaal geeft wanneer het radiosignaal niet zo goed is.

Dit is een apart Arduino Uno-bord met de Superfilter-software (je kunt het zien als een op zichzelf staande 'black box', die het signaal filtert) verbonden tussen de DCF77-antenne en de Arduino Mega die mijn schets uitvoert.

Dus ik maakte een 2.0-versie van de eerste klok:

  • volledig herschreven code
  • uitgebreide opmerkingen zodat hopelijk iedereen kan begrijpen wat er aan de hand is
  • een PIR-bewegingssensor toegevoegd om het stroomverbruik te verminderen
  • het DCF77-superfilter toegevoegd
  • extra display voor temperatuur of ander gebruik (zoals zonsopkomst/ondergang tijd)

Foto's en video's van de nieuwe DCF77 Analyzer/Clock v2.0:

Demo

klik HIER om de video te bekijken

Ingebouwde 'Grootvaderklok'

klik HIER om de video te bekijken

Het ontwerp

Het voorpaneel en de behuizing:

Het ontwerp van het frontpaneel is gemaakt in een freeware programma genaamd Inkscape (zie de download-URL aan het begin van deze pagina).

Het produceren van het frontpaneel bleek het moeilijkste. Ik heb veel geld uitgegeven om het in een lokaal FabLab te maken met een lasersnijder en een speciaal soort acryl met een aluminiumachtige coating. Het idee was om de gaten met de laser te snijden en de tekst en lijnen te graveren door de zeer dunne laag weg te branden die het zwarte acryl eronder blootlegt. Maar dit was een nachtmerrie omdat de lasersnijder niet in staat was om binnen de toleranties te produceren die ik nodig had vanwege intensief gebruik en 'misbruik' door veel gebruikers.

Toen kwam ik een online fotoservice tegen. Ze printen op allerlei materialen en een daarvan was een DiBond-paneel. De prijs was zeer goed, 28 Euro inclusief verzendkosten. Maar het resultaat viel in eerste instantie tegen omdat ze mijn ontwerp niet 1:1 afdrukten maar iets uitvergroot. Dus pas op als je besluit deze methode te gebruiken. Bel ze eerst en vraag of het mogelijk is om 1:1 te printen.

Na een telefoontje stuurden ze me een ander paneel met de juiste afmetingen. Het was beter dan verwacht, uitstekend!

Dan was er veel boren en frezen nodig:

Code

  • DCF Analyzer / Clock v2.1
  • Superfilterschets
DCF-analyser / klok v2.1Arduino
2020-01-18 bug release:energiebesparende schakelaar gerepareerd
/* ================================================================================DCF77-analyser / Klok versie 2 ================================================================================Deze schets is gratis software; u kunt het herdistribueren en/of wijzigen onder de voorwaarden van de GNU Lesser General Public License zoals gepubliceerd door de Free Software Foundation; ofwel versie 2.1 van de Licentie, of (naar uw keuze) een latere versie. Deze schets wordt verspreid in de hoop dat het nuttig zal zijn, maar ZONDER ENIGE GARANTIE; zonder zelfs de impliciete garantie van VERKOOPBAARHEID of GESCHIKTHEID VOOR EEN BEPAALD DOEL. Zie de GNU Lesser General Public License voor meer details. U zou samen met deze bibliotheek een kopie van de GNU Lesser General Public License moeten hebben ontvangen; zo niet, schrijf dan naar de Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ================================================================================Deze C++ code is verre van geoptimaliseerd omdat ik zelf een Arduino en C++ beginner ben. Maar zelfs nadat ik nu wat meer geleerd heb, wil ik de code simpel en leesbaar houden. Daarom heb ik de code misschien te veel gedocumenteerd om te helpen begrijpen wat er aan de hand is. Erik de Ruiter 2014-2020 mei 2014 Eerste versie maart 2016 - grote revisie... Juli 2016 - Start met het bouwen van de 2.0 Clock en het aanpassen van de schets Versie 2.1 datum 2020-01-18 - Powersafe functie opgelost. Versie 2.0 - Deze schets is aangepast voor mijn 2.0-versie van de DCF/Analyzer Clock. Het gebruikte standaard de Arduino MEGA en het DCF Superfilter en om de vele afzonderlijke LED's aan te sturen, gebruik ik nu de poorten van een Arduino Mega in plaats van een Maxim 7219-chip. Dit komt omdat het aansturen van LED's met veel verschillende spannings-/stroomspecificaties problematisch is met de Maxim-chip. Het aansteken van extra LED's heeft bijvoorbeeld invloed op (dim) de reeds brandende LED's. Aangezien ik geen elektronica-ingenieur ben, was mijn enige oplossing om de extra poorten van de Arduino Mega te gebruiken. Natuurlijk kun je transistors of extra chips gebruiken om de LED's aan te sturen, maar voor mij was dit de voor de hand liggende oplossing. - Alle Maxim Common Anode-displaycodes versie 1.72 verwijderd - Optie:gebruik een goedkope Ebay PIR-detector om selecteerbare displays uit te schakelen wanneer er geen activiteit wordt gedetecteerd. De uitschakelvertraging kan door de gebruiker worden ingesteld om te voorkomen dat het scherm wordt uitgeschakeld als een persoon niet beweegt, maar het scherm moet aan zijn. - Nu kan de weergave Nachtuitschakeling worden uitgeschakeld door beide waarden 'POWERSAVINGOFFTIME' en 'POWERSAVINGONTIME' nul te maken. - Vaste temperatuurweergave die niet wordt uitgeschakeld in de energiebesparende modus. - errorCounter display reset niet elk uur -fixed Version 1.71 - User optie om temperatuur min/max memory om middernacht te resetten Versie 1.7:- De resolutie van de temperatuur display is verbeterd:van 0,5 naar 0.1 graden Celsius Vanwege de tijd dat de DS18B20 sensor nodig heeft om de temperatuur om te zetten en om de code schoon te houden, wordt de temperatuurweergave eenmaal per minuut bijgewerkt. - Pariteitscontroleroutine geoptimaliseerd. - Betrouwbaardere controle op slechte DCF-gegevens, waardoor RTC-update met ongeldige gegevens wordt voorkomen. - EoB-fout wist nu de binnenste LED-ring zoals het hoort. - De DCF OK-LED geeft nu betrouwbaarder de toestand van het DCF-signaal weer. Schakelt onmiddellijk uit als er een fout optreedt en gaat alleen AAN als alle 3 pariteitsbits in orde zijn. Versie 1.6:- Gewijzigde temperatuurfunctie om slechts één keer per minuut te berekenen. Kreeg vreemde fouten voor de wijziging omdat ik een vertraging van 100 ms gebruikte om de DS18B20-sensor de tijd te geven om de temperatuur te berekenen. Maar de vertragingsfunctie is een heel slecht idee in de meeste c++-code, dus ik ben er eindelijk vanaf gekomen. Versie 1.5:- Volledige revisie van de scanSignal-functie en de rest van de code! Mijn eerste poging werkte, maar kan worden verbeterd... - De rPW- en rPT-led's werkten niet zoals ik had bedoeld, dus dat is nu gecorrigeerd. - De End of Buffer-foutcontroleroutine werkt nu zoals het hoort. - Ik heb een pariteitscontrole van het inkomende DCF-signaal ingebouwd. In het signaal worden 3 pariteitsbits verzonden, dus nu worden deze gecontroleerd en alleen als ze alle drie in orde zijn, wordt de ontvangen tijdinformatie geaccepteerd, wordt het display bijgewerkt en wordt de RTC gesynchroniseerd. indien gewenst kunt u 3 extra tweekleurige LED's (gemeenschappelijke kathode) bevestigen om te zien of elk van de 3 pariteitsbits in orde of defect is. - Ik heb de bedrading (of het wijzigen van de bedrading) veel gemakkelijker gemaakt, denk ik door alle PIN-configuraties in één gemakkelijk leesbare tabel te plaatsen - Zolang je 1 DS18B20 temp. sensor, heb ik de code bewerkt, zodat je niet langer het adres van het I2C-apparaat hoeft te achterhalen. - Grote opschoning van de code... - Energiebesparing door het uitschakelen van de displays (de klok blijft normaal functioneren) kan nu iets eenvoudiger worden geconfigureerd door twee variabelen POWERSAVINGONTIME en POWERSAVINGOFFTIME te bewerken. - enkele variabelenamen gewijzigd:- Maxim instances 'lc' en 'lc1' zijn nu MaximCC en MaximCA - Displaybeschrijving MaximDcfTime is nu DisplayTempWeek - DCF77SOUNDPIN is nu BUZZERSWITCHPIN - LED/Display-test na opstarten nu ingebouwd Korte beschrijving:Power On:Na het inschakelen wordt eerst een LED-test uitgevoerd. De LED's en displays lichten opeenvolgend op om het stroomverbruik laag te houden. Dan begint de klok DCF-pulsen te ontvangen en wanneer een minuutmarkering (tussenruimte van 2 seconden) wordt gedetecteerd, gaat de minutenmarkerings-LED branden en wordt de bufferteller gereset. De binnenste LED-ring toont nu de binnenkomende DCF-pulsen die ook in de buffer zijn opgeslagen. Op 3 momenten tijdens de ontvangst van data worden de pariteit DCF bits gecontroleerd om te zien of de data geldig is. Geldige gegevens ontvangen:Wanneer, aan het einde van de minuut, nadat de minuutmarkering is gedetecteerd (BF (Buffer Full)-LED brandt), alle drie de pariteitsbits in orde zijn ('DCF OK'-LED brandt), is de bufferinformatie gebruikt om tijd- en datuminformatie te extraheren. Vervolgens wordt de RTC-klok bijgewerkt ('RTC Synced'-LED brandt) en de informatie over de binnenste LED-ring wordt gekopieerd naar de buitenste LED-ring. De tijd-, datum- en weekweergave, dag-LED, zomer-/wintertijd en schrikkeljaar-LED-informatie wordt bijgewerkt met de nieuwe tijdinformatie. Geen geldige gegevens:Wanneer een of meer van de pariteitsbits niet in orde zijn vanwege een signaal met ruis, wordt de ontvangst van DCF-informatie voortgezet, maar wordt deze niet gebruikt om de RTC, display's en LED's bij te werken. De buitenste LED-ring, 'RTC synced' en 'DCF OK' LED's worden gereset. Tijd, datum, week, dag-LED, zomer-/wintertijd-LED en schrikkeljaar-LED worden niet beïnvloed en blijven de laatst ontvangen geldige waarden weergeven. De fout-LED's 'Periode Tijd' en/of 'Periode Met' geven de fout(en) aan en de weergave van de foutteller wordt bijgewerkt. Elk uur wordt de foutweergave op nul gezet. De EoB, End of Buffer-LED gaat branden wanneer er meer DCF-pulsen worden ontvangen voordat de minuutmarkering wordt gedetecteerd vanwege een signaal met ruis. (Als een minuutmarkering wordt gedetecteerd, mogen we niet meer dan 58 bits/pulsen hebben) Na de detectie van de minutenmarkering wordt een nieuwe cyclus gestart. Temperatuur:Bij de 30 seconden markering toont het temperatuurdisplay de hoge en lage waarden van de afgelopen periode na de laatste reset. Deurbel:Als de BEL-schakelaar AAN/HOOG staat, zal de deurbel (indien aangesloten) aan het begin van elk uur klinken. 's Nachts, een tijd die door de gebruiker in de code zelf is ingesteld, is de deurbel uitgeschakeld. Energiebesparing - scherm wordt uitgeschakeld Dit werkt alleen ALS de stroombesparingsschakelaar HOOG staat:1. NACHT UIT Op door de gebruiker ingestelde tijden worden de schermen 's nachts uitgeschakeld en' s ochtends ingeschakeld. Kijk naar de POWERSAVINGOFFTIME en POWERSAVINGONTIME variabelen. Vink de functie  aan om te selecteren WELKE schermen u 's nachts wilt uitschakelen. 2. PIR-SENSOR Sluit een PIR-sensor aan en activeer de PIR-optie POWERSAVE_BY_PIR en de vertraging op PIR_DELAY_TIME. Elke keer dat de PIR-detector beweging detecteert, wordt een minutenteller gereset, maar als er geen beweging wordt gedetecteerd langer dan de PIR_DELAY_TIME, worden de displays uitgeschakeld. Bij beweging gaan de displays direct aan. Opmerking:zoals eerder vermeld, zal de klok normaal functioneren terwijl de displays zijn uitgeschakeld. DCF-pieptoon:Met een schakelaar, aangesloten op pin BUZZERSWITCHPIN, hoor je de ontvangen DCF-bits binnenkomen. De toonduur is gelijk aan de pulsduur van de DCF-bits, dus 100 of 200 ms. Diversen:Wanneer de RTC-batterij leeg is of een verbindingsfout wordt gedetecteerd, brandt de RTC Error-LED. CREDITS:Ik heb veel geleerd van het werk van Matthias Dalheimer en Thijs Elenbaas die hun eigen DCF77-decoders maakten. Zonder hun werk had ik niet geweten waar ik moest beginnen. Uiteindelijk heb ik mijn eigen code geschreven (met stukjes en beetjes van hun ideeën), zodat ik kon begrijpen wat er gebeurt... Mijn code is verre van efficiënt of geavanceerd, maar het werkt wel en ik weet wat er aan de hand is. Interessante websites:- Brett Oliver :http://home.btconnect.com/brettoliver1/ - Joop Tap :http://www.jooptap.nl - Thijs Ellenbaas :http://thijs.elenbaas.net/2012/04/ arduino-dcf77-radio-clock-receiver-hardware-2/ - Mathias Dalheimer:https://github.com/roddi/DCF77-Arduino/blob/master/DCF77Servoclock/DCF77.h - DCF77 wikipedia:https://en .wikipedia.org/wiki/DCF77 - Veel meer DCF77-info:http://www.picbasic.nl/indexes_uk.htm - Mijn Flickr-website:https://www.flickr.com/photos/edr1924/albums - Mijn Github website:https://github.com/deruiter *///----------------------------------- -------------------------------------------------- ---------------------// Bibliotheken//------------------------ -------------------------------------------------- --------------------------------// Arduino (nieuw) Tijdbibliotheek .......... ........................... http://www.pjrc.com/teensy/td_libs_Time.html#include // Schakel deze regel in bij gebruik van Arduino Uno, Mega, etc.#include // een standaard DS1307-librar y die tijd retourneert als een time_t .......... http://www.pjrc.com/teensy/td_libs_DS1307RTC.html#include // Maxim 7219 geeft bibliotheek weer ..... .............................. http://playground.arduino.cc/Main/LEDMatrix// !!! OPMERKING:u moet een speciale versie van de Ledcontrol.h-bibliotheek gebruiken om Common Anode-ondersteuning te krijgen// omdat de Maxim-chip normaal gesproken alleen geschikt is voor gewone CATHODE-displays! #include //SPI-interfacebibliotheek .... ...................................... http://arduino.cc/en/Referentie/ SPI#include // OneWire geeft u toegang tot 1-draads apparaten gemaakt door Maxim/Dallas,// zoals DS18S20, DS18B20, DS1822 ................. ............. http://www.pjrc.com/teensy/td_libs_OneWire.html// De DallasTemperature-bibliotheek kan al dit werk voor u doen! ... http://milesburton.com/Dallas_Temperature_Control_Library#include //----------------------------- -------------------------------------------------- ---------------------------// Arduino UNO Pinverbindingen in een gemakkelijk leesbare tabel//// input - Rx - gebruikt voor programmering /communicatie met pc// uitgang - Tx - gebruikt voor programmering/communicatie met pc#define DCF77PIN 2 // ingang - DCF-signaal van antenneprint. Pin moet ingang onderbreken!#define PIRDETECTORPIN 3 // input - PIR detector:controleer op activiteit in de kamer om displays te activeren#define BUZZERSWITCHPIN 4 // input - SWITCH - zet DCF77 'piezo' piëzozoemer aan/uit / ON =HOOG , UIT =LAAG#define CHIMESWITCHPIN 5 // input - SWITCH - zet het uursignaal aan/uit / ON =HIGH, OFF =LOW#define POWERSAVESWITCHPIN 6 // input - SWITCH - zet de stroombesparingsfunctie aan/uit zodat weergave is altijd aan / AAN =HOOG, UIT =LAAG#define TEMPSENSORPIN 8 // input - Dallas One Wire DS18B20 temperatuursensor#define TEMPRETPIN 9 // input - DRUKKNOP - reset temperatuur min/max geheugen / HIGH =reset#define MAXIMCCLD 10 // output - CS/LOAD - pseudo SPI-verbinding met de Maxim 7219-chip - 7 segmentdisplays#define MAXIMCCCLK 11 // output - CLOCK - pseudo-SPI-verbinding met de Maxim 7219-chip - 7 segmentdisplays#define MAXIMCCDATA 12 // output - DATA - pseudo-SPI-verbinding met de Maxim 7219-chip - 7-segments displays// !! Pin 22 t/m 53 zijn alleen te gebruiken voor LED's#define LED_SUNDAY 22 // output - LED - Sunday#define LED_MONDAY 23 // output - LED - Monday#define LED_TUESDAY 24 // output - LED - Tuesday#define LED_WEDNESDAY 25 // output - LED - woensdag#define LED_THURSDAY 26 // output - LED - Thursday#define LED_FRIDAY 27 // output - LED - Friday#define LED_SATURDAY 28 // output - LED - zaterdag#define LED_CEST 29 // output - LED - Zomertijd CEST #define LED_CET 30 // output - LED - Wintertime CET#define LED_LEAPYEAR 31 // output - LED - Schrikkeljaar#define LED_RTCERROR 32 // output - LED - probleem met lezen van RTC-gegevens (lege batterij/aansluiting)#define LED_RTCSYNC 33 // output - LED - Aan wanneer RTC succesvol is gesynchroniseerd met de DCF-tijd#define LED_TEMP 34 // output - LED - temperatuur wordt weergegeven#define LED_OPTION1 35 // output - LED - optionele 1 data wordt weergegeven#define LED_OPTION2 36 // output - LED - optionele 2 gegevens worden weergegeven#define LED_ERRORPT 37 // output - LED - DCF Periode Tijdfout#define LED_ ERRORPW 38 // output - LED - DCF Periode Breedte fout#define LED_BUFFERFULL 39 // output - LED - Buffer vol indicator, daarna worden de data geanalyseerd#define LED_MINUTEMARKER 40 // output - LED - Einde van DCF datastroom gedetecteerd voor buffer is gevuld, gegevens zijn beschadigd#define LED_BUFFEROVERFLOW 41 // output - LED - Meer gegevens ontvangen in één minuut dan verwacht vanwege slecht signaal#define LED_DCFSTATUS 42 // output - LED - Aan als we goede DCF-gegevens hebben#define LED_POWERSAVE 43 / / output - LED - Energiebesparingsmodus is geactiveerd, sommige displays zijn uit#define LED_PARITY1PASS 44 // output - LED - Pariteit 1 bit is OK#define LED_PARITY1FAIL 45 // output - LED - Pariteit 1 bit FAILED#define LED_PARITY2PASS 46 // output - LED - Pariteit 2 bit is OK#define LED_PARITY2FAIL 47 // output - LED - Pariteit 2 bit FAILED#define LED_PARITY3PASS 48 // output - LED - Pariteit 3 ​​bit is OK#define LED_PARITY3FAIL 49 // output - LED - Pariteit 3 bit FAILED#define LED_PIRMOTION 50 // output - LED - Aan wanneer PIR beweging detecteert/ / Analoge pinnen#define BUZZER A7 // output - Piezo buzzer voor DCF77 'piep' (naar '+' van de buzzer)#define SPEAKERVOLPIN A6 // output - Sound Board volume - LOW =volume een tandje lager. SPEAKERVOLUME bepaalt hoe vaak deze uitgang wordt geactiveerd na inschakelen#define CHIMEPIN A5 // output - Chime Activate - OUTPUT LOW =Activeer Chime op Adafruit Soundboard FX// GEBRUIKT voor DS1307 RTC // I2C DATA - sluit aan op Real Time Clock pcb/ / GEBRUIKT voor DS1307 RTC // I2C CLOCK - sluit aan op Real Time Clock pcb//-------------------------------- -------------------------------------------------- ------------------------// DS18B20 initialisatie//-------------------- -------------------------------------------------- ------------------------------------OneWire ds(TEMPSENSORPIN); // definieer Onewire-instantie DS//------------------------------------------ -------------------------------------------------- --------------// Maxim 7219 Matrix Display initialisatie//--------------------------- -------------------------------------------------- -----------------------------/* clearDisplay(int addr) .............. ............................... wist het geselecteerde scherm MaximCC.shutdown(int addr, boolean) ...... ........................... de MAX72XX uit de energiebesparende modus halen (true =sleep, false =wake) MaximCC.setIntensity(int addr , waarde) .............................. stel een gemiddelde helderheid in voor de Leds (0=min - 15=max) MaximCC .setLed(int addr, int row, int col, boolean state) .......... schakel de led in rij, kolom in. onthoud dat indices beginnen bij 0! MaximCC.setRow(int addr, int row, byte value) ...................... deze functie heeft 3 argumenten. voorbeeld:MaximCC.setRow(0,2,B10110000); MaximCC.setColumn(int addr, int col, byte value) ................... deze functie heeft 3 argumenten. voorbeeld:MaximCC.setColumn(0,5,B00001111); MaximCC.setDigit(int addr, int digit, byte value, boolean dp) ...... deze functie neemt een argument van het type byte en drukt het corresponderende cijfer af in de gespecificeerde kolom. Het bereik van geldige waarden loopt van 0..15. Alle waarden tussen 0..9 worden afgedrukt als cijfers, waarden tussen 10..15 worden afgedrukt als hun hexadecimale equivalent MaximCC.setChar(int addr, int digit, char value, boolean dp) ....... zal weergeven:0 1 2 3 4 5 6 7 8 9 ABCDEFHLP; - . , _  (de spatie of spatie) POWERSAVESWITCHPIN ***** Stel het aantal apparaten in dat u heeft ***** Maar de maximale standaardwaarde van 8 MAX72XX zal ook werken. LedConrol(DATAIN, CLOCK, CS/LOAD, AANTAL MAXIM CHIPS) */// lc is voor de Maxim displaysLedControl MaximCC =LedControl(MAXIMCCDATA, MAXIMCCCLK, MAXIMCCLD, 7, false); // Definieer pinnen voor Maxim 72xx en hoeveel 72xx we gebruiken//----------------------------------- -------------------------------------------------- ---------------------// Gebruikersinstellingen, variabelen en arraydefinities//------------------ -------------------------------------------------- --------------------------------------// Onderstaande waarde is geen pincode maar een waarde om in te stellen hoe vaak de 'Lower volume'-ingang op de geluidskaart wordt geactiveerd// zodat het volume van de geluidskaart desgewenst kan worden verlaagd na het inschakelen. #define SPEAKERVOLUME 12// Kies of u een test van alle LED's en displays na een opstart// '1' =Ja, '0' =Nee#define PERFORM_LED_TEST 1// Vertraging tussen elk 7-segments display in ms#define LEDTEST_DELAY_DISPLAYS 600// Vertraging tussen elke LED in de LED-ring en andere LED's in ms#define LEDTEST_DELAY_LED_RING 20// Kies of u de DS18B20 temperatuursensor EENMAAL naar de hoogste resolutie wilt configureren.// dit is nodig na gebruik van de sensor voor de ste tijd. Na het draaien van de software// met deze instelling één keer AAN, zet u deze uit.// '1' =AAN, '0' =UIT#define CONFIGURE_DS18B20 0// POWERSAVE TIME - VERPLICHTE waarden!//// om dag en nacht tijd. Dit wordt gebruikt voor de energiebesparende weergave AAN en UIT tijd// EN om te bepalen of de gong zal worden geactiveerd (overdag).//// ALLEEN de displays worden uitgeschakeld op energiebesparende tijd, de klok blijft volledig actief./ / OM het uitschakelen van het scherm op elk moment UIT TE SCHAKELEN, zet u de stroombesparingsschakelaar op UIT//// Stroombesparingsschakelaar AAN:schermen worden uitgeschakeld op de ingestelde nachttijd // EN als de POWERSAVE_BY_PIR-functie indien geactiveerd en daar is geen // beweging voor de ingestelde PIR_DELAY_TIME.// Stroombesparingsschakelaar UIT:displays altijd aan, bel alleen overdag.//// waarden zijn in 'Uur'-formaat, dus 20:00 uur is '20', NIET 20:00 of 8PM...#define POWERSAVINGOFFTIME 9 // displays zijn geactiveerd#define POWERSAVINGONTIME 22 // displays zijn uitgeschakeld// Gebruikersoptie:activeer de displays alleen als er activiteit is in de kamer// '1' =ON, '0 ' =UIT#define POWERSAVE_BY_PIR 1// vertraging in MINUTEN om te wachten na geen detectie voordat de displays worden uitgeschakeld#define PIR_DELAY_TIME 30// Gebruikersoptie om de temperatuur min te resetten /max geheugen om middernacht// '1' =Reset om middernacht, '0' =Alleen handmatige reset#define TEMRESET_MIDNIGHT 1//---------------------- -------------------------------------------------- -------// definieer diverse parameters#define DS1307_I2C_ADDRESS 0x68 // definieer het RTC I2C-adres#define DCF_INTERRUPT 0 // Interruptnummer geassocieerd met pin// definitie van Maxim 7219 weergavenummer bedradingsvolgorde// eerste Maxim 7219 in bedrading 'daisychain' moet '0' zijn, volgende '1' etc.// GEMEENSCHAPPELIJKE KATHODE DISPLAYS#define LedRingInner 0#define LedRingOuter 1#define DisplayBufferBitError 2#define DisplayPeriodPulse 3#define DisplayTempWeek 4#define DisplayDate 5#define DisplayTime 6/ / definitie van helderheidsniveaus van het scherm#define BrightnessLedRingOuter 1#define BrightnessLedRingInner 1#define BrightnessDisplayTime 1#define BrightnessDisplayDate 7#define BrightnessDisplayTempWeek 15#define BrightnessDisplayPeriodPulse 2#define BrightnessDisplayBufferBitErrorstatic 0 tatic unsigned long trailingEdge =0;unsigned long previousLeadingEdge =0;// gebruikt in vluchtige unsigned int DCFSignalState =0; // interruptvariabelen hebben ALTIJD een vluchtige kwalificatie nodig!!// gebruikt in 
int previousSecond =0;unsigned int previousSignalState =0;// DCF-buffers en indicatorsstatic int DCFbitBuffer[59]; // hier worden de ontvangen DCFbits opgeslagenconst int bitValue [] ={1, 2, 4, 8, 10, 20, 40, 80}; // dit zijn de decimale waarden van de ontvangen DCFbits// pas na het starten op een nieuwe minuut de ontvangen bits weergeven op de binnenste LED-ringboolean MinuteMarkerFlag =false;int bufferPosition =0;int previousMinute =0;int previousHour =0;// variabelen om te controleren of DCF-bits valdbool zijn dcfValidSignal =false;int dcfP1counter =0;int dcfP2counter =0;int dcfP3counter =0;int dcfParityCheckP1 =0;int dcfParityCheckP2 =0;int dcfParityCheckP2 =0;int dcfParityCheckP2 =0;int dcfParityCheckP2 =0;int dcfParityCheckP2 =0;int dcfParityCheckP2 =0;int dcfParity inint dcfMinute =0;int dcfHour =0;int dcfDay =0;int dcfWeekDay =0;int dcfMonth =0;int dcfYear =0;int dcfDST =0;int leapYear =0;// variabelen die worden gebruikt om weeknummer- en dagnummerwaarden op te slaan dayNumber;int weekNumber;// error counter variableint errorCounter =0;boolean errorCondition =false;// diverse variabelenboolean daytimeChange =true;boolean dayTime =false;int dcf77SoundSwitch =0;// temperatuurvariabelenbyte present =0;byte DS18B20Data[12];int maxTemp =0;int minTemp =0;int lowByte =0;int hi ghByte =0;float tempReading =0;int tempCelsius =0;boolean tempResetButton =false;// PIR-detectorvariabelenint pirActivity =0;int pirDisplaysState =1;unsigned int pirTimer =0;unsigned long previousTimePIR =0;//==============================================================================// INSTELLEN//==============================================================================void setup () {// initialiseer seriële communicatie Serial.begin (9600); // initialiseer PIN-verbindingen pinMode (DCF77PIN, INPUT); pinMode (TEMPRESETPIN, INGANG); pinMode (ZOEMERSCHAKELAAR, INGANG); pinMode (CHIMESWITCHPIN, INPUT); pinMode (VERMOGENSSCHAKELAAR, INGANG); pinMode (PIRDETECTORPIN, INGANG); pinMode (CHIMEPIN, UITGANG); pinMode (LUIDSPREKERVOLPIN, UITGANG); // initialiseer LED-pinnen 22 - 50 voor (int i1 =22; i1 <=50; i1++) {pinMode (i1, OUTPUT); } // Initialiseer variabelen, LED-displays en LED's initialize(); // Initialiseer DCF77-pulsonderbreking op pin DCF_INTERRUPT, op zoek naar een verandering van het signaal, // dus ofwel stijgende of dalende flankpulsen zullen de interrupt-handler activeren en // de int0handler-functie uitvoeren. attachInterrupt(DCF_INTERRUPT, int0handler, CHANGE); // Initialiseer RTC en stel in als SyncProvider. // Latere RTC wordt gesynchroniseerd met DCF time setSyncProvider(RTC.get); // de functie om de tijd van de RTC te krijgen // controleer of RTC de systeemtijd heeft ingesteld if (timeStatus() !=timeSet) { // Kan niet synchroniseren met de RTC - activeer RTCError LED digitalWrite (LED_RTCERROR, HIGH); } else { // RTC heeft de systeemtijd ingesteld - dim RTCError LED digitalWrite (LED_RTCERROR, LOW); } // Stel na het inschakelen het luidsprekervolume van de Adafruit Audio Board in // initialiseer beide pinnen op LAAG, wat de standaard uitgangsstatus is digitalWrite (SPEAKERVOLPIN, LOW); digitalWrite (CHIMEPIN, LAAG); // verlaag het standaardvolume van het klankbord met 'SPEAKERVOLUME'-stappen voor (int i =0; i <=SPEAKERVOLUME; i++) {digitalWrite (SPEAKERVOLPIN, HIGH); vertraging (100); digitalWrite (LUIDSPREKERVOLPIN, LAAG); vertraging (100); } // De volgende functie mag maar één keer worden uitgevoerd. // Het wordt gebruikt om de temperatuurresolutie van de DS18B20-sensor te configureren als (CONFIGURE_DS18B20 ==1) { configureDS18B20(); } // gebruik voor testdoeleinden en/of handmatig instellen van de RTC-tijd // setTime(23, 59, 40, 31, 12, 13); // RTC.set (nu ()); // Vraag de temperatuurconversie calculatorTemp(); // controleer of een LED-test nodig is if (PERFORM_LED_TEST ==1) { // doe een LED-test ledTest(); } else { // als we geen LED-test doen, moeten we even wachten tot de DS18B20-sensor gereed is vertraging (750); } // Haal nu de temperatuur van de sensor en toon deze displayTemp(); // activeer errorCounter-weergave na LED-test ledDisplay (DisplayBufferBitError, "R", 0);}//==============================================================================// LUS//==============================================================================void loop(){ // controleer eerst of de pulsrichting is veranderd (stijgend of vallen) // anders zouden we dezelfde puls blijven evalueren if (DCFSignalState! =previousSignalState) { // 'reset'-status van variabele previousSignalState =DCFSignalState; // evalueer inkomende puls scanSignal (); } // controleer of schakelaars zijn gewijzigd en handel ernaar checkSwitches(); // controleer op PIR-beweging checkPIR(); // voer taken uit die slechts één keer per seconde, minuut of uur mogen gebeuren //--------------------------------- ------------------------------------------- takenEverySecond(); takenElkeMinuut(); takenEveryHour();}//================================================================================================================//// Functienaam:processDcfBit// opgeroepen vanaf://// Doel:Evalueert het signaal zoals het wordt ontvangen. Bepaalt of we een "1" of een "0"// hebben ontvangen en voert controles uit om te zien of de pulstiming binnen de limieten valt// Parameters:geen// Retourwaarde:geen////================================================================================================================/* puls pulsbreedte |- -| |-- --| |----- END OF MINUTE-markering:2000 ms -----| ___ _______ ___ ___ _______ | 0 | | 1 | | 0 | | 0 | | 1 | | | | | | | | | | | | | | | | | | | | | ______| |_______________| |___________| |_______________________________________| |_______________| |__ _ _ _ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1000 2100 2000 2200 3000 3100 GEEN PULSE 5000 5100 6000 6200 < REJECTED error(LED_ERRORPW); errorCondition =true; } //-------------------------------------------------------------------------------- // CHECK PULSE TIME //-------------------------------------------------------------------------------- // If the detected pulse is too short it will be an incorrect pulse that we shall reject // should be 100 and 200 ms ideally if (((trailingEdge - leadingEdge) <70) || ((trailingEdge - leadingEdge)> 230)) { //rPT - ERROR:Pulse Width too short or too long -> REJECTED error(LED_ERRORPT); errorCondition =true; } // if we had an error return and start over if (errorCondition ==true) { errorCondition =false; // although we have an error, store current rising edge time to compare at the next Rising-Edge. previousLeadingEdge =leadingEdge; opbrengst; } //-------------------------------------------------------------------- // no errors found so now we can continue //-------------------------------------------------------------------- // first we turn any error Led's OFF digitalWrite(LED_ERRORPW, LOW); digitalWrite(LED_ERRORPT, LOW); digitalWrite(LED_BUFFERFULL, LOW); // previous BF digitalWrite(LED_BUFFEROVERFLOW, LOW); // previous EoB digitalWrite(LED_MINUTEMARKER, LOW); // previous EoM // END OF MINUTE check, looking for a gap of approx. 2000ms if (leadingEdge - previousLeadingEdge> 1900 &&leadingEdge - previousLeadingEdge <2100) { // end of minute detected:finalizeBuffer(); } // refresh previousLeadingEdge time with the new leading edge time previousLeadingEdge =leadingEdge; //-------------------------------------------------------------------------------- // process DCF bits //-------------------------------------------------------------------------------- // distinguish between long and short pulses if (trailingEdge - leadingEdge <170) { // call processDcfBit function and sent it the value '0' processDcfBit(0); // if switch is HIGH, the DCF pulses are audible if (dcf77SoundSwitch ==1) buzzer(100); } else { // call processDcfBit function and sent it the value '1' processDcfBit(1); // if switch is HIGH, the DCF pulses are audible if (dcf77SoundSwitch ==1) buzzer(200); } } // if (DCFSignalState ==0)} // void scanSignal();//================================================================================================================//// Function name :processDcfBit// called from ://// Purpose :after reception of one good DCF bit, do some checks and save it in the DCFbitBuffer array// Parameters :none// Return value :none////================================================================================================================void processDcfBit(int dcfBit){ //-------------------------------------------------------------------- // display values on the 7 segment displays //-------------------------------------------------------------------- // display bufferPosition, digits 7,6 MaximCC.setChar(DisplayBufferBitError, 7, bufferPosition / 10, false); MaximCC.setChar(DisplayBufferBitError, 6, bufferPosition % 10, false); // display received DCFbit, digit 4 MaximCC.setChar(DisplayBufferBitError, 4, dcfBit, false); //-------------------------------------------------------------------- // display incoming DCF bits on inner LED ring //-------------------------------------------------------------------- // only if we have valid DCF data or after an Minute Mark (EoM) signal // activate the inner LED ring and diplay incoming data if (dcfValidSignal ==true || MinuteMarkerFlag ==true) { // display received bits on inner LED ring MaximCC.setLed(LedRingInner, bufferPosition / 8, bufferPosition % 8, dcfBit); } //-------------------------------------------------------------------- // // Fill DCFbitBuffer array with DCFbit //-------------------------------------------------------------------- DCFbitBuffer[bufferPosition] =dcfBit; //-------------------------------------------------------------------- // Parity check //-------------------------------------------------------------------- // DURING reception of the DCF bits, calculate and display the results of the DCF parity check. // // There is a Parity bit for the minutes, the hours and for the date. // DCF77 works with EVEN parity, this works as follows:// The hours for example have 6 bits plus a paritybit. The bits with value 1 are add up including the paritybit, // the result must be an even number. If there is a bit wrong received, a 0 is as 1, or a 1 is as 0 received, // then the result is uneven. source:http://www.picbasic.nl/frameload_uk.htm?http://www.picbasic.nl/info_dcf77_uk.htm if (bufferPosition ==0) { // reset the parity LED's digitalWrite(LED_PARITY1PASS, LOW); digitalWrite(LED_PARITY1FAIL, LOW); digitalWrite(LED_PARITY2PASS, LOW); digitalWrite(LED_PARITY2FAIL, LOW); digitalWrite(LED_PARITY3PASS, LOW); digitalWrite(LED_PARITY3FAIL, LOW); // reset variables dcfP1counter =0; dcfP2counter =0; dcfP3counter =0; dcfParityCheckP1 =0; dcfParityCheckP2 =0; dcfParityCheckP3 =0; } // ---------------------------------------- // First parity check:minute bits // ---------------------------------------- if (bufferPosition ==28) { for (int i =21; i <=27; i++) { // count the number of bits with the value '1' dcfP1counter +=DCFbitBuffer[i]; } // perform P1 parity check. Parity is OK if the sum is an EVEN value if ((DCFbitBuffer[28] + dcfP1counter) % 2 ==0) { // Parity1 PASS LED ON digitalWrite(LED_PARITY1PASS, HIGH); // Parity P1 PASS dcfParityCheckP1 =1; } else { // Parity1 FAIL LED ON digitalWrite(LED_PARITY1FAIL, HIGH); // we have no valid data! dcfValidSignal =false; // Turn DCF OK LED OFF digitalWrite(LED_DCFSTATUS, LOW); } } // ---------------------------------------- // Second parity check:hour bits // ---------------------------------------- if (bufferPosition ==35) { for (int i =29; i <=34; i++) { dcfP2counter +=DCFbitBuffer[i]; } // perform P2 parity check. Parity is OK if the sum is an EVEN value if ((DCFbitBuffer[35] + dcfP2counter) % 2 ==0) { // Parity2 PASS LED ON digitalWrite(LED_PARITY2PASS, HIGH); // Parity P2 PASS dcfParityCheckP2 =1; } else { // Parity2 FAIL LED ON digitalWrite(LED_PARITY2FAIL, HIGH); // we have no valid data! dcfValidSignal =false; // Turn DCF OK LED OFF digitalWrite(LED_DCFSTATUS, LOW); } } // ---------------------------------------- // Third parity check:date bits // ---------------------------------------- if (bufferPosition ==58) { for (int i =36; i <=57; i++) { dcfP3counter +=DCFbitBuffer[i]; } // perform P3 parity check. Parity is OK if the sum is an EVEN value (DCFbitBuffer[58] + dcfP3counter) % 2 ==0 ? dcfParityCheckP3 =1 :dcfParityCheckP3 =0; // Turn Parity2 'PASS' or 'FAIL' LED ON if (dcfParityCheckP3 ==1) { // Parity2 PASS LED ON digitalWrite(LED_PARITY3PASS, HIGH); // Parity P3 PASS dcfParityCheckP3 =1; } else { // Parity2 FAIL LED ON digitalWrite(LED_PARITY3FAIL, HIGH); // we have no valid data! dcfValidSignal =false; // Turn DCF OK LED OFF digitalWrite(LED_DCFSTATUS, LOW); } // ---------------------------------------- // finally, check all Parity bits // ---------------------------------------- dcfParityCheckP1 + dcfParityCheckP2 + dcfParityCheckP3 ==3 ? dcfValidSignal =true :dcfValidSignal =false; } //-------------------------------------------------------------------- // before continuing with the next bit, increment counter //-------------------------------------------------------------------- bufferPosition++; //-------------------------------------------------------------------- // check if we have not received too many pulses? //-------------------------------------------------------------------- if (bufferPosition> 59) { // Buffer Overflow ERROR - we have received more pulses before reaching // the 2 second 'gap' signalling the end of the minute. //This error may be due to a noisy signal giving addition peaks/dcfBits // So clear both DCFbit displays and start again. // Reset buffer counter bufferPosition =0; // clear inner LED ring MaximCC.clearDisplay(LedRingInner); // turn Buffer Overflow Error LED ON error(LED_BUFFEROVERFLOW); // exit return; } //-------------------------------------------------------------------- // everything OK so we wait for next incoming DCFbit //--------------------------------------------------------------------}//================================================================================================================//// Function name :finalizeBuffer// called from ://// Purpose :Process the succesfully received DCF data of one minute// Parameters :none// Return value :none////================================================================================================================void finalizeBuffer(void){ //-------------------------------------------------------------------- // We are here because of the detected 2 second 'gap'. // Now check if it correspondends with the buffer counter // 'bufferPosition' which should be value 59 //-------------------------------------------------------------------- if (bufferPosition ==59 &&dcfValidSignal ==true) { // bufferPosition ==59 so turn Buffer Full LED ON digitalWrite(LED_BUFFERFULL, HIGH); // Turn DCF OK LED ON digitalWrite(LED_DCFSTATUS, HIGH); // Reset inner LED ring (incoming time information) MaximCC.clearDisplay(LedRingInner); // copy 'contents' of inner LED ring to the outer LED ring (current time information) for (int i =0; i <59; i++) { MaximCC.setLed(LedRingOuter, i / 8, i % 8, DCFbitBuffer[i]); } // process buffer and extract data sync the time with the RTC decodeBufferContents(); // set Arduino time and after that set RTC time setTime(dcfHour, dcfMinute, 0, dcfDay, dcfMonth, dcfYear); RTC.set(now()); // activate Synced LED digitalWrite(LED_RTCSYNC, HIGH); // Reset running buffer bufferPosition =0; // Reset DCFbitBuffer array, positions 0-58 (=59 bits) for (int i =0; i <59; i++) { DCFbitBuffer[i] =0; } // reset flag MinuteMarkerFlag =false; } // if (bufferPosition ==59) //-------------------------------------------------------------------- // The buffer is not yet filled although the 2 second 'gap' was detected. // Can be result of a noisy signal, starting in middle of receiving data etc. // Turn 'Minute Mark' LED ON //-------------------------------------------------------------------- else { digitalWrite(LED_MINUTEMARKER, HIGH); // Clear displays MaximCC.clearDisplay(LedRingInner); MaximCC.clearDisplay(LedRingOuter); // Reset running buffer and start afresh. Now we are in sync with the incoming data bufferPosition =0; // Reset DCFbitBuffer array, positions 0-58 (=59 bits) for (int i =0; i <59; i++) { DCFbitBuffer[i] =0; } // set flag so we can display incoming pulsed on the inner LED ring. MinuteMarkerFlag =true; }}//================================================================================================================//// Function name :decodeBufferContents// called from ://// Purpose :Evaluates the information stored in the buffer.// This is where the DCF77 signal is decoded to time and date information// Parameters :none// Return value :none////================================================================================================================void decodeBufferContents(void){ // Buffer is full and ready to be decoded dcfMinute =bitDecode(21, 27); dcfHour =bitDecode(29, 34); dcfDay =bitDecode(36, 41); dcfWeekDay =bitDecode(42, 44); dcfMonth =bitDecode(45, 49); dcfYear =bitDecode(50, 57); //call function to calculate day of year and weeknumber dayWeekNumber(dcfYear, dcfMonth, dcfDay, dcfWeekDay); // Get value of Summertime DCFbit. '1' =Summertime, '0' =wintertime dcfDST =bitDecode(17, 17); // determine Leap Year leapYear =calculateLeapYear(dcfYear);}//================================================================================================================//// bitDecode//// called from //================================================================================================================int bitDecode(int bitStart, int bitEnd){ // reset 'bitValue-array' counter int i =0; int value =0;...This file has been truncated, please download it to see its full contents.
Superfilter sketchArduino
//// This is the Superfilter sketch I use with the DCF Analyzer/Clock 2.0 // Udo Klein did an amazing job with this filter//// Erik de Ruiter/* Arduino Uno pin connections I used for the DCF Analyzer Clock DCF input ................. A5 (19) =dcf77_sample_pin Output DCF Filtered ....... 12 =dcf77_filtered_pin Output DCF Semi Synthesized A2 (16) =dcf77_semi_synthesized_pin Output DCF Synthesized .... 6 =dcf77_synthesized_pin LED DCF output filtered ... A4 (18) =dcf77_monitor_pin =DCF Monitor LED LED 1 Hz pulse ............ 10 =dcf77_second_pulse_pin =Filter Locked LED LED DCF OK ................ 13 =dcf77_signal_good_indicator_pin =Signal Quality LED LED Difference Filtered ... 7 =dcf77_filter_diff_pin \ LED Difference Semi Synth.. A0 =dcf77_semi_synthesized_diff_pin -> =Signal Difference LED LED Difference Synthesized 4 =dcf77_synthesized_diff_pin /*/ //// www.blinkenlight.net//// Copyright 2014, 2015 Udo Klein//// This program is free software:you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program. If not, see http://www.gnu.org/licenses/#include /*const uint8_t pon_pin =51; // connect pon to ground !!!const uint8_t data_pin =19;const uint8_t gnd_pin =51;const uint8_t vcc_pin =49;*/const uint8_t dcf77_analog_samples =false;const uint8_t dcf77_analog_sample_pin =5;const uint8_t dcf77_sample_pin =19; // A5const uint8_t dcf77_inverted_samples =0;#if defined(__AVR__)#define ledpin(led) (led)#else#define ledpin(led) (led<14? led:led+(54-14))#endifconst uint8_t dcf77_monitor_pin =ledpin(18); // A4const bool provide_filtered_output =true;const uint8_t dcf77_filtered_pin =ledpin(12);const uint8_t dcf77_inverted_filtered_pin =ledpin(11);const uint8_t dcf77_filter_diff_pin =ledpin(7);const bool provide_semi_synthesized_output =true;const uint8_t dcf77_semi_synthesized_pin =ledpin(16);const uint8_t dcf77_inverted_semi_synthesized_pin =ledpin(15);const uint8_t dcf77_semi_synthesized_diff_pin =ledpin(14);const bool provide_synthesized_output =true;const uint8_t dcf77_synthesized_pin =ledpin(6);const uint8_t dcf77_inverted_synthesized_pin =ledpin(5);const uint8_t dcf77_synthesized_diff_pin =ledpin(4);const uint8_t dcf77_second_pulse_pin =ledpin(10);const uint8_t dcf77_signal_good_indicator_pin =ledpin(13);volatile uint16_t ms_counter =0;volatile Internal::DCF77::tick_t tick =Internal::DCF77::undefined;template void set_output(uint8_t clock_state, uint8_t sampled_d ata, uint8_t synthesized_signal){ if (enable) { const uint8_t filtered_output =clock_state  200) :digitalRead(dcf77_sample_pin)); #else dcf77_inverted_samples ^ digitalRead(dcf77_sample_pin); #endif digitalWrite(dcf77_monitor_pin, sampled_data); digitalWrite(dcf77_second_pulse_pin, ms_counter <500 &&clock_state>=Clock::locked); const uint8_t synthesized_signal =tick ==Internal::DCF77::long_tick ? ms_counter <200:tick ==Internal::DCF77::short_tick ? ms_counter <100:tick ==Internal::DCF77::sync_mark ? 0:// tick ==DCF77::undefined --> default handling // allow signal to pass for the first 200ms of each second (ms_counter <=200 &&sampled_data) || // if the clock has valid time data then undefined ticks // are data bits --> first 100ms of signal must be high ms_counter <100; set_output (clock_state, sampled_data, synthesized_signal); set_output (clock_state, sampled_data, synthesized_signal); set_output (clock_state, sampled_data, synthesized_signal); ms_counter+=(ms_counter <1000); scope_1.process_one_sample(sampled_data); scope_2.process_one_sample(digitalRead(dcf77_synthesized_pin)); return sampled_data;}void output_handler(const Clock::time_t &decoded_time) { // reset ms_counter for 1 Hz ticks ms_counter =0; // status indicator --> always on if signal is good // blink 3s on 1s off if signal is poor // blink 1s on 3s off if signal is very poor // always off if signal is bad const uint8_t clock_state =DCF77_Clock::get_clock_state(); digitalWrite(dcf77_signal_good_indicator_pin, clock_state>=Clock::locked ? 1:clock_state ==Clock::unlocked? (decoded_time.second.digit.lo &0x03) !=0:clock_state ==Clock::free ? (decoded_time.second.digit.lo &0x03) ==0:0); // compute output for signal synthesis Internal::DCF77_Encoder now; now.second =BCD::bcd_to_int(decoded_time.second); now.minute =decoded_time.minute; now.hour =decoded_time.hour; now.weekday =decoded_time.weekday; now.day =decoded_time.day; now.month =decoded_time.month; now.year =decoded_time.year; now.uses_summertime =decoded_time.uses_summertime; now.leap_second_scheduled =decoded_time.leap_second_scheduled; now.timezone_change_scheduled =decoded_time.timezone_change_scheduled; now.undefined_minute_output =false; now.undefined_uses_summertime_output =false; now.undefined_abnormal_transmitter_operation_output =false; now.undefined_timezone_change_scheduled_output =false; now.advance_minute(); tick =now.get_current_signal();}void setup_serial() { Serial.begin(115200);}void output_splash_screen() { Serial.println(); Serial.println(F("DCF77 Superfilter 3.0")); Serial.println(F("(c) 2015 Udo Klein")); Serial.println(F("www.blinkenlight.net")); Serieel.println(); Serial.print(F("Sample Pin:")); Serial.println(dcf77_sample_pin); Serial.print(F("Inverted Mode:")); Serial.println(dcf77_inverted_samples); #if defined(__AVR__) Serial.print(F("Analog Mode:")); Serial.println(dcf77_analog_samples); #endif Serial.print(F("Monitor Pin:")); Serial.println(dcf77_monitor_pin); Serieel.println(); if (provide_filtered_output) { Serial.println(F("Filtered Output")); Serial.print(F(" Filtered Pin:")); Serial.println(dcf77_filtered_pin); Serial.print(F(" Diff Pin:")); Serial.println(dcf77_filter_diff_pin); Serial.print(F(" Inverse Filtered Pin:")); Serial.println(dcf77_inverted_filtered_pin); Serieel.println(); } if (provide_semi_synthesized_output) { Serial.println(F("Semi Synthesized Output")); Serial.print(F(" Filtered Pin:")); Serial.println(dcf77_semi_synthesized_pin); Serial.print(F(" Diff Pin:")); Serial.println(dcf77_semi_synthesized_diff_pin); Serial.print(F(" Inverse Filtered Pin:")); Serial.println(dcf77_inverted_semi_synthesized_pin); Serieel.println(); } if (provide_synthesized_output) { Serial.println(F("Synthesized Output")); Serial.print(F(" Filtered Pin:")); Serial.println(dcf77_synthesized_pin); Serial.print(F(" Diff Pin:")); Serial.println(dcf77_synthesized_diff_pin); Serial.print(F(" Inverse Filtered Pin:")); Serial.println(dcf77_inverted_synthesized_pin); Serieel.println(); } Serial.print(F("Second Pulse Pin:")); Serial.println(dcf77_second_pulse_pin); Serial.print(F("Signal Good Pin:")); Serial.println(dcf77_signal_good_indicator_pin); Serieel.println(); Serieel.println(); Serial.println(F("Initializing...")); Serial.println();};void setup_pins() { if (provide_filtered_output) { pinMode(dcf77_filtered_pin, OUTPUT); pinMode(dcf77_filter_diff_pin, OUTPUT); pinMode(dcf77_inverted_filtered_pin, OUTPUT); } if (provide_semi_synthesized_output) { pinMode(dcf77_semi_synthesized_pin, OUTPUT); pinMode(dcf77_semi_synthesized_diff_pin, OUTPUT); pinMode(dcf77_inverted_semi_synthesized_pin, OUTPUT); } if (provide_synthesized_output) { pinMode(dcf77_synthesized_pin, OUTPUT); pinMode(dcf77_synthesized_diff_pin, OUTPUT); pinMode(dcf77_inverted_synthesized_pin, OUTPUT); } pinMode(dcf77_monitor_pin, OUTPUT); pinMode(dcf77_signal_good_indicator_pin, OUTPUT); pinMode(dcf77_second_pulse_pin, OUTPUT); pinMode(dcf77_sample_pin, INPUT); digitalWrite(dcf77_sample_pin, HIGH);}void setup_clock() { DCF77_Clock::setup(); DCF77_Clock::set_input_provider(sample_input_pin); DCF77_Clock::set_output_handler(output_handler);}void setup() { setup_serial(); output_splash_screen(); setup_pins(); setup_clock();/* pinMode(gnd_pin, OUTPUT); digitalWrite(gnd_pin, LOW); pinMode(pon_pin, OUTPUT); digitalWrite(pon_pin, LOW); pinMode(vcc_pin, OUTPUT); digitalWrite(vcc_pin, HIGH); */}void loop() { Clock::time_t now; DCF77_Clock::get_current_time(now); if (now.month.val> 0) { Serial.println(); Serial.print(F("Decoded time:")); DCF77_Clock::print(now); Serieel.println(); } Serial.print(DCF77_Clock::get_clock_state()); Serial.print(' '); DCF77_Clock::debug(); scope_1.print(); scope_2.print();}

Aangepaste onderdelen en behuizingen

This is a PCB I made for the Time and Date displays Maxim_7219_LED_display_unit_for_Adafruit_0_56inch_7_segment_v1_1.zipThis is my PCB design for the very compact smaller 7 segment displays Maxim_7219_LED_display_unit_for_KingBright_7_segment_SC39_11SRWAv1_1.zipTicking sound and Chime sound, see text for explanation Grandfather_Clock_Sound_files.zip

Schema's

DOWNLOAD to view details! dcf77-analyzer-clock-v2_1_jVZT5sqIwn.zip

Productieproces

  1. Koekoeksklok
  2. Arduino pov vision-klok
  3. DIY eenvoudigste IV9 Numitron-klok met Arduino
  4. Eenvoudige wandklok met Adafruit 1/4 60 Ring Neopixel
  5. Eenvoudige Word Clock (Arduino)
  6. Arduino klok met islamitische gebedstijden
  7. Arduino Spybot
  8. FlickMote
  9. Hoofdklok
  10. Arduino Temp. Monitor en realtimeklok met 3.2-weergave
  11. Eenvoudige wekker met DS1302 RTC