Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

DCF77 Analizador / Reloj v2.0

Componentes y suministros

Arduino Mega 2560
× 1
Arduino UNO
× 1

Acerca de este proyecto

Después de descubrir la plataforma Arduino, me sorprendió y mi sueño de algún día desarrollar mi propia electrónica se hizo realidad.

Como cualquiera hará, comencé con los bocetos básicos pero pronto quise hacer algo útil. Como siempre me encantaron los Radio Clocks (se sincronizan con la señal DCF77 de Alemania en mi caso), decidí hacer un reloj que no solo mostrara la hora sino un reloj que me mostrara lo que está pasando.

Después de cientos de horas jugando, cometiendo innumerables errores, finalmente tuve un reloj que funcionaba con mi propio código y diseños de placa de circuito impreso.

Fotos y videos de DCF77 Analyzer / Clock v1.0:

Pero más tarde descubrí el superfiltro DCF77 de Udo Klein que proporciona una señal limpia cuando la señal de radio no es tan buena.

Esta es una placa Arduino Uno separada con el software Superfilter (puede verla como una 'caja negra' independiente, que filtra la señal) conectada entre la antena DCF77 y el Arduino Mega ejecutando mi boceto.

Así que hice una versión 2.0 del primer reloj:

  • código completamente reescrito
  • comentado extensamente, por lo que es de esperar que cualquiera pueda entender lo que está sucediendo
  • agregó un sensor de movimiento PIR para reducir el consumo de energía
  • agregó el superfiltro DCF77
  • pantalla adicional para la temperatura u otro uso (como salida del sol / hora de puesta)

Fotos y videos del nuevo Analizador / Reloj DCF77 v2.0:

Demostración

para ver el video haga clic AQUÍ

Construir en 'Reloj de abuelo'

para ver el video haga clic AQUÍ

El Diseño

El panel frontal y la carcasa:

El diseño del panel frontal se realizó en un programa gratuito llamado Inkscape (consulte la URL de descarga al principio de esta página).

Realmente producir el panel frontal resultó ser la parte más difícil. Gasté mucho dinero tratando de hacerlo en un FabLab local usando un cortador láser y un tipo especial de acrílico con un recubrimiento similar al aluminio. La idea era cortar los agujeros con el láser y grabar el texto y las líneas quemando la capa muy fina que deja al descubierto el acrílico negro que se encuentra debajo. Pero esto fue una pesadilla ya que la cortadora láser no pudo producir dentro de las tolerancias que necesitaba debido al uso intensivo y al 'abuso' por parte de muchos usuarios.

Luego me encontré con un servicio de fotografía en línea. Imprimen en todo tipo de materiales y uno de ellos fue un panel DiBond. El precio era muy bueno, 28 euros con gastos de envío incluidos. Pero el resultado fue al principio decepcionante porque no imprimieron mi diseño 1:1 sino ligeramente ampliado. Así que tenga cuidado si decide utilizar este método. Llámelos primero y pregunte si es posible imprimir 1:1.

Después de una llamada telefónica me enviaron otro panel con las dimensiones adecuadas. ¡Fue mejor de lo esperado, excelente!

Entonces se necesitó mucha perforación y enrutamiento:

Código

  • Analizador DCF / Reloj v2.1
  • Bosquejo del superfiltro
Analizador / Reloj DCF v2.1 Arduino
Versión de error del 18 de enero de 2020:interruptor de ahorro de energía arreglado
 / * ============================================================================Analizador DCF77 / Versión 2 del reloj ==============================================================================Este boceto es un software gratuito; puede redistribuirlo y / o modificarlo según los términos de la Licencia Pública General Reducida GNU publicada por la Free Software Foundation; ya sea la versión 2.1 de la Licencia o (a su elección) cualquier versión posterior. Este boceto se distribuye con la esperanza de que sea útil, pero SIN NINGUNA GARANTÍA; incluso sin la garantía implícita de COMERCIABILIDAD o APTITUD PARA UN PROPÓSITO PARTICULAR. Consulte la Licencia pública general reducida de GNU para obtener más detalles. Debería haber recibido una copia de la Licencia Pública General Reducida GNU junto con esta biblioteca; si no es así, escriba a Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ==============================================================================Este código C ++ está lejos de estar optimizado porque yo mismo soy un novato en Arduino y C ++. Pero incluso después de aprender un poco más ahora, quiero mantener el código simple y legible. Es por eso que tal vez documenté en exceso el código para ayudar a comprender lo que está sucediendo. Erik de Ruiter 2014-2020 Mayo de 2014 Primera versión Marzo de 2016 - gran revisión ... Julio de 2016 - Comience con la construcción del Reloj 2.0 y adapte el boceto Versión 2.1 Fecha 2020-01-18 - Función Powersafe corregida. Versión 2.0:este boceto está adaptado para mi versión 2.0 del reloj DCF / Analyzer. Usó el Arduino MEGA y el Superfiltro DCF por defecto y para manejar los muchos LED separados, ahora uso los puertos de un Arduino Mega en lugar de un chip Maxim 7219. Esto se debe a que manejar LED con muchas especificaciones de voltaje / corriente diferentes es problemático con el chip Maxim. La iluminación de LED adicionales para el expample influirá (atenuará) los LED que ya están encendidos. Como no soy un ingeniero electrónico, mi única solución fue usar los puertos adicionales del Arduino Mega. Por supuesto, puede usar transistores o chips adicionales para impulsar los LED, pero para mí esta fue la solución obvia. - Eliminado todo el código de visualización del ánodo común de Maxim Versión 1.72 - Opción:Utilice un detector PIR de Ebay económico para apagar las pantallas seleccionables cuando no se detecte actividad. El usuario puede configurar el retardo de apagado para evitar que la pantalla se apague si una persona no se está moviendo pero la pantalla debe estar encendida. - Ahora la pantalla Apagado nocturno se puede desactivar haciendo que los valores 'POWERSAVINGOFFTIME' y 'POWERSAVINGONTIME' sean cero. - La pantalla de temperatura fija no se apaga en el modo de ahorro de energía. - La pantalla del contador de errores no se reiniciaba cada hora - Versión 1.71 corregida - Opción del usuario para reiniciar la memoria de temperatura mínima / máxima a la medianoche Versión 1.7:- La resolución de la pantalla de temperatura ha mejorado:de 0,5 a 0,1 grados Celsius Debido al tiempo del sensor DS18B20 necesita convertir la temperatura y mantener el código limpio, la pantalla de temperatura se actualiza una vez por minuto. - Rutina de control de paridad optimizada. - Verificación más confiable de datos DCF incorrectos, evitando la actualización de RTC con datos no válidos. - El error EoB ahora borra el anillo LED interno como debería. - El LED DCF OK ahora muestra el estado de la señal DCF de manera más confiable. Se apaga inmediatamente si ocurre un error y solo se enciende cuando los 3 bits de paridad son correctos. Versión 1.6:- Función de temperatura modificada para calcular solo una vez por minuto. Obtuve errores extraños antes del cambio porque usé un retraso de 100 ms para darle tiempo al sensor DS18B20 para calcular la temperatura. Pero la función de retardo es una muy mala idea en la mayoría de los códigos de C ++, así que finalmente me deshice de ella. Versión 1.5:- ¡Revisión completa de la función scanSignal y el resto del código! Mi primer intento funcionó, pero podría mejorarse ... - Los led rPW y rPT no funcionaron como pretendía, por lo que se corrigió ahora. - La rutina de comprobación de errores de fin de búfer funciona ahora como debería. - Incorporé una verificación de paridad de la señal DCF entrante. En la señal, se envían 3 bits de paridad, por lo que ahora se verifican y solo si los tres están bien, se acepta la información de tiempo recibida, se actualiza la pantalla y se sincroniza el RTC. si lo desea, puede conectar 3 LED de dos colores adicionales (cátodo común) para ver si cada uno de los 3 bits de paridad está bien o no. - Hice el cableado (o cambiar el cableado) mucho más fácil, creo, al poner toda la configuración del PIN en una tabla fácil de leer - Siempre que use 1 DS18B20 temp. sensor, edité el código para que ya no necesite averiguar la dirección del dispositivo I2C. - Gran limpieza del código ... - Ahorro de energía apagando las pantallas (el reloj sigue funcionando normalmente) ahora se puede configurar algo más fácil editando dos variables POWERSAVINGONTIME y POWERSAVINGOFFTIME. - cambiaron algunos nombres de variables:- Las instancias de Maxim 'lc' y 'lc1' ahora son MaximCC y MaximCA - Descripción de la pantalla MaximDcfTime ahora es DisplayTempWeek - DCF77SOUNDPIN ahora es BUZZERSWITCHPIN - Prueba de LED / pantalla después del encendido ahora integrada Descripción breve:Encendido:Después del encendido, primero se realiza una prueba de LED. Los LED y las pantallas se iluminan secuencialmente para mantener bajo el consumo de energía. Luego, el reloj comienza a recibir pulsos DCF y cuando se detecta una Marca de Minuto (espacio de 2 segundos), el LED de Marcador de Minuto se enciende y el contador de búfer se reinicia. El anillo LED interno ahora mostrará los pulsos DCF entrantes que también se almacenan en el búfer. En 3 momentos durante la recepción de datos, se comprueban los bits DCF de paridad para ver si los datos son válidos. Datos válidos recibidos:cuando, al final del minuto, después de que se detecta la marca de minuto (el LED BF (Buffer Full) está encendido), los tres bits de paridad están bien (el LED 'DCF OK' está encendido), la información del búfer es utilizado para extraer información de fecha y hora. Luego, el reloj RTC se actualiza (el LED 'RTC sincronizado' está encendido) y la información del anillo LED interno se copia en el anillo LED externo. La pantalla de hora, fecha y semana, LED de día, LED de verano / invierno y año bisiesto se actualiza con la nueva información de hora. No hay datos válidos:cuando uno o más de los bits de paridad no están bien debido a una señal ruidosa, la recepción de información DCF continúa, pero no se utilizará para actualizar el RTC, la pantalla y los LED. El anillo LED exterior, los LED 'RTC sincronizado' y 'DCF OK' se restablecerán. El LED de hora, fecha, semana, día, LED de verano / invierno y LED de año bisiesto no se ven afectados y siguen mostrando los últimos valores válidos recibidos. Los LED de error 'Periodo de tiempo' y / o 'Periodo con' indicarán los errores y la pantalla del contador de errores se actualizará. Cada hora, la pantalla de error se pondrá a cero. El LED EoB, End of Buffer se enciende cuando se reciben más pulsos DCF antes de que se detecte la Marca de Minuto debido a una señal ruidosa. (Cuando se detecta una marca de minuto no deberíamos tener más de 58 bits / pulsos) Después de la detección de la marca de minuto, se inicia un nuevo ciclo. Temperatura:en la marca de 30 segundos, la pantalla de temperatura mostrará los valores alto y bajo del período pasado después del último reinicio. Timbre:Si el interruptor de TIMBRE está ENCENDIDO / ALTO, entonces al comienzo de cada hora, el timbre (si está conectado) sonará por la noche, un tiempo establecido por el usuario en el código mismo, el timbre está desactivado. Ahorro de energía:la pantalla se apaga. Esto solo funcionará SI el interruptor de ahorro de energía está ALTO:1. APAGADO NOCTURNO En los horarios establecidos por el usuario, las pantallas se apagan por la noche y se encienden por la mañana. Observe las variables POWERSAVINGOFFTIME y POWERSAVINGONTIME. Marque la función  para seleccionar QUÉ pantallas desea apagar por la noche. 2. SENSOR PIR Conecte un sensor PIR y active la opción PIR POWERSAVE_BY_PIR y el retraso en PIR_DELAY_TIME. Cada vez que el detector PIR detecta movimiento, se pone a cero un contador de minutos, pero si no se detecta ningún movimiento durante más tiempo que el PIR_DELAY_TIME, las pantallas se apagan. Cuando se produce un movimiento, las pantallas se encienden inmediatamente. Nota:como se dijo antes, el reloj funcionará normalmente mientras las pantallas estén apagadas. Pitido DCF:Con un interruptor, conectado al pin BUZZERSWITCHPIN, puede escuchar los bits DCF recibidos entrando. La duración del tono es equivalente al ancho de pulso de los bits DCF, por lo tanto, 100 o 200 ms. Misceláneo:cuando la batería del RTC está vacía o se detecta una falla en la conexión, se enciende el LED de error del RTC. CRÉDITOS:Aprendí mucho del trabajo de Matthias Dalheimer y Thijs Elenbaas, quienes hicieron sus propios decodificadores DCF77. Sin su trabajo no hubiera sabido por dónde empezar. Terminé escribiendo mi propio código (usando fragmentos de sus ideas) para poder entender lo que está sucediendo ... Mi código está lejos de ser eficiente o avanzado, pero funciona y sé lo que está sucediendo. Sitios web interesantes:- 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:// es .wikipedia.org / wiki / DCF77 - Mucha más información sobre DCF77:http://www.picbasic.nl/indexes_uk.htm - Mi sitio web de Flickr:https://www.flickr.com/photos/edr1924/albums - Mi Github sitio web:https://github.com/deruiter * /// ----------------------------------- -------------------------------------------------- --------------------- // Bibliotecas // ------------------------ -------------------------------------------------- -------------------------------- // Arduino (nuevo) Biblioteca de tiempo .......... .......................... http://www.pjrc.com/teensy/td_libs_Time.html#include  // Habilite esta línea si usa Arduino Uno, Mega, etc. # incluya  // una biblioteca DS1307 básica y que devuelve el tiempo como time_t .......... http://www.pjrc.com/teensy/td_libs_DS1307RTC.html#include  // Maxim 7219 muestra la biblioteca ..... .............................. http://playground.arduino.cc/Main/LEDMatrix// !!! NOTA:debe usar una versión especial de la biblioteca Ledcontrol.h para obtener soporte de Common Anode // ¡porque el chip Maxim normalmente solo es adecuado para pantallas CATHODE comunes! #Include  // Biblioteca de interfaz SPI .... ...................................... http://arduino.cc/en/Reference/ SPI # include  // OneWire le permite acceder a dispositivos de 1 cable fabricados por Maxim / Dallas, // como DS18S20, DS18B20, DS1822 ................. ............. http://www.pjrc.com/teensy/td_libs_OneWire.html// ¡La biblioteca DallasTemperature puede hacer todo este trabajo por usted! ... http://milesburton.com/Dallas_Temperature_Control_Library#include  // ----------------------------- -------------------------------------------------- --------------------------- // Conexiones de pin Arduino UNO en una tabla fácil de leer //// entrada - Rx - usado para programación / comunicación con PC // salida - Tx - usado para programación / comunicación con PC # define DCF77PIN 2 // entrada - señal DCF de la placa de antena. ¡El pin debe ser una entrada de interrupción! #Define PIRDETECTORPIN 3 // entrada - detector PIR:verifique si hay actividad en la habitación para activar las pantallas , OFF =LOW # define CHIMESWITCHPIN 5 // entrada - SWITCH - enciende / apaga el timbre por hora / ON =HIGH, OFF =LOW # define POWERSAVESWITCHPIN 6 // input - SWITCH - enciende / apaga la función de ahorro de energía para que se muestre siempre está encendido / ENCENDIDO =ALTO, APAGADO =BAJO # define TEMPSENSORPIN 8 // entrada - Dallas One Wire DS18B20 sensor de temperatura # define TEMPRESETPIN 9 // entrada - PUSH BUTTON - restablecer temperatura mín. / máx. memoria / HIGH =restablecer # definir MAXIMCCLD 10 // salida - CS / LOAD - pseudo conexión SPI al chip Maxim 7219 - visualizaciones de 7 segmentos # define MAXIMCCCLK 11 // salida - CLOCK - pseudo conexión SPI al chip Maxim 7219 - visualizaciones de 7 segmentos # define MAXIMCCDATA 12 // salida - DATA - pseudo conexión SPI al chip Maxim 7219 - visualizaciones de 7 segmentos // !! Los pines 22 a 53 solo deben usarse para LED # definir LED_SUNDAY 22 // salida - LED - domingo # definir LED_MONDAY 23 // salida - LED - lunes # definir LED_TUESDAY 24 // salida - LED - martes # definir LED_WEDNESDAY 25 // salida - LED - Miércoles # define LED_JUEVES 26 // salida - LED - Jueves # define LED_FRIDAY 27 // salida - LED - Viernes # define LED_SATURDAY 28 // salida - LED - Sábado # define LED_CEST 29 // salida - LED - Hora de verano CEST #define LED_CET 30 // salida - LED - invierno CET # define LED_LEAPYEAR 31 // salida - LED - año bisiesto # define LED_RTCERROR 32 // salida - LED - problema al leer datos RTC (batería vacía / conexión) #define LED_RTCSYNC 33 // salida - LED - Encendido cuando RTC se sincroniza con éxito con el tiempo DCF # define LED_TEMP 34 // salida - LED - se muestra la temperatura # define LED_OPTION1 35 // salida - LED - se muestran datos opcionales 1 # define LED_OPTION2 36 // salida - LED:se muestran 2 datos opcionales # define LED_ERRORPT 37 // salida - LED - Error de tiempo del período DCF # define LED_ ERRORPW 38 // salida - LED - Error de ancho de período DCF # define LED_BUFFERFULL 39 // salida - LED - Indicador de búfer lleno, a continuación se analizarán los datos # define LED_MINUTEMARKER 40 // salida - LED - Fin del flujo de datos DCF detectado antes del búfer está lleno, los datos están corruptos # define LED_BUFFEROVERFLOW 41 // salida - LED - Más datos recibidos en un minuto de lo esperado debido a una mala señal # define LED_DCFSTATUS 42 // salida - LED - Encendido cuando tenemos buenos datos DCF # define LED_POWERSAVE 43 / / salida - LED - El modo de ahorro de energía está activado, algunas pantallas están apagadas # define LED_PARITY1PASS 44 // salida - LED - Paridad 1 bit está bien # define LED_PARITY1FAIL 45 // salida - LED - Paridad 1 bit FAILED # define LED_PARITY2PASS 46 // salida - LED - Paridad 2 bit es OK # define LED_PARITY2FAIL 47 // salida - LED - Paridad 2 bit FAILED # define LED_PARITY3PASS 48 // salida - LED - Paridad 3 bit es OK # define LED_PARITY3FAIL 49 // salida - LED - Paridad 3 bit FAILED # define LED_PIRMOTION 50 // salida - LED - Encendido cuando PIR detecta movimiento / / Pines analógicos # definir BUZZER A7 // salida - Zumbador piezo para DCF77 'beep' (a '+' del zumbador) #define SPEAKERVOLPIN A6 // salida - Volumen de la placa de sonido - LOW =volumen un nivel más bajo. SPEAKERVOLUME determina cuántas veces se activa esta salida después del encendido. / USADO para DS1307 RTC // I2C CLOCK - conectar a la PCB del reloj en tiempo real // -------------------------------- -------------------------------------------------- ------------------------ // Inicialización DS18B20 // -------------------- -------------------------------------------------- ------------------------------------ OneWire ds (TEMPSENSORPIN); // definir la instancia de Onewire DS // ------------------------------------------ -------------------------------------------------- -------------- // Inicialización de la pantalla de matriz Maxim 7219 // --------------------------- -------------------------------------------------- ----------------------------- / * clearDisplay (dirección int) .............. ............................... borra la pantalla seleccionada MaximCC.shutdown (int addr, boolean) ...... .......................... despierta el MAX72XX del modo de ahorro de energía (verdadero =sueño, falso =despierto) MaximCC.setIntensity (int addr , valor) .............................. establecer un brillo medio para los Leds (0 =min - 15 =max) MaximCC .setLed (int addr, int row, int col, boolean state) .......... enciende el led en fila, columna. ¡recuerde que los índices comienzan en 0! MaximCC.setRow (int addr, int row, byte value) ...................... esta función toma 3 argumentos. ejemplo:MaximCC.setRow (0,2, B10110000); MaximCC.setColumn (int addr, int col, byte value) ................... esta función toma 3 argumentos. ejemplo:MaximCC.setColumn (0,5, B00001111); MaximCC.setDigit (int addr, int digit, byte value, boolean dp) ...... esta función toma un argumento de tipo byte e imprime el dígito correspondiente en la columna especificada. El rango de valores válidos va de 0 a 15. Todos los valores entre 0..9 se imprimen como dígitos, los valores entre 10..15 se imprimen como su equivalente hexadecimal MaximCC.setChar (int addr, int digit, char value, boolean dp) ... mostrará:0 1 2 3 4 5 6 7 8 9 ABCDEFHLP; -. , _  (el espacio en blanco o el carácter) POWERSAVESWITCHPIN ***** Por favor, establezca el número de dispositivos que tiene ***** Pero el valor predeterminado máximo de 8 MAX72XX también funcionará. LedConrol (DATAIN, CLOCK, CS / LOAD, NUMBER OF MAXIM CHIPS) * /// lc es para las pantallas MaximLedControl MaximCC =LedControl (MAXIMCCDATA, MAXIMCCCLK, MAXIMCCLD, 7, falso); // Definir pines para Maxim 72xx y cuántos 72xx usamos // ----------------------------------- -------------------------------------------------- --------------------- // Configuración de usuario, definiciones de variables y matrices // ------------------ -------------------------------------------------- -------------------------------------- // El valor a continuación no es un número PIN sino un valor para establecer cuántas veces se activa la entrada 'Bajar volumen' en la placa de sonido // para que el volumen de la placa de sonido se pueda bajar después del encendido, si lo desea. # define SPEAKERVOLUME 12 // Elija si desea un prueba de todos los LED y pantallas después de un arranque // '1' =Sí, '0' =No # define PERFORM_LED_TEST 1 // Retraso entre cada pantalla de 7 segmentos en ms # define LEDTEST_DELAY_DISPLAYS 600 // Retraso entre cada LED en el anillo de LED y otros LED en ms # define LEDTEST_DELAY_LED_RING 20 // Elija si desea configurar el sensor de temperatura DS18B20 UNA VEZ a la resolución más alta.// esto es necesario después de usar el sensor para el primer st vez. Después de ejecutar el software // con esta configuración en ON una vez, apáguelo.// '1' =ON, '0' =OFF # define CONFIGURE_DS18B20 0 // POWERSAVE TIME - Valores OBLIGATORIOS! //// para definir el día y Noche. Esto se usa para la hora de ENCENDIDO y APAGADO de la pantalla de ahorro de energía // Y para determinar si el timbre se activará (durante el día) .//// SÓLO las pantallas se apagan a la hora de ahorro de energía, el reloj permanece completamente activo./ / PARA DESACTIVAR el apagado de la pantalla en cualquier momento, simplemente coloque el interruptor de ahorro de energía en APAGADO //// Interruptor de ahorro de energía ENCENDIDO:las pantallas se apagarán en el horario nocturno establecido // Y si la función POWERSAVE_BY_PIR está activada y no no hay // movimiento para el conjunto PIR_DELAY_TIME.// Interruptor de ahorro de energía APAGADO:se muestra siempre encendido, suena solo durante el día.//// Los valores están en formato 'Hora', por lo que las 8 p.m. serán '20', NO 20:00 o 8PM ... # define POWERSAVINGOFFTIME 9 // las pantallas están activadas # define POWERSAVINGONTIME 22 // las pantallas están apagadas // Opción de usuario:activar las pantallas solo cuando hay actividad en la habitación // '1' =ON, '0 '=OFF # define POWERSAVE_BY_PIR 1 // demora en MINUTOS para esperar después de que no se detecten antes de apagar las pantallas # define PIR_DELAY_TIME 30 // Opción del usuario para restablecer la temperatura min / memoria máxima a la medianoche // '1' =Restablecer a la medianoche, '0' =Solo restablecimiento manual # define TEMPRESET_MIDNIGHT 1 // ---------------------- -------------------------------------------------- ------- // definir parámetros varios # definir DS1307_I2C_ADDRESS 0x68 // definir la dirección RTC I2C # definir DCF_INTERRUPT 0 // Número de interrupción asociado con el pin // definición de la secuencia de cableado del número de pantalla Maxim 7219 // primer Maxim 7219 en el cableado 'daisychain' debe ser '0', el siguiente '1', etc.// PANTALLAS DE CATODOS COMUNES # definir LedRingInner 0 # definir LedRingOuter 1 # definir DisplayBufferBitError 2 # definir DisplayPeriodPulse 3 # definir DisplayTempWeek 4 # definir DisplayDate 5 # definir DisplayTime 6 / / definición de los niveles de brillo de la pantalla # define BrightnessLedRingOuter 1 # define BrightnessLedRingInner 1 # define BrightnessDisplayTime 1 # define BrightnessDisplayDate 7 # define BrightnessDisplayTempWeek 15 # define BrightnessDisplayPeriodPulse 2 # define Brightness LeadDisplayBufferBitError 15 // Pulse flanksstadgetic =0 unsigned; tatic unsigned long trailingEdge =0; unsigned long previousLeadingEdge =0; // utilizado en  volatile unsigned int DCFSignalState =0; // ¡las variables de interrupción SIEMPRE necesitan un calificador volátil! // se usa en 
 int previousSecond =0; unsigned int previousSignalState =0; // DCF Buffers e indicadoresstatic int DCFbitBuffer [59]; // aquí, los DCFbits recibidos se almacenan const int bitValue [] ={1, 2, 4, 8, 10, 20, 40, 80}; // estos son los valores decimales de los DCFbits recibidos // solo después de comenzar en un nuevo minuto, mostrar los bits recibidos en el anillo LED interno booleano MinuteMarkerFlag =false; int bufferPosition =0; int previousMinute =0; int previousHour =0; // variables para comprobar si los bits de DCF son valdbool dcfValidSignal =false; int dcfP1counter =0; int dcfP2counter =0; int dcfP3counter =0; int dcfParityCheckP1 =0; int dcfParityCheckP2 =0; int dcfPc3FarityCheck para almacenar variables de tiempo; // 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 utilizadas para almacenar los valores de número de semana y número de día dayNumber; int weekNumber; // variable del contador de erroresint errorCounter =0; boolean errorCondition =false; // variables misceláneas boolean daytimeChange =true; boolean dayTime =false; int dcf77SoundSwitch =0; // variables de temperatura byte presente =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 detector variablesint pirActivity =0; int pirDisplaysState =1; unsigned int pirTimer =0; unsigned long previousTimePIR =0; // ============================================================================// CONFIGURACIÓN // ============================================================================void setup () {// inicializar la comunicación serial Serial.begin (9600); // inicializar las conexiones PIN pinMode (DCF77PIN, INPUT); pinMode (TEMPRESETPIN, ENTRADA); pinMode (BUZZERSWITCHPIN, INPUT); pinMode (CHIMESWITCHPIN, ENTRADA); pinMode (POWERSAVESWITCHPIN, ENTRADA); pinMode (PIRDETECTORPIN, ENTRADA); pinMode (CHIMEPIN, SALIDA); pinMode (SPEAKERVOLPIN, SALIDA); // inicializar los pines LED 22 - 50 para (int i1 =22; i1 <=50; i1 ++) {pinMode (i1, OUTPUT); } // Inicializar variables, pantallas LED y LED initialize (); // Inicializa la interrupción de pulso DCF77 en el pin DCF_INTERRUPT, buscando un cambio en la señal, // para que los pulsos de flanco ascendente o descendente activen el manejador de interrupciones y // ejecuten la función int0handler. attachInterrupt (DCF_INTERRUPT, int0handler, CHANGE); // Inicialice RTC y configúrelo como SyncProvider. // Posteriormente, el RTC se sincronizará con el tiempo DCF setSyncProvider (RTC.get); // la función para obtener la hora del RTC // comprobar si el RTC ha establecido la hora del sistema if (timeStatus ()! =timeSet) {// No se puede sincronizar con el RTC - activar RTCError LED digitalWrite (LED_RTCERROR, HIGH); } else {// RTC ha establecido la hora del sistema - dim RTCError LED digitalWrite (LED_RTCERROR, LOW); } // Después de encender, configure el volumen del altavoz de la placa de audio Adafruit // inicialice ambos pines en LOW, que es el estado de salida predeterminado digitalWrite (SPEAKERVOLPIN, LOW); escritura digital (CHIMEPIN, BAJA); // bajar el volumen predeterminado de la caja de resonancia con los pasos de 'SPEAKERVOLUME' para (int i =0; i <=SPEAKERVOLUME; i ++) {digitalWrite (SPEAKERVOLPIN, HIGH); retraso (100); digitalWrite (SPEAKERVOLPIN, LOW); retraso (100); } // La siguiente función debe ejecutarse solo una vez. // Se utiliza para configurar la resolución de temperatura del sensor DS18B20 si (CONFIGURE_DS18B20 ==1) {configureDS18B20 (); } // usar con fines de prueba y / o configurar el tiempo RTC manualmente // setTime (23, 59, 40, 31, 12, 13); // RTC.set (ahora ()); // Solicita la conversión de temperatura calculateTemp (); // comprobar si se necesita una prueba de LED si (PERFORM_LED_TEST ==1) {// hacer una prueba de LED ledTest (); } else {// si no estamos haciendo una prueba de LED, debemos esperar un poco a que el sensor DS18B20 esté listo delay (750); } // Ahora obtenga la temperatura del sensor y muéstrela displayTemp (); // activar la pantalla del contador de errores después del LED de prueba LEDDisplay (DisplayBufferBitError, "R", 0);} // ============================================================================// LOOP // ==============================================================================void loop () {// compruebe primero si la dirección del pulso ha cambiado (ascendente o caída) // de lo contrario seguiríamos evaluando el mismo pulso if (DCFSignalState! =previousSignalState) {// 'restablecer' el estado de la variable previousSignalState =DCFSignalState; // evaluar el pulso entrante scanSignal (); } // verifica si se han cambiado los interruptores y actúa sobre ello checkSwitches (); // comprobar el movimiento PIR checkPIR (); // ejecutar tareas que deben suceder solo una vez cada segundo, minuto u hora // --------------------------------- ------------------------------------------- tasksEverySecond (); tasksEveryMinute (); tasksEveryHour ();} // ==============================================================================================================//// Nombre de la función:processDcfBit // llamada desde: //// Propósito:Evalúa la señal a medida que se recibe. Decide si recibimos un "1" o un "0" // y realizamos comprobaciones para ver si la sincronización del pulso está dentro de los límites // Parámetros:ninguno // Valor de retorno:ninguno //// ============================================================================================================/ * pulso ancho de pulso | - - | | - - | | ----- Marcador de FIN DE MINUTO:2000ms ----- | ___ _______ ___ ___ _______ | 0 | | 1 | | 0 | | 0 | | 1 | | | | | | | | | | | | | | | | | | | | | ______ | | _______________ | | ___________ | | ___________________________________ | | _______________ | | __ _ _ _ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1000 2100 2000 2200 3000 3100 SIN PULSO 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; regreso; } //-------------------------------------------------------------------- // 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")); 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();}

Piezas y carcasas personalizadas

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

Esquemas

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

Proceso de manufactura

  1. Reloj de cuco
  2. Reloj de visión pov de Arduino
  3. El reloj IV9 Numitron más simple de bricolaje con Arduino
  4. Reloj de pared simple con Adafruit 1/4 60 Ring Neopixel
  5. Reloj de palabras simple (Arduino)
  6. Reloj Arduino con tiempos de oración islámicos
  7. Arduino Spybot
  8. FlickMote
  9. Reloj maestro
  10. Arduino Temp. Monitor y reloj en tiempo real con pantalla 3.2
  11. Reloj despertador simple con DS1302 RTC