산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Arduino Shield NCS314 NIXIE 튜브 시계 IN-14

구성품 및 소모품

Shield Nixie Tubes IN-14 NCS314 Arduino for Nixie Tubes Clock 등 .
Nixie Tubes IN-14의 실드
× 1
Shield Nixie Tubes Clock IN-12 NCS312 for xUSSR Nixie Tubes
× 1
Arduino UNO
Shield는 Arduino UNO/Genuino 또는 Arduino MEGA를 지원합니다.
× 1
Arduino Mega 2560
Shield는 Arduino UNO/Genuino 또는 Arduino MEGA를 지원합니다.
× 1
전원 공급 장치 12V 1A
× 1
SHIELD NCS314용 아크릴 케이스
아름다운 아크릴 케이스 모델 ACNS314는 Nixie Arduino Shield NCS314 HW 버전 v1.X – 2와 완벽하게 호환됩니다. .X
× 1

앱 및 온라인 서비스

Arduino IDE

이 프로젝트 정보

개요

처음에는 우수한 품질의 소비에트 Nixie 튜브 IN-12, IN-14 및 IN-18을 거의 무한대로 공급할 수 있게 된 후 Arduino용 Shield로 Nixie 튜브를 간단하게 표시할 예정이었습니다. 그 당시 아두이노는 이미 가지고 있었기 때문에 케이스는 작게 남겨두었습니다(당시에는 생각했습니다). 그 당시 우리는 그러한 램프를 다루는 방법에 대해 아무것도 몰랐습니다.

인터넷에서 이러한 튜브에 전원을 공급하는 방식을 매우 빠르게 찾았습니다.

네! 빛난다! 우리가 방금 우리를 놀라게 한 사실은 작은 기적과도 같고 우리는 우리가 올바른 길로 가고 있음을 깨달았습니다. 즉시 사진 촬영 시작:

다음날, 미래 프로젝트의 개념에 대해 논의하기 시작했습니다. 비용을 단순화하고 줄이기 위해 동적 디스플레이 원칙을 사용하는 방식을 사용하기로 결정했지만 나중에 완전히 정적 디스플레이 모드. IN-14 Nixie 튜브의 경우 시각적 차이가 눈에 띄지 않지만 IN-18 램프의 경우 차이가 눈에 띄게 나타납니다. 동적 모드에서는 그렇게 밝지 않게 작동하며, 소위 청색 반점 효과가 나타납니다.

동적 디스플레이 모드는 매번 모든 튜브가 켜지지 않고 동시에 하나(한 번에)만 조명될 때 다른 종(예:두 개의 램프만 켜짐)이 될 수 있는 모드입니다.

컴퓨터에서 나오는 튜브에 정보를 표시하는 기능을 구현하기로 결정되면 장치의 미래를 논의할 때 매니아가 램프에 표시할 장치를 직접 만들 수 있습니다. 예를 들어, 읽지 않은 메시지 또는 Fallout과 같은 게임의 라운드 수.

그런 다음 튜브의 음극(숫자)을 전환할 수 있는 하드웨어 선택을 시작했습니다. 선택은 분명했습니다. MCU 핀을 절약하기 위해 SPI가 있는 시프트 레지스터였습니다. 그러나 공급 전압이 매우 높기 때문에 최대 200볼트이므로 HV513, HV5812, HV5122와 같은 옵션이 많지 않습니다. 그리고 이 칩 각각에 장치를 구축하는 동안 HV5812에서 멈췄습니다(새 Shields 버전에서는 NCS314 V2.X 및 NCS312 V1.X에서 IC HV5122 사용). 이 칩은 20비트 레지스터로 두 개의 램프를 동시에 제어할 수 있기 때문에 매우 편리합니다.

6개의 튜브를 제어하려면 이러한 회로 3개가 서로 직렬로 연결되어 있어야 합니다. 이것은 SPI를 통해 패킷을 한 번 보낼 수 있게 하고 동적 디스플레이 알고리즘의 경우와 같이 튜브에 대한 정보 업데이트에 신경 쓰지 않습니다. 즉, 우리가 튜브의 정보를 변경할 필요가 없는 한 MCU는 다른 작업으로 바쁠 수 있으며, 심지어는 잠자기까지 할 수 있습니다!

우리는 SPI에 대한 데이터 전송에 대해 말하고 싶습니다. Arudino는 한 번에 8비트만 전송할 수 있습니다. 그리고 우리는 60이 필요합니다. 가장 가까운 높은 정수는 8로 나눌 수 있으므로 64이므로 비트 마술을 적용해야 합니다. 각 레지스터에 대해 unsigned long long var64 비트 유형의 큰 변수 하나를 형성하고 매번 8 곱하기 8비트를 전달합니다. 변수 내부의 모든 비트를 오른쪽으로 이동:

<사전><코드> 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);

설정하고 달성한 목표:

<울>
  • 시프트 레지스터를 기반으로 한 정적 디스플레이.
  • 슬롯 머신(애니 중독)
  • 시계, 시계, 날짜, 시간, 알람 시계에 대한 표준 기능을 제공합니다.
  • 배터리 CR1220이 있는 RTC(실시간 시계). (V1.2-2.X 보드의 새 버전은 고정밀 시간 칩 RTC DS3231을 사용합니다.)
  • 온도 측정 DS18B20 [섭씨 또는 화씨].
  • IR 포트 TSOP4836을 통한 제어(Mega만 작동). 리모콘 Sony RM-X151로 확인했지만 36kHz의 다른 리모콘으로도 가능합니다.
  • 외부 GPS와 시간 동기화(Mega만 작동)
  • 간단한 메뉴.
  • 대장 분리 관리(하한점과 상한점)
  • 부드러운 수혈을 통한 RGB 백라이트 색상
  • 알람용 RTTTL 벨소리(Ring Tone Transfer Language)
  • 슬롯 머신(중독 표시 방지용)
  • 자체 테스트 중. (각 디스플레이의 모든 숫자를 0에서 9까지 확인하고 모든 LED를 확인하려면 직렬 스위치 색상 파란색, 빨간색, 녹색, 사운드 체크(벨소리 재생)
  • 완전히 실현할 수 없었던 작업.

    <울>
  • 조도 센서
  • <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • 제목 없는 파일
  • 제목 없는 파일C/C++
    const String FirmwareVersion="010000";//Format _X.XX__ //NIXIE CLOCK SHIELD NCS314 by GRA &AFCH ([email protected])//25.05.2016 #include #include #include #include #include #include const 바이트 LEpin=7; // HI levelconst byte DHVpin=5 동안 핀 래치 활성화 데이터가 허용됨; // 끄기/켜기 MAX1771 드라이버 고전압(DHV) 110-220V const byte RedLedPin=9; //적색 LED용 MCU WDM 출력 9-gconst byte GreenLedPin=6; //녹색 LED에 대한 MCU WDM 출력 6-bconst 바이트 BlueLedPin=3; //파란색 LED용 MCU WDM 출력 3-rconst byte pinSet=A0;const byte pinUp=A2;const byte pinDown=A1;const byte pinBuzzer=2;const byte pinUpperDots=12; //높은 값은 점을 밝힙니다. const 바이트 pinLowerDots=8; //높은 값은 점을 밝힙니다. const word fpsLimit=16666; // 1/60*1.000.000 //60fps에서 최대 새로 고침 빈도 제한String stringToDisplay="000000";// 이 문자열의 내용은 튜브에 표시됩니다(6자 길이여야 함) int menuPosition=0; // 0 - 시간 // 1 - 날짜 // 2 - 알람 // 3 - 12/24시간 모드 바이트 깜박임 마스크=B00000000; // 깜박이는 숫자에 대한 비트 마스크(1 - 깜박임, 0 - 계속 켜짐)//--------------------------0----- --1----------2----------3---------4--------5--------- ---6---------7---------8---------9-----//byte lowBytesArray[]={B11111110,B11111101 , B11111011, B11110111, B11101111, B11011111, B10111111, B01111111, B11111111, B11111111} // 바이트 highBytesArray [] ={B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111111, B11111110, B11111101} 바이트 =dotPattern B00000000; //점을 구분하기 위한 비트 마스크 //B00000000 - 위아래 점 끄기 //B1100000 - 모든 점 끄기#define DS1307_ADDRESS 0x68byte zero =0x00; //문제 #527에 대한 해결 방법 int 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// 이름:시간, 날짜, 알람, 12/24 시간, 분, 초, 일, 월, 년, 시, 분, 초 알람01 hour_format // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1int parent[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}; 정수 값[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};바이트 깜박임 패턴[15]={ B00000000, B00000000, 000, B0 B00000011, B00001100, B00110000, B00000011, B00001100, B00110000, B00000011, B00001100, B00110000, B11000 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 7#define#DateMonthIndex 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 enterEdit;bool RGBLEDsOn=true;바이트 RGBLEDsEEPROMAddress=0; byte HourFormatEEPROMAddress=1;byte AlarmTimeEEPROMAddress=2;//3,4,5byte AlarmArmedEEPROMAddress=6; //버튼 핀 선언ClickButton 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#,3 32c,32p,32c,32p,32g,32f,32d#,32d,32c,32d,32d#,32c,32d#,32f,16g,8p,16d7,32c7,32d7,32a#,32d7,32a,3 32g,32d7,32d7,32p,32d7,3 2p,32d7,32p,16d7,32c7,32d7,32a#,32d7,32a,32d7,32g,32d7,32d7,32p,32d7,32p,32d7,32p,22g,32f,32d2#, 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="팝콘: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 *노래="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,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_F6, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,NOTECS6 , 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[]=1 -1,0,0,//2 0,1,0,//3 0,0,-1,//4 1,0,0,//5 0,-1,0}; //RGB 규칙으로 배열(0 - 아무것도 하지 않음, -1 - 감소, +1 - incresevoid setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w=1);int functionDownButton=0;int functionUpButton=0;/******************************************** ************************************************** ***********초기화 프로그램************************************ ************************************************** ****************/void setup() { digitalWrite(DHVpin, LOW); // 꺼짐 MAX1771 드라이버 고전압(DHV) 110-220V Wire.begin(); // setRTCDateTime(23,40,00,25,7,15,1); Serial.begin(115200); Serial.println(""); if (EEPROM.read(HourFormatEEPROMAddress)!=12) 값[hModeValueIndex]=24; else 값[hModeValueIndex]=12; if (EEPROM.read(RGBLEDsEEPROMAddress)!=0) RGBLedsOn=true; else RGBLedsOn=false; if (EEPROM.read(AlarmTimeEEPROMAddress)==255) 값[AlarmHourIndex]=0; else 값[AlarmHourIndex]=EEPROM.read(AlarmTimeEEPROMAddress), if (EEPROM.read(AlarmTimeEEPROMAddress+1)==255) 값[AlarmMinuteIndex]=0, e 값[AlarmMinuteIndex]=EEPROM.read(AlarmTimeEEPROMAddress+1); if (EEPROM.read(AlarmTimeEEPROMAddress+2)==255) 값[AlarmSecondIndex]=0; else 값[AlarmSecondIndex]=EEPROM.read(AlarmTimeEEPROMAddress+2); if (EEPROM.read(AlarmArmedEEPROMAddress)==255) 값[Alarm01]=0; else 값[Alarm01]=EEPROM.read(AlarmArmedEEPROMAddress); tone1.begin(핀버저); 노래=parseSong(노래); 핀모드(LE핀, 출력); 핀모드(DHV핀, 출력); 핀모드(레드레드핀, 출력); 핀모드(그린레드핀, 출력); 핀모드(블루레드핀, 출력); // SPI 설정 SPI.begin(); // SPI.setDataMode(SPI_MODE3); // 모드 3 SPI SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK =16MHz/128=125kHz //버튼 핀 초기화 pinMode(pinSet, INPUT_PULLUP); 핀모드(핀업, INPUT_PULLUP); 핀모드(핀다운, INPUT_PULLUP); ///////////////////////////// 핀모드(핀버저, 출력); //버튼 객체 초기화 setButton.debounceTime =20; // ms의 디바운스 타이머 setButton.multiclickTime =30; // 다중 클릭에 대한 시간 제한 setButton.longClickTime =2000; // "누르고 있는 클릭"까지의 시간 register upButton.debounceTime =20; // ms의 디바운스 타이머 upButton.multiclickTime =30; // 다중 클릭에 대한 시간 제한 upButton.longClickTime =2000; // "누르고 있는 클릭"까지의 시간 register downButton.debounceTime =20; // ms의 디바운스 타이머 downButton.multiclickTime =30; // 다중 클릭에 대한 시간 제한 downButton.longClickTime =2000; // "누르고 있는 클릭"까지의 시간 레지스터 // digitalWrite(DHVpin, HIGH); // MAX1771 드라이버 고전압(DHV) 110-220V에서 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!! //doTest(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! getRTCTime(); setTime(RTC_시간, RTC_분, RTC_초, RTC_일, RTC_월, RTC_년); 디지털 쓰기(DHV핀, LOW); // 오프 MAX1771 드라이버 고전압(DHV) 110-220V setRTCDateTime(RTC_hours,RTC_minutes,RTC_seconds,RTC_day,RTC_month,RTC_year,1); // ... . . . . . . . . . . . . . . . . RTC . . � �... ..디지털 쓰기(DHVpin, HIGH); // MAX1771 드라이버 고전압(DHV) 110-220V에서 //p=song;}void rotateLeft(uint8_t &bits){ uint8_t high_bit =bits &(1 <<7) ? 1:0; 비트 =(비트 <<1) | high_bit;}int 회전자=0; // RGB "규칙"이 있는 배열의 인덱스(각 255주기마다 1씩 증가)int cycle=0; // 순환 카운터int RedLight=255;int GreenLight=0;int BlueLight=0;unsigned long prevTime=0; // 레이저 튜브의 시간이 litunsigned long prevTime4FireWorks=0; //마지막 RGB 변경 시간//int minL=0; //������� ����� �����/****************************** ************************************************** *******************************메인 프로그램******************** ************************************************** ********************************************/void 루프() { p=플레이뮤직(p); if ((millis()-prevTime4FireWorks)>5) { 회전불꽃웍스(); //색상 변경(1단계씩) prevTime4FireWorks=millis(); } doIndication(); setButton.Update(); upButton.Update(); downButton.Update(); if (editMode==false) { 깜박임 마스크=B00000000; } else if ((millis()-enteringEditModeTime)>60000) { editMode=false; menuPosition=firstChild[메뉴위치]; 깜박임 마스크 =깜박임 패턴[메뉴 위치]; } if (setButton.clicks>0) //짧은 클릭 { p=0; //음악 끄기 ))) tone1.play(1000,100); enterEditModeTime=밀리(); 메뉴포지션=메뉴포지션+1; if (menuPosition==hModeIndex+1) menuPosition=TimeIndex; Serial.print(F("menuPosition=")); Serial.println(메뉴 위치); Serial.print(F("값=")); Serial.println(값[메뉴 위치]); 깜박임 마스크 =깜박임 패턴[메뉴 위치]; if ((parent[menuPosition-1]!=0) and (lastChild[parent[menuPosition-1]-1]==(menuPosition-1))) { if ((parent[menuPosition-1]-1==1 ) &&(!isValidDate())) { menuPosition=DateDayIndex; 반품; } editMode=거짓; 메뉴포지션=부모[메뉴포지션-1]-1; if (menuPosition==TimeIndex) setTime(value[TimeHoursIndex], value[TimeMintuesIndex], value[TimeSecondsIndex], day(), month(), year()); if (menuPosition==DateIndex) setTime(시(), 분(), 초(), 값[DateDayIndex], 값[DateMonthIndex], 2000+값[DateYearIndex]); if (menuPosition==AlarmIndex) {EEPROM.write(AlarmTimeEEPROMAddress,value[AlarmHourIndex]); EEPROM.write(AlarmTimeEEPROMAddress+1,값[AlarmMinuteIndex]); EEPROM.write(AlarmTimeEEPROMAddress+2,값[AlarmSecondIndex]); EEPROM.write(AlarmArmedEEPROMAddress, 값[Alarm01]);}; if (menuPosition==hModeIndex) EEPROM.write(HourFormatEEPROMAddress, 값[hModeValueIndex]); 디지털 쓰기(DHV핀, LOW); // 꺼짐 MAX1771 드라이버 고전압(DHV) 110-220V setRTCDateTime(hour(),minute(),second(),day(),month(),year()%1000,1); 디지털 쓰기(DHV핀, 높음); // MAX1771 드라이버 고전압(DHV) 110-220V에서 } value[menuPosition]=extractDigits(blinkMask); } if (setButton.clicks<0) //롱클릭 { tone1.play(1000,100); if (!editMode) { enterEditModeTime=millis(); if (menuPosition==TimeIndex) stringToDisplay=PreZero(hour())+PreZero(분())+PreZero(second()); //설정 중 24시간 형식 임시 활성화 } menuPosition=firstChild[menuPosition]; if (menuPosition==AlarmHourIndex) {값[Alarm01]=1; /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;} editMode=!editMode; 깜박임 마스크 =깜박임 패턴[메뉴 위치]; 값[menuPosition]=extractDigits(blinkMask); } if (upButton.clicks !=0) functionUpButton =upButton.clicks; if (upButton.clicks>0) { p=0; //음악 끄기 ))) tone1.play(1000,100); 증분값(); } if (functionUpButton ==-1 &&upButton.depressed ==true) { BlinkUp=false; if (editMode==true) { if ( (millis() - upTime)> settingDelay) { upTime =millis();// + settingDelay; 증분값(); } } } 그렇지 않으면 BlinkUp=true; if (downButton.clicks !=0) functionDownButton =downButton.clicks; if (downButton.clicks>0) { p=0; //음악 끄기 ))) tone1.play(1000,100); dicrementValue(); } if (functionDownButton ==-1 &&downButton.depressed ==true) { BlinkDown=false; if (editMode==true) { if ( (millis() - downTime)> settingDelay) { downTime =millis();// + settingDelay; dicrementValue(); } } } 그렇지 않으면 BlinkDown=true; if (!editMode) { if (upButton.clicks<0) { tone1.play(1000,100); RGBLEDsOn=참; EEPROM.write(RGBLEDsEEPROM주소,1); Serial.println("RGB=on"); } if (downButton.clicks<0) { tone1.play(1000,100); RGBLEDsOn=거짓; EEPROM.write(RGBLEDsEEPROM주소,0); Serial.println("RGB=꺼짐"); } } 정적 부울 updateDateTime=거짓; switch (menuPosition) { case TimeIndex://시간 모드 stringToDisplay=updateDisplayString(); doDotBlink(); 체크알람타임(); 부서지다; case DateIndex://날짜 모드 stringToDisplay=PreZero(day())+PreZero(month())+PreZero(year()%1000); dotPattern=B01000000;//하단 점 켜기 /*digitalWrite(pinUpperDots, LOW); digitalWrite(pinLowerDots, HIGH);*/ checkAlarmTime(); 부서지다; case AlarmIndex://알람 모드 stringToDisplay=PreZero(value[AlarmHourIndex])+PreZero(value[AlarmMinuteIndex])+PreZero(value[AlarmSecondIndex]); if (값[Alarm01]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000; //상단 점 켜기 else { /*digitalWrite(pinUpperDots, LOW); digitalWrite(pinLowerDots, LOW);*/ dotPattern=B00000000; //상단 점 끄기 } checkAlarmTime(); 부서지다; case hModeIndex://12/24시간 모드 stringToDisplay="00"+String(value[hModeValueIndex])+"00"; dotPattern=B00000000;//모든 점 끄기 /*digitalWrite(pinUpperDots, LOW); digitalWrite(pinLowerDots, LOW);*/ checkAlarmTime(); 부서지다; }}String PreZero(int digit){ if (digit<10) return String("0")+String(digit); else return String(digit);}void rotateFireWorks(){ if (!RGBledsOn) { analogWrite(RedLedPin,0 ); analogWrite(GreenLedPin,0); analogWrite(BlueLedPin,0); 반품; } RedLight=레드라이트+파이어포크[rotator*3]; GreenLight=GreenLight+fireforks[rotator*3+1]; BlueLight=BlueLight+파이어포크[rotator*3+2]; analogWrite(RedLedPin,RedLight); analogWrite(GreenLedPin,GreenLight); analogWrite(BlueLedPin,BlueLight); 주기=주기+1; if (주기==255) { 회전자=회전자+1; 주기=0; } if (rotator>5) rotator=0;}void doIndication(){ //정적 바이트 b=B00000001; 정적 서명되지 않은 long lastTimeInterval1Started; if ((micros()-lastTimeInterval1Started)>2; Var64|=tmpVar64; Var64=(Var64>>4); 부호 없는 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); 디지털 쓰기(LEpin, LOW); // 래칭 데이터 }byte CheckButtonsState(){ static boolean buttonsWasChecked; 정적 부호 없는 긴 startBuzzTime; 정적 서명되지 않은 long lastTimeButtonsPressed; if ((digitalRead(pinSet)==0)||(digitalRead(pinUp)==0)||(digitalRead(pinDown)==0)) { if (buttonsWasChecked==false) startBuzzTime=millis(); buttonWasChecked=참; } else buttonsWasChecked=거짓; if (millis()-startBuzzTime<30) { digitalWrite(pinBuzzer, HIGH); } else { digitalWrite(pinBuzzer, LOW); }}String updateDisplayString(){ 정적 서명되지 않은 long lastTimeStringWasUpdated; if ((millis()-lastTimeStringWasUpdated)>1000) { //Serial.println("doDotBlink"); //doDotBlink(); lastTimeStringWasUpdated=밀리(); if (value[hModeValueIndex]==24) 반환 PreZero(hour())+PreZero(분())+PreZero(second()); 그렇지 않으면 반환 PreZero(hourFormat12())+PreZero(분())+PreZero(초()); } return stringToDisplay;}void doTest(){ Serial.print(F("펌웨어 버전:")); Serial.println(FirmwareVersion.substring(1,2)+"."+FirmwareVersion.substring(2,4)); Serial.println(F("테스트 시작")); int adc=analogRead(A3); float Uinput=4.6*(5.0*adc)/1024.0+0.7; Serial.print(F("U 입력=")); Serial.print(Uinput); p=노래; 파스송(p); analogWrite(RedLedPin,255); 지연(1000); analogWrite(RedLedPin,0); analogWrite(GreenLedPin,255); 지연(1000); analogWrite(GreenLedPin,0); analogWrite(BlueLedPin,255); 지연(1000); //동안(1); 문자열 testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","9999"9 ""}; if (Uinput<10) testStringArray[10]="000"+String(int(Uinput*100)); else testStringArray[10]="00"+String(int(Uinput*100)); testStringArray[11]=펌웨어 버전; int 지연 =500; 부울 테스트 =1; 바이트 strIndex=0; 부호 없는 긴 startOfTest=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) 테스트=0; switch (strIndex) { /* 경우 10:SPI.transfer((b|B01000000)&B11111100); 부서지다; 사례 11:SPI.transfer((b|B01000000)&B11001110); 부서지다; */ //기본값:SPI.transfer(b|B11000000); 기본값:stringToDisplay=testStringArray[strIndex]; } } delayMicroseconds(2000); }; Serial.println(F("테스트 중지")); }void doDotBlink(){ 정적 부호 없는 long lastTimeBlink=millis(); 정적 부울 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(바이트 h, 바이트 m, 바이트 s, 바이트 d, 바이트 몬, 바이트 y, 바이트 w){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(제로); //오실레이터 중지 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(제로); //start Wire.endTransmission();}byte decToBcd(byte val){// 일반 십진수를 이진 코드 십진수로 변환 반환 ( (val/10*16) + (val%10) );}byte bcdToDec(byte val ) {// 이진 코드 십진수를 일반 십진수로 변환 return ( (val/16*10) + (val%16) );}void getRTCTime(){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(제로); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); RTC_seconds =bcdToDec(Wire.read()); RTC_분 =bcdToDec(Wire.read()); RTC_시간 =bcdToDec(Wire.read() &0b111111); //24시간제 RTC_day_of_week =bcdToDec(Wire.read()); //0-6 -> 일요일 - 토요일 RTC_day =bcdToDec(Wire.read()); RTC_month =bcdToDec(Wire.read()); RTC_year =bcdToDec(Wire.read());}단어 doEditBlink(int pos){ if (!BlinkUp) return 0; (!BlinkDown)이 0을 반환하면; int lowBit=blinkMask>>pos; lowBit=lowBit&B00000001; 정적 부호 없는 long lastTimeEditBlink=millis(); 정적 부울 깜박임 상태 =거짓; 워드 마스크=0; 정적 정수 tmp=0;//blinkMask; if ((millis()-lastTimeEditBlink)>300) { lastTimeEditBlink=millis(); 깜박임 상태 =! 깜박임 상태; /*Serial.print("blinkpattern="); Serial.println(blinkPattern[메뉴 위치]); if (((blinkPattern[menuPosition]>>8)&1==1) &&깜박임 상태==true) digitalWrite(pinLowerDots, HIGH); 그렇지 않으면 digitalWrite(pinLowerDots, LOW); if (((blinkPattern[menuPosition]>>7)&1==1) &&깜박임 상태==true) digitalWrite(pinUpperDots, HIGH); 그렇지 않으면 digitalWrite(pinUpperDots, LOW); */ if (blinkState) tmp=0; 그렇지 않으면 tmp=blinkMask; } if (((dotPattern&~tmp)>>6)&1==1) digitalWrite(pinLowerDots, HIGH); 그렇지 않으면 digitalWrite(pinLowerDots, LOW); if (((dotPattern&~tmp)>>7)&1==1) digitalWrite(pinUpperDots, HIGH); 그렇지 않으면 digitalWrite(pinUpperDots, LOW); if ((blinkState==true) &&(lowBit==1)) mask=0xFFFF;//mask=B11111111; 리턴 마스크;}int extractDigits(바이트 b){ 문자열 tmp="1"; /*Serial.print("깜박임 패턴="); 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 값){ if (b==B00000011) stringToDisplay=PreZero(값)+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; 부서지다; case 'd':note =3; 부서지다; case 'e':note =5; 부서지다; case 'f':note =6; 부서지다; case 'g':note =8; 부서지다; case 'a':note =10; 부서지다; case 'b':note =12; 부서지다; 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!")); 반환 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/

    회로도


    제조공정

    1. Arduino 관점 시계
    2. 웹 운영 DMX 컨트롤러
    3. 단순 워드 클럭(Arduino)
    4. 이슬람 기도 시간이 있는 Arduino 시계
    5. Arduino 스파이봇
    6. 마스터 시계
    7. MDF 나무 케이스에 Arduino로 Nixie 시계 만들기
    8. 7-세그먼트 어레이 시계
    9. BLUE_P:무선 Arduino 프로그래밍 실드
    10. DS1302 RTC가 있는 간단한 알람 시계