Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Komponen dan Perlengkapan

Pelindung Tabung Nixie IN-14 NCS314 Arduino untuk Jam Tabung Nixie dll.
Pelindung pada Tabung Nixie IN-14
×1
Pelindung Jam Tabung Nixie IN-12 NCS312 untuk Tabung Nixie xUSSR
×1
Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
Arduino UNO
Pelindung mendukung Arduino UNO/Genuino atau Arduino MEGA
×1
Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
Arduino Mega 2560
Pelindung mendukung Arduino UNO/Genuino atau Arduino MEGA
×1
Sumber Daya 12V 1A
×1
Kotak Akrilik untuk PELINDUNG NCS314
Model Kotak Akrilik Indah ACNS314 sepenuhnya kompatibel dengan Versi HW v1.X – 2.X PELINDUNG Arduino Nixie NCS314
×1

Aplikasi dan Layanan Online

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
Arduino IDE

Tentang Proyek Ini

Ringkasan

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Awalnya, setelah kami memiliki akses ke pasokan hampir tak terbatas tabung Nixie Soviet berkualitas tinggi IN-12, IN-14, dan IN-18, rencana kami adalah membuat layar sederhana dari tabung Nixie sebagai Pelindung untuk Arduino. Arduino saat itu sudah kami miliki, jadi yang tersisa hanyalah hal kecil (seperti yang kami pikir pada saat itu). Pada saat itu kami tidak tahu apa-apa tentang cara menangani lampu semacam itu.

Sekali cepat kami menemukan di internet skema untuk menyediakan daya pada tabung semacam itu:

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

YA! Itu menyala! Fakta bahwa kami melihatnya sangat mengagetkan kami seperti keajaiban kecil, dan kami menyadari bahwa kami berada di jalur yang benar. Segera dimulai sesi foto:

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Hari berikutnya, dimulai diskusi konsep proyek masa depan: untuk menyederhanakan dan mengurangi biaya, diputuskan untuk menggunakan skema dengan prinsip layar dinamis, tetapi nanti diputuskan untuk meninggalkannya untuknya skema dengan mode layar statis sepenuhnya. Meskipun untuk tabung Nixie IN-14 perbedaan visual tidak terlihat, tetapi untuk lampu IN-18 perbedaan terlihat - dalam mode dinamis, mereka tidak terlalu terang banyak dari mereka muncul, efek titik biru yang disebut:

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Mode layar dinamis adalah mode di mana pada setiap waktu tidak semua tabung menyala, dan hanya satu (saat satu waktu), mungkin juga ada jenis lain saat dihidupkan secara bersamaan, misalnya, hanya dua lampu.

Dalam diskusi masa depan perangkat setelah itu diputuskan untuk mengimplementasikan kemampuan untuk menampilkan informasi pada tabung yang datang dari komputer, ini akan memungkinkan penggemar untuk membuat perangkat mereka sendiri yang akan ditampilkan pada lampu, misalnya, jumlah pesan yang belum dibaca atau jumlah putaran dalam game, seperti Fallout.

Lalu dimulai pemilihan perangkat keras yang dapat mengalihkan katoda (angka) di dalam tabung. Pilihan jelas - register geser dengan SPI untuk menghemat pin MCU. Namun karena tegangan pasokan tabung sangat tinggi - hingga 200 volt, opsi tidak begitu banyak: HV513, HV5812, HV5122. Dan sementara kami membangun perangkat pada masing-masing chip ini, kami berhenti pada HV5812 (Pada versi Pelindung baru NCS314 V2.X dan NCS312 V1.X digunakan IC HV5122). Chip ini sangat nyaman karena memungkinkan Anda untuk mengontrol dua lampu secara bersamaan, sebagai register 20 bit.

Untuk mengontrol 6 tabung kita akan membutuhkan tiga rangkaian semacam itu yang terhubung satu sama lain secara berurutan. Ini memungkinkan untuk sekali mengirim paket melalui SPI dan tidak peduli tentang pembaruan informasi pada tabung, seperti yang akan terjadi dengan algoritma layar dinamis. Artinya, dengan kata lain - selama kita tidak perlu mengubah informasi pada tabung MCU dapat sibuk dengan tugas lain, bahkan tidur!

Kami ingin mengatakan tentang transfer data melalui SPI. Arduino dapat transmitsi sekaligus hanya 8 bit. Dan kita butuh 60, bilangan bulat terdekat yang lebih tinggi yang habis dibagi 8 adalah 64, jadi harus menerapkan sedikit sihir bit - untuk membentuk satu variabel besar tipe unsigned long long var64 bit untuk setiap register dan melewati 8 kali 8 bit setiap kali dengan menggeser semua bit di dalam variabel ke kanan:

 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); 

Tujuan yang ditetapkan dan berhasil diimplementasikan:

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12
  • Layar statis berdasarkan register geser.
  • Mesin Slot (Anansi racun)
  • Menawarkan fungsi standar untuk jam, jam, tanggal, waktu, alarm.
  • RTC (Jam Waktu Nyata) dengan baterai CR1220. (Versi baru papan V1.2-2.X menggunakan chip waktu presisi tinggi RTC DS3231).
  • Pengukuran suhu DS18B20 [Celsius atau Fahrenheit].
  • Kontrol melalui port IR TSOP4836 (Hanya berfungsi pada Mega). Diuji dengan Remote Sony RM-X151, Namun mungkin juga remote lain dengan frekuensi 36kHz.
  • Sinkronisasi Waktu dengan GPS eksternal (Hanya berfungsi pada Mega)
  • Menu yang mudah.
  • Pengelolaan terpisah titik dua (titik bawah dan atas)
  • Warna latar belakang RGB dengan aliran halus
  • Suara alarm RTTTL (Ring Tone Transfer Language)
  • Mesin slot (untuk mencegah racun indikator)
  • Tes sendiri. (Periksa semua angka di setiap layar dari 0 hingga 9, untuk memeriksa semua LED, perpindahan warna berurutan biru, merah, hijau, pemeriksaan suara (suara alarm berdengung)

Tugas yang tidak dapat direalisasikan sepenuhnya.

  • Sensor cahaya

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Kode

  • File Tanpa Judul
File Tanpa JudulC/C++
const String FirmwareVersion="010000"; //Format _X.XX__ //PELINDUNG JAM NIXIE NCS314 oleh GRA & AFCH (fominalec@gmail.com) //25.05.2016 #include <SPI.h> #include <Wire.h> #include <ClickButton.h> #include <Time.h> #include <Tone.h> #include <EEPROM.h> const byte LEpin=7; //pin Laktan Diaktifkan data diterima saat HI level const byte DHVpin=5; // off/on Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V const byte RedLedPin=9; //MCU WDM output untuk LED merah 9-g const byte GreenLedPin=6; //MCU WDM output untuk LED hijau 6-b const byte BlueLedPin=3; //MCU WDM output untuk LED biru 3-r const byte pinSet=A0; const byte pinUp=A2; const byte pinDown=A1; const byte pinBuzzer=2; const byte pinUpperDots=12; //HIGH value menyala titik const byte pinLowerDots=8; //HIGH value menyala titik const word fpsLimit=16666; // 1/60*1.000.000 //batas refresh rate maksimal pada 60 fps String stringToDisplay="000000";// Isi string ini akan ditampilkan pada tabung (harus 6 karakter panjang) int menuPosition=0; // 0 - waktu // 1 - tanggal // 2 - alarm // 3 - mode 12/24 jam byte blinkMask=B00000000; //bit mask untuk berkedip digit (1 - berkedip, 0 - cahaya konstan) //-------------------------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; //bit mask untuk memisahkan titik //B00000000 - matikan titik atas dan bawah //B1100000 - matikan semua titik #define DS1307_ADDRESS 0x68 byte zero = 0x00; //workaround untuk issue #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 // nama: Waktu, Tanggal, Alarm, 12/24 jam, menit, detik, hari, bulan, tahun, jam, menit, detik alarm01 hour_format // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 int 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}; int value[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, B11000000, 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 9 #define AlarmHourIndex 10 #define AlarmMinuteIndex 11 #define AlarmSecondIndex 12 #define Alarm01 13 #define hModeValueIndex 14 bool editMode=false; long downTime=0; long upTime=0; const long settingDelay=150; bool BlinkUp=false; bool BlinkDown=false; unsigned long enteringEditModeTime=0; bool RGBLedsOn=true; byte RGBLEDsEEPROMAddress=0; byte HourFormatEEPROMAddress=1; byte AlarmTimeEEPROMAddress=2;//3,4,5 byte AlarmArmedEEPROMAddress=6; //deklarasi pin tombol 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#,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,32p,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="Popcorn: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 0 char *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_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, 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 dengan aturan RGB (0 - lakukan apa-apa, -1 - kurangi, +1 - tambah void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w=1); int functionDownButton=0; int functionUpButton=0; /******************************************************************************************************* Inisialisasi Program *******************************************************************************************************/ void setup() { digitalWrite(DHVpin, LOW); // matikan Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V Wire.begin(); //setRTCDateTime(23,40,00,25,7,15,1); Serial.begin(115200); Serial.println(""); if (EEPROM.read(HourFormatEEPROMAddress)!=12) value[hModeValueIndex]=24; else value[hModeValueIndex]=12; if (EEPROM.read(RGBLEDsEEPROMAddress)!=0) RGBLedsOn=true; else RGBLedsOn=false; if (EEPROM.read(AlarmTimeEEPROMAddress)==255) value[AlarmHourIndex]=0; else value[AlarmHourIndex]=EEPROM.read(AlarmTimeEEPROMAddress); if (EEPROM.read(AlarmTimeEEPROMAddress+1)==255) value[AlarmMinuteIndex]=0; else value[AlarmMinuteIndex]=EEPROM.read(AlarmTimeEEPROMAddress+1); if (EEPROM.read(AlarmTimeEEPROMAddress+2)==255) value[AlarmSecondIndex]=0; else value[AlarmSecondIndex]=EEPROM.read(AlarmTimeEEPROMAddress+2); if (EEPROM.read(AlarmArmedEEPROMAddress)==255) value[Alarm01]=0; else value[Alarm01]=EEPROM.read(AlarmArmedEEPROMAddress); tone1.begin(pinBuzzer); song=parseSong(song); pinMode(LEpin, OUTPUT); pinMode(DHVpin, OUTPUT); pinMode(RedLedPin, OUTPUT); pinMode(GreenLedPin, OUTPUT); pinMode(BlueLedPin, OUTPUT); // SPI setup SPI.begin(); // SPI.setDataMode (SPI_MODE3); // Mode 3 SPI SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK = 16MHz/128= 125kHz //inisialisasi pin tombol pinMode(pinSet, INPUT_PULLUP); pinMode(pinUp, INPUT_PULLUP); pinMode(pinDown, INPUT_PULLUP); //////////////////////////// pinMode(pinBuzzer, OUTPUT); //inisialisasi objek tombol setButton.debounceTime = 20; // Timer debounce dalam ms setButton.multiclickTime = 30; // Batas waktu untuk multi klik setButton.longClickTime = 2000; // waktu hingga "klik ditekan" terdaftar upButton.debounceTime = 20; // Timer debounce dalam ms upButton.multiclickTime = 30; // Batas waktu untuk multi klik upButton.longClickTime = 2000; // waktu hingga "klik ditekan" terdaftar downButton.debounceTime = 20; // Timer debounce dalam ms downButton.multiclickTime = 30; // Batas waktu untuk multi klik downButton.longClickTime = 2000; // waktu hingga "klik ditekan" terdaftar // digitalWrite(DHVpin, HIGH); // nyalakan Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //doTest(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! getRTCTime(); setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); digitalWrite(DHVpin, LOW); // matikan Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V setRTCDateTime(RTC_hours,RTC_minutes,RTC_seconds,RTC_day,RTC_month,RTC_year,1); //      RTC     digitalWrite(DHVpin, HIGH); // nyalakan Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V //p=song; } void rotateLeft(uint8_t &bits) { uint8_t high_bit = bits & (1 << 7) ? 1 : 0; bits = (bits << 1) | high_bit; } int rotator=0; //index dalam array dengan "aturan" RGB (ditambah satu setiap 255 siklus) int cycle=0; //penghitung siklus int RedLight=255; int GreenLight=0; int BlueLight=0; unsigned long prevTime=0; // waktu terakhir tabung nyala unsigned long prevTime4FireWorks=0; //waktu terakhir RGB diubah //int minuteL=0; //   /*************************************************************************************************************** Program Utama ***************************************************************************************************************/ void loop() { p=playmusic(p); if ((millis()-prevTime4FireWorks)>5) { rotateFireWorks(); //ubah warna (dengan 1 langkah) prevTime4FireWorks=millis(); } doIndication(); setButton.Update(); upButton.Update(); downButton.Update(); if (editMode==false) { blinkMask=B00000000; } else if ((millis()-enteringEditModeTime)>60000) { editMode=false; menuPosition=firstChild[menuPosition]; blinkMask=blinkPattern[menuPosition]; } if (setButton.clicks>0) //klik pendek { p=0; //matikan musik ))) tone1.play(1000,100); enteringEditModeTime=millis(); menuPosition=menuPosition+1; if (menuPosition==hModeIndex+1) menuPosition=TimeIndex; Serial.print(F("menuPosition=")); Serial.println(menuPosition); Serial.print(F("value=")); Serial.println(value[menuPosition]); blinkMask=blinkPattern[menuPosition]; if ((parent[menuPosition-1]!=0) and (lastChild[parent[menuPosition-1]-1]==(menuPosition-1))) { if ((parent[menuPosition-1]-1==1) && (!isValidDate())) { menuPosition=DateDayIndex; return; } editMode=false; menuPosition=parent[menuPosition-1]-1; if (menuPosition==TimeIndex) setTime(value[TimeHoursIndex], value[TimeMintuesIndex], value[TimeSecondsIndex], day(), month(), year()); if (menuPosition==DateIndex) setTime(hour(), minute(), second(),value[DateDayIndex], value[DateMonthIndex], 2000+value[DateYearIndex]); if (menuPosition==AlarmIndex) {EEPROM.write(AlarmTimeEEPROMAddress,value[AlarmHourIndex]); EEPROM.write(AlarmTimeEEPROMAddress+1,value[AlarmMinuteIndex]); EEPROM.write(AlarmTimeEEPROMAddress+2,value[AlarmSecondIndex]); EEPROM.write(AlarmArmedEEPROMAddress, value[Alarm01]);}; if (menuPosition==hModeIndex) EEPROM.write(HourFormatEEPROMAddress, value[hModeValueIndex]); digitalWrite(DHVpin, LOW); // matikan Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V setRTCDateTime(hour(),minute(),second(),day(),month(),year()%1000,1); digitalWrite(DHVpin, HIGH); // nyalakan Pengemudi MAX1771 Tegangan Tinggi(DHV) 110-220V } value[menuPosition]=extractDigits(blinkMask); } if (setButton.clicks<0) //klik panjang { tone1.play(1000,100); if (!editMode) { enteringEditModeTime=millis(); if (menuPosition==TimeIndex) stringToDisplay=PreZero(hour())+PreZero(minute())+PreZero(second()); //aktifkan sementara format 24 jam saat pengaturan } menuPosition=firstChild[menuPosition]; if (menuPosition==AlarmHourIndex) {value[Alarm01]=1; /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;} editMode=!editMode; blinkMask=blinkPattern[menuPosition]; value[menuPosition]=extractDigits(blinkMask); } if (upButton.clicks != 0) functionUpButton = upButton.clicks; if (upButton.clicks>0) { p=0; //matikan musik ))) 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; //matikan musik ))) 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=true; EEPROM.write(RGBLEDsEEPROMAddress,1); Serial.println("RGB=on"); } if (downButton.clicks<0) { tone1.play(1000,100); RGBLedsOn=false; EEPROM.write(RGBLEDsEEPROMAddress,0); Serial.println("RGB=off"); } } static bool updateDateTime=false; switch (menuPosition) { case TimeIndex: //mode waktu stringToDisplay=updateDisplayString(); doDotBlink(); checkAlarmTime(); break; case DateIndex: //mode tanggal stringToDisplay=PreZero(day())+PreZero(month())+PreZero(year()%1000); dotPattern=B01000000;//nyalakan titik bawah /*digitalWrite(pinUpperDots, LOW); digitalWrite(pinLowerDots, HIGH);*/ checkAlarmTime(); break; case AlarmIndex: //mode alarm stringToDisplay=PreZero(value[AlarmHourIndex])+PreZero(value[AlarmMinuteIndex])+PreZero(value[AlarmSecondIndex]); if (value[Alarm01]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000; //nyalakan titik atas else { /*digitalWrite(pinUpperDots, LOW); digitalWrite(pinLowerDots, LOW);*/ dotPattern=B00000000; //matikan titik atas } checkAlarmTime(); break; case hModeIndex: //mode 12/24 jam stringToDisplay="00"+String(value[hModeValueIndex])+"00"; dotPattern=B00000000;//matikan semua titik /*digitalWrite(pinUpperDots, LOW); digitalWrite(pinLowerDots, LOW);*/ checkAlarmTime(); break; } } 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); return; } RedLight=RedLight+fireforks[rotator*3]; GreenLight=GreenLight+fireforks[rotator*3+1]; BlueLight=BlueLight+fireforks[rotator*3+2]; analogWrite(RedLedPin,RedLight ); analogWrite(GreenLedPin,GreenLight); analogWrite(BlueLedPin,BlueLight); cycle=cycle+1; if (cycle==255) { rotator=rotator+1; cycle=0; } if (rotator>5) rotator=0; } void doIndication() { //static byte b=B00000001; static unsigned long lastTimeInterval1Started; if ((micros()-lastTimeInterval1Started)<fpsLimit) return; //if (menuPosition==TimeIndex) doDotBlink(); lastTimeInterval1Started=micros(); digitalWrite(LEpin, HIGH); // izinkan input data (mode transparan) /* SPI.transfer((b|dotPattern) & doEditBlink()); // anode SPI.transfer(highBytesArray[stringToDisplay.substring(curTube,curTube+1).toInt()]); SPI.transfer(lowBytesArray[stringToDisplay.substring(curTube,curTube+1).toInt()]); */ // 0 1 2 3 4 5 6 7 8 9 //long mass1[10]={B1111111111111110, B1111111111111101, B1111111111111011, B1111111111110111, B1111111111101111, B1111111111011111, B1111111110111111, B1111111101111111, B1111111011111111, B1111110111111111}; //long mass2[10]={B1111111111111110, B1111110111111111, B1111111011111111, B1111111101111111, B1111111110111111, B1111111111011111, B1111111111101111, B1111111111110111, B1111111111111011, B1111111111111101}; // digunakan hanya versi pelindung 1.0 //karena beberapa bug hardware dalam pengkabelan // 0 1 2 3 4 5 6 7 8 9 word mass1[10]={65534, 65533, 65531, 65527, 65519, 65503, 65471, 65407, 65279, 65023}; word mass2[10]={65534, 65023, 65279, 65407, 65471, 65503, 65519, 65527, 65531, 65533}; // digunakan hanya versi pelindung 1.0 //karena beberapa bug hardware dalam pengkabelan unsigned long long Var64=0; unsigned long long tmpVar64=0; long digits=stringToDisplay.toInt(); Var64=~Var64; tmpVar64=~tmpVar64; Var64=Var64&((mass2[digits%10]|doEditBlink(5))<<6); Var64=Var64<<48; digits=digits/10; tmpVar64=(mass1[digits%10]|doEditBlink(4))<<6; Var64|=(tmpVar64<<38); digits=digits/10; tmpVar64=(mass2[digits%10]|doEditBlink(3))<<6; Var64|=(tmpVar64<<28); digits=digits/10; tmpVar64=(mass1[digits%10]|doEditBlink(2))<<6; Var64|=(tmpVar64<<18); digits=digits/10; tmpVar64=(mass2[digits%10]|doEditBlink(1))<<6; Var64|=(tmpVar64<<8); digits=digits/10; tmpVar64=(mass1[digits%10]|doEditBlink(0))<<6>>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); digitalWrite(LEpin, LOW); // menyimpan data } 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 (value[hModeValueIndex]==24) return PreZero(hour())+PreZero(minute())+PreZero(second()); else return PreZero(hourFormat12())+PreZero(minute())+PreZero(second()); } return stringToDisplay; } void doTest() { Serial.print(F("Versi Firmware: ")); Serial.println(FirmwareVersion.substring(1,2)+"."+FirmwareVersion.substring(2,4)); Serial.println(F("Mulai Tes")); int adc=analogRead(A3); float Uinput=4.6*(5.0*adc)/1024.0+0.7; Serial.print(F("U input=")); Serial.print(Uinput); p=song; parseSong(p); analogWrite(RedLedPin,255); delay(1000); analogWrite(RedLedPin,0); analogWrite(GreenLedPin,255); delay(1000); analogWrite(GreenLedPin,0); analogWrite(BlueLedPin,255); delay(1000); //while(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; bool test=1; byte strIndex=0; unsigned long 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) test=0; switch (strIndex) { /* case 10: SPI.transfer((b|B01000000)&B11111100); break; case 11: SPI.transfer((b|B01000000)&B11001110); break; */ //default: SPI.transfer(b|B11000000); default: stringToDisplay=testStringArray[strIndex]; } } delayMicroseconds(2000); }; Serial.println(F("Stop Tes")); } 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, 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); //hentikan osilator 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); //mulai Wire.endTransmission(); } byte decToBcd(byte val){ // Konversi angka desimal normal ke binary coded decimal return ( (val/10*16) + (val%10) ); } byte bcdToDec(byte val) { // Konversi binary coded decimal ke angka desimal normal return ( (val/16*10) + (val%16) ); } void getRTCTime() { Wire.beginTransmission(DS1307_ADDRESS); Wire.write(zero); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); RTC_seconds = bcdToDec(Wire.read()); RTC_minutes = bcdToDec(Wire.read()); RTC_hours = bcdToDec(Wire.read() & 0b111111); //waktu 24 jam RTC_day_of_week = bcdToDec(Wire.read()); //0-6 -> minggu - Sabtu RTC_day = bcdToDec(Wire.read()); RTC_month = bcdToDec(Wire.read()); RTC_year = bcdToDec(Wire.read()); } word 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; word mask=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)) mask=0xFFFF;//mask=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) { // Tidak ada pemeriksaan kesalahan di sini // format: d=N,o=N,b=NNN: // cari awal (lewati nama, dll) while(*p != ':') p++; // abaikan nama p++; // skip ':' // dapatkan durasi default 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 koma } // dapatkan oktav default if(*p == 'o') { p++; p++; // skip "o=" num = *p++ - '0'; if(num >= 3 && num <=7) default_oct = num; p++; // skip koma } // dapatkan BPM if(*p == 'b') { p++; p++; // skip "b=" num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } bpm = num; p++; // skip titik dua } // BPM biasanya menunjukkan jumlah nada separuh per menit wholenote = (60 * 1000L / bpm) * 4; // ini adalah waktu untuk nada utuh (dalam milidetik) return p; } // sekarang mulai loop nada static unsigned long lastTimeNotePlaying=0; char* playmusic(char *p) { if(*p==0) { return p; } if (millis()-lastTimeNotePlaying>duration) lastTimeNotePlaying=millis(); else return p; // pertama, dapatkan durasi nada, jika tersedia num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } if(num) duration = wholenote / num; else duration = wholenote / default_dur; // kita perlu memeriksa apakah kita nada titik setelah // sekarang dapatkan nada note = 0; switch(*p) { case 'c': note = 1; break; case 'd': note = 3; break; case 'e': note = 5; break; case 'f': note = 6; break; case 'g': note = 8; break; case 'a': note = 10; break; case 'b': note = 12; break; case 'p': default: note = 0; } p++; // sekarang, dapatkan '#' optional sharp if(*p == '#') { note++; p++; } // sekarang, dapatkan '.' optional dotted note if(*p == '.') { duration += duration/2; p++; } // sekarang, dapatkan skala if(isdigit(*p)) { scale = *p - '0'; p++; } else { scale = default_oct; } scale += OCTAVE_OFFSET; if(*p == ',') p++; // skip koma untuk nada berikutnya (atau kita mungkin di akhir) // sekarang mainkan nada 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("Format Lagu Salah!")); return 0; //error } void incrementValue() { enteringEditModeTime=millis(); if (editMode==true) { if(menuPosition!=hModeValueIndex) // posisi menu mode 12/24 jam 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;//nyalakan semua titik /*else digitalWrite(pinUpperDots, LOW); */ dotPattern=B00000000; //matikan semua titik } 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]<minValue[menuPosition]) value[menuPosition]=maxValue[menuPosition]; if (menuPosition==Alarm01) { if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000;//nyalakan titik atas    else /*digitalWrite(pinUpperDots, LOW);*/ dotPattern=B00000000; //matikan titik atas } injectDigits(blinkMask, value[menuPosition]); } } bool Alarm1SecondBlock=false; unsigned long lastTimeAlarmTriggired=0; void checkAlarmTime() { if (value[Alarm01]==0) return; if ((Alarm1SecondBlock==true) && ((millis()-lastTimeAlarmTriggired)>1000)) Alarm1SecondBlock=false; if (Alarm1SecondBlock==true) return; if ((hour()==value[AlarmHourIndex]) && (minute()==value[AlarmMinuteIndex]) && (second()==value[AlarmSecondIndex])) { lastTimeAlarmTriggired=millis(); Alarm1SecondBlock=true; Serial.println(F("Bangun, Neo!")); p=song; } } 
Program JAM NIXIE Tabung Pelindung NCS314
https://github.com/afch/NixeTubesShieldNCS314/

Skematik

Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12Pelindung Jam Tabung Nixie NCS314 untuk Arduino UNO/MEGA – Kompatibilitas IN‑14/IN‑12

Proses manufaktur

  1. Jam POV Arduino: Buat Tampilan LED Persistensi Penglihatan
  2. Sistem Pencahayaan DMX Dikonrol Web – Kontroler Master Arduino
  3. Jam Kata Arduino DIY – Buat Tampilan Waktu Real-Time yang Elegan
  4. Membuat Jam Waktu Nyata Arduino untuk Waktu Sholat Islam
  5. Membuat Spybot Arduino yang Dikontrol melalui Bluetooth
  6. Bangun Jam Master LED Kustom dengan Alarm – Terlihat dari Jarak 12 Meter
  7. Buat Jam Tabung Nixie Elegan dalam Kotak Kayu MDF Khusus dengan Arduino
  8. Membuat Jam 7-Segmen Akurat dengan Arduino Pro Mini & DS1302 RTC
  9. Shield Pemrograman Arduino Nirkabel dengan HC-05 Bluetooth – Tanpa USB
  10. Membuat Jam Alarm Andalan dengan DS1302 RTC dan Arduino UNO