#define data 9
#define clock 7
#define latchPin 8
int ledPin = 10;    
int readPin = 6;
int resistorPin = 5;

byte zero  = B10101111;
byte one   = B10100000;
byte two   = B10011110;
byte three = B10111010;
byte four  = B10110001;
byte five  = B00111011;
byte six   = B00111111;
byte seven = B10100010;
byte eight = B10111111;
byte nine  = B10111011;
byte nano  = B00110100; 
byte micro = B10010101; 
byte numberList[] = {zero, one, two, three, four, five, six, seven, eight, nine};

float R = 0;                  
float C = 0;                       
long t_begin = 0;        
long t_end = 0;        
long T = 0;                      
int prevState = 0;
int multiplier = 0;
int number = 0;
int times=0;

void setup(){  
  pinMode(data, OUTPUT); 
  pinMode(clock, OUTPUT); 
  pinMode(latchPin, OUTPUT);  
  pinMode(ledPin, OUTPUT);      
  pinMode(readPin, INPUT);
  pinMode(resistorPin, INPUT);
  for (int i = 4; i >=1; i--){
    pinMode(i, OUTPUT);
  }
}
 
void loop(){
  if (digitalRead(readPin)==HIGH && prevState == 0){
    t_begin = micros();  
    t_end = 0;   
    times = 0;
    prevState=1;
    digitalWrite(ledPin, HIGH);        
    if (digitalRead(resistorPin) == HIGH){
      R=1e6; //1M Ohm
    }
    else{
      R=1e4; //10k Ohm
    }
  }  
  
  if (digitalRead(readPin)==LOW && prevState == 1){
    t_end = micros();
    prevState=0;    
    digitalWrite(ledPin, LOW);     
  }  
    
  if (t_end > 0 && times <200) //Stop the display after a few seconds with the time variable
  {
      T = t_end - t_begin;        
      C = T / (1.1 * R);   //microF 
      while (C<100){ //Remove the dot to make display algoritm easier. e.g.: 1.21 ==> 121, multiplier = 2
        C *= 10;     
        multiplier += 1;
      }
      Display(C, multiplier);   
      multiplier = 0; 
      times++;  
  }
  
}

void Display(float C, int multiplier){
  number = C; //Converts float to int
  
  //Display the number in digits
  for (int digit = 4; digit >= 1; digit --){ //Go through all 4 digits on pins 4,3,2,1
    if(C <= 1000 && digit == 4){
      if(multiplier >= 3){ //nanoFarad range
        Light(nano);
      }
      else{ //microFarad range
        Light(micro);
      }
    }
    else{
      if((digit == 3 - (multiplier %3))&& multiplier%3 !=0){ //Check if a dot needs to be displayed
        Light(number % 10, B01000000); //Gives last digit and dot
      }
      else{
        Light(number % 10, B00000000);
      }
      number /= 10; //annihilates last digit for next loop
    }
    digitalWrite(digit, HIGH); //Set the pin HIGH (enables transistor to sink current)
    delay(2);
    digitalWrite(digit, LOW); //disable the digit
  }
  
}

void Light(int digitToDisplay, byte dot){
  digitalWrite(latchPin, LOW);
  digitToDisplay = numberList[digitToDisplay] | dot; //Takes the number out of the list and adds the dot if necessary
  shiftOut(data, clock, LSBFIRST, digitToDisplay);
  digitalWrite(latchPin, HIGH);
}

void Light(byte magnitude){
  digitalWrite(latchPin, LOW);
  shiftOut(data, clock, LSBFIRST, magnitude);
  digitalWrite(latchPin, HIGH);
}
