Nixie clock

angersos
angersos аватар
Offline
Зарегистрирован: 09.06.2016

При настройке имеено часов перескок 05 часов до 12часов.

В чем проблема?

#include <EEPROM.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
 
// K155ID1 : Truth Table
//D C B A #
//L,L,L,L 0
//L,L,L,H 1
//L,L,H,L 2
//L,L,H,H 3
//L,H,L,L 4
//L,H,L,H 5
//L,H,H,L 6
//L,H,H,H 7
//H,L,L,L 8
//H,L,L,H 9
 
// K155ID1 (1)
int ledPin_0_a = 2;                
int ledPin_0_b = 3;
int ledPin_0_c = 4;
int ledPin_0_d = 5;
 
// K155ID1 (2)
int ledPin_1_a = 6;                
int ledPin_1_b = 7;
int ledPin_1_c = 8;
int ledPin_1_d = 9;
 
// anode pins
int ledPin_a_1 = 10;
int ledPin_a_2 = 11;
int ledPin_a_3 = 12;
int ledPin_a_4 = 13;
 
void setup() 
{
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()){
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled. 
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
 
  pinMode(ledPin_0_a, OUTPUT);      
  pinMode(ledPin_0_b, OUTPUT);      
  pinMode(ledPin_0_c, OUTPUT);      
  pinMode(ledPin_0_d, OUTPUT);    
   
  pinMode(ledPin_1_a, OUTPUT);      
  pinMode(ledPin_1_b, OUTPUT);      
  pinMode(ledPin_1_c, OUTPUT);      
  pinMode(ledPin_1_d, OUTPUT);      
   
  pinMode(ledPin_a_1, OUTPUT);      
  pinMode(ledPin_a_2, OUTPUT);      
  pinMode(ledPin_a_3, OUTPUT);
  pinMode(ledPin_a_4, OUTPUT);  
  
  // NOTE: All analog pins as digital inputs with pull-up resistor activated.
   
  pinMode(A0, INPUT_PULLUP); // Set (Press for > 1sec)   
  pinMode(A1, INPUT_PULLUP); // Mode switch
  pinMode(A2, INPUT_PULLUP); // Pair selection
  pinMode(A3, INPUT_PULLUP); // Increase switch
  pinMode(A6, INPUT_PULLUP); // Decrease switch
  pinMode(A7, OUTPUT);        // Alarm tone will be sent there
   
}
 
void SetSN74141Chips( int num2, int num1 )
{
  int a,b,c,d;
   
  // set defaults.
  a=0;b=0;c=0;d=0; // will display a zero.
   
  // Load the a,b,c,d.. to send to the SN74141 IC (1)
  switch( num1 )
  {
    case 0: a=0;b=0;c=0;d=0;break;
    case 1: a=1;b=0;c=0;d=0;break;
    case 2: a=0;b=1;c=0;d=0;break;
    case 3: a=1;b=1;c=0;d=0;break;
    case 4: a=0;b=0;c=1;d=0;break;
    case 5: a=1;b=0;c=1;d=0;break;
    case 6: a=0;b=1;c=1;d=0;break;
    case 7: a=1;b=1;c=1;d=0;break;
    case 8: a=0;b=0;c=0;d=1;break;
    case 9: a=1;b=0;c=0;d=1;break;
    default: a=1;b=1;c=1;d=1;
    break;
  }  
   
  // Write to output pins.
  digitalWrite(ledPin_0_d, d);
  digitalWrite(ledPin_0_c, c);
  digitalWrite(ledPin_0_b, b);
  digitalWrite(ledPin_0_a, a);
 
  // Load the a,b,c,d.. to send to the SN74141 IC (2)
  switch( num2 )
  {
    case 0: a=0;b=0;c=0;d=0;break;
    case 1: a=1;b=0;c=0;d=0;break;
    case 2: a=0;b=1;c=0;d=0;break;
    case 3: a=1;b=1;c=0;d=0;break;
    case 4: a=0;b=0;c=1;d=0;break;
    case 5: a=1;b=0;c=1;d=0;break;
    case 6: a=0;b=1;c=1;d=0;break;
    case 7: a=1;b=1;c=1;d=0;break;
    case 8: a=0;b=0;c=0;d=1;break;
    case 9: a=1;b=0;c=0;d=1;break;
    default: a=1;b=1;c=1;d=1;
    break;
  }
   
  // Write to output pins
  digitalWrite(ledPin_1_d, d);
  digitalWrite(ledPin_1_c, c);
  digitalWrite(ledPin_1_b, b);
  digitalWrite(ledPin_1_a, a);
}
 
 
float fadeMax = 5.0f;
float fadeStep = 1.0f;
int NumberArray[6]={0,0,0,0,0,0};
int currNumberArray[6]={0,0,0,0,0,0};
float NumberArrayFadeInValue[6]={0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
float NumberArrayFadeOutValue[6]={8.0f,8.0f,8.0f,8.0f,8.0f,8.0f};
 
void DisplayFadeNumberString()
{
  
  // Anode channel 1 - numerals 0,3
  SetSN74141Chips(currNumberArray[0],currNumberArray[3]);   
  digitalWrite(ledPin_a_2, HIGH);   
  delay(NumberArrayFadeOutValue[0]);
  SetSN74141Chips(NumberArray[0],NumberArray[3]);   
  delay(NumberArrayFadeInValue[0]);
  digitalWrite(ledPin_a_2, LOW);
   
  // Anode channel 2 - numerals 1,4
  SetSN74141Chips(currNumberArray[1],currNumberArray[4]);   
  digitalWrite(ledPin_a_3, HIGH);   
  delay(NumberArrayFadeOutValue[1]);
  SetSN74141Chips(NumberArray[1],NumberArray[4]);   
  delay(NumberArrayFadeInValue[1]);
  digitalWrite(ledPin_a_3, LOW);
   
   // Anode channel 3 - numerals 2,5
  SetSN74141Chips(currNumberArray[2],currNumberArray[5]);   
  digitalWrite(ledPin_a_4, HIGH);   
  delay(NumberArrayFadeOutValue[2]);
  SetSN74141Chips(NumberArray[2],NumberArray[5]);   
  delay(NumberArrayFadeInValue[2]);
  digitalWrite(ledPin_a_4, LOW);
   
  // Loop thru and update all the arrays, and fades.
  for( int i = 0 ; i < 6 ; i ++ )
  {
    if( NumberArray[i] != currNumberArray[i] )
    {
      NumberArrayFadeInValue[i] += fadeStep;
      NumberArrayFadeOutValue[i] -= fadeStep;
   
      if( NumberArrayFadeInValue[i] >= fadeMax )
      {
        NumberArrayFadeInValue[i] = 0.0f;
        NumberArrayFadeOutValue[i] = fadeMax;
        currNumberArray[i] = NumberArray[i];
      }
    }
  }  
}
//Read the EEPROM just at switch-on.
int ClockHourSet = word(EEPROM.read(1), EEPROM.read(0));  //Reconstruction the integer form the two bytes saved on the EEPROM.
int ClockMinSet = word(EEPROM.read(3), EEPROM.read(2));   
int ClockSecSet = word(EEPROM.read(5), EEPROM.read(4));   
int ClockDaySet = word(EEPROM.read(7), EEPROM.read(6));  
int ClockMonthSet = word(EEPROM.read(9), EEPROM.read(8));  
int ClockYearSet = word(EEPROM.read(11), EEPROM.read(10));
int AlmHours = word(EEPROM.read(13), EEPROM.read(12));
int AlmMins = word(EEPROM.read(15), EEPROM.read(14));
byte AlmArmed= EEPROM.read(16); // Used as flag as well as indicator on the tube themselves (0 or 1).
 
byte Mode = 1;  //1: time, 2: date, 3: alarm
byte ModeButtonPressed = false;
byte Set = 1;   //1: left, 2: middle, 3: right
long SetTimer = 0;
byte SETMODE = false;
byte SETMODEentered = false;
byte SetButtonPressed = false;
byte IncreaseButtonPressed = false;
byte DecreaseButtonPressed = false;
byte AlmButtonPressed = false;
int nixState = HIGH;
int toneState = LOW;
long previousTimeBlink = 0;
long previousTimeTone= 0;
byte AlmPlaying=false;
 
void loop(){
  // Get milliseconds.
  unsigned long runTime = millis();  
 
// MODE SELECTION ///////////////////////////////////
/////////////////////////////////////////////////////  
  byte ModeInput = digitalRead(A1);
  if(ModeInput==0)  ModeButtonPressed = true;
   
  if (Mode==1 && ModeButtonPressed==true && ModeInput==1)
  {
    Mode = 2;    //Switching from Time to Date mode
    ModeButtonPressed = false;
  }
  if (Mode==2 && ModeButtonPressed==true && ModeInput==1)
  {
    Mode = 3;    //Switching from Date to Alarm mode
    ModeButtonPressed = false;
  }
  if (Mode==3 && ModeButtonPressed==true && ModeInput==1)
  {
    Mode = 1;    //Switching from Alarm to Time mode
    ModeButtonPressed = false;
  } 
 
// ALARM ARMING /////////////////////////////////////
/////////////////////////////////////////////////////
  if(Mode==3 && AlmPlaying==false){
    int AlmInput = analogRead(A6);
    if(AlmInput==0)  AlmButtonPressed = true;
     
    if(AlmButtonPressed==true && AlmInput>250){
      if(AlmArmed==true)  AlmArmed=false;
      else  AlmArmed=true;
      AlmButtonPressed = false;
    }
  }
   
// SETTING //////////////////////////////////////////
///////////////////////////////////////////////////// 
  byte SetInput = digitalRead(A0);
  if(SetInput==0)  SetButtonPressed = true;
  while(SetInput==0){
    SetTimer++;
    delay(10);
    SetInput = digitalRead(A0);
  } 
   
  if(SetTimer>=70){
    if(SETMODE==false)  SETMODE=true;  //A long press will either enter or exit the setting mode option.
    else SETMODE=false;
  }
  SetTimer=0;  //Reinitializing.
   
  if(SETMODE==true){
    SETMODEentered=true;
    if (Set==1 && SetButtonPressed==true && SetInput==1)
    {
      Set = 2;    //Switching from left to middle pair available for setting.
      SetButtonPressed = false;
    }
    if (Set==2 && SetButtonPressed==true && SetInput==1)
    {
      Set = 3;    //Switching from middle to right pair available for setting.
      SetButtonPressed = false;
    }
    if (Set==3 && SetButtonPressed==true && SetInput==1)
    {
      Set = 1;    //Switching from right to left pair available for setting.
      SetButtonPressed = false;
    }
  
    //Now we set the selected the pair of tube, let's modify its value:
    int DecreaseInput = digitalRead(A3);  
    int IncreaseInput  = digitalRead(A2);
   
    if(DecreaseInput==0)    DecreaseButtonPressed = true;
    if(IncreaseInput==0)    IncreaseButtonPressed = true;
     
    if(DecreaseButtonPressed==true && DecreaseInput==1)
    {
      if(Set==1){
        if(Mode==1)  ClockHourSet--;
        if(Mode==2)  ClockDaySet--;
        if(Mode==3)  AlmHours--;
      }
      if(Set==2){
        if(Mode==1)  ClockMinSet--;
        if(Mode==2)  ClockMonthSet--;
        if(Mode==3)  AlmMins--;
      }
      if(Set==3){
        if(Mode==1)  ClockSecSet--;
        if(Mode==2)  ClockYearSet--;
      }
      DecreaseButtonPressed = false;
    }
    if(IncreaseButtonPressed==true && IncreaseInput==1)
    {
      if(Set==1){
        if(Mode==1)  ClockHourSet++;
        if(Mode==2)  ClockDaySet++;
        if(Mode==3)  AlmHours++;
      }
      if(Set==2){
        if(Mode==1)  ClockMinSet++;
        if(Mode==2)  ClockMonthSet++;
        if(Mode==3)  AlmMins++;
      }
      if(Set==3){
        if(Mode==1)  ClockSecSet++;
        if(Mode==2)  ClockYearSet++;
      }
      IncreaseButtonPressed = false;
    }
  }
   
  long TimeShift = ClockSecSet + 60*ClockMinSet + 3600*ClockHourSet + 86400*ClockDaySet + 2678400*ClockMonthSet + 31536000*ClockYearSet;
   
  //Saving to EEPROM after exiting the SETMODE
  if(SETMODE==false && SETMODEentered==true){
    SETMODEentered=false;
 
    byte lowCHS = lowByte(ClockHourSet);    //Split the 2-bytes integer into the respecting "high" and "low" parts in order to save them on the EEPROM.
    byte highCHS = highByte(ClockHourSet);
    byte lowCMS = lowByte(ClockMinSet);
    byte highCMS = highByte(ClockMinSet);
    byte lowCSS = lowByte(ClockSecSet);
    byte highCSS = highByte(ClockSecSet);
    byte lowCDS = lowByte(ClockDaySet);
    byte highCDS = highByte(ClockDaySet);
    byte lowCOS = lowByte(ClockMonthSet);
    byte highCOS = highByte(ClockMonthSet);
    byte lowCYS = lowByte(ClockYearSet);
    byte highCYS = highByte(ClockYearSet);
    byte lowAH = lowByte(AlmHours);
    byte highAH = highByte(AlmHours);
    byte lowAM = lowByte(AlmMins);
    byte highAM = highByte(AlmMins);
     
    EEPROM.write(0, lowCHS);  EEPROM.write(1, highCHS); //Saving
    EEPROM.write(2, lowCMS);  EEPROM.write(3, highCMS);
    EEPROM.write(4, lowCSS);  EEPROM.write(5, highCSS);
    EEPROM.write(6, lowCDS);  EEPROM.write(7, highCDS);
    EEPROM.write(8, lowCOS);  EEPROM.write(9, highCOS);
    EEPROM.write(10, lowCYS);  EEPROM.write(11, highCYS);
    EEPROM.write(12, lowAH);  EEPROM.write(13, highAH);
    EEPROM.write(14, lowAM);  EEPROM.write(15, highAM);
    EEPROM.write(16, AlmArmed);
  }
// TIME RETRIEVING //////////////////////////////////
/////////////////////////////////////////////////////
 
  DateTime now = RTC.now();
  DateTime future = (now.unixtime() + TimeShift);
 
  // Convert time to days,hours,mins,seconds
  long Year = future.year()%100;
  long Month = future.month();
  long Day = future.day();
  long hours = future.hour();
  long minutes = future.minute();
  long seconds = future.second(); 
 
  // Get the high and low order values for hours,min,seconds. 
  byte lowerHours = hours % 10;
  byte upperHours = hours - lowerHours;
  byte lowerMins = minutes % 10;
  byte upperMins = minutes - lowerMins;
  byte lowerSeconds = seconds % 10;
  byte upperSeconds = seconds - lowerSeconds;
  if( upperSeconds >= 10 )   upperSeconds = upperSeconds / 10;
  if( upperMins >= 10 )      upperMins = upperMins / 10;
  if( upperHours >= 10 )     upperHours = upperHours / 10;
 
  // Same for date. 
  byte lowerYears = Year % 10;
  byte upperYears = Year - lowerYears;
  byte lowerMonths = Month % 10;
  byte upperMonths = Month - lowerMonths;
  byte lowerDays = Day % 10;
  byte upperDays = Day - lowerDays;
  if( upperDays >= 10 ) upperDays = upperDays / 10;
  if( upperMonths >= 10 ) upperMonths = upperMonths / 10; 
  if( upperYears >= 10 ) upperYears = upperYears / 10;
 
// ALM RULES /////////////////////////////////
////////////////////////////////////////////// 
  if(AlmHours>23)  AlmHours=AlmHours-24;  //After 23:00 comes 00:00
  if(AlmHours<0)  AlmHours=AlmHours+23;   //vice-versa
  if(AlmMins>59)  AlmMins=AlmMins-60;     //same thing
  if(AlmMins<0)  AlmMins=AlmMins+59;
   
   // Splitting.    
  byte lowerAlmHours = AlmHours % 10;
  byte upperAlmHours = AlmHours - lowerAlmHours;
  byte lowerAlmMins = AlmMins % 10;
  byte upperAlmMins = AlmMins - lowerAlmMins;
  if( upperAlmMins >= 10 )      upperAlmMins = upperAlmMins / 10;
  if( upperAlmHours >= 10 )     upperAlmHours = upperAlmHours / 10;
   
  //Alm actions:
  if(AlmArmed==true){
    if(upperAlmHours==upperHours && lowerAlmHours==lowerHours && upperAlmMins==upperMins && lowerAlmMins==lowerMins && upperSeconds==0 && lowerSeconds==0){
      AlmPlaying = true;  //Alarm rings when the time matches the pre-entered alarm values.
    }
  }
   
  if(AlmPlaying==true){
    if(runTime-previousTimeTone > 500){    //Play an intermittent (1s period) tune.
      previousTimeTone = runTime;
      if(toneState == HIGH){
        tone(10, 200);                      //Tune is 200Hz.
        toneState=LOW;
      }
      else{
        noTone(10);
        toneState=HIGH;
      }
    }
    if(digitalRead(A0)==LOW || digitalRead(A1)==LOW || digitalRead(A2)==LOW || digitalRead(A3)==LOW)  AlmPlaying=false;  //Press anything to stop it.
  }
  else  noTone(10);
// SHOWTIME /////////////////////////////////////////
///////////////////////////////////////////////////// 
// Fill in the Number array used to display on the tubes following the Mode.
  if(Mode==1){
    if(SETMODE==true){
      if(Set==1){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[5] = 11;  //Turning this pair off.
            NumberArray[1] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[5] = upperHours;  //Turning this pair on again.
            NumberArray[1] = lowerHours;
            nixState = LOW;
          }
        }
        NumberArray[3] = upperMins;    //Makes sure no pair stays off even if left in that state in the previous set mode.
        NumberArray[2] = lowerMins;
        NumberArray[4] = upperSeconds;
        NumberArray[0] = lowerSeconds;
      }
      if(Set==2){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[3] = 11;
            NumberArray[2] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[3] = upperMins;
            NumberArray[2] = lowerMins;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperHours;
        NumberArray[1] = lowerHours;
        NumberArray[4] = upperSeconds;
        NumberArray[0] = lowerSeconds;
      }
      if(Set==3){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[4] = 11;
            NumberArray[0] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[4] = upperSeconds;
            NumberArray[0] = lowerSeconds;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperHours;
        NumberArray[1] = lowerHours;
        NumberArray[3] = upperMins;
        NumberArray[2] = lowerMins;
      }
    }
    else{  //Fill the digits normally.
      NumberArray[5] = upperHours;
      NumberArray[1] = lowerHours;
      NumberArray[3] = upperMins;
      NumberArray[2] = lowerMins;
      NumberArray[4] = upperSeconds;
      NumberArray[0] = lowerSeconds;
    }
 
     DisplayFadeNumberString();// Display time.
 
      if((lowerMins==5)&&upperSeconds==0&&lowerSeconds==1)//lighting all the numbers every 10min to prevent cathode poisoning.
      {
        for(int j=-1; j<11; j++){//alternating to make it more beautiful. the -1 and 11 value will turn the digits off to mark a short pause.
         NumberArray[5] = j; 
         NumberArray[1] = 9-j;
         NumberArray[3] = j;
         NumberArray[2] = 9-j;
         NumberArray[4] = j;
         NumberArray[0] = 9-j;
         int k = 0;
         while(k<10){
           DisplayFadeNumberString();// Clean each nixie digits for 2 seconds.
           k++;
           delay(1);
         }
        }
      }
      if(lowerMins==3 && upperSeconds==0 && lowerSeconds==1){ //Display date only on every (03,13,23,33) mins.
        NumberArray[5] = upperDays;
        NumberArray[1] = lowerDays;
        NumberArray[3] = upperMonths;
        NumberArray[2] = lowerMonths;
        NumberArray[4] = upperYears;
        NumberArray[0] = lowerYears;
        int k = 0;
        while(k<550){                   // Display date for 10 seconds (50 = 1sec).
            DisplayFadeNumberString(); // Display date.
            k++;
            delay(1);
        }
      }
  }
   
  if(Mode==2){
    if(SETMODE==true){
      if(Set==1){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[5] = 11;  //Turning this pair off.
            NumberArray[1] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[5] = upperDays;
            NumberArray[1] = lowerDays;
            nixState = LOW;
          }
        }
        NumberArray[3] = upperMonths;
        NumberArray[2] = lowerMonths;
        NumberArray[4] = upperYears;
        NumberArray[0] = lowerYears;
      }
      if(Set==2){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[3] = 11;
            NumberArray[2] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[3] = upperMonths;
            NumberArray[2] = lowerMonths;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperDays;
        NumberArray[1] = lowerDays;
        NumberArray[4] = upperYears;
        NumberArray[0] = lowerYears;
      }
      if(Set==3){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[4] = 11;
            NumberArray[0] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[4] = upperYears;
            NumberArray[0] = lowerYears;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperDays;
        NumberArray[1] = lowerDays;
        NumberArray[3] = upperMonths;
        NumberArray[2] = lowerMonths;
      }
    }
    else{  //Fill the digits normally.
     NumberArray[5] = upperDays;
     NumberArray[1] = lowerDays;
     NumberArray[3] = upperMonths;
     NumberArray[2] = lowerMonths;
     NumberArray[4] = upperYears;
     NumberArray[0] = lowerYears;
    }
 
     DisplayFadeNumberString();  // Display date.
  }
   
  if(Mode==3){
    if(SETMODE==true){
      if(Set==1){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[5] = 11;  //Turning this pair off.
            NumberArray[1] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[5] = upperAlmHours;
            NumberArray[1] = lowerAlmHours;
            nixState = LOW;
          }
        }
        NumberArray[3] = upperAlmMins;
        NumberArray[2] = lowerAlmMins;
        NumberArray[0] = AlmArmed;  //1: armed, 0: not armed
      }
      if(Set==2){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[3] = 11;
            NumberArray[2] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[3] = upperAlmMins;
            NumberArray[2] = lowerAlmMins;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperAlmHours;
        NumberArray[1] = lowerAlmHours;
        NumberArray[0] = AlmArmed;
      }
    if(Set==3)  Set=1;  //Dirty fix to convert a 3-cycle into a 2-cycle.
    }
    else{   //Fill the digits normally.
     NumberArray[5] = upperAlmHours;
     NumberArray[1] = lowerAlmHours;
     NumberArray[3] = upperAlmMins;
     NumberArray[2] = lowerAlmMins;
     NumberArray[0] = AlmArmed;
    }
     NumberArray[4] = 11;           //Eleven will turn off the tube
     DisplayFadeNumberString();     // Display alarm.
  }
  
}

 

vvadim
Offline
Зарегистрирован: 23.05.2012

вы суровый чел

заставляете смотреть 660 строк кода

таких героев здесь не много))))

angersos
angersos аватар
Offline
Зарегистрирован: 09.06.2016

Могу другой скинуть, там ошибка не правильно показывает дату. Только год и месец.


#include "pitches.h"
#include <EEPROM.h>
#include <Wire.h>
#include <RTClib.h>
RTC_DS1307 RTC; 

// SN74141 : Truth Table
//D C B A #
//L,L,L,L 0
//L,L,L,H 1
//L,L,H,L 2
//L,L,H,H 3
//L,H,L,L 4
//L,H,L,H 5
//L,H,H,L 6
//L,H,H,H 7
//H,L,L,L 8
//H,L,L,H 9

// SN74141 (1)
int ledPin_0_a = 2;                
int ledPin_0_b = 3;
int ledPin_0_c = 4;
int ledPin_0_d = 5;

// SN74141 (2)
int ledPin_1_a = 6;                
int ledPin_1_b = 7;
int ledPin_1_c = 8;
int ledPin_1_d = 9;

// anode pins
//int ledPin_a_1 = 10; now used for Alarm output
int ledPin_a_2 = 11;
int ledPin_a_3 = 12;
int ledPin_a_4 = 13;

// notes in the melody
int melody[] = {
  NOTE_C7, NOTE_C7, NOTE_C7, NOTE_C7, NOTE_C7 };
  
// note duration: 4 =quater note, 8 = eight note, ect.:
int noteDurations[] = {
  2, 2, 2, 2, 2 };

void setup() 
{
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()){
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  
  pinMode(ledPin_0_a, OUTPUT);      
  pinMode(ledPin_0_b, OUTPUT);      
  pinMode(ledPin_0_c, OUTPUT);      
  pinMode(ledPin_0_d, OUTPUT);    
  
  pinMode(ledPin_1_a, OUTPUT);      
  pinMode(ledPin_1_b, OUTPUT);      
  pinMode(ledPin_1_c, OUTPUT);      
  pinMode(ledPin_1_d, OUTPUT);      
   
  pinMode(ledPin_a_2, OUTPUT);      
  pinMode(ledPin_a_3, OUTPUT);
  pinMode(ledPin_a_4, OUTPUT);  
 
  // NOTE: All analog pins as digital inputs with pull-up resistor activated.
  
  pinMode(A1, INPUT_PULLUP); // Mode swicth  
  pinMode(A0, INPUT_PULLUP); // Set (Press for >3sec)
  pinMode(A6, INPUT_PULLUP); // Alarm arming
  pinMode(A3, INPUT_PULLUP); // increase
  pinMode(A2, INPUT_PULLUP); // decrease
  pinMode(10, OUTPUT);       // Alarm tone will be sent there 
  
}


void SetSN74141Chips( int num2, int num1 )
{
  int a,b,c,d;
  
  // set defaults.
  a=0;b=0;c=0;d=0; // will display a zero.
  
  // Load the a,b,c,d.. to send to the SN74141 IC (1)
  switch( num1 )
  {
    case 0: a=0;b=0;c=0;d=0;break;
    case 1: a=1;b=0;c=0;d=0;break;
    case 2: a=0;b=1;c=0;d=0;break;
    case 3: a=1;b=1;c=0;d=0;break;
    case 4: a=0;b=0;c=1;d=0;break;
    case 5: a=1;b=0;c=1;d=0;break;
    case 6: a=0;b=1;c=1;d=0;break;
    case 7: a=1;b=1;c=1;d=0;break;
    case 8: a=0;b=0;c=0;d=1;break;
    case 9: a=1;b=0;c=0;d=1;break;
    default: a=1;b=1;c=1;d=1;
    break;
  }  
  
  // Write to output pins.
  digitalWrite(ledPin_0_d, d);
  digitalWrite(ledPin_0_c, c);
  digitalWrite(ledPin_0_b, b);
  digitalWrite(ledPin_0_a, a);

  // Load the a,b,c,d.. to send to the SN74141 IC (2)
  switch( num2 )
  {
    case 0: a=0;b=0;c=0;d=0;break;
    case 1: a=1;b=0;c=0;d=0;break;
    case 2: a=0;b=1;c=0;d=0;break;
    case 3: a=1;b=1;c=0;d=0;break;
    case 4: a=0;b=0;c=1;d=0;break;
    case 5: a=1;b=0;c=1;d=0;break;
    case 6: a=0;b=1;c=1;d=0;break;
    case 7: a=1;b=1;c=1;d=0;break;
    case 8: a=0;b=0;c=0;d=1;break;
    case 9: a=1;b=0;c=0;d=1;break;
    default: a=1;b=1;c=1;d=1;
    break;
  }
  
  // Write to output pins
  digitalWrite(ledPin_1_d, d);
  digitalWrite(ledPin_1_c, c);
  digitalWrite(ledPin_1_b, b);
  digitalWrite(ledPin_1_a, a);
}


float fadeMax = 5.0f;
float fadeStep = 1.0f;
int NumberArray[6]={0,0,0,0,0,0};
int currNumberArray[6]={0,0,0,0,0,0};
float NumberArrayFadeInValue[6]={0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
float NumberArrayFadeOutValue[6]={8.0f,8.0f,8.0f,8.0f,8.0f,8.0f};


void DisplayFadeNumberString()
{
 
  // Anode channel 1 - numerals 0,3
  SetSN74141Chips(currNumberArray[0],currNumberArray[3]);   
  digitalWrite(ledPin_a_2, HIGH);   
  delay(NumberArrayFadeOutValue[0]);
  SetSN74141Chips(NumberArray[0],NumberArray[3]);   
  delay(NumberArrayFadeInValue[0]);
  digitalWrite(ledPin_a_2, LOW);
  
  // Anode channel 2 - numerals 1,4
  SetSN74141Chips(currNumberArray[1],currNumberArray[4]);   
  digitalWrite(ledPin_a_3, HIGH);   
  delay(NumberArrayFadeOutValue[1]);
  SetSN74141Chips(NumberArray[1],NumberArray[4]);   
  delay(NumberArrayFadeInValue[1]);
  digitalWrite(ledPin_a_3, LOW);
  
   // Anode channel 3 - numerals 2,5
  SetSN74141Chips(currNumberArray[2],currNumberArray[5]);   
  digitalWrite(ledPin_a_4, HIGH);   
  delay(NumberArrayFadeOutValue[2]);
  SetSN74141Chips(NumberArray[2],NumberArray[5]);   
  delay(NumberArrayFadeInValue[2]);
  digitalWrite(ledPin_a_4, LOW);
  
  // Loop thru and update all the arrays, and fades.
  for( int i = 0 ; i < 6 ; i ++ )
  {
    if( NumberArray[i] != currNumberArray[i] )
    {
      NumberArrayFadeInValue[i] += fadeStep;
      NumberArrayFadeOutValue[i] -= fadeStep;
  
      if( NumberArrayFadeInValue[i] >= fadeMax )
      {
        NumberArrayFadeInValue[i] = 0.0f;
        NumberArrayFadeOutValue[i] = fadeMax;
        currNumberArray[i] = NumberArray[i];
      }
    }
  }  
}

//Read the EEPROM just at switch-on.
int ClockHourSet = word(EEPROM.read(1), EEPROM.read(0));  //Reconstruction the integer form the two bytes saved on the EEPROM.
int ClockMinSet = word(EEPROM.read(3), EEPROM.read(2));   
int ClockSecSet = word(EEPROM.read(5), EEPROM.read(4));   
int ClockDaySet = word(EEPROM.read(7), EEPROM.read(6));  
int ClockMonthSet = word(EEPROM.read(9), EEPROM.read(8));  
int ClockYearSet = word(EEPROM.read(11), EEPROM.read(10));
int AlmHours = word(EEPROM.read(13), EEPROM.read(12));
int AlmMins = word(EEPROM.read(15), EEPROM.read(14));

byte Mode = 1;  //1: time, 2: date, 3: alarm
byte ModeButtonPressed = false;
byte Set = 1;   //1: left, 2: middle, 3: right
long SetTimer = 0;
byte SETMODE = false;
byte SETMODEentered = false;
byte SetButtonPressed = false;
byte IncreaseButtonPressed = false;
byte DecreaseButtonPressed = false;
byte AlmButtonPressed = false;
int nixState = HIGH;
int toneState = LOW;
long previousTimeBlink = 0;
long previousTimeTone= 0;
byte AlmArmed=false;  // Used as flag as well as indicator on the tube themselves (0 or 1).
byte AlmPlaying=false;

void loop(){
  // Get milliseconds.
  unsigned long runTime = millis();  

// MODE SELECTION ///////////////////////////////////
/////////////////////////////////////////////////////  
  byte ModeInput = digitalRead(A1);
  if(ModeInput==0)  ModeButtonPressed = true;
  
  if (Mode==1 && ModeButtonPressed==true && ModeInput==1)
  {
    Mode = 2;    //Switching from Time to Date mode
    ModeButtonPressed = false;
  }
  if (Mode==2 && ModeButtonPressed==true && ModeInput==1)
  {
    Mode = 3;    //Switching from Date to Alarm mode
    ModeButtonPressed = false;
  }
  if (Mode==3 && ModeButtonPressed==true && ModeInput==1)
  {
    Mode = 1;    //Switching from Alarm to Time mode
    ModeButtonPressed = false;
  }

// SETTING //////////////////////////////////////////
///////////////////////////////////////////////////// 
  byte SetInput = digitalRead(A0);
  if(SetInput==0)  SetButtonPressed = true;
  while(SetInput==0){
    SetTimer++;
    delay(10);
    SetInput = digitalRead(A0);
  } 
  
  if(SetTimer>=70){
    if(SETMODE==false)  SETMODE=true;  //A long press will either enter or exit the setting mode option.
    else SETMODE=false;
  }
  SetTimer=0;  //Reinitializing.
  
  if(SETMODE==true){
    SETMODEentered=true;
    if (Set==1 && SetButtonPressed==true && SetInput==1)
    {
      Set = 2;    //Switching from left to middle pair available for setting.
      SetButtonPressed = false;
    }
    if (Set==2 && SetButtonPressed==true && SetInput==1)
    {
      Set = 3;    //Switching from middle to right pair available for setting.
      SetButtonPressed = false;
    }
    if (Set==3 && SetButtonPressed==true && SetInput==1)
    {
      Set = 1;    //Switching from right to left pair available for setting.
      SetButtonPressed = false;
    }
 
    //Now we set the selected the pair of tube, let's modify its value:  
    int IncreaseInput = digitalRead(A3);
    int DecreaseInput = digitalRead(A2);
  
    if(DecreaseInput==0)    DecreaseButtonPressed = true;
    if(IncreaseInput==0)    IncreaseButtonPressed = true;
    
    if(DecreaseButtonPressed==true && DecreaseInput==1)
    {
      if(Set==1){
        if(Mode==1)  ClockHourSet--;
        if(Mode==2)  ClockDaySet--;
        if(Mode==3)  AlmHours--;
      }
      if(Set==2){
        if(Mode==1)  ClockMinSet--;
        if(Mode==2)  ClockMonthSet--;
        if(Mode==3)  AlmMins--;
      }
      if(Set==3){
        if(Mode==1)  ClockSecSet--;
        if(Mode==2)  ClockYearSet--;
      }
      DecreaseButtonPressed = false;
    }
    if(IncreaseButtonPressed==true && IncreaseInput==1)
    {
      if(Set==1){
        if(Mode==1)  ClockHourSet++;
        if(Mode==2)  ClockDaySet++;
        if(Mode==3)  AlmHours++;
      }
      if(Set==2){
        if(Mode==1)  ClockMinSet++;
        if(Mode==2)  ClockMonthSet++;
        if(Mode==3)  AlmMins++;
      }
      if(Set==3){
        if(Mode==1)  ClockSecSet++;
        if(Mode==2)  ClockYearSet++;
      }
      IncreaseButtonPressed = false;
    }
  }
  
  //Saving to EEPROM after exiting the SETMODE
  if(SETMODE==false && SETMODEentered==true){
    SETMODEentered=false;
    
    byte lowCHS = lowByte(ClockHourSet);    //Split the 2-bytes integer into the respecting "high" and "low" parts in order to save them on the EEPROM.
    byte highCHS = highByte(ClockHourSet);
    byte lowCMS = lowByte(ClockMinSet);
    byte highCMS = highByte(ClockMinSet);
    byte lowCSS = lowByte(ClockSecSet);
    byte highCSS = highByte(ClockSecSet);
    byte lowCDS = lowByte(ClockDaySet);
    byte highCDS = highByte(ClockDaySet);
    byte lowCOS = lowByte(ClockMonthSet);
    byte highCOS = highByte(ClockMonthSet);
    byte lowCYS = lowByte(ClockYearSet);
    byte highCYS = highByte(ClockYearSet);
    byte lowAH = lowByte(AlmHours);
    byte highAH = highByte(AlmHours);
    byte lowAM = lowByte(AlmMins);
    byte highAM = highByte(AlmMins);
    
    EEPROM.write(0, lowCHS);  EEPROM.write(1, highCHS); //Saving
    EEPROM.write(2, lowCMS);  EEPROM.write(3, highCMS);
    EEPROM.write(4, lowCSS);  EEPROM.write(5, highCSS);
    EEPROM.write(6, lowCDS);  EEPROM.write(7, highCDS);
    EEPROM.write(8, lowCOS);  EEPROM.write(9, highCOS);
    EEPROM.write(10, lowCYS);  EEPROM.write(11, highCYS);
    EEPROM.write(12, lowAH);  EEPROM.write(13, highAH);
    EEPROM.write(14, lowAM);  EEPROM.write(15, highAM);
  }
 

// ALARM ARMING /////////////////////////////////////
/////////////////////////////////////////////////////
  if(Mode==3 && AlmPlaying==false){
    int AlmInput = analogRead(A6);
    if(AlmInput==0)  AlmButtonPressed = true;
    
    if(AlmButtonPressed==true && AlmInput>250){
      if(AlmArmed==true)  AlmArmed=false;
      else  AlmArmed=true;
      AlmButtonPressed = false;
    }
  }
  
  
// TIME CALCULATION /////////////////////////////////
/////////////////////////////////////////////////////

  DateTime now = RTC.now();

  unsigned long time = now.unixtime() - 1401000000; 
  time += (long) ClockSecSet + 60* (long) ClockMinSet + 3600* (long) ClockHourSet + 86400* (long) ClockDaySet;    //time in seconds, based on offset

  // Convert time to days,hours,mins,seconds
  long days  = time / 86400;    time -= days  * 86400; 
  long hours = time / 3600;   time -= hours * 3600; 
  long minutes  = time / 60;    time -= minutes  * 60; 
  long seconds  = time; 

  // Get the high and low order values for hours,min,seconds. 
  byte lowerHours = hours % 10;
  byte upperHours = hours - lowerHours;
  byte lowerMins = minutes % 10;
  byte upperMins = minutes - lowerMins;
  byte lowerSeconds = seconds % 10;
  byte upperSeconds = seconds - lowerSeconds;
  if( upperSeconds >= 10 )   upperSeconds = upperSeconds / 10;
  if( upperMins >= 10 )      upperMins = upperMins / 10;
  if( upperHours >= 10 )     upperHours = upperHours / 10;

// DATE CALCULATION /////////////////////////////////
/////////////////////////////////////////////////////

  int Day = days;
  int Month = ClockMonthSet;
  int Year = abs(ClockYearSet%100);

    //Defining years incrementation.
  if(Month>=13){
   Year++;
   Month=Month-12;
  }
  if(Month<=0){
   Year--;
   Month=Month+12;
  }

  //Number of days in a month:
  byte February;
  if(Year%4==0) February=29;
  else February=28;
  byte MonthArray[13] = {0,31,February,31,30,31,30,31,31,30,31,30,31};  //we'll skip the first entry, so we can use the array's index directly.

  //Defining Month incrementation.
  for(byte i=1;i<13;i++){
    if(Month==i){
      if(Day>MonthArray[i]){  //If "Day" exceeds the number of days in the present month, it is resetted to 1 and we step into the next month.
        Day -= MonthArray[i];
        Month++;
      }
      if(Day<1){  //Similarly if "Day" is to become 0.
        if(i-1==0) i=13;  //Before January comes December.
        Day += MonthArray[i-1];
        Month--;
      }
    }
  }

  // Splitting date. 
  byte lowerYears = Year % 10;
  byte upperYears = Year - lowerYears;
  byte lowerMonths = Month % 10;
  byte upperMonths = Month - lowerMonths;
  byte lowerDays = Day % 10;
  byte upperDays = Day - lowerDays;
  if( upperDays >= 10 ) upperDays = upperDays / 10;
  if( upperMonths >= 10 ) upperMonths = upperMonths / 10; 
  if( upperYears >= 10 ) upperYears = upperYears / 10;

// ALM RULES /////////////////////////////////
////////////////////////////////////////////// 
  if(AlmHours>23)  AlmHours=AlmHours-24;  //After 23:00 comes 00:00
  if(AlmHours<0)  AlmHours=AlmHours+23;   //vice-versa
  if(AlmMins>59)  AlmMins=AlmMins-60;   //same thing
  if(AlmMins<0)  AlmMins=AlmMins+59;
  
   // Splitting.    
  byte lowerAlmHours = AlmHours % 10;
  byte upperAlmHours = AlmHours - lowerAlmHours;
  byte lowerAlmMins = AlmMins % 10;
  byte upperAlmMins = AlmMins - lowerAlmMins;
  if( upperAlmMins >= 10 )      upperAlmMins = upperAlmMins / 10;
  if( upperAlmHours >= 10 )     upperAlmHours = upperAlmHours / 10;
  
  //Alm actions:
  if(AlmArmed==true){
    if(upperAlmHours==upperHours && lowerAlmHours==lowerHours && upperAlmMins==upperMins && lowerAlmMins==lowerMins && upperSeconds==0 && lowerSeconds==0){
      AlmPlaying = true;  //Alarm rings when the time matches the pre-entered alarm values.
    }
  }
  
  if(AlmPlaying==true){
    if(runTime-previousTimeTone > 2000){    //Play an intermitten (1s period) tune.
      previousTimeTone = runTime;
      if(toneState == HIGH){
        for (int thisNote = 0; thisNote < 5; thisNote++) {
    int noteDuration = 1000/noteDurations[thisNote];
     tone(10, melody[thisNote], noteDuration);
      int pauseBetweenNotes = noteDuration * 1.30;
     delay(pauseBetweenNotes);
        toneState=LOW;
      }
      }
      else{
        noTone(10);
        toneState=HIGH;
      }
    }
    if(digitalRead(A0)==LOW || digitalRead(A1)==LOW || digitalRead(A2)==LOW || digitalRead(A3)==LOW)  AlmPlaying=false;  //Press anything to stop it.
  }
  else  noTone(10);
  
  
// SHOWTIME /////////////////////////////////////////
///////////////////////////////////////////////////// 
// Fill in the Number array used to display on the tubes following the Mode.
  if(Mode==1){
    if(SETMODE==true){
      if(Set==1){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[5] = 11;  //Turning this pair off.
            NumberArray[1] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[5] = upperHours;  //Turning this pair on again.
            NumberArray[1] = lowerHours;
            nixState = LOW;
          }
        }
        NumberArray[3] = upperMins;    //Makes sure no pair stays off even if left in that state in the previous set mode.
        NumberArray[2] = lowerMins;
        NumberArray[4] = upperSeconds;
        NumberArray[0] = lowerSeconds;
      }
      if(Set==2){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[3] = 11;
            NumberArray[2] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[3] = upperMins;
            NumberArray[2] = lowerMins;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperHours;
        NumberArray[1] = lowerHours;
        NumberArray[4] = upperSeconds;
        NumberArray[0] = lowerSeconds;
      }
      if(Set==3){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[4] = 11;
            NumberArray[0] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[4] = upperSeconds;
            NumberArray[0] = lowerSeconds;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperHours;
        NumberArray[1] = lowerHours;
        NumberArray[3] = upperMins;
        NumberArray[2] = lowerMins;
      }
    }
    else{  //Fill the digits normally.
      NumberArray[5] = upperHours;
      NumberArray[1] = lowerHours;
      NumberArray[3] = upperMins;
      NumberArray[2] = lowerMins;
      NumberArray[4] = upperSeconds;
      NumberArray[0] = lowerSeconds;
    }

     DisplayFadeNumberString();// Display time.

      if((lowerMins==5)&&upperSeconds==0&&lowerSeconds==1)//lighting all the numbers every 10min to prevent cathode poisining.
      {
        for(int j=-1; j<11; j++){//alternating to make it more beautiful. the -1 and 11 value will turn the digits off to mark a short pause.
         NumberArray[5] = j; 
         NumberArray[1] = 9-j;
         NumberArray[3] = j;
         NumberArray[2] = 9-j;
         NumberArray[4] = j;
         NumberArray[0] = 9-j;
         int k = 0;
         while(k<10){
           DisplayFadeNumberString();// Clean each nixie digits for 2 seconds.
           k++;
           delay(1);
         }
        }
      }
      if(lowerMins==3 && upperSeconds==0 && lowerSeconds==1){ //Display date only on every (03,13,23,33) mins.
        NumberArray[5] = upperDays;
        NumberArray[1] = lowerDays;
        NumberArray[3] = upperMonths;
        NumberArray[2] = lowerMonths;
        NumberArray[4] = upperYears;
        NumberArray[0] = lowerYears;
        int k = 0;
        while(k<550){          // Display date for 10 seconds (50 = 1sec).
          DisplayFadeNumberString(); // Display date.
          k++;
          delay(1);
        }
      }
  }
  
  if(Mode==2){
    if(SETMODE==true){
      if(Set==1){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[5] = 11;  //Turning this pair off.
            NumberArray[1] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[5] = upperDays;
            NumberArray[1] = lowerDays;
            nixState = LOW;
          }
        }
        NumberArray[3] = upperMonths;
        NumberArray[2] = lowerMonths;
        NumberArray[4] = upperYears;
        NumberArray[0] = lowerYears;
      }
      if(Set==2){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[3] = 11;
            NumberArray[2] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[3] = upperMonths;
            NumberArray[2] = lowerMonths;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperDays;
        NumberArray[1] = lowerDays;
        NumberArray[4] = upperYears;
        NumberArray[0] = lowerYears;
      }
      if(Set==3){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[4] = 11;
            NumberArray[0] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[4] = upperYears;
            NumberArray[0] = lowerYears;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperDays;
        NumberArray[1] = lowerDays;
        NumberArray[3] = upperMonths;
        NumberArray[2] = lowerMonths;
      }
    }
    else{  //Fill the digits normally.
     NumberArray[5] = upperDays;
     NumberArray[1] = lowerDays;
     NumberArray[3] = upperMonths;
     NumberArray[2] = lowerMonths;
     NumberArray[4] = upperYears;
     NumberArray[0] = lowerYears;
    }

     DisplayFadeNumberString();  // Display date.
  }
  
  if(Mode==3){
    if(SETMODE==true){
      if(Set==1){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[5] = 11;  //Turning this pair off.
            NumberArray[1] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[5] = upperAlmHours;
            NumberArray[1] = lowerAlmHours;
            nixState = LOW;
          }
        }
        NumberArray[3] = upperAlmMins;
        NumberArray[2] = lowerAlmMins;
        NumberArray[0] = AlmArmed;  //1: armed, 0: not armed
      }
      if(Set==2){
        if(runTime-previousTimeBlink > 500){  //Blinking these digits while in setmode.
          previousTimeBlink = runTime;
          if(nixState == LOW){
            NumberArray[3] = 11;
            NumberArray[2] = 11;
            nixState = HIGH;
          }
          else{
            NumberArray[3] = upperAlmMins;
            NumberArray[2] = lowerAlmMins;
            nixState = LOW;
          }
        }
        NumberArray[5] = upperAlmHours;
        NumberArray[1] = lowerAlmHours;
        NumberArray[0] = AlmArmed;
      }
    if(Set==3)  Set=1;  //Dirty fix to convert a 3-cycle into a 2-cycle.
    }
    else{ //Fill the digits normally.
     NumberArray[5] = upperAlmHours;
     NumberArray[1] = lowerAlmHours;
     NumberArray[3] = upperAlmMins;
     NumberArray[2] = lowerAlmMins;
     NumberArray[0] = AlmArmed;
    }
     NumberArray[4] = 11;     //Eleven will turn off the tube
     DisplayFadeNumberString();   // Display alarm.
  }
 
}