Components and supplies
Shield Nixie Tubes IN-14 NCS314 Arduino for Nixie Tubes Clock etc.
Arduino Mega 2560
Power Supply 12V 1A
Shield Nixie Tubes Clock IN-12 NCS312 for xUSSR Nixie Tubes
Acrylic Case for SHIELD NCS314
Arduino UNO
Apps and platforms
Arduino IDE
Project description
Code
Prog NIXIE Clock Tubes Shield NCS314
Prog NIXIE Clock Tubes Shield NCS314
Untitled file
c_cpp
1const String FirmwareVersion="010000"; 2//Format _X.XX__ 3//NIXIE CLOCK SHIELD NCS314 by GRA & AFCH (fominalec@gmail.com) 4//25.05.2016 5 6#include <SPI.h> 7#include <Wire.h> 8#include <ClickButton.h> 9#include <Time.h> 10#include <Tone.h> 11#include <EEPROM.h> 12 13const byte LEpin=7; //pin Latch Enabled data accepted while HI level 14const byte DHVpin=5; // off/on MAX1771 Driver Hight Voltage(DHV) 110-220V 15const byte RedLedPin=9; //MCU WDM output for red LEDs 9-g 16const byte GreenLedPin=6; //MCU WDM output for green LEDs 6-b 17const byte BlueLedPin=3; //MCU WDM output for blue LEDs 3-r 18const byte pinSet=A0; 19const byte pinUp=A2; 20const byte pinDown=A1; 21const byte pinBuzzer=2; 22const byte pinUpperDots=12; //HIGH value light a dots 23const byte pinLowerDots=8; //HIGH value light a dots 24const word fpsLimit=16666; // 1/60*1.000.000 //limit maximum refresh rate on 60 fps 25 26String stringToDisplay="000000";// Conten of this string will be displayed on tubes (must be 6 chars length) 27int menuPosition=0; // 0 - time 28 // 1 - date 29 // 2 - alarm 30 // 3 - 12/24 hours mode 31 32byte blinkMask=B00000000; //bit mask for blinkin digits (1 - blink, 0 - constant light) 33 34//-------------------------0-------1----------2----------3---------4--------5---------6---------7---------8---------9----- 35//byte lowBytesArray[]={B11111110,B11111101,B11111011,B11110111,B11101111,B11011111,B10111111,B01111111,B11111111,B11111111}; 36//byte highBytesArray[]={B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111110,B11111101}; 37 38byte dotPattern=B00000000; //bit mask for separeting dots 39 //B00000000 - turn off up and down dots 40 //B1100000 - turn off all dots 41 42#define DS1307_ADDRESS 0x68 43byte zero = 0x00; //workaround for issue #527 44int RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year, RTC_day_of_week; 45 46//-- ------------0--------1--------2-------3--------4--------5--------6--------7--------8--------9--------10-------11-------12-------13-------14 47// names: Time, Date, Alarm, 12/24 hours, mintues, seconds, day, month, year, hour, minute, second alarm01 hour_format 48// 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 49int parent[15]={ 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4}; 50int firstChild[15]={4, 7, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 51int lastChild[15]={ 6, 9, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 52int value[15]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24}; 53int maxValue[15]={ 0, 0, 0, 0, 23, 59, 59, 31, 12, 99, 23, 59, 59, 1, 24}; 54int minValue[15]={ 0, 0, 0, 12, 00, 00, 00, 1, 1, 00, 00, 00, 00, 0, 12}; 55byte blinkPattern[15]={ 56 B00000000, 57 B00000000, 58 B00000000, 59 B00000000, 60 B00000011, 61 B00001100, 62 B00110000, 63 B00000011, 64 B00001100, 65 B00110000, 66 B00000011, 67 B00001100, 68 B00110000, 69 B11000000, 70 B00001100}; 71#define TimeIndex 0 72#define DateIndex 1 73#define AlarmIndex 2 74#define hModeIndex 3 75#define TimeHoursIndex 4 76#define TimeMintuesIndex 5 77#define TimeSecondsIndex 6 78#define DateDayIndex 7 79#define DateMonthIndex 8 80#define DateYearIndex 9 81#define AlarmHourIndex 10 82#define AlarmMinuteIndex 11 83#define AlarmSecondIndex 12 84#define Alarm01 13 85#define hModeValueIndex 14 86 87bool editMode=false; 88 89long downTime=0; 90long upTime=0; 91const long settingDelay=150; 92bool BlinkUp=false; 93bool BlinkDown=false; 94unsigned long enteringEditModeTime=0; 95bool RGBLedsOn=true; 96byte RGBLEDsEEPROMAddress=0; 97byte HourFormatEEPROMAddress=1; 98byte AlarmTimeEEPROMAddress=2;//3,4,5 99byte AlarmArmedEEPROMAddress=6; 100 101//buttons pins declarations 102ClickButton setButton(pinSet, LOW, CLICKBTN_PULLUP); 103ClickButton upButton(pinUp, LOW, CLICKBTN_PULLUP); 104ClickButton downButton(pinDown, LOW, CLICKBTN_PULLUP); 105/////////////////// 106 107Tone tone1; 108#define isdigit(n) (n >= '0' && n <= '9') 109//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"; 110char *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"; 111//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"; 112//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"; 113//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."; 114//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"; 115//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"; 116#define OCTAVE_OFFSET 0 117char *p; 118 119int notes[] = { 0, 120NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, 121NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, 122NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, 123NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 124}; 125 126int fireforks[]={0,0,1,//1 127 -1,0,0,//2 128 0,1,0,//3 129 0,0,-1,//4 130 1,0,0,//5 131 0,-1,0}; //array with RGB rules (0 - do nothing, -1 - decrese, +1 - increse 132 133void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w=1); 134 135int functionDownButton=0; 136int functionUpButton=0; 137 138/******************************************************************************************************* 139Init Programm 140*******************************************************************************************************/ 141void setup() 142{ 143 digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V 144 145 Wire.begin(); 146 //setRTCDateTime(23,40,00,25,7,15,1); 147 148 Serial.begin(115200); 149 Serial.println(""); 150 151 if (EEPROM.read(HourFormatEEPROMAddress)!=12) value[hModeValueIndex]=24; else value[hModeValueIndex]=12; 152 if (EEPROM.read(RGBLEDsEEPROMAddress)!=0) RGBLedsOn=true; else RGBLedsOn=false; 153 if (EEPROM.read(AlarmTimeEEPROMAddress)==255) value[AlarmHourIndex]=0; else value[AlarmHourIndex]=EEPROM.read(AlarmTimeEEPROMAddress); 154 if (EEPROM.read(AlarmTimeEEPROMAddress+1)==255) value[AlarmMinuteIndex]=0; else value[AlarmMinuteIndex]=EEPROM.read(AlarmTimeEEPROMAddress+1); 155 if (EEPROM.read(AlarmTimeEEPROMAddress+2)==255) value[AlarmSecondIndex]=0; else value[AlarmSecondIndex]=EEPROM.read(AlarmTimeEEPROMAddress+2); 156 if (EEPROM.read(AlarmArmedEEPROMAddress)==255) value[Alarm01]=0; else value[Alarm01]=EEPROM.read(AlarmArmedEEPROMAddress); 157 158 tone1.begin(pinBuzzer); 159 song=parseSong(song); 160 161 pinMode(LEpin, OUTPUT); 162 pinMode(DHVpin, OUTPUT); 163 164 pinMode(RedLedPin, OUTPUT); 165 pinMode(GreenLedPin, OUTPUT); 166 pinMode(BlueLedPin, OUTPUT); 167 168 169 // SPI setup 170 171 SPI.begin(); // 172 SPI.setDataMode (SPI_MODE3); // Mode 3 SPI 173 SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK = 16MHz/128= 125kHz 174 175 //buttons pins inits 176 pinMode(pinSet, INPUT_PULLUP); 177 pinMode(pinUp, INPUT_PULLUP); 178 pinMode(pinDown, INPUT_PULLUP); 179 //////////////////////////// 180 pinMode(pinBuzzer, OUTPUT); 181 182 //buttons objects inits 183 setButton.debounceTime = 20; // Debounce timer in ms 184 setButton.multiclickTime = 30; // Time limit for multi clicks 185 setButton.longClickTime = 2000; // time until "held-down clicks" register 186 187 upButton.debounceTime = 20; // Debounce timer in ms 188 upButton.multiclickTime = 30; // Time limit for multi clicks 189 upButton.longClickTime = 2000; // time until "held-down clicks" register 190 191 downButton.debounceTime = 20; // Debounce timer in ms 192 downButton.multiclickTime = 30; // Time limit for multi clicks 193 downButton.longClickTime = 2000; // time until "held-down clicks" register 194 195 // 196 digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V 197 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 198 //doTest(); 199 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 200 getRTCTime(); 201 setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year); 202 digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V 203 setRTCDateTime(RTC_hours,RTC_minutes,RTC_seconds,RTC_day,RTC_month,RTC_year,1); //���������� ������ ��� ��������� ����� � RTC ����� ��������� ����� ���������� 204 digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V 205 //p=song; 206} 207 208void rotateLeft(uint8_t &bits) 209{ 210 uint8_t high_bit = bits & (1 << 7) ? 1 : 0; 211 bits = (bits << 1) | high_bit; 212} 213 214int rotator=0; //index in array with RGB "rules" (increse by one on each 255 cycles) 215int cycle=0; //cycles counter 216int RedLight=255; 217int GreenLight=0; 218int BlueLight=0; 219unsigned long prevTime=0; // time of lase tube was lit 220unsigned long prevTime4FireWorks=0; //time of last RGB changed 221//int minuteL=0; //������� ����� ����� 222 223/*************************************************************************************************************** 224MAIN Programm 225***************************************************************************************************************/ 226void loop() { 227 228 p=playmusic(p); 229 230 if ((millis()-prevTime4FireWorks)>5) 231 { 232 rotateFireWorks(); //change color (by 1 step) 233 prevTime4FireWorks=millis(); 234 } 235 236 doIndication(); 237 238 setButton.Update(); 239 upButton.Update(); 240 downButton.Update(); 241 if (editMode==false) 242 { 243 blinkMask=B00000000; 244 245 } else if ((millis()-enteringEditModeTime)>60000) 246 { 247 editMode=false; 248 menuPosition=firstChild[menuPosition]; 249 blinkMask=blinkPattern[menuPosition]; 250 } 251 if (setButton.clicks>0) //short click 252 { 253 p=0; //shut off music ))) 254 tone1.play(1000,100); 255 enteringEditModeTime=millis(); 256 menuPosition=menuPosition+1; 257 if (menuPosition==hModeIndex+1) menuPosition=TimeIndex; 258 Serial.print(F("menuPosition=")); 259 Serial.println(menuPosition); 260 Serial.print(F("value=")); 261 Serial.println(value[menuPosition]); 262 263 blinkMask=blinkPattern[menuPosition]; 264 if ((parent[menuPosition-1]!=0) and (lastChild[parent[menuPosition-1]-1]==(menuPosition-1))) 265 { 266 if ((parent[menuPosition-1]-1==1) && (!isValidDate())) 267 { 268 menuPosition=DateDayIndex; 269 return; 270 } 271 editMode=false; 272 menuPosition=parent[menuPosition-1]-1; 273 if (menuPosition==TimeIndex) setTime(value[TimeHoursIndex], value[TimeMintuesIndex], value[TimeSecondsIndex], day(), month(), year()); 274 if (menuPosition==DateIndex) setTime(hour(), minute(), second(),value[DateDayIndex], value[DateMonthIndex], 2000+value[DateYearIndex]); 275 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]);}; 276 if (menuPosition==hModeIndex) EEPROM.write(HourFormatEEPROMAddress, value[hModeValueIndex]); 277 digitalWrite(DHVpin, LOW); // off MAX1771 Driver Hight Voltage(DHV) 110-220V 278 setRTCDateTime(hour(),minute(),second(),day(),month(),year()%1000,1); 279 digitalWrite(DHVpin, HIGH); // on MAX1771 Driver Hight Voltage(DHV) 110-220V 280 } 281 value[menuPosition]=extractDigits(blinkMask); 282 } 283 if (setButton.clicks<0) //long click 284 { 285 tone1.play(1000,100); 286 if (!editMode) 287 { 288 enteringEditModeTime=millis(); 289 if (menuPosition==TimeIndex) stringToDisplay=PreZero(hour())+PreZero(minute())+PreZero(second()); //temporary enabled 24 hour format while settings 290 } 291 menuPosition=firstChild[menuPosition]; 292 if (menuPosition==AlarmHourIndex) {value[Alarm01]=1; /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;} 293 editMode=!editMode; 294 blinkMask=blinkPattern[menuPosition]; 295 value[menuPosition]=extractDigits(blinkMask); 296 } 297 298 if (upButton.clicks != 0) functionUpButton = upButton.clicks; 299 300 if (upButton.clicks>0) 301 { 302 p=0; //shut off music ))) 303 tone1.play(1000,100); 304 incrementValue(); 305 } 306 307 if (functionUpButton == -1 && upButton.depressed == true) 308 { 309 BlinkUp=false; 310 if (editMode==true) 311 { 312 if ( (millis() - upTime) > settingDelay) 313 { 314 upTime = millis();// + settingDelay; 315 incrementValue(); 316 } 317 } 318 } else BlinkUp=true; 319 320 if (downButton.clicks != 0) functionDownButton = downButton.clicks; 321 322 if (downButton.clicks>0) 323 { 324 p=0; //shut off music ))) 325 tone1.play(1000,100); 326 dicrementValue(); 327 } 328 329 if (functionDownButton == -1 && downButton.depressed == true) 330 { 331 BlinkDown=false; 332 if (editMode==true) 333 { 334 if ( (millis() - downTime) > settingDelay) 335 { 336 downTime = millis();// + settingDelay; 337 dicrementValue(); 338 } 339 } 340 } else BlinkDown=true; 341 342 if (!editMode) 343 { 344 if (upButton.clicks<0) 345 { 346 tone1.play(1000,100); 347 RGBLedsOn=true; 348 EEPROM.write(RGBLEDsEEPROMAddress,1); 349 Serial.println("RGB=on"); 350 } 351 if (downButton.clicks<0) 352 { 353 tone1.play(1000,100); 354 RGBLedsOn=false; 355 EEPROM.write(RGBLEDsEEPROMAddress,0); 356 Serial.println("RGB=off"); 357 } 358 } 359 360 361 static bool updateDateTime=false; 362 switch (menuPosition) 363 { 364 case TimeIndex: //time mode 365 stringToDisplay=updateDisplayString(); 366 doDotBlink(); 367 checkAlarmTime(); 368 break; 369 case DateIndex: //date mode 370 stringToDisplay=PreZero(day())+PreZero(month())+PreZero(year()%1000); 371 dotPattern=B01000000;//turn on lower dots 372 /*digitalWrite(pinUpperDots, LOW); 373 digitalWrite(pinLowerDots, HIGH);*/ 374 checkAlarmTime(); 375 break; 376 case AlarmIndex: //alarm mode 377 stringToDisplay=PreZero(value[AlarmHourIndex])+PreZero(value[AlarmMinuteIndex])+PreZero(value[AlarmSecondIndex]); 378 if (value[Alarm01]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000; //turn on upper dots 379 else 380 { 381 /*digitalWrite(pinUpperDots, LOW); 382 digitalWrite(pinLowerDots, LOW);*/ 383 dotPattern=B00000000; //turn off upper dots 384 } 385 checkAlarmTime(); 386 break; 387 case hModeIndex: //12/24 hours mode 388 stringToDisplay="00"+String(value[hModeValueIndex])+"00"; 389 dotPattern=B00000000;//turn off all dots 390 /*digitalWrite(pinUpperDots, LOW); 391 digitalWrite(pinLowerDots, LOW);*/ 392 checkAlarmTime(); 393 break; 394 } 395} 396 397String PreZero(int digit) 398{ 399 if (digit<10) return String("0")+String(digit); 400 else return String(digit); 401} 402 403void rotateFireWorks() 404{ 405 if (!RGBLedsOn) 406 { 407 analogWrite(RedLedPin,0 ); 408 analogWrite(GreenLedPin,0); 409 analogWrite(BlueLedPin,0); 410 return; 411 } 412 RedLight=RedLight+fireforks[rotator*3]; 413 GreenLight=GreenLight+fireforks[rotator*3+1]; 414 BlueLight=BlueLight+fireforks[rotator*3+2]; 415 analogWrite(RedLedPin,RedLight ); 416 analogWrite(GreenLedPin,GreenLight); 417 analogWrite(BlueLedPin,BlueLight); 418 cycle=cycle+1; 419 if (cycle==255) 420 { 421 rotator=rotator+1; 422 cycle=0; 423 } 424 if (rotator>5) rotator=0; 425} 426 427 428void doIndication() 429{ 430 431 //static byte b=B00000001; 432 433 static unsigned long lastTimeInterval1Started; 434 if ((micros()-lastTimeInterval1Started)<fpsLimit) return; 435 //if (menuPosition==TimeIndex) doDotBlink(); 436 lastTimeInterval1Started=micros(); 437 438 digitalWrite(LEpin, HIGH); // allow data input (Transparent mode) 439 440 /* 441 SPI.transfer((b|dotPattern) & doEditBlink()); // anode 442 SPI.transfer(highBytesArray[stringToDisplay.substring(curTube,curTube+1).toInt()]); 443 SPI.transfer(lowBytesArray[stringToDisplay.substring(curTube,curTube+1).toInt()]); 444 */ 445 446 // 0 1 2 3 4 5 6 7 8 9 447 //long mass1[10]={B1111111111111110, B1111111111111101, B1111111111111011, B1111111111110111, B1111111111101111, B1111111111011111, B1111111110111111, B1111111101111111, B1111111011111111, B1111110111111111}; 448 //long mass2[10]={B1111111111111110, B1111110111111111, B1111111011111111, B1111111101111111, B1111111110111111, B1111111111011111, B1111111111101111, B1111111111110111, B1111111111111011, B1111111111111101}; // used only shiled ver 1.0 //for some hardware bug in wiring 449 450 // 0 1 2 3 4 5 6 7 8 9 451 word mass1[10]={65534, 65533, 65531, 65527, 65519, 65503, 65471, 65407, 65279, 65023}; 452 word mass2[10]={65534, 65023, 65279, 65407, 65471, 65503, 65519, 65527, 65531, 65533}; // used only shiled ver 1.0 //for some hardware bug in wiring 453 454 unsigned long long Var64=0; 455 unsigned long long tmpVar64=0; 456 457 long digits=stringToDisplay.toInt(); 458 459 Var64=~Var64; 460 tmpVar64=~tmpVar64; 461 462 Var64=Var64&((mass2[digits%10]|doEditBlink(5))<<6); 463 Var64=Var64<<48; 464 digits=digits/10; 465 466 tmpVar64=(mass1[digits%10]|doEditBlink(4))<<6; 467 Var64|=(tmpVar64<<38); 468 digits=digits/10; 469 470 tmpVar64=(mass2[digits%10]|doEditBlink(3))<<6; 471 Var64|=(tmpVar64<<28); 472 digits=digits/10; 473 474 tmpVar64=(mass1[digits%10]|doEditBlink(2))<<6; 475 Var64|=(tmpVar64<<18); 476 digits=digits/10; 477 478 tmpVar64=(mass2[digits%10]|doEditBlink(1))<<6; 479 Var64|=(tmpVar64<<8); 480 digits=digits/10; 481 482 tmpVar64=(mass1[digits%10]|doEditBlink(0))<<6>>2; 483 Var64|=tmpVar64; 484 485 Var64=(Var64>>4); 486 487 unsigned int iTmp=0; 488 489 iTmp=Var64>>56; 490 SPI.transfer(iTmp); 491 iTmp=Var64>>48; 492 SPI.transfer(iTmp); 493 iTmp=Var64>>40; 494 SPI.transfer(iTmp); 495 iTmp=Var64>>32; 496 SPI.transfer(iTmp); 497 iTmp=Var64>>24; 498 SPI.transfer(iTmp); 499 iTmp=Var64>>16; 500 SPI.transfer(iTmp); 501 iTmp=Var64>>8; 502 SPI.transfer(iTmp); 503 iTmp=Var64; 504 SPI.transfer(iTmp); 505 506 digitalWrite(LEpin, LOW); // latching data 507} 508 509byte CheckButtonsState() 510{ 511 static boolean buttonsWasChecked; 512 static unsigned long startBuzzTime; 513 static unsigned long lastTimeButtonsPressed; 514 if ((digitalRead(pinSet)==0)||(digitalRead(pinUp)==0)||(digitalRead(pinDown)==0)) 515 { 516 if (buttonsWasChecked==false) startBuzzTime=millis(); 517 buttonsWasChecked=true; 518 } else buttonsWasChecked=false; 519 if (millis()-startBuzzTime<30) 520 { 521 digitalWrite(pinBuzzer, HIGH); 522 } else 523 { 524 digitalWrite(pinBuzzer, LOW); 525 } 526} 527 528String updateDisplayString() 529{ 530 static unsigned long lastTimeStringWasUpdated; 531 if ((millis()-lastTimeStringWasUpdated)>1000) 532 { 533 //Serial.println("doDotBlink"); 534 //doDotBlink(); 535 lastTimeStringWasUpdated=millis(); 536 if (value[hModeValueIndex]==24) return PreZero(hour())+PreZero(minute())+PreZero(second()); 537 else return PreZero(hourFormat12())+PreZero(minute())+PreZero(second()); 538 539 } 540 return stringToDisplay; 541} 542 543void doTest() 544{ 545 Serial.print(F("Firmware version: ")); 546 Serial.println(FirmwareVersion.substring(1,2)+"."+FirmwareVersion.substring(2,4)); 547 Serial.println(F("Start Test")); 548 int adc=analogRead(A3); 549 float Uinput=4.6*(5.0*adc)/1024.0+0.7; 550 Serial.print(F("U input=")); 551 Serial.print(Uinput); 552 553 p=song; 554 parseSong(p); 555 556 analogWrite(RedLedPin,255); 557 delay(1000); 558 analogWrite(RedLedPin,0); 559 analogWrite(GreenLedPin,255); 560 delay(1000); 561 analogWrite(GreenLedPin,0); 562 analogWrite(BlueLedPin,255); 563 delay(1000); 564 //while(1); 565 566 String testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888","999999","",""}; 567 568 if (Uinput<10) testStringArray[10]="000"+String(int(Uinput*100)); else testStringArray[10]="00"+String(int(Uinput*100)); 569 testStringArray[11]=FirmwareVersion; 570 571 int dlay=500; 572 bool test=1; 573 byte strIndex=0; 574 unsigned long startOfTest=millis(); 575 for (int i=0; i<12; i++) 576 { 577 if ((millis()-startOfTest)>dlay) 578 { 579 startOfTest=millis(); 580 strIndex=strIndex+1; 581 if (strIndex==10) dlay=3000; 582 if (strIndex==12) test=0; 583 584 switch (strIndex) 585 { 586 /* 587 case 10: SPI.transfer((b|B01000000)&B11111100); 588 break; 589 case 11: SPI.transfer((b|B01000000)&B11001110); 590 break; 591 */ 592 //default: SPI.transfer(b|B11000000); 593 default: stringToDisplay=testStringArray[strIndex]; 594 } 595 } 596 597 delayMicroseconds(2000); 598 }; 599 600 Serial.println(F("Stop Test")); 601 602} 603 604void doDotBlink() 605{ 606 static unsigned long lastTimeBlink=millis(); 607 static bool dotState=0; 608 if ((millis()-lastTimeBlink)>1000) 609 { 610 lastTimeBlink=millis(); 611 dotState=!dotState; 612 if (dotState) 613 { 614 dotPattern=B11000000; 615 /*digitalWrite(pinUpperDots, HIGH); 616 digitalWrite(pinLowerDots, HIGH);*/ 617 } 618 else 619 { 620 dotPattern=B00000000; 621 /*digitalWrite(pinUpperDots, LOW); 622 digitalWrite(pinLowerDots, LOW);*/ 623 } 624 } 625} 626 627void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w) 628{ 629 Wire.beginTransmission(DS1307_ADDRESS); 630 Wire.write(zero); //stop Oscillator 631 632 Wire.write(decToBcd(s)); 633 Wire.write(decToBcd(m)); 634 Wire.write(decToBcd(h)); 635 Wire.write(decToBcd(w)); 636 Wire.write(decToBcd(d)); 637 Wire.write(decToBcd(mon)); 638 Wire.write(decToBcd(y)); 639 640 Wire.write(zero); //start 641 642 Wire.endTransmission(); 643 644} 645 646byte decToBcd(byte val){ 647// Convert normal decimal numbers to binary coded decimal 648 return ( (val/10*16) + (val%10) ); 649} 650 651byte bcdToDec(byte val) { 652// Convert binary coded decimal to normal decimal numbers 653 return ( (val/16*10) + (val%16) ); 654} 655 656void getRTCTime() 657{ 658 Wire.beginTransmission(DS1307_ADDRESS); 659 Wire.write(zero); 660 Wire.endTransmission(); 661 662 Wire.requestFrom(DS1307_ADDRESS, 7); 663 664 RTC_seconds = bcdToDec(Wire.read()); 665 RTC_minutes = bcdToDec(Wire.read()); 666 RTC_hours = bcdToDec(Wire.read() & 0b111111); //24 hour time 667 RTC_day_of_week = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday 668 RTC_day = bcdToDec(Wire.read()); 669 RTC_month = bcdToDec(Wire.read()); 670 RTC_year = bcdToDec(Wire.read()); 671} 672 673word doEditBlink(int pos) 674{ 675 if (!BlinkUp) return 0; 676 if (!BlinkDown) return 0; 677 678 int lowBit=blinkMask>>pos; 679 lowBit=lowBit&B00000001; 680 681 static unsigned long lastTimeEditBlink=millis(); 682 static bool blinkState=false; 683 word mask=0; 684 static int tmp=0;//blinkMask; 685 if ((millis()-lastTimeEditBlink)>300) 686 { 687 lastTimeEditBlink=millis(); 688 blinkState=!blinkState; 689 /*Serial.print("blinkpattern= "); 690 Serial.println(blinkPattern[menuPosition]); 691 if (((blinkPattern[menuPosition]>>8)&1==1) && blinkState==true) digitalWrite(pinLowerDots, HIGH); 692 else digitalWrite(pinLowerDots, LOW); 693 if (((blinkPattern[menuPosition]>>7)&1==1) && blinkState==true) digitalWrite(pinUpperDots, HIGH); 694 else digitalWrite(pinUpperDots, LOW); 695 */ 696 if (blinkState) tmp= 0; 697 else tmp=blinkMask; 698 } 699 if (((dotPattern&~tmp)>>6)&1==1) digitalWrite(pinLowerDots, HIGH); 700 else digitalWrite(pinLowerDots, LOW); 701 if (((dotPattern&~tmp)>>7)&1==1) digitalWrite(pinUpperDots, HIGH); 702 else digitalWrite(pinUpperDots, LOW); 703 704 if ((blinkState==true) && (lowBit==1)) mask=0xFFFF;//mask=B11111111; 705 return mask; 706} 707 708int extractDigits(byte b) 709{ 710 String tmp="1"; 711 /*Serial.print("blink pattern= "); 712 Serial.println(b); 713 Serial.print("stringToDisplay= "); 714 Serial.println(stringToDisplay);*/ 715 if (b==B00000011) 716 { 717 tmp=stringToDisplay.substring(0,2); 718 /*Serial.print("stringToDisplay1= "); 719 Serial.println(stringToDisplay);*/ 720 } 721 if (b==B00001100) 722 { 723 tmp=stringToDisplay.substring(2,4); 724 /*Serial.print("stringToDisplay2= "); 725 Serial.println(stringToDisplay);*/ 726 } 727 if (b==B00110000) 728 { 729 tmp=stringToDisplay.substring(4); 730 /*Serial.print("stringToDisplay3= "); 731 Serial.println(stringToDisplay);*/ 732 } 733 /*Serial.print("stringToDisplay4= "); 734 Serial.println(stringToDisplay);*/ 735 return tmp.toInt(); 736} 737 738void injectDigits(byte b, int value) 739{ 740 if (b==B00000011) stringToDisplay=PreZero(value)+stringToDisplay.substring(2); 741 if (b==B00001100) stringToDisplay=stringToDisplay.substring(0,2)+PreZero(value)+stringToDisplay.substring(4); 742 if (b==B00110000) stringToDisplay=stringToDisplay.substring(0,4)+PreZero(value); 743} 744 745bool isValidDate() 746{ 747 int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; 748 if (value[DateYearIndex]%4==0) days[1]=29; 749 if (value[DateDayIndex]>days[value[DateMonthIndex]-1]) return false; 750 else return true; 751 752} 753 754byte default_dur = 4; 755byte default_oct = 6; 756int bpm = 63; 757int num; 758long wholenote; 759long duration; 760byte note; 761byte scale; 762char* parseSong(char *p) 763{ 764 // Absolutely no error checking in here 765 // format: d=N,o=N,b=NNN: 766 // find the start (skip name, etc) 767 768 while(*p != ':') p++; // ignore name 769 p++; // skip ':' 770 771 // get default duration 772 if(*p == 'd') 773 { 774 p++; p++; // skip "d=" 775 num = 0; 776 while(isdigit(*p)) 777 { 778 num = (num * 10) + (*p++ - '0'); 779 } 780 if(num > 0) default_dur = num; 781 p++; // skip comma 782 } 783 784 // get default octave 785 if(*p == 'o') 786 { 787 p++; p++; // skip "o=" 788 num = *p++ - '0'; 789 if(num >= 3 && num <=7) default_oct = num; 790 p++; // skip comma 791 } 792 793 // get BPM 794 if(*p == 'b') 795 { 796 p++; p++; // skip "b=" 797 num = 0; 798 while(isdigit(*p)) 799 { 800 num = (num * 10) + (*p++ - '0'); 801 } 802 bpm = num; 803 p++; // skip colon 804 } 805 806 // BPM usually expresses the number of quarter notes per minute 807 wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) 808 return p; 809} 810 811 // now begin note loop 812 static unsigned long lastTimeNotePlaying=0; 813 char* playmusic(char *p) 814 { 815 if(*p==0) 816 { 817 return p; 818 } 819 if (millis()-lastTimeNotePlaying>duration) 820 lastTimeNotePlaying=millis(); 821 else return p; 822 // first, get note duration, if available 823 num = 0; 824 while(isdigit(*p)) 825 { 826 num = (num * 10) + (*p++ - '0'); 827 } 828 829 if(num) duration = wholenote / num; 830 else duration = wholenote / default_dur; // we will need to check if we are a dotted note after 831 832 // now get the note 833 note = 0; 834 835 switch(*p) 836 { 837 case 'c': 838 note = 1; 839 break; 840 case 'd': 841 note = 3; 842 break; 843 case 'e': 844 note = 5; 845 break; 846 case 'f': 847 note = 6; 848 break; 849 case 'g': 850 note = 8; 851 break; 852 case 'a': 853 note = 10; 854 break; 855 case 'b': 856 note = 12; 857 break; 858 case 'p': 859 default: 860 note = 0; 861 } 862 p++; 863 864 // now, get optional '#' sharp 865 if(*p == '#') 866 { 867 note++; 868 p++; 869 } 870 871 // now, get optional '.' dotted note 872 if(*p == '.') 873 { 874 duration += duration/2; 875 p++; 876 } 877 878 // now, get scale 879 if(isdigit(*p)) 880 { 881 scale = *p - '0'; 882 p++; 883 } 884 else 885 { 886 scale = default_oct; 887 } 888 889 scale += OCTAVE_OFFSET; 890 891 if(*p == ',') 892 p++; // skip comma for next note (or we may be at the end) 893 894 // now play the note 895 896 if(note) 897 { 898 tone1.play(notes[(scale - 4) * 12 + note], duration); 899 if (millis()-lastTimeNotePlaying>duration) 900 lastTimeNotePlaying=millis(); 901 else return p; 902 tone1.stop(); 903 } 904 else 905 { 906 return p; 907 } 908 Serial.println(F("Incorrect Song Format!")); 909 return 0; //error 910 } 911 912 913void incrementValue() 914 { 915 enteringEditModeTime=millis(); 916 if (editMode==true) 917 { 918 if(menuPosition!=hModeValueIndex) // 12/24 hour mode menu position 919 value[menuPosition]=value[menuPosition]+1; else value[menuPosition]=value[menuPosition]+12; 920 if (value[menuPosition]>maxValue[menuPosition]) value[menuPosition]=minValue[menuPosition]; 921 if (menuPosition==Alarm01) 922 { 923 if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;//turn on all dots 924 /*else digitalWrite(pinUpperDots, LOW); */ dotPattern=B00000000; //turn off all dots 925 } 926 injectDigits(blinkMask, value[menuPosition]); 927 } 928 } 929 930void dicrementValue() 931{ 932 enteringEditModeTime=millis(); 933 if (editMode==true) 934 { 935 if (menuPosition!=hModeValueIndex) value[menuPosition]=value[menuPosition]-1; else value[menuPosition]=value[menuPosition]-12; 936 if (value[menuPosition]<minValue[menuPosition]) value[menuPosition]=maxValue[menuPosition]; 937 if (menuPosition==Alarm01) 938 { 939 if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000;//turn on upper dots �������� ������� ����� 940 else /*digitalWrite(pinUpperDots, LOW);*/ dotPattern=B00000000; //turn off upper dots 941 } 942 injectDigits(blinkMask, value[menuPosition]); 943 } 944} 945 946bool Alarm1SecondBlock=false; 947unsigned long lastTimeAlarmTriggired=0; 948void checkAlarmTime() 949{ 950 if (value[Alarm01]==0) return; 951 if ((Alarm1SecondBlock==true) && ((millis()-lastTimeAlarmTriggired)>1000)) Alarm1SecondBlock=false; 952 if (Alarm1SecondBlock==true) return; 953 if ((hour()==value[AlarmHourIndex]) && (minute()==value[AlarmMinuteIndex]) && (second()==value[AlarmSecondIndex])) 954 { 955 lastTimeAlarmTriggired=millis(); 956 Alarm1SecondBlock=true; 957 Serial.println(F("Wake up, Neo!")); 958 p=song; 959 } 960} 961 962
Downloadable files
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v2.0
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v2.0
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v1.2
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v1.2
Scheme Nixie Tubes Clock IN-12 SHIELD NCS312 v1.2
Scheme Nixie Tubes Clock IN-12 SHIELD NCS312 v1.2
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v2.0
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v2.0
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v1.2
Scheme Nixie Tubes Clock IN-14 SHIELD NCS314 v1.2
Scheme Nixie Tubes Clock IN-12 SHIELD NCS312 v1.2
Scheme Nixie Tubes Clock IN-12 SHIELD NCS312 v1.2
Comments
Only logged in users can leave comments
GRA_AND_AFCH
0 Followers
•0 Projects
Table of contents
Intro
56
0