//////////////////////////////////////////////////////////////////////////////////////
//  INITALIZATIONS
//////////////////////////////////////////////////////////////////////////////////////
#include "Ultrasonic.h"

//////////////////////////////////
//  PIN ASSIGNMENTS
//////////////////////////////////
//LEFT SIDE, TOP TO BOTTOM
//    RESET
//    IO0 = 0;    //TX PIN
//    IO1 = 1;    //RX PIN
  int IO2 = 2;
  int IO3 = 3;    //PWM PIN
  int IO4 = 4;
//    VCC 
//    GND 
//    XTAL1       //CRYSTAL PIN
//    XTAL2       //CRYSTAL PIN
  int IO5 = 5;    //PWM PIN
  int IO6 = 6;    //PWM PIN
  int IO7 = 7;
  int IO8 = 8;
//RIGHT SIDE, BOTTOM TO TOP
  int IO9 = 9;    //PWM PIN
  int IO10 = 10;  //PWM PIN
  int IO11 = 11;  //PWM PIN
  int IO12 = 12;
  int IO13 = 13;
//    AVCC 
//    AREF 
//    AGND 
  int AD0 = A0;
  int AD1 = A1;
  int AD2 = A2;
  int AD3 = A3;
  int AD4 = A4;
  int AD5 = A5; 

//////////////////////////////////}
//  INITIALIZE PINS FOR LED SHIFT REGISTER
//////////////////////////////////
int LATCH_LED = IO9;       
int CLOCK_LED = IO10;       
int DATA_LED = IO8;       

//////////////////////////////////
//  INITIALIZE PINS FOR 7-SEGMENT SHIFT REGISTER
//////////////////////////////////
int LATCH_7 = IO3;        
int CLOCK_7 = IO2;       
int DATA_7 = IO4;       
int DIG1 = IO5;     //select digit '0'0'X  (display is upside down)
int DIG2 = IO6;     //select digit '0'X'0
int DIG3 = IO7;     //select digit 'X'0'0

//////////////////////////////////
//  INITIALIZE PINS FOR ACCLEDS
//////////////////////////////////
int MODE_LED = AD0; //ACCESSORY LED 1 (FOR MODE)
int TEMP_LED = AD1; //ACCESSORY LED 2 (FOR TEMP ERROR)
int XBEE_LED = AD2; //ACCESSORY LED 3 (FOR XBEE CONNECTION)
int PROX_LED = AD3; //ACCESSORY LED 4 (FOR PROXIMITY)
//int _LED = AD4; //ACCESSORY LED 5 
//int _LED = AD5; //ACCESSORY LED 6

//////////////////////////////////
//  INITIALIZE PINS FOR SWITCH
//////////////////////////////////
int SWITCH = IO13;   //TO CONTROL OSCILLATOR POWER

//////////////////////////////////
//  INITIALIZE PINS FOR PROXIMITY SENSOR
//////////////////////////////////
int ECHO = IO11;     //RECEIVING FROM PROX SENSOR
int TRIG = IO12;     //PROC RANGING MEASUREMENT

//////////////////////////////////
//  INITIALIZE PINS FOR XBEE (NOT NECESSARY IF USING SERIAL)
//////////////////////////////////
//int TX = IO1;       //DATA TO XBEE PIN 2 (DIN)
//int RX = IO0;       //DATA FROM XBEE PIN 3 (DOUT)

//////////////////////////////////
//  OTHER INITIALIZATIONS 
//////////////////////////////////
// If comment exist, you can edit value
int i=0, j=0, k=0, t=0;
int range=0;                
int display_range=0;
int prev_range=0;
int startup_delay = 2000;   //(ms) delay time until program runs
int ledtest_delay = 20;     //(ms) delay for leds during testing
int seg_freq_time = 5;      //(ms) time between each digit display (10ms = 100Hz)
int prox_refresh_time =1000;//(ms) time it takes to display a new range value
int level1 = 75;            //(in) distance for proximity level activation
int level2 = 70;            //(in) distance for proximity level activation
int level3 = 65;            //(in) distance for proximity level activation
int level4 = 60;            //(in) distance for proximity level activation
int level5 = 55;            //(in) distance for proximity level activation
int level6 = 50;            //(in) distance for proximity level activation
int level7 = 45;            //(in) distance for proximity level activation
int level8 = 40;            //(in) distance for proximity level activation
int level9 = 30;             //(in) distance for proximity level activation
int levelmax = 80;          //(in) max distance for proximity sensor
int prox_counter=0;
int sec_counter=0;
int determination_time = 5000;//(ms) time it takes to determine if car is in correct position
boolean mode_flag=0;        
boolean prox_flag=0;
boolean prox_int_flag=0;
boolean range_int_flag=0;
boolean temp_flag=0;
boolean volt_flag=0;
int xbtemp=0;
int xbtemp_C=0;
int xbvolt=0;
int volt_tolerance = 2;     //amount of levels under 9 to begin charging again
byte xb1=0;
byte xb2=0;
int temp_high = 125;        //(F) upper temp limit for charging
int temp_low = 40;          //(F) lower temp limit for charging
int temp_tolerance = 10;    //(F) buffer temp to continue charging
int xbee_refresh_time = 500;//(ms) time it takes to realize unconnectivity
long int ptimer=0;
long int xbee_start=0;
long int xbee_stop=0;
long int prox_start=0;
long int prox_stop=0;
long int prox_timer=0;
long int range_start=0;
long int range_stop=0;
long int range_timer=0;

Ultrasonic ultrasonic(TRIG, ECHO);


//////////////////////////////////////////////////////////////////////////////////////
//  SETUP
//////////////////////////////////////////////////////////////////////////////////////
void setup() {

  Serial.begin(9600);         //set BAUD rate for XBee
  pinMode(LATCH_LED, OUTPUT);
  pinMode(CLOCK_LED, OUTPUT);
  pinMode(DATA_LED, OUTPUT);
  pinMode(LATCH_7, OUTPUT);
  pinMode(CLOCK_7, OUTPUT);
  pinMode(DATA_7, OUTPUT);
  pinMode(DIG1, OUTPUT);
  pinMode(DIG2, OUTPUT);
  pinMode(DIG3, OUTPUT);  
  pinMode(MODE_LED, OUTPUT);
  pinMode(TEMP_LED, OUTPUT); 
  pinMode(XBEE_LED, OUTPUT);
  pinMode(PROX_LED, OUTPUT);
  //pinMode(_LED, OUTPUT);
  //pinMode(_LED, OUTPUT);
  pinMode(SWITCH, OUTPUT);
  pinMode(ECHO, INPUT);   
  pinMode(TRIG, OUTPUT);
  //pinMode(TX, OUTPUT);
  //pinMode(RX, INPUT);

  digitalWrite(SWITCH, LOW);  //switch initial OFF
  digitalWrite(LATCH_7, LOW);
  digitalWrite(LATCH_LED, LOW);

  digitalWrite(A0, LOW);
  digitalWrite(A1, LOW);
  digitalWrite(A2, LOW);
  digitalWrite(A3, LOW);

  ledbartest();
}


//////////////////////////////////////////////////////////////////////////////////////
//  MAIN CODE 
//////////////////////////////////////////////////////////////////////////////////////
void loop() {

  digitalWrite(PROX_LED, LOW);
  digitalWrite(SWITCH, LOW);
  digitalWrite(TEMP_LED, LOW);

  ptimer = millis();
  ptimer = ptimer/10;

  if (mode_flag)
    enter_mode1();

  if ( fmod(floor((ptimer % 1000) / 100),2) == 0){
    selectdigit(1);
    shiftOut7(B11111011);
    latch7(0);
  }
  else{
    selectdigit(1);
    clear7(0);
  }

  enter_mode0();
}

//  MAIN CODE FOR MODE 0
void enter_mode0(){

  digitalWrite(MODE_LED, LOW);
  if ( prox_flag && prox_int_flag )
    prox_start = millis();
  if ( prox_flag ){
    prox_int_flag = 0;
    prox_check();
  } 
  else
    digitalWrite(PROX_LED, LOW);

  prev_range = display_range;
  display_range = range_level();
  
  if ( range_int_flag )
    range_start = millis();
  else
    range_check();
  /*
  Serial.print(prev_range);
  Serial.print("\t");
  Serial.print(display_range);
  Serial.print("\t");
  Serial.print(range);
  Serial.print("\t");
  Serial.print(range_start);
  Serial.print("\t");
  Serial.print(range_stop);
  Serial.print("\t");
  Serial.println(range_timer);
  */
  
  if ( xbee_check() ){
    display_prox( display_range );
  }
  else
    clearled(0);
    
}

//  MAIN CODE FOR MODE 1
void enter_mode1(){

  digitalWrite(MODE_LED, HIGH);
  digitalWrite(PROX_LED, HIGH);
  selectdigit(3);
  clear7(0);
  selectdigit(2);
  clear7(0);
  selectdigit(1);
  clear7(0);
  clearled(0);

  while( mode_flag ){

    ptimer = millis();
    ptimer = ptimer/10;

    if ( fmod(floor((ptimer % 1000) / 100),2) == 0){
      xbee_read();
      //HOW TO BREAK MODE

      prev_range = display_range;
      display_range = range_level();
      
      if ( range_int_flag )
        range_start = millis();
      else
        range_check();
      if ( display_range != 8 ){
        mode_flag = 0;
        break;
      }

      if ( !(xbee_check()) ){
        mode_flag = 0;
        break;
      }
    }
    
    if (xbvolt < 9)
      if (volt_flag){
        digitalWrite(SWITCH, LOW);
        if (xbee_temp_check()){
          temp_flag = 1;
          display_xbee(-1, xbtemp);
          digitalWrite(TEMP_LED, HIGH);
        }
        else{
          temp_flag = 0;
          display_xbee(xbvolt, xbtemp);
          digitalWrite(TEMP_LED, LOW);
        } 
        if (xbvolt <= 9-volt_tolerance)
          volt_flag = 0;     
      }
      else{
        if (xbee_temp_check()){
          temp_flag = 1;
          display_xbee(-1, xbtemp);
          digitalWrite(TEMP_LED, HIGH);
          digitalWrite(SWITCH, LOW);
        }
        else{
          temp_flag = 0;
          display_xbee(xbvolt, xbtemp);
          digitalWrite(TEMP_LED, LOW);
          digitalWrite(SWITCH, HIGH);
        }
      }
    else{
      volt_flag = 1;
      display_xbee(xbvolt, xbtemp);
      digitalWrite(SWITCH, LOW);
      if (xbee_temp_check()){
        temp_flag = 1;
        digitalWrite(TEMP_LED, HIGH);
      }
      else{
        temp_flag = 0;
        digitalWrite(TEMP_LED, LOW);
      }
    }
  }
  digitalWrite(PROX_LED, LOW);
  digitalWrite(SWITCH, LOW);
  digitalWrite(MODE_LED, LOW);
  selectdigit(3);
  clear7(0);
  selectdigit(2);
  clear7(0);
  selectdigit(1);
  clear7(0);
  clearled(0);
}


//////////////////////////////////////////////////////////////////////////////////////
//  IMPORTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////

//  TESTS THE LED BAR DISPLAY ON STARTUP
//  NO INPUTS
int ledbartest(){

  //green
  for(j=0; j<2; j++){
    shiftOutLED(B00000010);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00001000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00100000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B10000000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00000010);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00001000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00100000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B10000000);
    latchled(ledtest_delay);

    shiftOutLED(B00000000);
    shiftOutLED(B00100000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00001000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00000010);
    latchled(ledtest_delay);
    shiftOutLED(B10000000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00100000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00001000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00000010);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);

    //red
    shiftOutLED(B00000001);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00000100);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00010000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B01000000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00000001);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00000100);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00010000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B01000000);
    latchled(ledtest_delay);

    shiftOutLED(B00000000);
    shiftOutLED(B00010000);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00000100);
    latchled(ledtest_delay);
    shiftOutLED(B00000000);
    shiftOutLED(B00000001);
    latchled(ledtest_delay);
    shiftOutLED(B01000000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00010000);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00000100);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
    shiftOutLED(B00000001);
    shiftOutLED(B00000000);
    latchled(ledtest_delay);
  }

  //up-down
  shiftOutLED(B00000001);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000010);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000100);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00001000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00010000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00100000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B01000000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B10000000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00000001);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00000010);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00000100);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00001000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00010000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00100000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B01000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B10000000);
  latchled(ledtest_delay);

  shiftOutLED(B00000000);
  shiftOutLED(B01000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00100000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00010000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00001000);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00000100);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00000010);
  latchled(ledtest_delay);
  shiftOutLED(B00000000);
  shiftOutLED(B00000001);
  latchled(ledtest_delay);
  shiftOutLED(B10000000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B01000000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00100000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00010000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00001000);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000100);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000010);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);
  shiftOutLED(B00000001);
  shiftOutLED(B00000000);
  latchled(ledtest_delay);

  //blink
  for (i=0; i<3; i++){
    shiftOutLED(B01010101);
    shiftOutLED(B01010101);
    latchled(ledtest_delay*10);
    shiftOutLED(B10101010);
    shiftOutLED(B10101010);
    latchled(ledtest_delay*10);
  }

  //solid
  shiftOutLED(B11111111);
  shiftOutLED(B11111111);
  latchled(startup_delay);
}

/*
//  TESTS THE OTHER LED DISPLAYS
//  NO INPUTS
int led7test(){

  //7segment
  for ()
  selectdigit(1);
  shiftOut7(B11111011);
  latch7(ledtest_delay*5);
  selectdigit(2);
  shiftOut7(B11111011);
  latch7(ledtest_delay*5);
  selectdigit(3);
  shiftOut7(B11111011);
  latch7(ledtest_delay*5);
}
*/

//  DETERMINES IF XBEES ARE COMMUNICATING
//  NO INPUTS, RETURNS 1 FOR CONNECTION, 0 FOR DISCONNECTION
int xbee_check(){

  if (Serial.available() == 0)
    xbee_stop = millis();
  else
    xbee_start = millis();

  while (Serial.available() > 0)
    Serial.read();

  if (xbee_stop - xbee_start > xbee_refresh_time){
    digitalWrite(XBEE_LED, LOW);
    return 0;
  }
  else{
    digitalWrite(XBEE_LED, HIGH);
    return 1;
  }

  /*
  if ( Serial.available() > 0 )
    xbee_counter = 0;
  else
    xbee_counter++;

  if (xbee_counter < xbee_refresh_time){
    digitalWrite(XBEE_LED, HIGH);
    return 1;
  }
  else if (xbee_counter >= xbee_refresh_time){
    xbee_counter = xbee_refresh_time;
    digitalWrite(XBEE_LED, LOW); 
    return 0;
  }
  */
}

//  CHECKS TO SEE IF RANGE HAS CHANGED
//  NO INPUTS
int range_check(){

  range_stop = millis();
  
  range_timer = range_stop - range_start;

  if (range_timer > prox_refresh_time){
    prev_range=0;
    display_range=0;
  }
}

//  DETERMINES RANGE LEVEL
//  NO INPUTS, OUTPUTS LEVEL FOR DISPLAY
int range_level(){

  range = ultrasonic.Ranging(0);
  range_int_flag=1;

  if (range < level9)
    return 9;
  else if (range < level8)
    return 8;
  else if (range < level7)
    return 7;
  else if (range < level6)
    return 6;
  else if (range < level5)
    return 5;
  else if (range < level4)
    return 4;
  else if (range < level3)
    return 3;
  else if (range < level2)
    return 2;
  else if (range < level1)
    return 1;
  else if (range >= level1 && range < 90)
    return 0;
  else{
    range_int_flag=0;
    return prev_range;
  }
}

//  CHECK TO SEE IF BATTERY TEMPERATURE IS IN SAFE RANGE
//  NO INPUTS, OUTPUTS 1 (fail) OR 0 (pass)
int xbee_temp_check(){

  //xbee_read();
  if (temp_flag){
    if (xbtemp > temp_high-temp_tolerance || xbtemp < temp_low+temp_tolerance)
      return 1;
    else
      return 0; 
  }
  else{
    if (xbtemp > temp_high || xbtemp < temp_low)
      return 1;
    else
      return 0; 
  }
}

//  READS XBTEMP AND XBVOLT FROM XBEE
//  NO INPUTS
void xbee_read(){

  if (Serial.available() > 0){
    
    xb1 = Serial.read(); 
    xb2 = Serial.read();

    if (xb1 >= 30 && xb2 < 30){
      xbtemp = xb1;
      xbvolt = xb2;
    }
    else if (xb2 >= 30 && xb1 < 30){
      xbtemp = xb2;
      xbvolt = xb1;
    }
  }
}

//  DISPLAYS XBEE TEMPERATURE AND VOLTAGE
//  INPUTS = XBVOLT, XBTEMP
void display_xbee(int xbvolt, int xbtemp){

  display_xbtemp(xbtemp);

  switch(xbvolt){
    case 0:             //Reserved for very low (red blink)
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B00000000);
        shiftOutLED(B10000000);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B00000000);
        latchled(0);
      }
      break;
    case 1:             //0-1
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B00000000);
        shiftOutLED(B00000000);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B01000000);
        latchled(0);
      }
      break;
    case 2:             //1-2
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B00000000);
        shiftOutLED(B01010000);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B01000000);
        latchled(0);
      }
      break;
    case 3:             //2-3
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B00000000);
        shiftOutLED(B01010100);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B01010000);
        latchled(0);
      }
      break;
    case 4:             //3-4
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B00000000);
        shiftOutLED(B01010101);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B01010100);
        latchled(0);
      }
      break;
    case 5:             //4-5
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B01000000);
        shiftOutLED(B01010101);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B01010101);
        latchled(0);
      }
      break;
    case 6:             //5-6
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B01010000);
        shiftOutLED(B01010101);
        latchled(0);
      }
      else{
        shiftOutLED(B01000000);
        shiftOutLED(B01010101);
        latchled(0);
      }
      break;      
    case 7:             //6-7
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B01010100);
        shiftOutLED(B01010101);
        latchled(0);
      }
      else{
        shiftOutLED(B01010000);
        shiftOutLED(B01010101);
        latchled(0);
      }
      break;      
    case 8:             //7-8
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B01010101);
        shiftOutLED(B01010101);
        latchled(0);
      }
      else{
        shiftOutLED(B01010100);
        shiftOutLED(B01010101);
        latchled(0);
      }
      break;  
    case 9:             //Fully charged
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B01010101);
        shiftOutLED(B01010101);
        latchled(0);
      }
      else{
        shiftOutLED(B01010101);
        shiftOutLED(B01010101);
        latchled(0);
      }
      break;
    default:            //Error
      if ( (ptimer/50) % 2 == 0){
        shiftOutLED(B10101010);
        shiftOutLED(B10101010);
        latchled(0);
      }
      else{
        shiftOutLED(B00000000);
        shiftOutLED(B00000000);
        latchled(0);
      }
      break;
  }
}

//  DISPLAYS XBTEMP TO 7SEGMENT
//  INPUT = XBTEMP
void display_xbtemp(int xbtemp){

  if (xbtemp > 210 || xbtemp < 30){      //210F == 99C
    selectdigit(1);
    delay(seg_freq_time);  
    clear7(0);
    selectdigit(2);
    delay(seg_freq_time);  
    clear7(0);
    selectdigit(3);
    delay(seg_freq_time);  
    clear7(0);
  }
  else if (xbtemp > 99){
    xbtemp_C = (xbtemp - 32) * 5/9;
    selectdigit(3);
    displaydegree( 'C' );
    delay(seg_freq_time);  
    clear7(0);           
    selectdigit(2);
    displaynumber( xbtemp_C % 10 );
    delay(seg_freq_time);          
    clear7(0);   
    selectdigit(1);
    displaynumber( floor((xbtemp_C % 100)/10) );
    delay(seg_freq_time);    
    clear7(0);     
  }
  else if (xbtemp >= 30){
    selectdigit(3);
    displaydegree( 'F' );
    delay(seg_freq_time);
    clear7(0);             
    selectdigit(2);
    displaynumber( xbtemp % 10 );
    delay(seg_freq_time);     
    clear7(0);
    selectdigit(1);
    displaynumber( floor((xbtemp % 100)/10) );
    delay(seg_freq_time);     
    clear7(0);        
  }
}

//  DISPLAYS LEVEL OF FILL FOR PROXIMITY
//  INPUTS = LEVEL 0-9 (9 overflow)
void display_prox(int fill){

  switch(fill){
    case 0:
      shiftOutLED(B00000000);
      shiftOutLED(B00000000);
      latchled(0);
      prox_int_flag=1;
      break;
    case 1:
      shiftOutLED(B00000000);
      shiftOutLED(B01000000);
      latchled(0);
      prox_int_flag=1;
      break;
    case 2:
      shiftOutLED(B00000000);
      shiftOutLED(B01010000);
      latchled(0);
      prox_int_flag=1;
      break;
    case 3:
      shiftOutLED(B00000000);
      shiftOutLED(B01010100);
      latchled(0);
      prox_int_flag=1;
      break;
    case 4:
      shiftOutLED(B00000000);
      shiftOutLED(B01010101);
      latchled(0);
      prox_int_flag=1;
      break;
    case 5:
      shiftOutLED(B01000000);
      shiftOutLED(B01010101);
      latchled(0);
      prox_int_flag=1;
      break;
    case 6:
      shiftOutLED(B01010000);
      shiftOutLED(B01010101);
      latchled(0);
      prox_int_flag=1;
      break;
    case 7:
      if ( (ptimer/10) % 2 == 0){
        shiftOutLED(B01000100);
        shiftOutLED(B01000100);
        latchled(0);
      }
      else{
        shiftOutLED(B00010000);
        shiftOutLED(B00010001);
        latchled(0);
      }
      prox_int_flag=1;
      break;
    case 8:
      if ( (ptimer/10) % 2 == 0){
        shiftOutLED(B01000110);
        shiftOutLED(B01000100);
        latchled(0);
      }
      else{
        shiftOutLED(B00010011);
        shiftOutLED(B00010001);
        latchled(0);
      }
      prox_flag=1;
      break;
    case 9:
      if ( (ptimer/10) % 2 == 0){
        shiftOutLED(B10001000);
        shiftOutLED(B10001000);
        latchled(0);
      }
      else{
        shiftOutLED(B00100010);
        shiftOutLED(B00100010);
        latchled(0);
      }
      prox_int_flag=1;
      break;
    default:                    
      shiftOutLED(B00000000);
      shiftOutLED(B00000000);
      latchled(0);
      prox_int_flag=1;
      break;
  }
}

//  MAKES SURE CAR IS IN CORRECT POSITION
//  NO INPUTS
void prox_check(){

  digitalWrite(PROX_LED, HIGH);

  prox_stop = millis();
  
  if ( display_range != 8 )
    prox_flag=0;
  
  prox_timer = prox_stop - prox_start;

  if (prox_timer > determination_time)
    mode_flag = 1;
  else
    mode_flag = 0;

  selectdigit(3);
  displaynumber( floor((prox_timer % 10000) / 1000) );
  delay(seg_freq_time);  
  clear7(0);      
  selectdigit(2);
  if ( floor((prox_timer % 100000) / 10000) == 0 )
    clear7(0);
  else
    displaynumber( floor((prox_timer % 100000) / 10000) );
  delay(seg_freq_time);  
  clear7(0);    
  selectdigit(1);
  clear7(0);    
}

//  SELECTS WHICH DIGIT TO DISPLAY
//  INPUTS = 1-3 (ONLY 3 7-SEGMENT DISPLAYS)
void selectdigit(int digit){
 
  switch (digit){
    case 1:
      digitalWrite(DIG1, HIGH);
      digitalWrite(DIG2, LOW);
      digitalWrite(DIG3, LOW);
      break;
    case 2:
      digitalWrite(DIG1, LOW);
      digitalWrite(DIG2, HIGH);
      digitalWrite(DIG3, LOW);
      break;
    case 3:  
      digitalWrite(DIG1, LOW);
      digitalWrite(DIG2, LOW);
      digitalWrite(DIG3, HIGH);
      break;
  }  
}

//  DISPLAYS NUMBER WITH DECIMAL ON TO A DIGIT
//  INPUTS = 0-9, -1 for "-"
void displaynumberdot(int num){

  switch(num){
    case 0:
      shiftOut7(B10000000);
      latch7(0);
      break;
    case 1:
      shiftOut7(B11011010);
      latch7(0);
      break;
    case 2:
      shiftOut7(B00101000);
      latch7(0);
      break;
    case 3:
      shiftOut7(B01001000);
      latch7(0);
      break;
    case 4:
      shiftOut7(B01010010);
      latch7(0);
      break;
    case 5:
      shiftOut7(B01000001);
      latch7(0);
      break;
    case 6:
      shiftOut7(B00000001);
      latch7(0);
      break;
    case 7:
      shiftOut7(B11011000);
      latch7(0);
      break;
    case 8:
      shiftOut7(B00000000);
      latch7(0);
      break;
    case 9:
      shiftOut7(B01000000);
      latch7(0);
      break;
    case -1:  //shows a "-"
      shiftOut7(B01111011);
      latch7(0);
      break;
    default:  //defaults to 3 lines w/ dot for error spotting
      shiftOut7(B01101001);
      latch7(0);
      break;
  }
}

//  DISPLAYS NUMBER TO A DIGIT
//  INPUTS = 0-9, -1 for "-" 
void displaynumber(int num){

  switch(num){
    case 0:
      shiftOut7(B10000100);
      latch7(0);
      break;
    case 1:
      shiftOut7(B11011110);
      latch7(0);
      break;
    case 2:
      shiftOut7(B00101100);
      latch7(0);
      break;
    case 3:
      shiftOut7(B01001100);
      latch7(0);
      break;
    case 4:
      shiftOut7(B01010110);
      latch7(0);
      break;
    case 5:
      shiftOut7(B01000101);
      latch7(0);
      break;
    case 6:
      shiftOut7(B00000101);
      latch7(0);
      break;
    case 7:
      shiftOut7(B11011100);
      latch7(0);
      break;
    case 8:
      shiftOut7(B00000100);
      latch7(0);
      break;
    case 9:
      shiftOut7(B01000100);
      latch7(0);
      break;
    case -1:  //shows a "-"
      shiftOut7(B01111111);
      latch7(0);
      break;
    default:  //defaults to 3 lines for error spotting
      shiftOut7(B01101101);
      latch7(0);
      break;
  }
}

//  DISPLAYS DEGREE TO A DIGIT (MEANT FOR '0'0'X)
//  INPUTS = 'C' OR 'F'
void displaydegree(char letter){

  switch(letter){
    case 'C':
      shiftOut7(B10100001);
      latch7(0);
      break;
    case 'F':
      shiftOut7(B00110001);
      latch7(0);
      break;
    default:  //defaults to 2 lines for error spotting
      shiftOut7(B11101110);
      latch7(0);
      break;
  }
}

//  WRITES DATA TO 7-SEGMENT SHIFT REGISTERS
//  INPUTS = BINARY TO TURN ON EACH SEGMENT B[g][b][f][a][c][DP][d][e]
void shiftOut7(byte dataOut){
  
  boolean STATE;   
  
  digitalWrite(DATA_7, LOW);      //clear shift register 
  digitalWrite(CLOCK_7, LOW);
  
  for (i=0; i<8; i++){
    digitalWrite(CLOCK_7, LOW); 

    if ( dataOut & (1<<i) ) 
        STATE = HIGH;
    else 
        STATE = LOW;

    digitalWrite(DATA_7, STATE);
    digitalWrite(CLOCK_7, HIGH);
  }
  digitalWrite(CLOCK_7, LOW);     //stop shifting out data
}

//  WRITES DATA TO LED SHIFT REGISTERS
//  INPUTS = BINARY TO TURN ON EACH LED B[1G][1R][2G][2R][3G][3R][4G][4R] (WRITTEN TWICE)
void shiftOutLED(byte dataOut){
  
  boolean STATE;   
  
  digitalWrite(DATA_LED, LOW);    //clear shift register 
  digitalWrite(CLOCK_LED, LOW);
  
  for (int i=0; i<8; i++){
    digitalWrite(CLOCK_LED, LOW); 

    if ( dataOut & (1<<i) ) 
        STATE = HIGH;
    else 
        STATE = LOW;
  
    digitalWrite(DATA_LED, STATE);
    digitalWrite(CLOCK_LED, HIGH);
  }
  digitalWrite(CLOCK_LED, LOW);   //stop shifting out data
}

//  ACTIVATES 7 SEGMENT SHIFT REGISTER TO SHOW CURRENT DATA
//  INPUT = DELAY IN MS
void latch7(int time){

  digitalWrite(LATCH_7, HIGH);
  digitalWrite(LATCH_7, LOW);
  delay(time);
}

//  ACTIVATES LED SHIFT REGISTER TO SHOW CURRENT DATA
//  INPUT = DELAY IN MS
void latchled(int time){

  digitalWrite(LATCH_LED, HIGH);
  digitalWrite(LATCH_LED, LOW);
  delay(time);
}

//  CLEARS 7 SEGMENT SHIFT REGISTER
//  INPUT = DELAY IN MS
void clear7(int time){

  shiftOut7(B11111111);
  latch7(time);
}

//  CLEARS LED SHIFT REGISTER
//  INPUT = DELAY IN MS
void clearled(int time){

  shiftOutLED(B00000000);
  shiftOutLED(B00000000);
  latchled(time);
}