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

Arduino Shield NCS314 Reloj de tubos NIXIE IN-14

Componentes y suministros

Shield Nixie Tubes IN-14 NCS314 Arduino para Nixie Tubes Clock, etc. .
Escudo en Nixie Tubes IN-14
× 1
Shield Nixie Tubes Clock IN-12 NCS312 para xUSSR Nixie Tubes
× 1
Arduino UNO
Shield es compatible con Arduino UNO / Genuino o Arduino MEGA
× 1
Arduino Mega 2560
Shield es compatible con Arduino UNO / Genuino o Arduino MEGA
× 1
Fuente de alimentación 12V 1A
× 1
Estuche de acrílico para SHIELD NCS314
Beautiful Acrylic Сase Model ACNS314 es totalmente compatible con las versiones HW de Nixie Arduino Shield NCS314 de v1.X - 2 .X
× 1

Aplicaciones y servicios en línea

Arduino IDE

Acerca de este proyecto

Descripción general

Inicialmente, después de que tuviéramos acceso a un suministro casi inagotable de tubos Nixie soviéticos IN-12, IN-14 e IN-18 de excelente calidad, se iba a hacer una exhibición simple de los tubos Nixie como Shield para Arduino. Arduino en ese momento ya lo teníamos, por lo que el caso se quedó por pequeño (eso pensamos en ese momento). En ese momento no sabíamos nada sobre cómo lidiar con tales lámparas.

Muy rápidamente, encontramos en Internet un esquema para alimentar dichos tubos:

¡SÍ! ¡Eso brilla! El hecho de que lo viéramos simplemente nos sorprendió es como un pequeño milagro, y nos dimos cuenta de que estamos en el camino correcto. Inmediatamente comenzó la sesión de fotos:

Al día siguiente, se comenzó a discutir el concepto del proyecto futuro:para simplificar y reducir el costo, se decidió utilizar el esquema con un principio de visualización dinámica, pero luego se decidió abandonarlo a favor del esquema con un total modo de visualización estática. Aunque para los tubos IN-14 Nixie la diferencia visual no es notable, pero para las lámparas IN-18 la diferencia es notable:en modo dinámico, no funcionan tan brillantes, muchos de ellos aparecen, el llamado efecto de manchas azules:

El modo de visualización dinámica es un modo en el que en cada momento no se encienden todos los tubos, y solo uno (a la vez), también puede ser de otras especies cuando se iluminan simultáneamente, por ejemplo, solo dos lámparas.

Al discutir el futuro del dispositivo una vez que se haya decidido implementar la capacidad de mostrar información en los tubos proveniente de la computadora, permitirá a los entusiastas crear su propio dispositivo que se mostrará en las lámparas, por ejemplo, el número de mensajes no leídos o el número de rondas en el juego, como Fallout.

Luego comenzó la selección de hardware que podría cambiar cátodos (números) en los tubos. La elección fue obvia:el cambio se registra con SPI para guardar los pines MCU. Pero como los tubos de voltaje de suministro son muy altos, hasta 200 voltios, las opciones no son tanto:HV513, HV5812, HV5122. Y mientras construimos el dispositivo en cada uno de estos chips, nos detuvimos en el HV5812 (en la nueva versión de Shields, NCS314 V2.X y NCS312 V1.X usamos IC HV5122). Este chip es muy conveniente porque le permite controlar simultáneamente dos lámparas, como un registro de 20 bits.

Para controlar 6 tubos necesitaremos que tres de estos circuitos estén conectados entre sí en serie. Esto permite enviar paquetes una vez a través de SPI y no importa actualizar la información en los tubos, como sería el caso con un algoritmo de visualización dinámica. Es decir, en otras palabras, siempre que no necesitemos cambiar la información de los tubos, la MCU puede estar ocupada con otras tareas, ¡incluso dormir!

Nos gustaría hablar sobre la transferencia de datos en SPI. Arudino puede transmitir a la vez, solo 8 bits. Y necesitamos 60, el número entero más alto más cercano es divisible por 8 es 64, y por lo tanto tenemos que aplicar un poco de magia - para formar una gran variable de tipo unsigned long long var64 bits para cada registro y pasar 8 veces 8 bits cada vez por desplazando todos los bits dentro de la variable a la derecha:

  SPI.transfer (var64); SPI.transfer (var64>> 48); SPI.transfer (var64>> 40); SPI.transfer (var64>> 32); SPI.transfer (var64>> 24); SPI.transfer (var64>> 16); SPI.transfer (var64>> 8); SPI.transfer (iTmp);  

Aquellos objetivos que se establecieron y alcanzaron implementados:

  • Visualización estática basada en registros de turno.
  • Máquina tragamonedas (envenenamiento por Ani)
  • Proporcione las funciones estándar para el reloj, el reloj, la fecha, la hora y el despertador.
  • RTC (Reloj en tiempo real) con pila CR1220. (La nueva versión de la placa V1.2-2.X utiliza un chip de tiempo de alta precisión RTC DS3231).
  • Medición de temperatura DS18B20 [Celsius o Fahrenheit].
  • Control a través del puerto IR TSOP4836 (funciona solo Mega). Comprobado con el mando a distancia Sony RM-X151, pero es posible y otro mando a distancia con una frecuencia de 36kHz.
  • Sincronización de tiempo con GPS externo (solo funciona Mega)
  • Menú fácil.
  • Manejo separado del colon (el punto superior e inferior)
  • Colores de retroiluminación RGB con una suave transfusión
  • Tono de llamada RTTTL para la alarma (idioma de transferencia de tono de llamada)
  • Máquina tragamonedas (para prevenir indicadores de envenenamiento)
  • En la autocomprobación. (Verifique todos los números en cada pantalla del 0 al 9, para verificar todos los LED, un interruptor en serie de colores azul, rojo, verde, prueba de sonido (tonos de llamada)

Aquellas tareas que no se pudieron realizar por completo.

  • Sensor de luz

Código

  • Archivo sin título
Archivo sin título C / C ++
 const String FirmwareVersion ="010000"; // Formato _X.XX__ // NIXIE CLOCK SHIELD NCS314 de GRA &AFCH ([email protected]) // 25.05.2016 #include  #include  #include  #include  #include  #include  const byte LEpin =7; // pin Latch Enabled datos aceptados mientras HI levelconst byte DHVpin =5; // apagado / encendido MAX1771 Driver Hight Voltage (DHV) 110-220V const byte RedLedPin =9; // Salida MCU WDM para LED rojos 9-gconst byte GreenLedPin =6; // Salida MCU WDM para LED verdes 6-bconst byte BlueLedPin =3; // Salida MCU WDM para LED azules 3-rconst byte pinSet =A0; const byte pinUp =A2; const byte pinDown =A1; const byte pinBuzzer =2; const byte pinUpperDots =12; // El valor ALTO ilumina un byte de consistencia de puntos pinLowerDots =8; // El valor ALTO ilumina una palabra de puntos constantes fpsLimit =16666; // 1/60 * 1.000.000 // limitar la frecuencia de actualización máxima en 60 fpsString stringToDisplay ="000000"; // El contenido de esta cadena se mostrará en los tubos (debe tener una longitud de 6 caracteres) int menuPosition =0; // 0 - hora // 1 - fecha // 2 - alarma // 3 - 12/24 horas modo byte blinkMask =B00000000; // máscara de bits para dígitos parpadeantes (1 - parpadeo, 0 - luz constante) // ------------------------- 0 ----- --1 ---------- 2 ---------- 3 --------- 4 -------- 5 ------ --- 6 --------- 7 --------- 8 --------- 9 ----- // byte lowBytesArray [] ={B11111110, B11111101 , B11111011, B11110111, B11101111, B11011111, B10111111, B01111111, B11111111, B11111111}; // byte highBytesArray [] ={B11111111, B11111111, B11111111, B111111, B11te B00000000; // máscara de bits para separar puntos // B00000000 - apaga los puntos hacia arriba y hacia abajo // B1100000 - apaga todos los puntos # define DS1307_ADDRESS 0x68byte zero =0x00; // solución para el problema # 527int RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year, RTC_day_of_week; // - ------------ 0 -------- 1 --- ----- 2 ------- 3 -------- 4 -------- 5 -------- 6 -------- 7 -------- 8 -------- 9 -------- 10 ------- 11 ------- 12 ------- 13 ------- 14 // nombres:hora, fecha, alarma, 12/24 horas, minutos, segundos, día, mes, año, hora, minuto, segunda alarma 01 formato_hora // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1int padre [15] ={0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4}; int firstChild [15] ={4, 7, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int lastChild [15] ={6, 9, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; valor int [15] ={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24}; int maxValue [15] ={0, 0, 0, 0, 23, 59, 59, 31, 12, 99, 23, 59, 59, 1, 24}; int minValue [ 15] ={0, 0, 0, 12, 00, 00, 00, 1, 1, 00, 00, 00, 00, 0, 12}; byte blinkPattern [15] ={B00000000, B00000000, B00000000, B00000000, B00000011, B00001100, B00110000, B00000011, B00001100, B00110000, B00000011, B00001100, B00110000, B110000 00, B00001100}; # define TimeIndex 0 #define DateIndex 1 #define AlarmIndex 2 #define hModeIndex 3 #define TimeHoursIndex 4 #define TimeMintuesIndex 5 # define TimeSecondsIndex 6 # define DateDayIndex 7 # define DateMonthIndex 8 # define DateYearIndex define AlarmMinuteIndex 11 # define AlarmSecondIndex 12 # define Alarm01 13 # define hModeValueIndex 14bool editMode =false; long downTime =0; long upTime =0; const long settingDelay =150; bool BlinkUp =false; bool BlinkDown =false; unsigned long enterEditModeTime =0; bool RGBLedsOn =verdadero; byte RGBLEDsEEPROMAddress =0; byte HourFormatEEPROMAddress =1; byte AlarmTimeEEPROMAddress =2; // 3,4,5byte AlarmArmedEEPROMAddress =6; // botones pines declaracionesClickButton setButton (pinSet, LOW, CLICKBTN_PULLUP); ClickButton upButton (pinUp, LOW, CLICKBTN_PULLUP); ClickButton downButton (pinDown, LOW, CLICKBTN_PULLUP); ////////////////// /// Tono tone1; #define isdigit (n) (n> ='0' &&n <='9') // char * song ="MissionImp:d =16, o =6, b =95:32d, 32d #, 32d, 32d #, 32d, 32d #, 32d, 32d #, 32d, 32d, 32d #, 32e, 32f, 32f #, 32g, g, 8p, g, 8p, a #, p, c7, p, g, 8p, g, 8p, f, p, f #, p, g, 8p, g, 8p, a #, p, c7, p, g, 8p, g, 8p, f, p, f #, p, a #, g, 2d, 32p, a #, g, 2c #, 32p, a #, g, 2c, a # 5,8c, 2p, 32p, a # 5, g5,2f #, 32p, a # 5, g5,2f, 32p, a # 5, g5,2e, d #, 8d "; char * song =" PinkPanther:d =4, o =5, b =160:8d #, 8e, 2p, 8f #, 8g, 2p, 8d # , 8e, 16p, 8f #, 8g, 16p, 8c6,8b, 16p, 8d #, 8e, 16p, 8b, 2a #, 2p, 16a, 16g, 16e, 16d, 2e "; // char * song =" VanessaMae:d =4, o =6, b =70:32c7,32b, 16c7,32g, 32p, 32g, 32p, 32d #, 32p, 32d #, 32p, 32c, 32p, 32c, 32p, 32c7,32b, 16c7,32g #, 32p, 32g #, 32p, 32f, 32p, 16f, 32c, 32p, 32c, 32p, 32c7,32b, 16c7,32g, 32p, 32g, 32p, 32d #, 32p, 32d #, 32p, 32c, 32p, 32c, 32p, 32g, 32f, 32d #, 32d, 32c, 32d, 32d #, 32c, 32d #, 32f, 16g, 8p, 16d7,32c7,32d7,32a #, 32d7,32a, 32d7, 32g, 32d7,32d7,32p, 32d7,3 2p, 32d7,32p, 16d7,32c7,32d7,32a #, 32d7,32a, 32d7,32g, 32d7,32d7,32p, 32d7,32p, 32d7,32p, 32g, 32f, 32d #, 32d, 32c, 32d, 32d #, 32c, 32d #, 32f, 16c "; // char * song =" DasBoot:d =4, o =5, b =100:d # .4,8d4,8c4,8d4,8d # 4,8g4, a # .4,8a4,8g4,8a4,8a # 4,8d, 2f., p, f.4,8e4,8d4,8e4,8f4,8a4, c., 8b4,8a4,8b4,8c, 8e, 2g. , 2p "; // char * song =" Scatman:d =4, o =5, b =200:8b, 16b, 32p, 8b, 16b, 32p, 8b, 2d6,16p, 16c # .6,16p. , 8d6,16p, 16c # 6,8b, 16p, 8f #, 2p., 16c # 6,8p, 16d.6,16p., 16c # 6,16b, 8p, 8f #, 2p, 32p, 2d6,16p , 16c # 6,8p, 16d.6,16p., 16c # 6,16a., 16p., 8e, 2p., 16c # 6,8p, 16d.6,16p., 16c # 6,16b, 8p, 8b, 16b, 32p, 8b, 16b, 32p, 8b, 2d6,16p, 16c # .6,16p., 8d6,16p, 16c # 6,8b, 16p, 8f #, 2p., 16c # 6,8p, 16d.6,16p., 16c # 6,16b, 8p, 8f #, 2p, 32p, 2d6,16p, 16c # 6,8p, 16d.6,16p., 16c # 6,16a., 16p., 8e , 2p., 16c # 6,8p, 16d.6,16p., 16c # 6,16a, 8p, 8e, 2p, 32p, 16f # .6,16p., 16b., 16p. "; // char * song ="Palomitas de maíz:d =4, o =5, b =160:8c6,8a #, 8c6,8g, 8d #, 8g, c, 8c6,8a #, 8c6,8g, 8d #, 8g, c, 8c6 , 8d6,8d # 6,16c6,8d # 6,16c6,8d # 6,8d6,16a #, 8d6,16a #, 8d6,8c6,8a #, 8g, 8a #, c6 "; // char * song ="WeWishYou:d =4, o =5, b =200:d, g, 8g, 8a, 8g, 8f #, e, e, e, a, 8a, 8b, 8a, 8g, f #, d, d, b, 8b, 8c6,8b , 8a, g, e, d, e, a, f #, 2g, d, g, 8g, 8a, 8g, 8f #, e, e, e, a, 8a, 8b, 8a, 8g, f #, d, d, b, 8b, 8c6,8b, 8a, g, e, d, e, a, f #, 1g, d, g, g, g, 2f #, f #, g, f #, e, 2d, a, b , 8a, 8a, 8g, 8g, d6, d, d, e, a, f #, 2g "; # define OCTAVE_OFFSET 0char * p; int notes [] ={0, NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4 , NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, NOTE_D6, NOTA_C6, , NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, {NOTE_B7}; int. 1 -1,0,0, // 2 0,1,0, // 3 0,0, -1, // 4 1,0,0, // 5 0, -1,0}; // matriz con reglas RGB (0 - no hacer nada, -1 - decrese, +1 - incresevoid setRTCDateTime (byte h, byte m, byte s, byte d, byte mon, byte y, byte w =1); int functionDownButton =0; int functionUpButton =0; / **************************************** *********************************************** *********** Programa inicial *********************************** *********************************************** **************** / void setup () {digitalWrite (DHVpin, LOW); // desactivado MAX1771 Driver Hight Voltage (DHV) 110-220V Wire.begin (); // setRTCDateTime (23,40,00,25,7,15,1); Serial.begin (115200); Serial.println (""); if (EEPROM.read (HourFormatEEPROMAddress)! =12) valor [hModeValueIndex] =24; else valor [hModeValueIndex] =12; if (EEPROM.read (RGBLEDsEEPROMAddress)! =0) RGBLedsOn =true; else RGBLedsOn =false; if (EEPROM.read (AlarmTimeEEPROMAddress) ==255) valor [AlarmHourIndex] =0; más valor [AlarmHourIndex] =EEPROM.read (AlarmTimeEEPROMAddress); if (EEPROM.read (AlarmTimeEEPROMAddress + 1) ==255) valor [AlarmMinuteIndex] =0; e Este valor [AlarmMinuteIndex] =EEPROM.read (AlarmTimeEEPROMAddress + 1); if (EEPROM.read (AlarmTimeEEPROMAddress + 2) ==255) valor [AlarmSecondIndex] =0; si no valor [AlarmSecondIndex] =EEPROM.read (AlarmTimeEEPROMAddress + 2); if (EEPROM.read (AlarmArmedEEPROMAddress) ==255) valor [Alarm01] =0; si no valor [Alarm01] =EEPROM.read (AlarmArmedEEPROMAddress); tone1.begin (pinBuzzer); song =parseSong (canción); pinMode (LEpin, SALIDA); pinMode (DHVpin, SALIDA); pinMode (RedLedPin, SALIDA); pinMode (GreenLedPin, SALIDA); pinMode (BlueLedPin, SALIDA); // Configuración de SPI SPI.begin (); // SPI.setDataMode (SPI_MODE3); // Modo 3 SPI SPI.setClockDivider (SPI_CLOCK_DIV128); // SCK =16MHz / 128 =125kHz // pines de botones en su modo pin (pinSet, INPUT_PULLUP); pinMode (pinUp, INPUT_PULLUP); pinMode (pinDown, INPUT_PULLUP); //////////////////////////// pinMode (pinBuzzer, SALIDA); // botones de objetos en su setButton.debounceTime =20; // Temporizador de rebote en ms setButton.multiclickTime =30; // Límite de tiempo para múltiples clics setButton.longClickTime =2000; // tiempo hasta que los "clics presionados" se registren upButton.debounceTime =20; // Temporizador de rebote en ms upButton.multiclickTime =30; // Límite de tiempo para múltiples clics upButton.longClickTime =2000; // tiempo hasta que los "clics presionados" se registren downButton.debounceTime =20; // Temporizador de rebote en ms downButton.multiclickTime =30; // Límite de tiempo para múltiples clics downButton.longClickTime =2000; // tiempo hasta que se registre "clics retenidos" // digitalWrite (DHVpin, HIGH); // en MAX1771 Driver Hight Voltage (DHV) 110-220V // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!! // doTest (); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! getRTCTime (); setTime (RTC_horas, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); digitalWrite (DHVpin, BAJO); // apagado MAX1771 Driver Hight Voltage (DHV) 110-220V setRTCDateTime (RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year, 1); // ���������� ������ ��� ��������� ����� � RTC ����� �������� � ����� ���������� digitalWrite (DHVpin, HIGH); // en MAX1771 Driver Hight Voltage (DHV) 110-220V // p =song;} void rotateLeft (uint8_t &bits) {uint8_t high_bit =bits &(1 <<7)? 1:0; bits =(bits <<1) | bit_alto;} int rotador =0; // índice en matriz con "reglas" RGB (aumenta en uno en cada 255 ciclos) int ciclo =0; // ciclos contraint RedLight =255; int GreenLight =0; int BlueLight =0; unsigned long prevTime =0; // el tiempo del tubo láser se iluminó sin firmar largo prevTime4FireWorks =0; // hora del último cambio de RGB // int minuteL =0; // ������� ����� ����� / ***************************** *********************************************** ******************************* Programa PRINCIPAL ***************** *********************************************** ****************************************** / void loop () { p =playmusic (p); if ((millis () - prevTime4FireWorks)> 5) {rotateFireWorks (); // cambia el color (en 1 paso) prevTime4FireWorks =millis (); } doIndication (); setButton.Update (); upButton.Update (); downButton.Update (); if (editMode ==false) {blinkMask =B00000000; } else if ((millis () - entrandoEditModeTime)> 60000) {editMode =false; menuPosition =firstChild [menuPosition]; blinkMask =blinkPattern [menuPosition]; } if (setButton.clicks> 0) // clic corto {p =0; // apaga la música))) tone1.play (1000,100); entrandoEditModeTime =millis (); menuPosition =menuPosition + 1; if (menuPosition ==hModeIndex + 1) menuPosition =TimeIndex; Serial.print (F ("menuPosition =")); Serial.println (menuPosition); Serial.print (F ("valor =")); Serial.println (valor [menuPosition]); blinkMask =blinkPattern [menuPosition]; if ((parent [menuPosition-1]! =0) y (lastChild [parent [menuPosition-1] -1] ==(menuPosition-1))) {if ((parent [menuPosition-1] -1 ==1 ) &&(! isValidDate ())) {menuPosition =DateDayIndex; regreso; } editMode =falso; menuPosition =parent [menuPosition-1] -1; if (menuPosition ==TimeIndex) setTime (valor [TimeHoursIndex], valor [TimeMintuesIndex], valor [TimeSecondsIndex], día (), mes (), año ()); if (menuPosition ==DateIndex) setTime (hora (), minuto (), segundo (), valor [DateDayIndex], valor [DateMonthIndex], 2000 + valor [DateYearIndex]); if (menuPosition ==AlarmIndex) {EEPROM.write (AlarmTimeEEPROMAddress, valor [AlarmHourIndex]); EEPROM.write (AlarmTimeEEPROMAddress + 1, valor [AlarmMinuteIndex]); EEPROM.write (AlarmTimeEEPROMAddress + 2, valor [AlarmSecondIndex]); EEPROM.write (AlarmArmedEEPROMAddress, valor [Alarm01]);}; if (menuPosition ==hModeIndex) EEPROM.write (HourFormatEEPROMAddress, valor [hModeValueIndex]); digitalWrite (DHVpin, BAJO); // apagado MAX1771 Driver Hight Voltage (DHV) 110-220V setRTCDateTime (hora (), minuto (), segundo (), día (), mes (), año ()% 1000,1); escritura digital (DHVpin, ALTA); // en MAX1771 Driver Hight Voltage (DHV) 110-220V} valor [menuPosition] =extractDigits (blinkMask); } if (setButton.clicks <0) // clic largo {tone1.play (1000,100); if (! editMode) {entrandoEditModeTime =millis (); if (menuPosition ==TimeIndex) stringToDisplay =PreZero (hora ()) + PreZero (minuto ()) + PreZero (segundo ()); // formato de 24 horas habilitado temporalmente mientras que la configuración} menuPosition =firstChild [menuPosition]; if (menuPosition ==AlarmHourIndex) {valor [Alarm01] =1; / * digitalWrite (pinUpperDots, HIGH); * / dotPattern =B10000000;} editMode =! editMode; blinkMask =blinkPattern [menuPosition]; valor [menuPosition] =extractDigits (blinkMask); } if (upButton.clicks! =0) functionUpButton =upButton.clicks; if (upButton.clicks> 0) {p =0; // apaga la música))) tone1.play (1000,100); incrementValue (); } if (functionUpButton ==-1 &&upButton.depressed ==true) {BlinkUp =false; if (editMode ==true) {if ((millis () - upTime)> settingDelay) {upTime =millis (); // + settingDelay; incrementValue (); }}} else BlinkUp =true; if (downButton.clicks! =0) functionDownButton =downButton.clicks; if (downButton.clicks> 0) {p =0; // apaga la música))) tone1.play (1000,100); dicrementValue (); } if (functionDownButton ==-1 &&downButton.depressed ==true) {BlinkDown =false; if (editMode ==true) {if ((millis () - downTime)> settingDelay) {downTime =millis (); // + settingDelay; dicrementValue (); }}} else BlinkDown =true; if (! editMode) {if (upButton.clicks <0) {tone1.play (1000,100); RGBLedsOn =verdadero; EEPROM.write (RGBLEDsEEPROMAddress, 1); Serial.println ("RGB =activado"); } if (downButton.clicks <0) {tone1.play (1000,100); RGBLedsOn =falso; EEPROM.write (RGBLEDsEEPROMAddress, 0); Serial.println ("RGB =desactivado"); }} static bool updateDateTime =false; switch (menuPosition) {case TimeIndex:// modo de tiempo stringToDisplay =updateDisplayString (); doDotBlink (); checkAlarmTime (); descanso; case DateIndex:// modo de fecha stringToDisplay =PreZero (day ()) + PreZero (month ()) + PreZero (year ()% 1000); dotPattern =B01000000; // activar puntos inferiores / * digitalWrite (pinUpperDots, LOW); digitalWrite (pinLowerDots, HIGH); * / checkAlarmTime (); descanso; case AlarmIndex:// modo de alarma stringToDisplay =PreZero (valor [AlarmHourIndex]) + PreZero (valor [AlarmMinuteIndex]) + PreZero (valor [AlarmSecondIndex]); if (valor [Alarm01] ==1) / * digitalWrite (pinUpperDots, HIGH); * / dotPattern =B10000000; // activa los puntos superiores else {/ * digitalWrite (pinUpperDots, LOW); digitalWrite (pinLowerDots, LOW); * / dotPattern =B00000000; // apaga los puntos superiores} checkAlarmTime (); descanso; case hModeIndex:// Modo de 12/24 horas stringToDisplay ="00" + String (value [hModeValueIndex]) + "00"; dotPattern =B00000000; // apagar todos los puntos / * digitalWrite (pinUpperDots, LOW); digitalWrite (pinLowerDots, BAJO); * / checkAlarmTime (); descanso; }} String PreZero (int dígito) {if (dígito <10) return String ("0") + String (dígito); si no devuelve Cadena (dígito);} void rotateFireWorks () {if (! RGBLedsOn) {analogWrite (RedLedPin, 0); analogWrite (GreenLedPin, 0); analogWrite (BlueLedPin, 0); regreso; } RedLight =RedLight + horquillas de fuego [rotador * 3]; GreenLight =GreenLight + horquillas [rotador * 3 + 1]; BlueLight =BlueLight + horquillas de fuego [rotador * 3 + 2]; analogWrite (RedLedPin, RedLight); analogWrite (GreenLedPin, GreenLight); analogWrite (BlueLedPin, BlueLight); ciclo =ciclo + 1; if (ciclo ==255) {rotador =rotador + 1; ciclo =0; } if (rotador> 5) rotador =0;} void doIndication () {// byte estático b =B00000001; static unsigned long lastTimeInterval1Started; if ((micros () - lastTimeInterval1Started) > 2; Var64 | =tmpVar64; Var64 =(Var64>> 4); unsigned int iTmp =0; iTmp =Var64>> 56; SPI.transfer (iTmp); iTmp =Var64>> 48; SPI.transfer (iTmp); iTmp =Var64>> 40; SPI.transfer (iTmp); iTmp =Var64>> 32; SPI.transfer (iTmp); iTmp =Var64>> 24; SPI.transfer (iTmp); iTmp =Var64>> 16; SPI.transfer (iTmp); iTmp =Var64>> 8; SPI.transfer (iTmp); iTmp =Var64; SPI.transfer (iTmp); escritura digital (LEpin, BAJA); // datos de retención} byte CheckButtonsState () {botones booleanos estáticosWasChecked; startBuzzTime largo sin firmar estático; static unsigned long lastTimeButtonsPressed; if ((digitalRead (pinSet) ==0) || (digitalRead (pinUp) ==0) || (digitalRead (pinDown) ==0)) {if (botonesWasChecked ==false) startBuzzTime =millis (); botonesWasChecked =verdadero; } else buttonsWasChecked =false; if (millis () - startBuzzTime <30) {digitalWrite (pinBuzzer, ALTO); } else {digitalWrite (pinBuzzer, LOW); }} String updateDisplayString () {estático sin firmar largo lastTimeStringWasUpdated; if ((millis () - lastTimeStringWasUpdated)> 1000) {//Serial.println("doDotBlink "); // doDotBlink (); lastTimeStringWasUpdated =millis (); if (valor [hModeValueIndex] ==24) return PreZero (hora ()) + PreZero (minuto ()) + PreZero (segundo ()); de lo contrario, devuelve PreZero (hourFormat12 ()) + PreZero (minuto ()) + PreZero (segundo ()); } return stringToDisplay;} void doTest () {Serial.print (F ("Versión de firmware:")); Serial.println (FirmwareVersion.substring (1,2) + "." + FirmwareVersion.substring (2,4)); Serial.println (F ("Iniciar prueba")); int adc =analogRead (A3); flotación Uinput =4.6 * (5.0 * adc) /1024.0+0.7; Serial.print (F ("U entrada =")); Serial.print (Uinput); p =canción; parseSong (p); analogWrite (RedLedPin, 255); retraso (1000); analogWrite (RedLedPin, 0); analogWrite (GreenLedPin, 255); retraso (1000); analogWrite (GreenLedPin, 0); analogWrite (BlueLedPin, 255); retraso (1000); // mientras (1); String testStringArray [12] ={"000000", "111111", "222222", "333333", "444444", "555555", "666666", "777777", "888888", "999999", "", ""}; if (Uinput <10) testStringArray [10] ="000" + String (int (Uinput * 100)); else testStringArray [10] ="00" + String (int (Uinput * 100)); testStringArray [11] =FirmwareVersion; int dlay =500; prueba bool =1; byte strIndex =0; startOfTest largo sin firmar =millis (); for (int i =0; i <12; i ++) {if ((millis () - startOfTest)> dlay) {startOfTest =millis (); strIndex =strIndex + 1; if (strIndex ==10) dlay =3000; if (strIndex ==12) prueba =0; switch (strIndex) {/ * caso 10:SPI.transfer ((b | B01000000) &B11111100); descanso; caso 11:transferencia SPI ((b | B01000000) &B11001110); descanso; * / // predeterminado:SPI.transfer (b | B11000000); predeterminado:stringToDisplay =testStringArray [strIndex]; }} delayMicroseconds (2000); }; Serial.println (F ("Detener prueba")); } void doDotBlink () {static unsigned long lastTimeBlink =millis (); static bool dotState =0; if ((millis () - lastTimeBlink)> 1000) {lastTimeBlink =millis (); dotState =! dotState; if (dotState) {dotPattern =B11000000; / * digitalWrite (pinUpperDots, HIGH); digitalWrite (pinLowerDots, HIGH); * /} else {dotPattern =B00000000; / * digitalWrite (pinUpperDots, BAJO); digitalWrite (pinLowerDots, LOW); * /}}} void setRTCDateTime (byte h, byte m, byte s, byte d, byte mon, byte y, byte w) {Wire.beginTransmission (DS1307_ADDRESS); Wire.write (cero); // detiene Oscillator Wire.write (decToBcd (s)); Wire.write (decToBcd (m)); Wire.write (decToBcd (h)); Wire.write (decToBcd (w)); Wire.write (decToBcd (d)); Wire.write (decToBcd (mon)); Wire.write (decToBcd (y)); Wire.write (cero); // iniciar Wire.endTransmission ();} byte decToBcd (byte val) {// Convertir números decimales normales a decimal codificado en binario return ((val / 10 * 16) + (val% 10));} byte bcdToDec (byte val ) {// Convertir decimal codificado en binario a números decimales normales return ((val / 16 * 10) + (val% 16));} void getRTCTime () {Wire.beginTransmission (DS1307_ADDRESS); Wire.write (cero); Wire.endTransmission (); Wire.requestFrom (DS1307_ADDRESS, 7); RTC_seconds =bcdToDec (Wire.read ()); RTC_minutes =bcdToDec (Wire.read ()); RTC_horas =bcdToDec (Wire.read () &0b111111); // 24 horas RTC_day_of_week =bcdToDec (Wire.read ()); // 0-6 -> domingo - sábado RTC_day =bcdToDec (Wire.read ()); RTC_month =bcdToDec (Wire.read ()); RTC_year =bcdToDec (Wire.read ());} palabra doEditBlink (int pos) {if (! BlinkUp) return 0; if (! BlinkDown) return 0; int lowBit =blinkMask>> pos; lowBit =lowBit &B00000001; static unsigned long lastTimeEditBlink =millis (); static bool blinkState =false; máscara de palabra =0; static int tmp =0; // blinkMask; if ((millis () - lastTimeEditBlink)> 300) {lastTimeEditBlink =millis (); blinkState =! blinkState; /*Serial.print("blinkpattern="); Serial.println (blinkPattern [menuPosition]); if (((blinkPattern [menuPosition]>> 8) &1 ==1) &&blinkState ==true) digitalWrite (pinLowerDots, HIGH); else digitalWrite (pinLowerDots, LOW); if (((blinkPattern [menuPosition]>> 7) &1 ==1) &&blinkState ==true) digitalWrite (pinUpperDots, HIGH); else digitalWrite (pinUpperDots, LOW); * / if (blinkState) tmp =0; else tmp =blinkMask; } if (((dotPattern &~ tmp)>> 6) &1 ==1) digitalWrite (pinLowerDots, HIGH); else digitalWrite (pinLowerDots, LOW); if (((dotPattern &~ tmp)>> 7) &1 ==1) digitalWrite (pinUpperDots, HIGH); else digitalWrite (pinUpperDots, LOW); if ((blinkState ==true) &&(lowBit ==1)) máscara =0xFFFF; // máscara =B11111111; return mask;} int extractDigits (byte b) {String tmp ="1"; /*Serial.print("blink pattern ="); Serial.println (b); Serial.print ("stringToDisplay ="); Serial.println (stringToDisplay); * / if (b ==B00000011) {tmp =stringToDisplay.substring (0,2); /*Serial.print("stringToDisplay1="); Serial.println (stringToDisplay); * /} if (b ==B00001100) {tmp =stringToDisplay.substring (2,4); /*Serial.print("stringToDisplay2="); Serial.println (stringToDisplay); * /} if (b ==B00110000) {tmp =stringToDisplay.substring (4); /*Serial.print("stringToDisplay3="); Serial.println(stringToDisplay);*/ } /*Serial.print("stringToDisplay4="); Serial.println(stringToDisplay);*/ return tmp.toInt();}void injectDigits(byte b, int value){ if (b==B00000011) stringToDisplay=PreZero(value)+stringToDisplay.substring(2); if (b==B00001100) stringToDisplay=stringToDisplay.substring(0,2)+PreZero(value)+stringToDisplay.substring(4); if (b==B00110000) stringToDisplay=stringToDisplay.substring(0,4)+PreZero(value);}bool isValidDate(){ int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; if (value[DateYearIndex]%4==0) days[1]=29; if (value[DateDayIndex]>days[value[DateMonthIndex]-1]) return false; else return true; }byte default_dur =4;byte default_oct =6;int bpm =63;int num;long wholenote;long duration;byte note;byte scale;char* parseSong(char *p){ // Absolutely no error checking in here // format:d=N,o=N,b=NNN:// find the start (skip name, etc) while(*p !=':') p++; // ignore name p++; // skip ':' // get default duration if(*p =='d') { p++; p++; // skip "d=" num =0; while(isdigit(*p)) { num =(num * 10) + (*p++ - '0'); } if(num> 0) default_dur =num; p++; // skip comma } // get default octave if(*p =='o') { p++; p++; // skip "o=" num =*p++ - '0'; if(num>=3 &&num <=7) default_oct =num; p++; // skip comma } // get BPM if(*p =='b') { p++; p++; // skip "b=" num =0; while(isdigit(*p)) { num =(num * 10) + (*p++ - '0'); } bpm =num; p++; // skip colon } // BPM usually expresses the number of quarter notes per minute wholenote =(60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) return p;} // now begin note loop static unsigned long lastTimeNotePlaying=0; char* playmusic(char *p) { if(*p==0) { return p; } if (millis()-lastTimeNotePlaying>duration) lastTimeNotePlaying=millis(); else return p; // first, get note duration, if available num =0; while(isdigit(*p)) { num =(num * 10) + (*p++ - '0'); } if(num) duration =wholenote / num; else duration =wholenote / default_dur; // we will need to check if we are a dotted note after // now get the note note =0; switch(*p) { case 'c':note =1; descanso; case 'd':note =3; descanso; case 'e':note =5; descanso; case 'f':note =6; descanso; case 'g':note =8; descanso; case 'a':note =10; descanso; case 'b':note =12; descanso; case 'p':default:note =0; } p++; // now, get optional '#' sharp if(*p =='#') { note++; p++; } // now, get optional '.' dotted note if(*p =='.') { duration +=duration/2; p++; } // now, get scale if(isdigit(*p)) { scale =*p - '0'; p++; } else { scale =default_oct; } scale +=OCTAVE_OFFSET; if(*p ==',') p++; // skip comma for next note (or we may be at the end) // now play the note if(note) { tone1.play(notes[(scale - 4) * 12 + note], duration); if (millis()-lastTimeNotePlaying>duration) lastTimeNotePlaying=millis(); else return p; tone1.stop(); } else { return p; } Serial.println(F("Incorrect Song Format!")); return 0; //error } void incrementValue() { enteringEditModeTime=millis(); if (editMode==true) { if(menuPosition!=hModeValueIndex) // 12/24 hour mode menu position value[menuPosition]=value[menuPosition]+1; else value[menuPosition]=value[menuPosition]+12; if (value[menuPosition]>maxValue[menuPosition]) value[menuPosition]=minValue[menuPosition]; if (menuPosition==Alarm01) { if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;//turn on all dots /*else digitalWrite(pinUpperDots, LOW); */ dotPattern=B00000000; //turn off all dots } injectDigits(blinkMask, value[menuPosition]); } } void dicrementValue(){ enteringEditModeTime=millis(); if (editMode==true) { if (menuPosition!=hModeValueIndex) value[menuPosition]=value[menuPosition]-1; else value[menuPosition]=value[menuPosition]-12; if (value[menuPosition]1000)) Alarm1SecondBlock=false; if (Alarm1SecondBlock==true) return; if ((hour()==value[AlarmHourIndex]) &&(minute()==value[AlarmMinuteIndex]) &&(second()==value[AlarmSecondIndex])) { lastTimeAlarmTriggired=millis(); Alarm1SecondBlock=true; Serial.println(F("Wake up, Neo!")); p=song; }} 
Prog NIXIE Clock Tubes Shield NCS314
https://github.com/afch/NixeTubesShieldNCS314/

Esquemas


Proceso de manufactura

  1. Reloj de visión pov de Arduino
  2. Controlador DMX operado por la web
  3. Reloj de palabras simple (Arduino)
  4. Reloj Arduino con tiempos de oración islámicos
  5. Arduino Spybot
  6. Reloj maestro
  7. Hacer un reloj Nixie con Arduino en caja de madera MDF
  8. Reloj de matriz de 7 segmentos
  9. BLUE_P:Escudo de programación inalámbrico Arduino
  10. TFT Shield para Arduino Nano - Iniciar
  11. Reloj despertador simple con DS1302 RTC