Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Arduino Shield NCS314 NIXIE Tubes Clock IN-14

Componentes e suprimentos

Blindagem de tubos Nixie IN-14 NCS314 Arduino para relógio de tubos Nixie etc. .
Blindagem em tubos Nixie IN-14
× 1
Blindagem de tubos Nixie Clock IN-12 NCS312 para tubos xUSSR Nixie
× 1
Arduino UNO
Shield é compatível com Arduino UNO / Genuino ou Arduino MEGA
× 1
Arduino Mega 2560
Shield é compatível com Arduino UNO / Genuino ou Arduino MEGA
× 1
Fonte de alimentação 12V 1A
× 1
Estojo acrílico para SHIELD NCS314
Lindo Сase acrílico modelo ACNS314 é totalmente compatível com as versões Nixie Arduino Shield NCS314 HW de v1.X - 2 .X
× 1

Aplicativos e serviços online

Arduino IDE

Sobre este projeto





Visão geral


Inicialmente, depois de termos acesso a um suprimento quase inesgotável de tubos soviéticos Nixie de excelente qualidade IN-12, IN-14 e IN-18, íamos fazer uma exibição simples dos tubos Nixie como Escudo para Arduino. O Arduino naquela época já tínhamos, de modo que o case permaneceu por pequeno (assim pensamos na época). Naquela época, não sabíamos nada sobre como lidar com essas lâmpadas.





Rapidamente encontramos na internet um esquema para alimentar esses tubos:

SIM! Isso brilha! O fato de termos visto apenas nos surpreendeu é como um pequeno milagre, e percebemos que estamos no caminho certo. Imediatamente começou a sessão de fotos:

No dia seguinte, começou a discutir o conceito do futuro projeto:para simplificar e reduzir o custo, decidiu-se usar o esquema com um princípio de display dinâmico, mas posteriormente decidiu-se abandoná-lo em favor do esquema com um totalmente modo de exibição estático. Embora para as válvulas IN-14 Nixie a diferença visual não seja perceptível, mas para as lâmpadas IN-18 a diferença é perceptível - no modo dinâmico, elas funcionam não tão brilhantes que muitos deles aparecem, o chamado efeito de manchas azuis:

O modo de exibição dinâmica é um modo em que a cada momento nem todos os tubos estão acesos, e apenas um (de cada vez), também podem ser outras espécies quando iluminados simultaneamente, por exemplo, apenas duas lâmpadas.

Ao discutir o futuro do dispositivo, uma vez que tenha sido decidido implementar a capacidade de exibir informações nos tubos provenientes do computador, isso permitirá que os entusiastas criem seus próprios dispositivos que seriam exibidos nas lâmpadas, por exemplo, o número de mensagens não lidas ou o número de rodadas no jogo, como Fallout.

Em seguida, começou a seleção do hardware que poderia ser catodo de troca (números) nos tubos. A escolha era óbvia - os registros de deslocamento com SPI para salvar os pinos de MCU. Mas como a tensão de alimentação tubesis muito alta - até 200 volts, as opções não são tanto:HV513, HV5812, HV5122. E enquanto construímos o dispositivo em cada um desses chips, paramos no HV5812 (na nova versão do Shields NCS314 V2.X e NCS312 V1.X usava IC HV5122). Este chip é muito prático porque permite controlar simultaneamente duas lâmpadas, como um registro de 20 bits.

Para controlar 6 tubos, precisaremos de três desses circuitos conectados uns aos outros em série. Isso permite enviar o pacote uma vez sobre o SPI e não se preocupa em atualizar as informações nos tubos, como seria o caso com um algoritmo de exibição dinâmica. Ou seja, enquanto não precisarmos alterar as informações nas válvulas a MCU pode estar ocupada com outras tarefas, até mesmo dormir!

Gostaríamos de falar sobre a transferência de dados no SPI. Arudino pode transmitir por vez, apenas 8 bits. E precisamos de 60, o número inteiro superior mais próximo é divisível por 8 é 64 e, portanto, temos que aplicar um pouco de magia - para formar uma grande variável do tipo unsigned long long var64 bits para cada registro e passar 8 vezes 8 bits cada vez por deslocando todos os bits dentro da variável para a direita:
  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);  





Esses objetivos que foram definidos e alcançados foram implementados:

  • Exibição estática baseada em registradores de deslocamento.
  • Máquina caça-níqueis (envenenamento por Ani)
  • Fornece as funções padrão para relógio, relógio, data, hora e despertador.
  • RTC (Real Time Clock) com bateria CR1220. (A nova versão da placa V1.2-2.X usa um chip de tempo de alta precisão RTC DS3231).
  • Medição de temperatura DS18B20 [Celsius ou Fahrenheit].
  • Controle via porta de infravermelho TSOP4836 (Funciona apenas Mega). Verificado com controle remoto Sony RM-X151, mas é possível e outro controle remoto com uma frequência de 36kHz.
  • Sincronização de tempo com GPS externo (só trabalho Mega)
  • Menu fácil.
  • Gestão separada do cólon (ponto inferior e superior)
  • Cores de luz de fundo RGB com uma transfusão suave
  • Toque RTTTL para o alarme (idioma de transferência do toque)
  • Caça-níqueis (para evitar indicadores de envenenamento)
  • No autoteste. (Verifique todos os números em cada tela de 0 a 9, para verificar todos os LEDs, um switch serial de cores azul, vermelho, verde, verificação de som (toques tocando)





Essas tarefas que não puderam ser realizadas totalmente.

  • Sensor de luz


















Código

  • Arquivo sem título
Arquivo sem título C / C ++
 const String FirmwareVersion ="010000"; // Formato _X.XX__ // NIXIE CLOCK SHIELD NCS314 por GRA &AFCH ([email protected]) // 25.05.2016 #include  #include  #include  #include  #include  #include  const byte LEpin =7; // pin Latch Dados habilitados são aceitos enquanto o nível HIconst byte DHVpin =5; // off / on MAX1771 Driver Hight Voltage (DHV) 110-220V const byte RedLedPin =9; // Saída MCU WDM para LEDs vermelhos 9-gconst byte GreenLedPin =6; // Saída MCU WDM para LEDs verdes 6-bconst byte BlueLedPin =3; // Saída MCU WDM para LEDs azuis 3-rconst byte pinSet =A0; const byte pinUp =A2; const byte pinDown =A1; const byte pinBuzzer =2; const byte pinUpperDots =12; // Valor ALTO acende um byte dotsconst pinLowerDots =8; // Valor ALTO acende uma palavra de pontosconst fpsLimit =16666; // 1/60 * 1.000.000 // limite a taxa de atualização máxima em 60 fpsString stringToDisplay ="000000"; // Conteúdo desta string será exibido em tubos (deve ter comprimento de 6 caracteres) int menuPosition =0; // 0 - hora // 1 - data // 2 - alarme // 3 - modo 12/24 horas byte blinkMask =B00000000; // máscara de bits para dígitos intermitentes (1 - intermitente, 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, B11111111, B11111111, B11111111, B11111111, B11111111, B11111110, B11111101}; byte dotpattern =B00000000; // máscara de bits para separar os pontos // B00000000 - desliga os pontos para cima e para baixo // B1100000 - desliga todos os pontos # define DS1307_ADDRESS 0x68byte zero =0x00; // solução alternativa para o 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 // nomes:Hora, Data, Alarme, 12/24 horas, minutos, segundos, dia, mês, ano, hora, minuto, segundo alarme01 hora_formato // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1int pai [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 # defineIndex # define DateMonthIndex 9 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;; bool RGBLedsOn =true; byte RGBLEDsEEPROMAddress =0; byte HourFormatEEPROMAddress =1; byte AlarmTimeEEPROMAddress =2; // 3,4,5byte AlarmArmedEEPROMAddress =6; // botões pins declarationsClickButton setButton (pinSet, LOW, CLICKBTN_PULLUP); ClickButton upButton (pinUp, LOW, CLICKBTN_PULLUP); ClickButton downButton (pinDown, LOW, CLICKBTN_PULLUP); //////////////// /// Tone 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 * canção ="Pipoca: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 notas [] ={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_C6, NOTE_AS5, NOTE_B5, NOTE_C6, NOTE_D6, F6, , 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 fireforks [] ={0,0,1, // 1 -1,0,0, // 2 0,1,0, // 3 0,0, -1, // 4 1,0,0, // 5 0, -1,0}; // array com regras RGB (0 - não fazer nada, -1 - decréscimo, +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 de inicialização ************************************* *************************************************** ***************** / void setup () {digitalWrite (DHVpin, LOW); // off 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 value [hModeValueIndex] =12; if (EEPROM.read (RGBLEDsEEPROMAddress)! =0) RGBLedsOn =true; else RGBLedsOn =false; if (EEPROM.read (AlarmTimeEEPROMAddress) ==255) valor [AlarmHourIndex] =0 else; valor [AlarmHourIndex] =EEPROM.read (AlarmTimeEEPROMAddress); se (EEPROM.read (AlarmTimeEEPROMAddress + 1) ==255) valor [AlarmMinuteIndex] =0; e lse valor [AlarmMinuteIndex] =EEPROM.read (AlarmTimeEEPROMAddress + 1); if (EEPROM.read (AlarmTimeEEPROMAddress + 2) ==255) valor [AlarmSecondIndex] =0; else value [AlarmSecondIndex] =EEPROM.read (AlarmTimeEEPROMAddress + 2); if (EEPROM.read (AlarmArmedEEPROMAddress) ==255) valor [Alarm01] =0; else value [Alarm01] =EEPROM.read (AlarmArmedEEPROMAddress); tone1.begin (pinBuzzer); canção =parseSong (canção); pinMode (LEpin, OUTPUT); pinMode (DHVpin, OUTPUT); pinMode (RedLedPin, OUTPUT); pinMode (GreenLedPin, OUTPUT); pinMode (BlueLedPin, OUTPUT); // configuração do SPI SPI.begin (); // SPI.setDataMode (SPI_MODE3); // Modo 3 SPI SPI.setClockDivider (SPI_CLOCK_DIV128); // SCK =16MHz / 128 =125kHz // botões pins inits pinMode (pinSet, INPUT_PULLUP); pinMode (pinUp, INPUT_PULLUP); pinMode (pinDown, INPUT_PULLUP); //////////////////////////////// pinMode (pinBuzzer, OUTPUT); // objetos de botões inits setButton.debounceTime =20; // Cronômetro de depuração em ms setButton.multiclickTime =30; // Limite de tempo para cliques múltiplos setButton.longClickTime =2000; // tempo até que "cliques pressionados" registrem upButton.debounceTime =20; // Cronômetro de depuração em ms upButton.multiclickTime =30; // Limite de tempo para vários cliques upButton.longClickTime =2000; // tempo até que "cliques pressionados" registrem downButton.debounceTime =20; // Cronômetro de depuração em ms downButton.multiclickTime =30; // Limite de tempo para vários cliques downButton.longClickTime =2000; // tempo até que "cliques pressionados" registrem // digitalWrite (DHVpin, HIGH); // em MAX1771 Driver Hight Voltage (DHV) 110-220V // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!! // doTest (); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! getRTCTime (); setTime (RTC_horas, RTC_minutos, RTC_segundos, RTC_dia, RTC_mês, RTC_ano); digitalWrite (DHVpin, LOW); // off 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); // em 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) | high_bit;} rotador interno =0; // índice na matriz com "regras" RGB (incrementado por um a cada 255 ciclos) int cycle =0; // ciclos counterint RedLight =255; int GreenLight =0; int BlueLight =0; unsigned long prevTime =0; // o tempo do tubo lase foi aceso durante muito tempo prevTime4FireWorks =0; // hora da última alteração RGB // int minuteL =0; // ������� ����� ����� / ******************************** *************************************************** ******************************** Programa PRINCIPAL ****************** *************************************************** ********************************************** / void loop () { p =playmusic (p); if ((millis () - prevTime4FireWorks)> 5) {rotateFireWorks (); // muda a cor (em 1 passo) 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) // clique curto {p =0; // desligar a 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) e (lastChild [parent [menuPosition-1] -1] ==(menuPosition-1))) {if ((parent [menuPosition-1] -1 ==1 ) &&(! isValidDate ())) {menuPosition =DateDayIndex; Retorna; } editMode =false; menuPosition =pai [menuPosition-1] -1; if (menuPosition ==TimeIndex) setTime (valor [TimeHoursIndex], valor [TimeMintuesIndex], valor [TimeSecondsIndex], dia (), mês (), ano ()); if (menuPosition ==DateIndex) setTime (hora (), minuto (), second (), 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, value [hModeValueIndex]); digitalWrite (DHVpin, LOW); // desligado MAX1771 Driver Hight Voltage (DHV) 110-220V setRTCDateTime (hora (), minuto (), segundo (), dia (), mês (), ano ()% 1000,1); digitalWrite (DHVpin, HIGH); // em MAX1771 Driver Hight Voltage (DHV) 110-220V} valor [menuPosition] =extractDigits (blinkMask); } if (setButton.clicks <0) // clique longo {tone1.play (1000,100); if (! editMode) {entrandoEditModeTime =millis (); if (menuPosition ==TimeIndex) stringToDisplay =PreZero (hora ()) + PreZero (minuto ()) + PreZero (segundo ()); // formato de 24 horas habilitado temporariamente durante as configurações} menuPosition =firstChild [menuPosition]; if (menuPosition ==AlarmHourIndex) {value [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; // desligar a 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; // desligar a 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 =verdadeiro; EEPROM.write (RGBLEDsEEPROMAddress, 1); Serial.println ("RGB =ativado"); } if (downButton.clicks <0) {tone1.play (1000,100); RGBLedsOn =falso; EEPROM.write (RGBLEDsEEPROMAddress, 0); Serial.println ("RGB =desligado"); }} bool estático updateDateTime =false; switch (menuPosition) {case TimeIndex:// modo de tempo stringToDisplay =updateDisplayString (); doDotBlink (); checkAlarmTime (); pausa; case DateIndex:// modo de data stringToDisplay =PreZero (dia ()) + PreZero (mês ()) + PreZero (ano ()% 1000); dotPattern =B01000000; // ativa os pontos inferiores / * digitalWrite (pinUpperDots, LOW); digitalWrite (pinLowerDots, HIGH); * / checkAlarmTime (); pausa; case AlarmIndex:// modo de alarme stringToDisplay =PreZero (valor [AlarmHourIndex]) + PreZero (valor [AlarmMinuteIndex]) + PreZero (valor [AlarmSecondIndex]); if (valor [Alarm01] ==1) / * digitalWrite (pinUpperDots, HIGH); * / dotPattern =B10000000; // ativa os pontos superiores else {/ * digitalWrite (pinUpperDots, LOW); digitalWrite (pinLowerDots, LOW); * / dotPattern =B00000000; // desativa os pontos superiores} checkAlarmTime (); pausa; case hModeIndex:// modo 12/24 horas stringToDisplay ="00" + String (value [hModeValueIndex]) + "00"; dotPattern =B00000000; // desativa todos os pontos / * digitalWrite (pinUpperDots, LOW); digitalWrite (pinLowerDots, LOW); * / checkAlarmTime (); pausa; }} String PreZero (dígito interno) {if (dígito <10) return String ("0") + String (dígito); else return String (dígito);} void rotateFireWorks () {if (! RGBLedsOn) {analogWrite (RedLedPin, 0); analogWrite (GreenLedPin, 0); analogWrite (BlueLedPin, 0); Retorna; } RedLight =RedLight + fireforks [rotador * 3]; GreenLight =GreenLight + fireforks [rotador * 3 + 1]; BlueLight =BlueLight + forquilhas de incêndio [rotador * 3 + 2]; analogWrite (RedLedPin, RedLight); analogWrite (GreenLedPin, GreenLight); analogWrite (BlueLedPin, BlueLight); ciclo =ciclo + 1; if (ciclo ==255) {rotador =rotador + 1; ciclo =0; } if (rotator> 5) rotator =0;} void doIndication () {// byte estático b =B00000001; static unsigned long lastTimeInterval1Started; if ((micros () - lastTimeInterval1Started) > 2; Var64 | =tmpVar64; Var64 =(Var64>> 4); sem sinal 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); digitalWrite (LEpin, LOW); // travando dados} byte CheckButtonsState () {static boolean buttonsWasChecked; static unsigned long startBuzzTime; static unsigned long lastTimeButtonsPressed; if ((digitalRead (pinSet) ==0) || (digitalRead (pinUp) ==0) || (digitalRead (pinDown) ==0)) {if (buttonsWasChecked ==false) startBuzzTime =millis (); buttonsWasChecked =true; } else buttonsWasChecked =false; if (millis () - startBuzzTime <30) {digitalWrite (pinBuzzer, HIGH); } else {digitalWrite (pinBuzzer, LOW); }} String updateDisplayString () {static unsigned long lastTimeStringWasUpdated; if ((millis () - lastTimeStringWasUpdated)> 1000) {//Serial.println("doDotBlink "); // doDotBlink (); lastTimeStringWasUpdated =millis (); if (valor [hModeValueIndex] ==24) retornar PreZero (hora ()) + PreZero (minuto ()) + PreZero (segundo ()); senão retornar PreZero (horaFormato12 ()) + PreZero (minuto ()) + PreZero (segundo ()); } return stringToDisplay;} void doTest () {Serial.print (F ("Versão do firmware:")); Serial.println (FirmwareVersion.substring (1,2) + "." + FirmwareVersion.substring (2,4)); Serial.println (F ("Iniciar teste")); adc int =leitura analógica (A3); float Uinput =4,6 * (5,0 * adc) /1024,0+0,7; Serial.print (F ("entrada U =")); Serial.print (Uinput); p =música; parseSong (p); analogWrite (RedLedPin, 255); atraso (1000); analogWrite (RedLedPin, 0); analogWrite (GreenLedPin, 255); atraso (1000); analogWrite (GreenLedPin, 0); analogWrite (BlueLedPin, 255); atraso (1000); // enquanto (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; teste de bool =1; byte strIndex =0; startOfTest longo sem sinal =millis (); para (int i =0; i <12; i ++) {if ((millis () - startOfTest)> dlay) {startOfTest =millis (); strIndex =strIndex + 1; if (strIndex ==10) dlay =3000; if (strIndex ==12) test =0; switch (strIndex) {/ * case 10:SPI.transfer ((b | B01000000) &B11111100); pausa; caso 11:transferência de SPI ((b | B01000000) e B11001110); pausa; * / // padrão:SPI.transfer (b | B11000000); padrão:stringToDisplay =testStringArray [strIndex]; }} delayMicroseconds (2000); }; Serial.println (F ("Parar Teste")); } void doDotBlink () {static unsigned long lastTimeBlink =millis (); bool estático 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, LOW); 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 (zero); // interrompe o 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 (zero); // iniciar Wire.endTransmission ();} byte decToBcd (byte val) {// Converter números decimais normais em retorno decimal codificado binário ((val / 10 * 16) + (val% 10));} byte bcdToDec (byte val ) {// Converter decimal codificado em binário em números decimais normais return ((val / 16 * 10) + (val% 16));} void getRTCTime () {Wire.beginTransmission (DS1307_ADDRESS); Wire.write (zero); Wire.endTransmission (); Wire.requestFrom (DS1307_ADDRESS, 7); RTC_segundos =bcdToDec (Wire.read ()); RTC_minutes =bcdToDec (Wire.read ()); RTC_hours =bcdToDec (Wire.read () &0b111111); // tempo de 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 ());} palavra doEditBlink (int pos) {if (! BlinkUp) return 0; if (! BlinkDown) retorna 0; int lowBit =blinkMask>> pos; lowBit =lowBit &B00000001; estático não assinado long lastTimeEditBlink =millis (); bool estático blinkState =false; máscara de palavra =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; máscara de retorno;} 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, valor int) {if (b ==B00000011) stringToDisplay =PreZero (valor) + 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; pausa; case 'd':note =3; pausa; case 'e':note =5; pausa; case 'f':note =6; pausa; case 'g':note =8; pausa; case 'a':note =10; pausa; case 'b':note =12; pausa; 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


Processo de manufatura

  1. Relógio de visão pov do Arduino
  2. Controlador DMX operado pela web
  3. Simple Word Clock (Arduino)
  4. Relógio Arduino com horas de oração islâmica
  5. Arduino Spybot
  6. Relógio mestre
  7. Faça Nixie Clock com Arduino em caixa de madeira MDF
  8. Relógio de matriz de 7 segmentos
  9. BLUE_P:Wireless Arduino Programming Shield
  10. Despertador simples com DS1302 RTC