//-----------------------
//Stopwatch
//-----------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//---------------------------------
LiquidCrystal_I2C lcd(0x27, 20, 4);
//---------------------------------
String milliSec; boolean debounce1;
unsigned long btn1PressStart=0;
unsigned long Sec, Min, TenSec, HunSec, startMillis;
//
float minbattlevel = 3.3;                  // defining minimum voltage shown on display:
float maxbattlevel = 4.0;                  // defining maximum voltage shown on display:
//
//============================================================
// OPTION 1 - for text on line 1
byte x10[8] = {0x01, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x1F};   
byte x11[8] = {0x10, 0x18, 0x18, 0x1C, 0x1C, 0x1E, 0x1E, 0x1F};
byte x12[8] = {0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01};
byte x13[8] = {0x1F, 0x1E, 0x1E, 0x1C, 0x1C, 0x18, 0x18, 0x10};
byte x14[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F};
byte x15[8] = { 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
byte x16[8] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
byte x17[8] = {0x00,0x00,0x00,0x00,0x00,0x0E,0x0E,0x0E};

byte row = 0,col = 0;

const byte ledPin = 13;
const byte buttonPin = 2;
 
// Boolean to represent toggle state
 
volatile bool toggleState = false;
 
void checkSwitch() {
  // Check status of switch

  if(millis()-btn1PressStart > 2000) debounce1 = true;
  if(digitalRead(buttonPin) == LOW && debounce1 == true)
  {
    btn1PressStart = millis();
    debounce1 = false;
    // Switch was pressed
    // Change state of toggle
    toggleState = !toggleState;
    digitalWrite(ledPin, toggleState);
    

  }
}
//*****************************************************************************************//
//                                      Initial Setup
//*****************************************************************************************//
void setup() {

  // Set switch pin as INPUT with pullup
  pinMode(buttonPin, INPUT_PULLUP);
 
  // Attach Interrupt to Interrupt Service Routine
  attachInterrupt(digitalPinToInterrupt(buttonPin),checkSwitch, FALLING); 

    //  lcd.init();     THIS LINE CAUSES SIGNIFICANT REDUCTION IN RESOLUTION
    lcd.backlight();
    //  lcd.clear();    THIS LINE DOESNT SEEM TO CAUSE A REDUCTION IN RESOLUTION BUT IS ALSO NOT NECESSARY

    lcd.begin(20, 4);                            // setup LCD  for 20 columns and 4 rows
    lcd.createChar(0, x10);                      // #lower-rh triangle - byte 0
    lcd.createChar(1, x11);                      // #lower-lh triangle - byte 1
    lcd.createChar(2, x12);                      // #upper-rh triangle - byte 2
    lcd.createChar(3, x13);                      // #upper-lh triangle - byte 3
    lcd.createChar(4, x14);                      // #lower horiz bar - byte 4
    lcd.createChar(5, x15);                      // #upper horiz bar - byte 5
    lcd.createChar(6, x16);                      // #solid block - byte 6
    lcd.createChar(7, x17);                      // #decimal - byte 7

    row = 0;

    doNumber( 0,row,3);                          // 2 on row 5
    doNumber(11,row,6);                          // colon
    doNumber( 0,row,7);
    doNumber( 0,row,10);
    doNumber(12,row,13);                         // decimal
    doNumber( 0,row,14);
    doNumber( 0,row,17); 
 
 Serial.begin(9600);                             // initialize serial communication at 9600 bits per second:

}


//*****************************************************************************************//
//                                      MAIN LOOP
//*****************************************************************************************//
//============================================================

void loop()
{

    int sensorValue = analogRead(A1);
    float voltage = (sensorValue * (5 / 1023.0));
    Serial.println(voltage);        

if(voltage < minbattlevel)
  {
    doNumber((20),row,0);
  }
if(minbattlevel < voltage && maxbattlevel > voltage)
  {
    doNumber( ((voltage-minbattlevel) * (8/(maxbattlevel-minbattlevel))) +20 ,row,0);
  }
if(voltage > maxbattlevel)
  {
    doNumber((28),row,0);
  }

 
if(toggleState == true)
  {
    //toggleState = true; 
    stopWatch();
  }

}
//=============================================================
void stopWatch()
{

  //lcd.clear();
  startMillis = millis();
  while(1)
  {         
    if(toggleState == false)
    {
      btn1PressStart = millis();
      break;
    }
    //-------------------------------------------------
    HunSec = ((millis()-startMillis)%100)/10;
    TenSec = ((millis()-startMillis)%1000)/100;
    Sec = ((millis()-startMillis)/1000)%60;
    Min = ((millis()-startMillis)/60000)%60;
    //------------------------------------------------- 

    if(Min < 10)
    {
      doNumber( Min,row,3);
    }
    else doNumber( Min%10,row,3);

    doNumber(11,row,6);

    if(Sec < 10)
    {
      doNumber( 0,row,7); doNumber( Sec,row,10);
    }
    else doNumber(Sec/10,row,7); doNumber( Sec%10,row,10);
    
    doNumber(12,row,13);

    doNumber(TenSec,row,14); doNumber(HunSec,row,17);


    int sensorValue = analogRead(A1);
    float voltage = (sensorValue * (5 / 1023.0));
    Serial.println(voltage);        

if(voltage < minbattlevel)
  {
    doNumber((20),row,0);
  }
if(minbattlevel < voltage && maxbattlevel > voltage)
  {
    doNumber( ((voltage-minbattlevel) * (8/(maxbattlevel-minbattlevel))) +20 ,row,0);
  }
if(voltage > maxbattlevel)
  {
    doNumber((28),row,0);
  }


 }
}


//*****************************************************************************************//
// doNumber: routine to position number 'num' starting top left at row 'r', column 'c'
void doNumber(byte num, byte r, byte c) {

    lcd.setCursor(c,r);
    switch(num) {
      case 0: lcd.write(byte(0)); lcd.write(byte(6)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.print(" "); lcd.write(byte(6)); 
              lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.print(" "); lcd.write(byte(6)); 
              lcd.setCursor(c,r+3); lcd.write(byte(2)); lcd.write(byte(6)); lcd.write(byte(3)); break;
            
      case 1: lcd.write(byte(0)); lcd.write(byte(6)); lcd.print(" ");
              lcd.setCursor(c,r+1); lcd.print(" "); lcd.write(byte(6)); lcd.print(" ");
              lcd.setCursor(c,r+2); lcd.print(" "); lcd.write(byte(6)); lcd.print(" "); 
              lcd.setCursor(c,r+3); lcd.print(" "); lcd.write(byte(6)); lcd.print(" "); break;
            
      case 2: lcd.write(byte(0)); lcd.write(byte(6)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+1); lcd.write(byte(5)); lcd.write(byte(0)); lcd.write(byte(3)); 
              lcd.setCursor(c,r+2); lcd.write(byte(0)); lcd.write(byte(3)); lcd.print(" "); 
              lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); break;  
            
      case 3: lcd.write(byte(0)); lcd.write(byte(6)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+1); lcd.write(byte(5)); lcd.write(byte(4)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+2); lcd.write(byte(4)); lcd.write(byte(5)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+3); lcd.write(byte(2)); lcd.write(byte(6)); lcd.write(byte(3)); break; 
            
      case 4: lcd.write(byte(6)); lcd.print(" "); lcd.write(byte(6)); 
              lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(4)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+2); lcd.print(" "); lcd.write(byte(5)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+3); lcd.print(" "); lcd.print(" "); lcd.write(byte(6)); break;
            
      case 5: lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(4)); lcd.write(byte(4)); 
              lcd.setCursor(c,r+2); lcd.write(byte(4)); lcd.write(byte(5)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+3); lcd.write(byte(2)); lcd.write(byte(6)); lcd.write(byte(3)); break; 

      case 6: lcd.write(byte(0)); lcd.write(byte(6)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(4)); lcd.print(" "); 
              lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.write(byte(5)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+3); lcd.write(byte(2)); lcd.write(byte(6)); lcd.write(byte(3)); break;

      case 7: lcd.write(byte(6)); lcd.write(byte(6)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+1); lcd.print(" "); lcd.write(byte(0)); lcd.write(byte(3));
              lcd.setCursor(c,r+2); lcd.print(" "); lcd.write(byte(6)); lcd.print(" "); 
              lcd.setCursor(c,r+3); lcd.print(" "); lcd.write(byte(6)); lcd.print(" "); break;

      case 8: lcd.write(byte(0)); lcd.write(byte(6)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+1); lcd.write(byte(2)); lcd.write(byte(4)); lcd.write(byte(3)); 
              lcd.setCursor(c,r+2); lcd.write(byte(0)); lcd.write(byte(5)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+3); lcd.write(byte(2)); lcd.write(byte(6)); lcd.write(byte(3)); break;
   
      case 9: lcd.write(byte(0)); lcd.write(byte(6)); lcd.write(byte(1)); 
              lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(4)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+2); lcd.print(" "); lcd.write(byte(5)); lcd.write(byte(6)); 
              lcd.setCursor(c,r+3); lcd.write(byte(2)); lcd.write(byte(6)); lcd.write(byte(3)); break;

       case 11: lcd.setCursor(c,r+1); lcd.write(byte(7)); lcd.setCursor(c,r+2); lcd.write(byte(7)); break; 
       
       case 12: lcd.setCursor(c,r+3); lcd.write(byte(7)); break; 
              
       case 20:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+2); lcd.print(" "); lcd.print(" "); 
                lcd.setCursor(c,r+3); lcd.print(" "); lcd.print(" "); break;  // battery level 0/8
       
       case 21:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+2); lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+3); lcd.write(byte(4)); lcd.write(byte(4)); break;  // battery level 1/8

       case 22:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+2); lcd.print(" "); lcd.print(" "); 
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 2/8

       case 23:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+2); lcd.write(byte(4)); lcd.write(byte(4));
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 3/8

       case 24:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.write(byte(6)); 
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 4/8

       case 25:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.write(byte(4)); lcd.write(byte(4));
                lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.write(byte(6)); 
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 5/8

       case 26:                       lcd.print(" "); lcd.print(" ");
                lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 6/8

       case 27:                       lcd.write(byte(4)); lcd.write(byte(4));
                lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 7/8

       case 28:                       lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+1); lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+2); lcd.write(byte(6)); lcd.write(byte(6));
                lcd.setCursor(c,r+3); lcd.write(byte(6)); lcd.write(byte(6)); break;  // battery level 8/8

    } 
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
LCD1:GND
LCD1:VCC
LCD1:SDA
LCD1:SCL
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
pot1:GND
pot1:SIG
pot1:VCC