#include <SD.h>

//Author: cantone-electonics
//More information welcome to : http://www.canton-electronics.com 
//Arduino 1.6.
//for Arduino pro mini
//4 bit Common Cathode Digital Tube Module test code,use Timer2

/*---Segment Display Screen----
--A--
F---B
--G--
E---C
--D-- 
 __  __   __  __
|__||__|.|__||__|
|__||__|'|__||__|
----------------------*/   
#include <FlexiTimer2.h>
#define uchar unsigned char 
#define uint  unsigned int

int display_dat; 
int key_value;

//Pin connected to latch of Digital Tube Module
int latchPin = A2;
//Pin connected to clock of Digital Tube Module
int clockPin = A3;
//Pin connected to data of Digital Tube Module
int dataPin = 13;
//Pin connected to 595_OE of Digital Tube Module
int OE_595 = A1;

const int K1 = 7;
const int K2 = 8;
const int K3 = 9;
const int K4 = 10;

const int INPUT1 = 2;
const int INPUT2 = 3;
const int INPUT3 = 4;
const int INPUT4 = 5;
const int INPUT5 = 6;
const int INPUT6 = A0;
const int INPUT7 = 12;
const int INPUT8 = 11;


int relay1_delay_time = 1;//1-9999 seconds,Modify the number change the delay time
int relay2_delay_time = 2;//1-9999 seconds,Modify the number change the delay time
int relay3_delay_time = 3;//1-9999 seconds,Modify the number change the delay time
int relay4_delay_time = 4;//1-9999 seconds,Modify the number change the delay time
int relay5_delay_time = 5;//1-9999 seconds,Modify the number change the delay time
int relay6_delay_time = 6;//1-9999 seconds,Modify the number change the delay time
int relay7_delay_time = 7;//1-9999 seconds,Modify the number change the delay time
int relay8_delay_time = 8;//1-9999 seconds,Modify the number change the delay time

int relay1_time_left;
int relay2_time_left;
int relay3_time_left;
int relay4_time_left;
int relay5_time_left;
int relay6_time_left;
int relay7_time_left;
int relay8_time_left;

int relay1_display;
int relay2_display;
int relay3_display;
int relay4_display;
int relay5_display;
int relay6_display;
int relay7_display;
int relay8_display;


/*       NO.:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 23 24 25 26 27 28      
/*Character :0,1,2,3,4,5,6,7,8,9,A, b, C, c, d, E, F, H, h, L, n, N, o, P, r, t, U, -,  ,*/
uchar  TUBE_SEG[] = 
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa7,0xa1,0x86,0x8e,0x89,0x8b,0xc7,0xab,0xc8,0xa3,0x8c,0xaf,0x87,0xc1,0xbf,0xff};//Common anode Digital Tube Character Gallery

uchar TUBE_NUM[8]={0xfe,0xff,0xfd,0xff,0xfb,0xff,0xf7,0xff,};//Tuble bit number

uchar dat_buf[8];

//***********************************************
// dat : Data to be displayed
// com_num :  Digital Tube Common 
//relay_port : Relay port
//***********************************************
uchar dat;
uchar com_num;
uchar relay_port;
void TubeDisplayOneBit()
{
  uchar tube_dat,bit_num;
  uchar display_l,display_h,relay_dat;
   
   tube_dat = TUBE_SEG[dat]; //Common Cathode Digital Tube,bit negated
   bit_num = ~TUBE_NUM[com_num];
   
   display_l  = ((tube_dat & 0x10)>>3);  //Q4   <-D1 -3
   display_l |= ((bit_num & 0x01)<<2);   //DIGI0<-D2 +2
   display_l |= ((tube_dat & 0x08)>>0);  //Q3   <-D3 0
   display_l |= ((tube_dat & 0x01)<<4);  //Q0   <-D4 -4
   display_l |= ((tube_dat & 0x80)>>2);  //Q7   <-D5 -2
   display_l |= ((tube_dat & 0x20)<<1);  //Q5   <-D6 1
   display_l |= ((tube_dat & 0x04)<<5);  //Q2   <-D7 5
	
   display_h  = ((bit_num & 0x02)>>0);   //DIGI1<-D1 0
   display_h |= ((bit_num & 0x04)>>0);   //DIGI2<-D2 0
   display_h |= ((tube_dat  & 0x40)>>3); //Q6   <-D3 -3
   display_h |= ((tube_dat  & 0x02)<<3); //Q1   <-D4 3
   display_h |= ((bit_num & 0x08)<<2);  //DIGI3<-D5 2

   relay_dat = ((relay_port & 0x7f)<<1); 
   relay_dat = relay_dat | ((relay_port & 0x80)>>7);
   
     //ground latchPin and hold low for as long as you are transmitting
     digitalWrite(latchPin, LOW);  
     
     shiftOut(dataPin, clockPin, MSBFIRST, display_h);
     shiftOut(dataPin, clockPin, MSBFIRST, display_l);  
     shiftOut(dataPin, clockPin, MSBFIRST, relay_dat); 
     
     //return the latch pin high to signal chip that it 
     //no longer needs to listen for information
     digitalWrite(latchPin, HIGH);

}




uint OneSecondCnt=500;
void TubeDisplay4Bit(void)
{
  if(com_num<7) com_num ++;else com_num=0;
  dat = dat_buf[com_num];
  TubeDisplayOneBit();

  OneSecondCnt--;
  if(OneSecondCnt==0)
  {
    OneSecondCnt = 500;
    if(relay1_time_left>0){relay1_time_left--; relay1_display = relay1_time_left;} else {bitClear(relay_port,0);relay1_display = relay1_delay_time;}
    if(relay2_time_left>0){relay2_time_left--; relay2_display = relay2_time_left;} else {bitClear(relay_port,1);relay2_display = relay2_delay_time;}
    if(relay3_time_left>0){relay3_time_left--; relay3_display = relay3_time_left;} else {bitClear(relay_port,2);relay3_display = relay3_delay_time;}
    if(relay4_time_left>0){relay4_time_left--; relay4_display = relay4_time_left;} else {bitClear(relay_port,3);relay4_display = relay4_delay_time;}
    if(relay5_time_left>0){relay5_time_left--; relay5_display = relay5_time_left;} else {bitClear(relay_port,4);relay5_display = relay5_delay_time;}
    if(relay6_time_left>0){relay6_time_left--; relay6_display = relay6_time_left;} else {bitClear(relay_port,5);relay6_display = relay6_delay_time;}
    if(relay7_time_left>0){relay7_time_left--; relay7_display = relay7_time_left;} else {bitClear(relay_port,6);relay7_display = relay7_delay_time;}
    if(relay8_time_left>0){relay8_time_left--; relay8_display = relay8_time_left;} else {bitClear(relay_port,7);relay8_display = relay8_delay_time;}
   
  }

 
  if(key_value==0) display_dat = relay1_display; 
  else if(key_value==1) display_dat = relay2_display;
  else if(key_value==2) display_dat = relay3_display;  
  else if(key_value==3) display_dat = relay4_display;

   /*
  if(key_value==0) display_dat = relay5_display; 
  else if(key_value==1) display_dat = relay6_display;
  else if(key_value==2) display_dat = relay7_display;  
  else if(key_value==3) display_dat = relay8_display;
    */
    
   dat_buf[0] = display_dat/1000;
   display_dat = display_dat%1000;
   dat_buf[2] = display_dat/100;
   display_dat = display_dat%100;
   dat_buf[4] = display_dat/10;
   dat_buf[6] = display_dat%10;
  
}

void setup() {
   //set pins to output because they are addressed in the main loop
   
   
   pinMode(latchPin, OUTPUT);
   pinMode(clockPin, OUTPUT);
   pinMode(dataPin, OUTPUT);
   pinMode(OE_595, OUTPUT);
   
   pinMode(K1, INPUT);
   pinMode(K2, INPUT);
   pinMode(K3, INPUT);
   pinMode(K4, INPUT);
   
   pinMode(INPUT1, INPUT);
   pinMode(INPUT2, INPUT);
   pinMode(INPUT3, INPUT);
   pinMode(INPUT4, INPUT);
   pinMode(INPUT5, INPUT);
   pinMode(INPUT6, INPUT);
   pinMode(INPUT7, INPUT);
   pinMode(INPUT8, INPUT);
 
   
  FlexiTimer2::set(2, 1.0/1000, TubeDisplay4Bit); // call every 2ms "ticks"
  FlexiTimer2::start();
  
  digitalWrite(OE_595, LOW);// Enable 74HC595  

  digitalWrite(INPUT1, HIGH);
  digitalWrite(INPUT2, HIGH);
  digitalWrite(INPUT3, HIGH);
  digitalWrite(INPUT4, HIGH);
  digitalWrite(INPUT5, HIGH);
  digitalWrite(INPUT6, HIGH);
  digitalWrite(INPUT7, HIGH);
  digitalWrite(INPUT8, HIGH);
  
  
  digitalWrite(K1, HIGH);
  digitalWrite(K2, HIGH);
  digitalWrite(K3, HIGH);
  digitalWrite(K4, HIGH);
  
  key_value = 0;
}

void loop() {

  
  while(1)
  {

    if(digitalRead(INPUT1)==LOW) {relay1_time_left = relay1_delay_time;bitSet(relay_port,0);}

    if(digitalRead(INPUT2)==LOW) {relay2_time_left = relay2_delay_time;bitSet(relay_port,1);}

    if(digitalRead(INPUT3)==LOW) {relay3_time_left = relay3_delay_time;bitSet(relay_port,2);}

    if(digitalRead(INPUT4)==LOW) {relay4_time_left = relay4_delay_time;bitSet(relay_port,3);}
    
    if(digitalRead(INPUT5)==LOW) {relay5_time_left = relay5_delay_time;bitSet(relay_port,4);}
    
    if(digitalRead(INPUT6)==LOW) {relay6_time_left = relay6_delay_time;bitSet(relay_port,5);}
    
    if(digitalRead(INPUT7)==LOW) {relay7_time_left = relay7_delay_time;bitSet(relay_port,6);}
    
    if(digitalRead(INPUT8)==LOW) {relay8_time_left = relay8_delay_time;bitSet(relay_port,7);}
    
    if     (digitalRead(K1)==LOW) {key_value = 0; } 
    else if(digitalRead(K2)==LOW) {key_value = 1; } 
    else if(digitalRead(K3)==LOW) {key_value = 2; } 
    else if(digitalRead(K4)==LOW) {key_value = 3; } 

      
  }
} 


