Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Analyseur/Horloge DCF77 v2.0

Composants et fournitures

Arduino Mega 2560
× 1
Arduino UNO
× 1

À propos de ce projet

Après avoir découvert la plate-forme Arduino, j'ai été stupéfait et mon rêve de développer un jour ma propre électronique est devenu réalité.

Comme tout le monde le fera, j'ai commencé par les croquis de base mais j'ai vite voulu faire quelque chose d'utile. Comme j'ai toujours aimé les radio-horloges (elles se synchronisent avec le signal DCF77 d'Allemagne dans mon cas), j'ai décidé de faire une horloge qui n'affichait pas seulement l'heure mais une horloge qui me montre ce qui se passe.

Après des centaines d'heures à bricoler, à commettre d'innombrables erreurs, j'avais enfin une horloge fonctionnelle avec mon propre code et mes propres conceptions de circuits imprimés.

Photos et vidéos de l'analyseur/horloge DCF77 v1.0 :

Mais plus tard, j'ai découvert le superfiltre DCF77 d'Udo Klein qui fournit un signal propre lorsque le signal radio n'est pas très bon.

Il s'agit d'une carte Arduino Uno séparée avec le logiciel Superfilter (vous pouvez la considérer comme une "boîte noire" autonome, filtrant le signal) connectée entre l'antenne DCF77 et l'Arduino Mega exécutant mon croquis.

J'ai donc fait une version 2.0 de la première horloge :

  • code complètement réécrit
  • abondamment commenté afin que tout le monde puisse comprendre ce qui se passe
  • ajout d'un capteur de mouvement PIR pour réduire la consommation d'énergie
  • ajout du superfiltre DCF77
  • affichage supplémentaire pour la température ou autre utilisation (comme l'heure de lever/coucher du soleil)

Photos et vidéos du nouvel analyseur/horloge DCF77 v2.0 :

Démo

pour voir la vidéo cliquez ICI

Construire dans « Grand-père Horloge »

pour voir la vidéo cliquez ICI

La conception

La face avant et le boîtier :

La conception du panneau avant a été réalisée dans un programme gratuit appelé Inkscape (voir l'URL de téléchargement au début de cette page).

En fait, produire le panneau avant s'est avéré être la partie la plus difficile. J'ai dépensé beaucoup d'argent pour essayer de le faire dans un FabLab local à l'aide d'un cutter laser et d'un type spécial d'acrylique avec un revêtement semblable à de l'aluminium. L'idée était de découper les trous au laser et de graver le texte et les lignes en brûlant le très fin revêtement exposant l'acrylique noir en dessous. Mais c'était un cauchemar car la découpeuse laser n'était pas en mesure de produire dans les tolérances dont j'avais besoin en raison d'une utilisation intensive et des « abus » de la part de nombreux utilisateurs.

Puis je suis tombé sur un service photo en ligne. Ils impriment sur toutes sortes de matériaux et l'un d'eux était un panneau DiBond. Le prix était très bon, 28 euros, frais de port compris. Mais le résultat a d'abord été décevant car ils n'ont pas imprimé mon design 1:1 mais légèrement agrandi. Alors méfiez-vous si vous décidez d'utiliser cette méthode. Appelez-les d'abord et demandez s'il est possible d'imprimer 1:1.

Après un appel téléphonique, ils m'ont envoyé un autre panneau avec les bonnes dimensions. C'était mieux que prévu, excellent !

Ensuite, de nombreux perçages et fraisages ont été nécessaires :

Code

  • Analyseur DCF / Horloge v2.1
  • Esquisse du superfiltre
Analyseur DCF / Horloge v2.1Arduino
2020-01-18 bug release :interrupteur d'économie d'énergie corrigé/* ================================================================================Analyseur DCF77 / Horloge version 2 ================================================================================Ce croquis est un logiciel gratuit; vous pouvez le redistribuer et/ou le modifier selon les termes de la licence publique générale limitée GNU telle que publiée par la Free Software Foundation ; soit la version 2.1 de la Licence, soit (à votre choix) toute version ultérieure. Ce croquis est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE; sans même la garantie implicite de QUALITÉ MARCHANDE ou D'ADAPTATION À UN USAGE PARTICULIER. Voir la licence publique générale limitée GNU pour plus de détails. Vous devriez avoir reçu une copie de la licence publique générale limitée GNU avec cette bibliothèque ; sinon, écrivez à la Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =================================================================================Ce code C++ est loin d'être optimisé car je suis moi-même un novice Arduino et C++. Mais même après avoir appris un peu plus maintenant, je veux garder le code simple et lisible. C'est pourquoi j'ai peut-être sur-documenté le code pour aider à comprendre ce qui se passe. Erik de Ruiter 2014-2020 Mai 2014 Première version Mars 2016 - grosse refonte... Juillet 2016 - Commencer par construire l'Horloge 2.0 et adapter le sketch Version 2.1 du 18-01-2020 - Fonction Powersafe corrigée. Version 2.0 - Ce croquis est adapté pour ma version 2.0 de l'horloge DCF/Analyzer. Il utilisait par défaut l'Arduino MEGA et le DCF Superfilter et pour piloter les nombreuses LED séparées, j'utilise maintenant les ports d'un Arduino Mega au lieu d'une puce Maxim 7219. C'est parce que la conduite de LED avec de nombreuses spécifications de tension/courant différentes est problématique avec la puce Maxim. L'éclairage de LED supplémentaires par exemple influencera (atténuera) les LED déjà allumées. Comme je ne suis pas ingénieur en électronique, ma seule solution était d'utiliser les ports supplémentaires de l'Arduino Mega. Bien sûr, vous pouvez utiliser des transistors ou des puces supplémentaires pour piloter les LED, mais pour moi, c'était la solution évidente. - Suppression de tout le code d'affichage Maxim Common AnodeVersion 1.72 - Option :utilisez un détecteur PIR Ebay bon marché pour éteindre les écrans sélectionnables lorsqu'aucune activité n'est détectée. Le délai d'extinction peut être réglé par l'utilisateur pour empêcher l'extinction de l'écran si une personne ne bouge pas mais que l'écran doit être allumé. - Maintenant, l'affichage Arrêt de nuit peut être désactivé en mettant à zéro les deux valeurs 'POWERSAVINGOFFTIME' et 'POWERSAVINGONTIME'. - L'affichage de la température fixe ne s'éteint pas en mode économie d'énergie. - L'affichage du compteur d'erreurs ne s'est pas réinitialisé toutes les heures - Version 1.71 fixe - Option utilisateur pour réinitialiser la mémoire min/max de la température à minuit Version 1.7 :- La résolution de l'affichage de la température est améliorée :de 0,5 à 0,1 degrés Celsius En raison de l'heure du capteur DS18B20 doit convertir la température et garder le code propre, l'affichage de la température est mis à jour une fois par minute. - Routine de contrôle de parité optimisée. - Vérification plus fiable des mauvaises données DCF, empêchant la mise à jour RTC avec des données invalides. - L'erreur EoB efface maintenant l'anneau LED interne comme il se doit. - La LED DCF OK affiche désormais l'état du signal DCF de manière plus fiable. S'éteint immédiatement en cas d'erreur et ne s'active que lorsque les 3 bits de parité sont OK. Version 1.6 :- Fonction de température modifiée pour ne calculer qu'une fois par minute. J'ai eu des erreurs étranges avant le changement car j'ai utilisé un délai de 100 ms pour donner au capteur DS18B20 le temps de calculer la température. Mais la fonction de délai est une très mauvaise idée dans la plupart des codes C++, alors je m'en suis finalement débarrassée. Version 1.5 :- Refonte complète de la fonction scanSignal et du reste du code ! Ma première tentative a fonctionné mais pourrait être améliorée... - Les leds rPW et rPT n'ont pas fonctionné comme je le souhaitais donc c'est corrigé maintenant. - La routine de vérification d'erreur de fin de tampon fonctionne maintenant comme il se doit. - J'ai intégré un contrôle de parité du signal DCF entrant. Dans le signal, 3 bits de parité sont envoyés, ils sont maintenant vérifiés et seulement si les trois sont OK, les informations de temps reçues sont acceptées, l'affichage est mis à jour et le RTC synchronisé. si vous le souhaitez, vous pouvez attacher 3 LED bicolores supplémentaires (cathode commune) pour voir si chacun des 3 bits de parité est OK ou Échec. - J'ai rendu le câblage (ou le changement de câblage) beaucoup plus facile je pense en mettant toutes les configurations de PIN dans un seul tableau facile à lire - Tant que vous utilisez 1 DS18B20 temp. capteur, j'ai modifié le code pour que vous n'ayez plus besoin de trouver l'adresse du périphérique I2C. - Grand nettoyage du code... - L'économie d'énergie en éteignant les affichages (l'horloge continue de fonctionner normalement) peut maintenant être configurée un peu plus facilement en éditant deux variables POWERSAVINGONTIME et POWERSAVINGOFFTIME. - Modification de certains noms de variables :- Les instances Maxim 'lc' et 'lc1' sont maintenant MaximCC et MaximCA - La description de l'affichage MaximDcfTime est maintenant DisplayTempWeek - DCF77SOUNDPIN est maintenant BUZZERSWITCHPIN - Le test LED/affichage après la mise sous tension est maintenant intégré Description courte :Mise sous tension :Après la mise sous tension, un test de LED est d'abord effectué. Les LED et les affichages s'allument séquentiellement pour maintenir une faible consommation d'énergie. Ensuite, l'horloge commence à recevoir des impulsions DCF et lorsqu'une marque de minute (intervalle de 2 secondes) est détectée, la LED de marque de minute est allumée et le compteur de tampon est réinitialisé. L'anneau LED intérieur affichera maintenant les impulsions DCF entrantes qui sont également stockées dans la mémoire tampon. A 3 instants pendant la réception des données, les bits de parité DCF sont vérifiés pour voir si les données sont valides. Données valides reçues :Lorsqu'à la fin de la minute, après la détection de la marque de minute (la LED BF (Buffer Full) est allumée), les trois bits de parité sont OK (la LED 'DCF OK' est allumée), les informations de la mémoire tampon sont utilisé pour extraire des informations sur l'heure et la date. Ensuite, l'horloge RTC est mise à jour (la LED 'RTC Synced' est allumée) et les informations de l'anneau LED interne sont copiées sur l'anneau LED externe. Les informations d'affichage de l'heure, de la date et de la semaine, de la LED du jour, de l'heure d'été/d'hiver et de l'année bissextile sont mises à jour avec les nouvelles informations de l'heure. Aucune donnée valide :lorsqu'un ou plusieurs bits de parité ne sont pas OK en raison d'un signal bruyant, la réception des informations DCF se poursuit mais ne sera pas utilisée pour mettre à jour le RTC, l'affichage et les LED. L'anneau LED extérieur, les LED 'RTC synced' et 'DCF OK' seront réinitialisés. Les LED heure, date, semaine, jour, été/hiver et année bissextile ne sont pas affectées et continuent d'afficher les dernières valeurs valides reçues. Les LED d'erreur « Période Temps » et/ou « Période avec » indiqueront la ou les erreurs et l'affichage du compteur d'erreurs est mis à jour. Toutes les heures, l'affichage d'erreur sera mis à zéro. La LED EoB, End of Buffer s'allume lorsque d'autres impulsions DCF sont reçues avant que la marque des minutes ne soit détectée en raison d'un signal bruyant. (Quand une marque minute est détectée, nous ne devrions pas avoir plus de 58 bits/impulsions) Après la détection de la marque minute, un nouveau cycle est démarré. Température :Au bout de 30 secondes, l'affichage de la température affichera les valeurs haute et basse de la période écoulée après la dernière réinitialisation. Carillon :si le commutateur CARILLON est activé/élevé, alors au début de chaque heure, le carillon (s'il est connecté) sonnera. La nuit, une heure définie par l'utilisateur dans le code lui-même, le carillon est désactivé. Économie d'énergie - l'écran s'éteint Cela ne fonctionnera que SI l'interrupteur d'économie d'énergie est ÉLEVÉ :1. ARRÊT DE NUIT À des heures définies par l'utilisateur, les écrans sont éteints la nuit et allumés le matin. Examinez les variables POWERSAVINGOFFTIME et POWERSAVINGONTIME. Vérifiez la fonction pour sélectionner QUELS affichages vous souhaitez éteindre la nuit. 2. CAPTEUR PIR Connectez un capteur PIR et activez l'option PIR POWERSAVE_BY_PIR et le délai à PIR_DELAY_TIME. Chaque fois que le détecteur PIR détecte un mouvement, un compteur de minutes est réinitialisé, mais si aucun mouvement n'est détecté plus longtemps que PIR_DELAY_TIME, les affichages sont éteints. Lorsqu'un mouvement se produit, les affichages s'allument immédiatement. Remarque :comme indiqué précédemment, l'horloge fonctionnera normalement lorsque les écrans seront éteints. Bip DCF :Avec un commutateur connecté à la broche BUZZERSWITCHPIN, vous pouvez entendre les bits DCF reçus entrer. La durée de la tonalité est équivalente à la largeur d'impulsion des bits DCF, soit 100 ou 200 ms. Divers :Lorsque la batterie RTC est vide ou qu'un défaut de connexion est détecté, la LED d'erreur RTC est allumée. CRÉDITS :J'ai beaucoup appris du travail de Matthias Dalheimer et Thijs Elenbaas qui ont fabriqué leurs propres décodeurs DCF77. Sans leur travail, je n'aurais pas su par où commencer. J'ai fini par écrire mon propre code (en utilisant des morceaux de leurs idées) pour que je puisse comprendre ce qui se passe... Mon code est loin d'être efficace ou avancé mais il fonctionne et je sais ce qui se passe. Sites Internet intéressants :- 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 - Beaucoup plus d'infos DCF77 :http://www.picbasic.nl/indexes_uk.htm - Mon site Flickr :https://www.flickr.com/photos/edr1924/albums - Mon Github site web :https://github.com/deruiter *///----------------------------------- -------------------------------------------------- ---------------------// Bibliothèques//------------------------ -------------------------------------------------- ----------------------------------// Bibliothèque de temps Arduino (nouveau) .......... .......................... http://www.pjrc.com/teensy/td_libs_Time.html#include // Activez cette ligne si vous utilisez Arduino Uno, Mega, etc.#i nclude // une bibliothèque DS1307 de base qui renvoie l'heure sous la forme d'un time_t .......... http://www.pjrc.com/teensy/td_libs_DS1307RTC.html#include // Maxim 7219 affiche la bibliothèque ................................. http://playground.arduino.cc /Principal/LEDMatrix// !!! REMARQUE :vous devez utiliser une version spéciale de la bibliothèque Ledcontrol.h pour obtenir le support Common Anode// car la puce Maxim ne convient normalement qu'aux écrans CATHODE courants ! #include //Bibliothèque d'interface SPI .... ...................................... http://arduino.cc/en/Reference/ SPI#include // OneWire vous permet d'accéder aux appareils 1 fil fabriqués par Maxim/Dallas,// tels que DS18S20, DS18B20, DS1822 ................. ............. http://www.pjrc.com/teensy/td_libs_OneWire.html// La bibliothèque DallasTemperature peut faire tout ce travail pour vous ! ... http://milesburton.com/Dallas_Temperature_Control_Library#include //----------------------------- -------------------------------------------------- ---------------------------// Connexions Arduino UNO Pin dans un tableau facile à lire//// entrée - Rx - utilisé pour la programmation /communication avec PC// sortie - Tx - utilisé pour la programmation/communication avec PC #define DCF77PIN 2 // entrée - signal DCF du PCB de l'antenne. La broche doit être une entrée d'interruption !#define PIRDETECTORPIN 3 // entrée - Détecteur PIR :vérifiez l'activité dans la pièce pour activer les affichages#define BUZZERSWITCHPIN 4 // entrée - SWITCH - allumez/éteignez le buzzer piézo 'bip' DCF77 / ON =HIGH , OFF =LOW#define CHIMESWITCHPIN 5 // entrée - SWITCH - active/désactive le carillon horaire / ON =HIGH, OFF =LOW#define POWERSAVESWITCHPIN 6 // entrée - SWITCH - active/désactive la fonction d'économie d'énergie pour afficher est toujours allumé / ON =HIGH, OFF =LOW#define TEMPSENSORPIN 8 // entrée - capteur de température Dallas One Wire DS18B20#define TEMPRESETPIN 9 // entrée - BOUTON-POUSSOIR - réinitialiser la mémoire min/max de la température / HIGH =reset#define MAXIMCCLD 10 // sortie - CS/LOAD - pseudo connexion SPI à la puce Maxim 7219 - 7 segments display#define MAXIMCCCLK 11 // sortie - CLOCK - pseudo connexion SPI à la puce Maxim 7219 - 7 segments display#define MAXIMCCDATA 12 // sortie - DATA - connexion pseudo SPI à la puce Maxim 7219 - 7 s affichages d'éléments// !! Les broches 22 à 53 ne doivent être utilisées que pour les LED#define LED_SUNDAY 22 // sortie - LED - Sunday#define LED_MONDAY 23 // sortie - LED - Monday#define LED_TUESDAY 24 // sortie - LED - Tuesday#define LED_WEDNESDAY 25 // sortie - LED - mercredi#define LED_THURSDAY 26 // sortie - LED - jeudi#define LED_FRIDAY 27 // sortie - LED - vendredi#define LED_SATURDAY 28 // sortie - LED - samedi#define LED_CEST 29 // sortie - LED - Summertime CEST #define LED_CET 30 // sortie - LED - Hiver CET#define LED_LEAPYEAR 31 // sortie - LED - Année bissextile#define LED_RTCERROR 32 // sortie - LED - problème de lecture des données RTC (batterie vide/connexion)#define LED_RTCSYNC 33 // sortie - LED - Allumée lorsque RTC est synchronisé avec succès avec l'heure DCF#define LED_TEMP 34 // sortie - LED - la température est affichée#define LED_OPTION1 35 // sortie - LED - en option 1 données sont affichées#define LED_OPTION2 36 // sortie t - LED - 2 données en option sont affichées#define LED_ERRORPT 37 // sortie - LED - DCF Period Time error#define LED_ERRORPW 38 // sortie - LED - DCF Period Width error#define LED_BUFFERFULL 39 // sortie - LED - Indicateur de tampon plein , les données seront ensuite analysées#define LED_MINUTEMARKER 40 // sortie - LED - Fin du flux de données DCF détectée avant que le tampon ne soit rempli, les données sont corrompues#define LED_BUFFEROVERFLOW 41 // sortie - LED - Plus de données reçues en une minute que prévu en raison au mauvais signal#define LED_DCFSTATUS 42 // sortie - LED - Allumée lorsque nous avons de bonnes données DCF#define LED_POWERSAVE 43 // sortie - LED - Le mode d'économie d'énergie est activé, certains affichages sont éteints#define LED_PARITY1PASS 44 // sortie - LED - La parité 1 bit est OK#define LED_PARITY1FAIL 45 // sortie - LED - Parité 1 bit ÉCHEC#define LED_PARITY2PASS 46 // sortie - LED - Parité 2 bits est OK#define LED_PARITY2FAIL 47 // sortie - LED - Parité 2 bits ÉCHEC#define LED_PARITY3PASS 48 // sortie - LED - La parité 3 bits est OK#define LED_PARITY3FAIL 49 // sortie - LED - Parité 3 bits ÉCHEC#define LED_PIRMOTION 50 // sortie - LED - Allumée lorsque PIR détecte un mouvement// Broches analogiques#define BUZZER A7 // sortie - Buzzer piézo pour DCF77 'bip' (au '+' du buzzer)#define SPEAKERVOLPIN A6 // sortie - Volume de la carte son - LOW =volume un cran plus bas. SPEAKERVOLUME détermine combien de fois cette sortie est activée après la mise sous tension#define CHIMEPIN A5 // sortie - Chime Activate - OUTPUT LOW =Activer le carillon sur Adafruit Soundboard FX// UTILISÉ pour DS1307 RTC // I2C DATA - se connecter à l'horloge en temps réel pcb/ / UTILISÉ pour DS1307 RTC // HORLOGE I2C - se connecte à la carte PCB de l'horloge en temps réel //-------------------------------- -------------------------------------------------- ------------------------// Initialisation DS18B20//-------------------- -------------------------------------------------- ------------------------------------OneWire ds(TEMPSENSORPIN); // définir l'instance Onewire DS//------------------------------------------ -------------------------------------------------- --------------// Initialisation de l'affichage matriciel Maxim 7219 //--------------------------- -------------------------------------------------- -----------------------------/* clearDisplay(int addr) .............. .............................. efface l'affichage sélectionné MaximCC.shutdown(int addr, boolean) ...... .......................... réveille le MAX72XX du mode d'économie d'énergie (true =veille, false =éveillé) MaximCC.setIntensity(int addr , valeur) .............................. régler une luminosité moyenne pour les Leds (0=min - 15=max) MaximCC .setLed(int addr, int row, int col, boolean state) .......... allume la led en ligne, colonne. rappelez-vous que les indices commencent à 0 ! MaximCC.setRow(int addr, int row, byte value) ...................... cette fonction prend 3 arguments. exemple :MaximCC.setRow(0,2,B10110000); MaximCC.setColumn(int addr, int col, byte value) ................... cette fonction prend 3 arguments. exemple :MaximCC.setColumn(0,5,B00001111) ; MaximCC.setDigit(int addr, int digit, byte value, boolean dp) ...... cette fonction prend un argument de type byte et imprime le chiffre correspondant sur la colonne spécifiée. La plage de valeurs valides s'étend de 0 à 15. Toutes les valeurs entre 0..9 sont imprimées sous forme de chiffres, les valeurs entre 10..15 sont imprimées sous forme d'équivalent hexadécimal MaximCC.setChar(int addr, int digit, char value, boolean dp) ....... affichera :0 1 2 3 4 5 6 7 8 9 ABCDEFHLP; - . , _ (le caractère vide ou espace) POWERSAVESWITCHPIN ***** Veuillez définir le nombre d'appareils que vous avez ***** Mais la valeur par défaut maximale de 8 MAX72XX fonctionnera également. LedConrol(DATAIN, CLOCK, CS/LOAD, NUMBER OF MAXIM CHIPS) */// lc est pour les affichages MaximLedControl MaximCC =LedControl(MAXIMCCDATA, MAXIMCCCLK, MAXIMCCLD, 7, false); // Définir les broches pour Maxim 72xx et combien de 72xx nous utilisons //----------------------------------- -------------------------------------------------- ---------------------// Paramètres utilisateur, définitions de variables et de tableaux//------------------ -------------------------------------------------- ----------------------------------------------------// La valeur ci-dessous n'est pas un code PIN mais un valeur pour définir combien de fois l'entrée « Lower volume » sur la carte son est activée// de cette façon, le volume de la carte son peut être abaissé après la mise sous tension, si vous le souhaitez.#define SPEAKERVOLUME 12// Choisissez si vous voulez un test de toutes les LED et affichages après un démarrage// '1' =Oui, '0' =Non#define PERFORM_LED_TEST 1// Délai entre chaque affichage de 7 segments en ms#define LEDTEST_DELAY_DISPLAYS 600// Délai entre chaque LED dans l'anneau LED et d'autres LED en ms#define LEDTEST_DELAY_LED_RING 20// Choisissez si vous souhaitez configurer le capteur de température DS18B20 UNE FOIS à la résolution la plus élevée.// Ceci est nécessaire après avoir utilisé le capteur pour le sapin ère fois. Après avoir exécuté le logiciel// avec ce paramètre activé une fois, éteignez-le.// '1' =ON, '0' =OFF#define CONFIGURE_DS18B20 0// POWERSAVE TIME - valeurs OBLIGATOIRES ! //// pour définir le jour et la nuit. Ceci est utilisé pour l'heure d'activation et de désactivation de l'affichage d'économie d'énergie// ET pour déterminer si le carillon sera activé (pendant la journée).//// SEULEMENT les affichages sont éteints à l'heure d'économie d'énergie, l'horloge reste entièrement active./ / POUR DÉSACTIVER la mise hors tension de l'écran à tout moment, réglez simplement l'interrupteur d'économie d'énergie sur OFF //// Interrupteur d'économie d'énergie sur ON :les écrans seront éteints à l'heure de nuit définie // ET si la fonction POWERSAVE_BY_PIR est activée et là n'est pas // mouvement pour l'ensemble PIR_DELAY_TIME.// Interrupteur d'économie d'énergie sur OFF :s'affiche toujours, carillon uniquement pendant la journée. //// les valeurs sont au format 'Heure', donc 20h sera '20', PAS 20:00 ou 20h...#define POWERSAVINGOFFTIME 9 // les affichages sont activés#define POWERSAVINGONTIME 22 // les affichages sont éteints// Option utilisateur :activer les affichages uniquement lorsqu'il y a de l'activité dans la pièce// '1' =ON, '0 ' =OFF#define POWERSAVE_BY_PIR 1// délai en MINUTES pour attendre après aucune détection avant d'éteindre les affichages#define PIR_DELAY_T IME 30// Option utilisateur pour réinitialiser la mémoire min/max de la température à minuit// '1' =Réinitialiser à minuit, '0' =Réinitialisation manuelle uniquement#define TEMPRESET_MIDNIGHT 1//------------ -------------------------------------------------- -----------------// définir divers paramètres#define DS1307_I2C_ADDRESS 0x68 // définir l'adresse RTC I2C#define DCF_INTERRUPT 0 // Numéro d'interruption associé à la broche // définition de Maxim 7219 numéro d'affichage séquence de câblage// le premier Maxim 7219 dans le câblage 'daisychain' doit être '0', le suivant '1' etc.// COMMON CATHODE DISPLAYS#define LedRingInner 0#define LedRingOuter 1#define DisplayBufferBitError 2#define DisplayPeriodPulse 3#define DisplayTempWeek 4#define DisplayDate 5#define DisplayTime 6// définition des niveaux de luminosité de l'affichage#define BrightnessLedRingOuter 1#define BrightnessLedRingInner 1#define BrightnessDisplayTime 1#define BrightnessDisplayDate 7#define BrightnessDisplayTempWeek 15#define BrightnessDisplayPeriodPulse 2#Budefine Brightness // Pulse flancs long non signé leaderEdge =0 ; statique long non signé trailingEdge =0 ; non signé long précédentLeadingEdge =0 ; // utilisé dans int volatile non signé DCFSignalState =0 ; // les variables d'interruption ont TOUJOURS besoin d'un qualificateur volatile!!// utilisé dans int previousSecond =0;unsigned int previousSignalState =0;// Tampons et indicateurs DCFstatic int DCFbitBuffer[59]; // ici, les bits DCF reçus sont stockésconst int bitValue[] ={1, 2, 4, 8, 10, 20, 40, 80} ; // ce sont les valeurs décimales des DCFbits reçus// uniquement après le démarrage d'une nouvelle minute, afficher les bits reçus sur la LED interne ringboolean MinuteMarkerFlag =false;int bufferPosition =0;int previousMinute =0;int previousHour =0;// variables pour vérifier si les bits DCF sont valdbool dcfValidSignal =false;int dcfP1counter =0;int dcfP2counter =0;int dcfP3counter =0;int dcfParityCheckP1 =0;int dcfParityCheckP2 =0;int dcfParityCheckP3 =0;// variables dcf pour stocker l'heure DCF décodée inint dcfMinute =0;int dcfHour =0;int dcfDay =0;int dcfWeekDay =0;int dcfMonth =0;int dcfYear =0;int dcfDST =0;int leapYear =0;// variables utilisées pour stocker les valeurs de numéro de semaine et de numéro de jourint dayNumber;int weekNumber;// error counter variableint errorCounter =0;boolean errorCondition =false;// variables diversesboolean daytimeChange =true;boolean dayTime =false;int dcf77SoundSwitch =0;// temperature variablesbyte 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;// Détecteur PIR variablesint pirActivity =0;int pirDisplaysState =1;unsigned int pirTimer =0;unsigned long previousTimePIR =0;//==============================================================================// CONFIGURATION//==============================================================================void setup(){ // initialize Serial communication Serial.begin(9600); // initialize PIN connections pinMode(DCF77PIN, INPUT); pinMode(TEMPRESETPIN, INPUT); pinMode(BUZZERSWITCHPIN, INPUT); pinMode(CHIMESWITCHPIN, INPUT); pinMode(POWERSAVESWITCHPIN, INPUT); pinMode(PIRDETECTORPIN, INPUT); pinMode(CHIMEPIN, OUTPUT); pinMode(SPEAKERVOLPIN, OUTPUT); // initialize LED pins 22 - 50 for (int i1 =22; i1 <=50; i1++) { pinMode(i1, OUTPUT); } // Initialize variables, LED displays and LED's initialize(); // Initialize DCF77 pulse interrupt on pin DCF_INTERRUPT, looking for a change of the signal, // so either rising or falling edge pulses will trigger the interrupt handler and // execute the int0handler function. attachInterrupt(DCF_INTERRUPT, int0handler, CHANGE); // Initialize RTC and set as SyncProvider. // Later RTC will be synced with DCF time setSyncProvider(RTC.get); // the function to get the time from the RTC // check if RTC has set the system time if (timeStatus() !=timeSet) { // Unable to sync with the RTC - activate RTCError LED digitalWrite(LED_RTCERROR, HIGH); } else { // RTC has set the system time - dim RTCError LED digitalWrite(LED_RTCERROR, LOW); } // After power on, set the speaker volume of the Adafruit Audio Board // initialize both pins to LOW which is the default output state digitalWrite(SPEAKERVOLPIN, LOW); digitalWrite(CHIMEPIN, LOW); // lower soundboard default volume with 'SPEAKERVOLUME' steps for (int i =0; i <=SPEAKERVOLUME; i++) { digitalWrite(SPEAKERVOLPIN, HIGH); retard (100); digitalWrite(SPEAKERVOLPIN, LOW); retard (100); } // The following function should run only once. // It is used to configure the temperature resolution of the DS18B20 sensor if (CONFIGURE_DS18B20 ==1) { configureDS18B20(); } // use for test purposes and/or setting the RTC time manually // setTime(23, 59, 40, 31, 12, 13); // RTC.set(now()); // Request the temperature conversion calculateTemp(); // check if a LED test is needed if (PERFORM_LED_TEST ==1) { // do a LED test ledTest(); } else { // if not doing a LED test, we need to wait a bit for the DS18B20 sensor to get ready delay(750); } // Now get the temperature from the sensor and display it displayTemp(); // activate errorCounter display after LED test ledDisplay(DisplayBufferBitError, "R", 0);}//==============================================================================// LOOP//==============================================================================void loop(){ // check first if pulse direction is changed (rising or falling) // else we would keep evaluating the same pulse if (DCFSignalState !=previousSignalState) { // 'reset' state of variable previousSignalState =DCFSignalState; // evaluate incoming pulse scanSignal(); } // check if switches are changed and act upon it checkSwitches(); // check for PIR movement checkPIR(); // execute tasks that must happen only once every second, minute or hour //---------------------------------------------------------------------------- tasksEverySecond(); tasksEveryMinute(); tasksEveryHour();}//================================================================================================================//// Function name :processDcfBit// called from ://// Purpose :Evaluates the signal as it is received. Decides whether we received a "1" or a "0"// and perform checks to see if the pulse timing is within limits// Parameters :none// Return value :none////================================================================================================================/* pulse pulse width width |- -| |-- --| |----- END OF MINUTE marker:2000ms -----| ___ _______ ___ ___ _______ | 0 | | 1 | | 0 | | 0 | | 1 | | | | | | | | | | | | | | | | | | | | | ______| |_______________| |___________| |___________________________________| |_______________| |__ _ _ _ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1000 2100 2000 2200 3000 3100 NO 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; retourner; } //-------------------------------------------------------------------- // 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_data, 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")); Serial.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); Serial.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); Serial.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); Serial.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); Serial.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); Serial.println(); Serial.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); Serial.println(); } Serial.print(DCF77_Clock::get_clock_state()); Serial.print(' '); DCF77_Clock::debug(); scope_1.print(); scope_2.print();}

Pièces et boîtiers personnalisés

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

Schémas

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

Processus de fabrication

  1. horloge à coucou
  2. horloge de vision Arduino pov
  3. horloge IV9 Numitron DIY la plus simple avec Arduino
  4. Horloge murale simple utilisant Adafruit 1/4 60 Ring Neopixel
  5. Horloge de mots simple (Arduino)
  6. Horloge Arduino avec heures de prière islamique
  7. Arduino Spybot
  8. FlickMote
  9. Réveil simple avec DS1302 RTC