[Progress 003] Closed Circuit Password Keeper

I decided to optimize the coding for the project but I give up just now! The huge problem is that the code I coded a year ago was to long and is about over a thousand lines! I may decide to recode this from scratch but steal some out of the this code because not all the lines are bad some are very useful (Now where to start hmm). This program is written in Arduino IDE

for more details about this project >> http://davidsblog.life/projects/closed-circuit-password-keeper/

If you’d like to see my longest coding in something look at this below! This code is very messy & long, be warned!!! 😛

[code language=”cpp”]
// First Edited: December 13, 2013
// Redo Edit: December 28, 2013 (Compared December 27 & 24, 2013)
// Last Edited: January 25, 2014 // FIRST GENERATION
// Last Edited: Novemeber 15, 2014 // SECOND GENERATION
/********************************************************************
*                      LOGIN LOGGER DEVICE                          *
*********************************************************************/
#include <DogLcd.h>
#include <Wire.h>
#include "RTClib.h"
#include <EEPROM.h>
#include <Arduino.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h> // December 23, 2013

DogLcd LCD(2, 3, 4, 5);
RTC_DS1307 RTC1;
unsigned long Millis;

///////////////////// Print Optimization /////////////////////  December 23, 2013
// http://forum.arduino.cc/index.php/topic,45245.0.html
#define fp(string) flashprint(PSTR(string), false);
#define fpln(string) flashprint(PSTR(string), true);

#define fplcd(string) flashprintlcd(PSTR(string), false);
#define fplcdln(string) flashprintlcd(PSTR(string), true);

// SERIAL CONST FLASH PRINT
void flashprint(const char p[], boolean NextRow) {
  digitalWrite(13, HIGH);
  byte c;
  while (0!=(c= pgm_read_byte(p++))) {Serial.write(c);}
  if (NextRow) {Serial.write("\n");}
  digitalWrite(13, LOW);
}
// LCD CONST FLASH PRINT
void flashprintlcd(const char p[], boolean NextRow) {
  digitalWrite(13, HIGH);
  byte c;
  while (0!=(c= pgm_read_byte(p++))) {LCD.write(c);}
  if (NextRow) {LCD.write("\n");}
  digitalWrite(13, LOW);
}
// SERIAL DYNAMIC PRINT
void print(String Word, boolean NextRow) {
  digitalWrite(13, HIGH);
  Serial.print(Word);
  if (NextRow) {Serial.write("\n");}
  digitalWrite(13, LOW);
}
// LCD DYNAMIC PRINT
void printlcd(String Word, boolean NextRow) {
  digitalWrite(13, HIGH);
  LCD.print(Word);
  if (NextRow) {LCD.write("\n");}
  digitalWrite(13, LOW);
}
// SERIAL DYNAMIC NUMBER PRINT
void print(int Number, boolean NextRow) {
  digitalWrite(13, HIGH);
  Serial.print(Number);
  if (NextRow) {Serial.write("\n");}
  digitalWrite(13, LOW);
}

//////////////////////////////// SETUP //////////////////
String inputString= "";

void setup() {
  Serial.begin(9600);
  Wire.begin();
  RTC1.begin();
  LCD.begin(DOG_LCD_M163);
  inputString.reserve(200);
  print(TimeStampMake(), true);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  fpln("PinMode 13 Set Output!  ");
  pinMode(6, OUTPUT);
  fpln("PinMode 6 Set Output!  ");
  for(int PullUp= 14; PullUp<=17; PullUp++) {
    fp("PinMode ");
    print(String(PullUp), false);
    fpln(" Set Input Pullup!  ");
    pinMode(PullUp, INPUT_PULLUP);
  }
  // Tell what devices are connected
  // http://forum.arduino.cc/index.php/topic,158103.0.html
  for(int Connect= 0; Connect<=120; Connect++) {
    Wire.beginTransmission(Connect);
    if (Wire.endTransmission()==0) {
      fp("Found Device: ");
      print(Connect, false);
      fp(" (0x");
      print(String(Connect, HEX), false);
      fpln(")");
    }
  }
 
  TimeStamp(1);
  wdt_enable(WDTO_4S); // WATCHDOG SETUP 8 Seconds
  fpln("Watchdog Enabled 4 Seconds!!");
  DisplayLight(1);
  LCDInterface(0);
  TimeStamp(1);
  fpln("Hiding LCD Cursor!");
  LCD.noCursor();
  TimeStamp(1);
  fpln("Ready!");
 
}

////////////////////////////// LCD Interface ///////////////////////////
// Made on December 24, 2013
// Optimized in November 15, 2014 (Saved 1K Bytes)
void LCDInterface(int Func) {
  //Start Mode
  ////////////////////////////////////////////// First Row ///////////////////////////////////////////
  LCD.setCursor(0, 0);
  switch (Func) {
    case 0:
      TimeStamp(2);
    break;
    //Surf Help Menu
    case 1:
      TimeStamp(2);
    break;
    // Option Menu
    case 2:
      fplcd("Option Menu     ");
    break;
    // Memory Option Menu
    case 3:
      fplcd("Memory Menu     ");
    break;
    // Memory Option Edit Menu
    case 4:
      fplcd("Memory Edit Menu");
    break;
    // Clock Option Menu
    case 5:
      fplcd("Clock Menu      ");
    break;
    // Add Log Operation
    case 6:
      fplcd("A)Back B)Ok     ");
    break;
    // Deleting a file message // and Used to Ask to reset CLock
    case 7:
      fplcd("Delete File #");
      int Sum= InternalEEPROM(0);
      printlcd(String(Sum), false);
      if (Sum<100) {fplcd(" ");}
    break;
  }
 
  ////////////////////////////////////////////// Second Row ///////////////////////////////////////////
  LCD.setCursor(0, 1);
  switch (Func) {
    case 0:
      fplcd(" ");
      printlcd(String(short((InternalEEPROM(0)/511.00)*100.00)), false);
      fplcd("% Used          ");
    break;
    //Surf Help Menu
    case 1:
      fplcd("A)Open B)Menu   ");
    break;
    // Option Menu
    case 2:
      fplcd("A)Menu B)Memory ");
    break;
    // Memory Option Menu
    case 3:
      fplcd("A)Back B)Edit   ");
    break;
    // Memory Option Edit Menu
    case 4:
      fplcd("A)Back B)Edit");
      printlcd(String(InternalEEPROM(0)), false);
    break;
    // Clock Option Menu
    case 5:
      fplcd("A)Back B)Reset  ");
    break;
    // Add Log Operation
    case 6:
      fplcd("—–Input——");
    break;
    // Deleting a file message // and Used to Ask to reset CLock
    case 7:
      fplcd("Are you sure?   ");
    break;
    // Default
    default:
      fplcd("Error: "); // Should Not appear on screen if Select Area is not empty
      fplcd("No Select Menu Seen");
    break;
  }
 
  ////////////////////////////////////////////// Third Row ///////////////////////////////////////////
  LCD.setCursor(0, 2);
  switch (Func) {
    case 0:
      fplcd("A=Ok C=Option   ");
    break;
    //Surf Help Menu
    case 1:
      fplcd("C)Next D)Back   ");
    break;
    // Option Menu
    case 2:
      fplcd("C)AddLog D)Clock");
    break;
    // Memory Option Menu
    case 3:
      fplcd("C)Delete #[");
      printlcd(String(InternalEEPROM(0)), false);
      fplcd("]");
    break;
    // Memory Option Edit Menu
    case 4:
      fplcd("C)Edit Used Size");
    break;
    // Clock Option Menu
    case 5:
      fplcd("C)Change        ");
    break;
    // Add Log Operation
    case 6:
      fplcd("________________");
    break;
    // Deleting a file message // and Used to Ask to reset CLock
    case 7:
      fplcd("A)Confirm B)Deny");
    break;
  }
}

/////////////////////////////// BUTTON INTERFACE //////////////////////////// DECEMBER 24, 2013
// Aka EVENT CODE
int MenuType;
unsigned long LastMillis;
void ButtonInterface(int Button, boolean Awake) {
  static int Limit;
  static int Sweep;
  int MenuInside= 0;
  if (Button==1&!MenuType) { // Select Surf Menu
    LCDInterface(1);
    TimeStamp(1);
    fpln("Selected Surf Menu!");
    MenuType= 1;
    Limit= InternalEEPROM(0);
    Sweep= Limit;
    return;
  }
  if (Button==3&!MenuType) { // Select Option Menu
    TimeStamp(1);
    fpln("Selected Option Menu!");
    LCDInterface(2);
    MenuType= 2;
    return;
  }
  if ((Button==2|Button==4)&!MenuType) { // Blank Selection
    LCDInterface(0);
    return;
  }
  static boolean Busy;
  String RawData;
  if (!Awake) {
    MenuType = 0;
    Busy= false;
  }
  // Racist if statement… Need to be forced too do stuff
  if ((MenuType|MenuType==2|MenuType==4|MenuType==6)&Busy) {MenuInside= Button;} ////////// Busy Enables InsideMenu [Bugger (MenuType==2)]
  else {LastMillis= Millis;} // Updates LastMillis if not Busy
  switch (MenuType) {
    //////////////////////////////////// Break
    case 1: ////////////////////////////////////////////////////////////////////// Surf Menu (1) December 24, 2013
    static boolean SweepChange;
    static boolean Perms;
    if (!Busy) {
      LCD.setCursor(0, 0);
      TimeStamp(2);
      delay(3000);
      SweepChange= true;
      Busy= true;
    }
    switch (MenuInside) {
      case 1: // Opens File (A)
      if (!Perms) {
        TimeStamp(1);
        fpln("Opening File!");
        RawData= ExternalEEPROM(0, Sweep, "");
        LCD.setCursor(0, 0);
        printlcd(RawData.substring(0,16), false); // Date&Time
        LCD.setCursor(0, 1);
        printlcd(RawData.substring(32,48), false); // User
        LCD.setCursor(0, 2);
        printlcd(RawData.substring(48,60), false); // Password
        Perms= true;
      }
      else {
        Perms= false;
        SweepChange= true;
      }
      break;
      case 2: // Back To Menu (B)
      TimeStamp(1);
      fpln("Back to Menu!");
      Busy= false;
      LCDInterface(0);
      MenuType= 0;
      break;
      case 3: // Foward Surf (C)
      if (!Perms) { // If File is open , turns into Back Button for Open File
        TimeStamp(1);
        if (Limit>Sweep) {Sweep++;}
        fp("Forward Surfing #");
        print(Sweep, true);
        SweepChange= true;
      }
      else {
        Perms= false;
        SweepChange= true;
      }
      break;
      case 4: // Back Surf (D)
      if (!Perms) { // If File is open , turns into Back Button for Open File
        TimeStamp(1);
        if (Sweep) {Sweep–;}
        fp("Back Surfing #");
        print(Sweep, true);
        SweepChange= true;
      }
      else {
        Perms= false;
        SweepChange= true;
      }
      break;  
    }
    if (SweepChange) {
      LCD.clear();
      TimeStamp(1);
      fp("Sweep Number at ");
      print(Sweep, true);
      LCD.setCursor(0, 2);
      int Boundaries= round(Limit/3); // Divides into 3.. Lowest..Middle…Highest
      char temp[1];
      if(!Sweep|Sweep>=Limit) {printlcd(String(char(18)), false);} // ↕  Boarder Line
      else if (Sweep<=Boundaries) {printlcd(String(char(95)), false);} // _ Lowest
      else if(Sweep<=Boundaries*2) {printlcd(String(char(176)), false);} // – Middle
      else if(Sweep<=Boundaries*3+3) {printlcd(String(char(255)), false);} // _ Highest
      printlcd(String(Sweep), false);
      fplcd("/511 Slot(s)");
      RawData= ExternalEEPROM(0, Sweep, "");
      LCD.setCursor(0, 0);
      printlcd(RawData.substring(0,16), false); // Date&Time
      LCD.setCursor(0, 1);
      printlcd(RawData.substring(16,32), false); // Title
      SweepChange= false;
    }
    break;
    /////////////////////////////////// Break
    case 2: ///////////////////////////////////////////////////////// Option Menu (2) December 25&28, 2013
    MenuTitle("Option Menu");
    Busy= true;
    switch (MenuInside) {
      case 1: // Back to Menu (A)
      TimeStamp(1);
      fpln("Back to Menu!");
      Busy= false;
      LCDInterface(0);
      MenuType= 0;
      break;
      case 2: // Memory (B)
      TimeStamp(1);
      fpln("To Memory Menu!");
      Busy= false;
      LCDInterface(3);
      MenuType= 3;
      break;
      case 4: // Clock (D)
      TimeStamp(1);
      fpln("To Clock Menu!");
      Busy= false;
      LCDInterface(5);
      MenuType= 5;
      break;
      case 3: // Add Log (C)
      if (InternalEEPROM(0)<=512) { // Prevents Overceeding 512
        TimeStamp(1);
        fpln("Going to Add Log!");
        Busy= false;
        LCDInterface(6);
        MenuType= 6;
      }
      else { // IF EXCEEDS 512 CANNOT ADD ANYMORE ERROR
        TimeStamp(1);
        fpln("Cannot addlog anymore!");
        LCDInterface(2);
      }
      break;
    }
    break;
    /////////////////////////////////// Break
    case 3: /////////////////////////////////////////////////////////////// Memory Menu (3) December 26, 2013
    if (Perms) {MenuInside= 3;}
    else {
      MenuTitle("Memory Menu");
    }
    Busy= true;
    switch (MenuInside) {
      case 1: // Back to Option (A)
      TimeStamp(1);
      fpln("Back to Option Menu!");
      Busy= false;
      LCDInterface(2);
      MenuType= 2;
      break;
      case 2: // Goto Memory Option Edit (B)
      TimeStamp(1);
      fpln("Going to Memory Edit Option!");
      Busy= false;
      LCDInterface(4);
      MenuType= 4;
      break;
      case 3: // Deleting a File (C)
      if (!Perms) { // First Message
        TimeStamp(1);
        fp("Asking to Delete #");
        print(Limit, true);
        fp(" Memory!");
        LCDInterface(7);
        Perms= true;
      }
      else if (Button==1) { // Confirm
        TimeStamp(1);
        fpln("Confirmed to Delete!");
        LCDInterface(3);
        LCD.setCursor(0, 0);
        fplcd("Success Deleted!");
        Perms= false;
        delay(2000);
      }
      else if (Button==2) { // Deny
        TimeStamp(1);
        fp("Denied to Delete!");
        LCDInterface(3);
        LCD.setCursor(0, 0);
        fplcd("Denied Deleting!");
        Perms= false;
        delay(2000);
      }
      else if (Button) {LCDInterface(7);} // Anything else
      
      break;
      case 4: // Nothing (D)
      LCDInterface(3);
      break;
    }
    break;
    //////////////////////////////////////// Break
    case 4: /////////////////////////////////////////////////////////// Memory Option Edit Menu 4
    MenuTitle("Memory Edit Menu");
    Busy= true;
    switch (MenuInside) {
      case 1: // Back to Memory Menu (A)
      TimeStamp(1);
      fpln("Back to Memory Menu!");
      Busy= false;
      LCDInterface(3);
      MenuType= 3;
      break;
      case 2: // Edit (B)
      TimeStamp(1);
      fpln("Going Editing Memory");
      break;
      case 3: // Edit Used Size (C)
      TimeStamp(1);
      fpln("Entering Edit Used Size");
      MenuType= 8;
      break;
      case 4: // Nothing (D)
      LCDInterface(4);
      break;
    }
    break;
    //////////////////////////////////////// Break
    case 5: ///////////////////////////////////////////////////////////////// Clock Option Menu 5
    if (Perms) {MenuInside= 2;}
    else {
      MenuTitle("Clock Menu");
    }
    Busy= true;
    switch (MenuInside) {
      case 1: // Back To Option Menu (A)
      TimeStamp(1);
      fpln("Back to Option Menu!");
      Busy= false;
      LCDInterface(2);
      MenuType= 2;
      break;
      case 2: // Reset Clock (B)
      if (!Perms) { // Tells user to confirm
        TimeStamp(1);
        fpln("Asking to Reset the clock!");
        LCDInterface(7);
        LCD.setCursor(0, 0);
        fplcd("Reset the Clock");
        Perms= true;
      }
      else if (Button==1) { // Confirm
        TimeStamp(1);
        fpln("Confirmed to reset Clock!");
        Clock(0);
        Perms= false;
        LCDInterface(5);
        LCD.setCursor(0, 0);
        fplcd("Successful Reset");
        delay(2000);
      }
      else if (Button==2) { // Deny
        TimeStamp(1);
        fpln("Denied to reset CLock!");
        Perms= false;
        LCDInterface(5);
        LCD.setCursor(0, 0);
        fplcd("Denied Reset");
        delay(2000);
      }
      else if (Button) { // if anything
        LCDInterface(7);
        LCD.setCursor(0, 0);
        fplcd("Reset the Clock");
      }
      
      break;
      case 3:
      TimeStamp(1);
      fpln("Going to edit Time");
      Busy= false;
      MenuType= 7;
      break;
      case 4:
      LCDInterface(5);
      break;
      
    }
    break;
    //////////////////////////////////////// Break
    static int Letter;
    static int Part;
    case 8: ////////////////////////////////////////////////////////////////////// Editing Used Size (8) December 4, 2014
    if (Part==0) {
      Letter= InternalEEPROM(0);
      Part= 1;
    }
    else if (Part==1) {
      LCD.setCursor(0, 0);
      fplcd("Size of Memory");
      LCD.setCursor(0, 1);
      printlcd(String(Letter), false);
      LCD.setCursor(0, 2);
      fplcd("A)Ok B)Cancel");
      
      if (Button==3&Letter<512) { // UP
        Letter++;
        TimeStamp(1);
        fp("Increasing: ");
        print(String(Letter), true);
      }
      if(Button==4&Letter>0) { // DOWN
        Letter–;
        TimeStamp(1);
        fp("Decreasing: ");
        print(String(Letter), true);
      }
      
      if(Button==1) {// Okay
        TimeStamp(1);
        fpln("Asking Permission to set Memory Used Size!");
        Part= 2;
        LCDInterface(7);
        LCD.setCursor(0, 0);
        fplcd("Size:  ");
        printlcd(String(Letter), false);
        fplcd("<<<");
      }
      if(Button==2) { // Cancel
        TimeStamp(1);
        fpln("Back to Edit Memory Menu!");
        Part= 0;
        Letter= 0;
        LCDInterface(4);
        MenuType= 4;
      }
      
    }
    else if (Part==2) {
      
      if (Button==1) { // Confirm
        TimeStamp(1);
        fp("Confirmed to set used memory to ");
        print(String(Letter), true);
        if (InternalEEPROM(0)>Letter) {InternalEEPROM(2);} // If Lower it will rewrite from 0
        for(int Scan= InternalEEPROM(0); Scan<Letter; Scan++) { // Scan to that Number set
          LCD.setCursor(0, 0);
          fplcd("Writting Data…");
          LCD.setCursor(0, 1);
          printlcd(String(Scan), false);
          fplcd("/");
          printlcd(String(Letter), false);
          InternalEEPROM(1);
          wdt_reset();
        }
        Part= 0;
        Letter= 0;
        LCDInterface(4);
        MenuType= 4;
        LCD.setCursor(0, 0);
        fplcd("Success Edit!   ");
      }
      else if (Button==2) { // Cancel
        TimeStamp(1);
        fpln("Cancel to set used memory");
        Part= 0;
        Letter= 0;
        LCDInterface(4);
        MenuType= 4;
        LCD.setCursor(0, 0);
        fplcd("Cancel Edit!    ");
      }
      else if(Button) { // Any Button nothing
        LCDInterface(7);
        LCD.setCursor(0, 0);
        fplcd("Size: ");
        printlcd(String(Letter), false);
        fplcd("<<<");
        
      }
      
    }
    
    break;
    /////////////////////////////////////// Break
    static String Wording;
    case 7: ////////////////////////////////////////////////////////////////////// Editing Clock (7) December 1, 2014
    static int EditedTime[6];
    int MinLetter, MaxLetter;
    LCD.setCursor(0, 0);
    fplcd("A)Back B)Okay");
    //if (EditType==0) { // TIME
      LCD.setCursor(0, 1);
      fplcd("   Adjust Time  ");
      LCD.setCursor(0,2);
      if (Part==0) { // Month
        fplcd("Month:");
        MinLetter= 1;
        MaxLetter= 12;
      }
      else if (Part==1) { // Day
        fplcd("Day:");
        MinLetter= 1;
        MaxLetter= 31;
      }
      else if (Part==2) { // Year
        fplcd("Year:");
        MinLetter= 2010;
        MaxLetter= 3000;
      }
      else if (Part==3) { // Hour
        fplcd("Hour:");
        MinLetter= 0;
        MaxLetter= 23;
      }
      else if (Part==4) { // Minute
        fplcd("Minute:");
        MinLetter= 0;
        MaxLetter= 59;
      }
      else if (Part==5) { // Second
        fplcd("Second:");
        MinLetter= 0;
        MaxLetter= 59;
      }
      else if (Part==6) {
        LCD.setCursor(0, 0);
        fplcd("A)Set B)Canel");
        LCD.setCursor(0, 1);
        printlcd(String(EditedTime[0]), false); // Month
        fplcd("/");
        printlcd(String(EditedTime[1]), false); // Day
        fplcd("/");
        printlcd(String(EditedTime[2]), false); // Year
        LCD.setCursor(0, 2);
        printlcd(String(EditedTime[3]), false); // Hour
        fplcd(":");
        printlcd(String(EditedTime[4]), false); // Minute
        fplcd(":");
        printlcd(String(EditedTime[5]), false); // Second
        
        if (Button==1) {
          RTC1.adjust(DateTime(EditedTime[2],EditedTime[0],EditedTime[1],EditedTime[3],EditedTime[4],EditedTime[5]));
          LCDInterface(5);
          LCD.setCursor(0, 0);
          fplcd("Set Clock!");
          Part= 0;
          MenuType= 5;
          delay(2000);
        }
        if (Button==2) {
          LCDInterface(5);
          LCD.setCursor(0, 0);
          fplcd("Cancel Clock!");
          Part= 0;
          MenuType= 5;
          delay(2000);
        }
      }
      
      
      if (Part<=5) {
        if (Button==2) {
          if (Part==0) {EditedTime[0]= Letter;}
          else if (Part==1) {EditedTime[1]= Letter;}
          else if (Part==2) {EditedTime[2]= Letter;}
          else if (Part==3) {EditedTime[3]= Letter;}
          else if (Part==4) {EditedTime[4]= Letter;}
          else if (Part==5) {EditedTime[5]= Letter;}
          Part++;
          Letter= MinLetter;
        }
        else if (Button==1) {
          Part–;
          if (Part==0) {Letter= EditedTime[0];}
          else if (Part==1) {Letter= EditedTime[1];}
          else if (Part==2) {Letter= EditedTime[2];}
          else if (Part==3) {Letter= EditedTime[3];}
          else if (Part==4) {Letter= EditedTime[4];}
          else if (Part==5) {Letter= EditedTime[5];}
        }
        if (Part==0&Button==1) {
          Letter= 0;
          EditedTime[0];
          LCDInterface(5);
          MenuType= 5;
        }
        else {
          if (Button==3) {Letter++; if(Letter>MaxLetter){Letter= MinLetter;}}
          if (Button==4) {Letter–; if(Letter<MinLetter){Letter= MaxLetter;}}
          LCD.setCursor(9, 2);
          printlcd(String(Letter), false);
        }
        
      }
      
    //}
    
    break;
    //////////////////////////////////////// Break
    static int Ok;
    static String Title, Username, Password;
    static boolean OnePush;
    case 6: ///////////////////////////////////////////////////////////////////// Add Log Control (6) December 25, 2013
    Busy= true; // Set Busy Line
    // If Under Part 2 Do these
    if (Part<=2) {
      if (MenuInside==1) { // Back (A)
        if (!Ok&!Part) {
          TimeStamp(1);
          fpln("Back to Option Menu!");
          Busy= false;
          Letter= 0;
          LCDInterface(2);
          MenuType= 2;
          return;
        }
        else {
          LCDInterface(6);
          // Probably Another Racist if Statement!
          if (!Ok) {
            Part–;
            if (Part==0) {Wording= Title;}
            if (Part==1) {Wording= Username;}
            if (Part==2) {Wording= Password;}
            if (Part==2) {Ok=11;} else{Ok= 15;}
            TimeStamp(1);
            fp("Part(");
            print(Part, false);
            fp(") Digit(");
            print(Ok, false);
            fpln(")");
          } else {Ok–, Letter= 0;}
          Letter= Wording.charAt(Ok); // goes to that last letter
          Wording= Wording.substring(0, Ok);
          LCD.setCursor(0, 2);
          printlcd(Wording, false);
          TimeStamp(1);
          fp("Digit(");
          print(Ok, false);
          fp(") Data(‘");
          print(Wording, false);
          fpln("’)");
        }
      }
      if (!Letter) {Letter= 32;} // Sets it to 32 aka Blank
      if (MenuInside==3) { // /////////////////////Increment (C)
        if (Letter>=127) {Letter= 32;}
        Letter++;
      }
      else if (MenuInside==4) { ///////////////// Decreasement (D)
        if (Letter<=32) {Letter= 127;}
        Letter–;
      }
      // Meh another racist if statement
      if (Part<=2&(Button|Button==4)&Button!=1) { // APpears THe Text
        LCDInterface(6);
        LCD.setCursor(Ok, 2);
        printlcd(String(char(Letter)), false);
        TimeStamp(1);
        fp("Letter(");
        print(Letter, false);
        fp(") Char(‘");
        print(String(char(Letter)), false);
        fpln("’)");
      }
      if (MenuInside==2) { //////////////////////// Move on (B)
        Ok++;
        Wording+= char(int(Letter));
        TimeStamp(1);
        fp("Digit(");
        print(Ok, false);
        fp(") Data(‘");
        print(Wording, false);
        fpln("’)");
        Letter= 0;
        LCDInterface(6);
      }
      if (((Ok>=16&Part!=2)|(Ok>=12&Part==2))&Button!=1) { // If Exceeds 16 Saves Data and moves next Part
        TimeStamp(1);
        fp("Part(");
        print(Part, false);  
        fp(") Data(‘");
        print(Wording, false);
        fpln("’)");
        if (Part==0) {Title= Wording;}
        if (Part==1) {Username= Wording;}
        if (Part==2) {Password= Wording;}
        Wording= "";
        Ok= 0;
        Part++;
      }
      
      if (Wording=="#") {// Generate The Radom Password with code when called ‘#’
        Wording= CreatePassword(8);
        Ok= 8;
      }
      
       //////////////////////////////////////// PARTS
      else if (Part==0) { /// TITLE INPUT
        LCD.setCursor(0, 1);
        fplcd("Name the Title: ");
      }
      else if (Part==1) {  /// USERNAME INPUT
        LCD.setCursor(0, 1);
        fplcd("Username:       ");
      }
      else if (Part==2) { //// PASSWORD INPUT
        LCD.setCursor(0, 1);
        fplcd("’#’Genr/Passwrd:");
        LCD.setCursor(12, 2);
        fplcd("    ");
      }
      LCD.setCursor(0, 2);
      printlcd(Wording, false);
    }
    else if (Part==3) { /////////////////// ACCEPTING THE SAVE INPUT
      LCD.setCursor(0, 0);
      TimeStamp(2);
      if (!OnePush|MenuInside==2|MenuInside==4) {
        fp("Title: ");
        print(Title, true);
        fp("Username: ");
        print(Username, true);
        fp("Password: ");
        print(Password, true);
        TimeStamp(1);
        fpln("Asking for permission to save data!");
        LCD.setCursor(0, 1);
        fplcd("Save it?        ");
        LCD.setCursor(0, 2);
        fplcd("A)Accept C)Deny ");
        OnePush= true;
      }
      else if (MenuInside==1) { // ACCEPT (A)
        TimeStamp(1);
        fpln("Accepted Save Data!");
        OnePush= false;
        Part= 4;
      }
      else if (MenuInside==3) { // DENY (C)
        TimeStamp(1);
        fpln("Denied Saved Data!");
        Part= 5;
      }
    }
    else if (Part==4) {  ////////////////////////// SAVING to EEPROM!
      
      if (!OnePush) {
        TimeStamp(1);
        fpln("Adding Data to EEPROM!!!!!");
        TimeStamp(1);
        fpln("SAVING DATA!")
        LCD.setCursor(0, 1);
        fplcd("Inner EPROM: ");
        
        // Manually Adjusted Fragile
        String Data= TimeStampMake(); // Put together the data to save
        Data= (Data.substring(0,14)+Data.substring(17,19)); // Date/Time-Title-Username: 16Bit, Password: 12Bit, Total: 60/60
        Data+=(Title.substring(0,14));
        Data+=(Title.substring(12,16));
        Data+=(Username);
        Data+=(Password);
        
        char DataSeg[66];
        Data.toCharArray(DataSeg, 66);
        TimeStamp(1);
        fpln("Created Data to Save!!!");
        TimeStamp(1);
        print(DataSeg, false);
        ExternalEEPROM(1,InternalEEPROM(1),DataSeg); // Actaully Write into EEPROM
        printlcd(String(InternalEEPROM(0)), false);
        LCD.setCursor(0, 2);
        fplcd("Added! Any)Exit");
        OnePush= true;
      }
      
      if (MenuInside) {Part=5;}
      
    }
    else if (Part==5) {
      ///////////////////////////////////// EXITING
      TimeStamp(1);
      fpln("Back to Option Menu!");
      Busy= false;
      Letter= 0;
      Part= 0;
      OnePush= false;
      LCDInterface(2);
      MenuType= 2;
    }
    else {
       TimeStamp(1);
       fpln("Add Log Error: Unknown Part Function!");
    }
    break;
    /////////////////////////////////////// Break
    default: ////////////////////////////////////////////////////////////////////// Default Menu 0
    if (Awake) {LCD.setCursor(0, 0);}
    else {LCD.setCursor(0, 1);}
    TimeStamp(2);
    if (!Awake) {
      LCD.setCursor(0, 0);
      if (Clock(7)==1) {fplcd("     Monday     ");}
      if (Clock(7)==2) {fplcd("     Tuesday    ");}
      if (Clock(7)==3) {fplcd("    Wednesday   ");}
      if (Clock(7)==4) {fplcd("    Thursday    ");}
      if (Clock(7)==5) {fplcd("     Friday     ");}
      if (Clock(7)==6) {fplcd("    Saturday    ");}
      if (Clock(7)==7) {fplcd("     Sunday     ");}
      LCD.setCursor(0, 2);
      fplcd("Voltage: ");
      printlcd(String(readVcc()).substring(0,1)+"."+String(readVcc()).substring(1,3), false);
    }
    break;
  }
 
}

//////////////////////////// Title Menu Switching Back to Clock /////////////////////////////////
void MenuTitle(String Title) {
  if (Millis-LastMillis>10000) {
    LCD.setCursor(0, 0);
    TimeStamp(2);
    LastMillis= Millis;
  }
  else if (Millis-LastMillis>3000) {
    LCD.setCursor(0, 0);
    fplcd("                ");
    LCD.setCursor(0, 0);
    printlcd(Title, false);
  }
}

/////////////////////////// LOOP //////////////////////////////
boolean stringComplete= false;

void loop() {
  while (!digitalRead(A1)&!digitalRead(A3)&!MenuType) { // Force to reset!!!! Prevents going to wdt_reset()
    LCD.clear();
    TimeStamp(2);
    LCD.setCursor(0, 1);
    fplcd("Hold to reset!");
    LCD.setCursor(0, 2);
    fplcd("B)Hold D)Hold");
    delay(1000);
  }
  wdt_reset(); // Acknowledge to watchdog program still running!!
  Millis= millis();
  unsigned static long LastSleep;
  // Serial Communication Commands
  if (stringComplete) {
    TimeStamp(0);
    if (inputString=="ineeprom sum;") {(InternalEEPROM(0));} // Internal EEPROM SUM
    else if (inputString=="ineeprom clear;") {(InternalEEPROM(2));} // Internal EEPROM CLEAR
    else if (inputString=="ineeprom write;") {(InternalEEPROM(1));} // Internal EEPROM WRITE
    else if (inputString=="generate password;") {CreatePassword(50);} // Create Random Password Generator
    else if (inputString=="backlight enable;") {DisplayLight(1);} // Turn on Display Power
    else if (inputString=="backlight disable;") {DisplayLight(0);} // Turn off Display Power
    else if (inputString=="clock;") { (Clock(8));} // Tell Clock Time
    // Reset Clock to last upload sketch
    else if (inputString=="clockreset;") {Clock(0);} // Resets Clock to reset clock back to last upload
    else if (inputString=="clockstop;") {Clock(9);} // Halts the clock to 0
    // Read External EEPROM
    else if (inputString=="exeeprom read;") {
      for(int RowInput= 0; RowInput<=511; RowInput++) {(ExternalEEPROM(0,RowInput,""));}
    }
    // printserial Millis
    else if (inputString=="millis;") {TimeStamp(1), print(Millis, true);}
    // Whats the inside voltage
    else if (inputString=="voltage;") {TimeStamp(1), print(round(readVcc()), true);}
    // HELP
    else if (inputString=="help;") {
      TimeStamp(1);
      fpln("");
      fpln("Note:               All commands lowercase, and must end with ‘;’ .");
      fpln("INEEPROM SUM        Display the sum of the internal eeprom markers.");
      fpln("INEEPROM CLEAR      Clears out internal eeprom markers.");
      fpln("INEEPROM WRITE      Writes a marker into internal eeprom markers.");
      fpln("GENERATE PASSWORD   Generates random password.");
      fpln("BACKLIGHT ENABLE    Enable the Display Backlight.");
      fpln("BACKLIGHT DISABLE   Disable the Display Backlight.");
      fpln("CLOCK               printserials out clock from RTC.");
      fpln("CLOCKRESET          Reset RTC back to last upload time.");
      fpln("EXEEPROM READ       Reads Entire External EEPROM 512 Data.");
      fpln("MILLIS              Tells how long mcu has been running.");
      fpln("VOLTAGE             Tells much voltage is inputting.");
      fpln("HELP                To Display this again.");
    }
    else {
      TimeStamp(1);
      fpln("not recognized!");
    }
    inputString="";
    stringComplete = false;
  }
  // Buttons Controler
  unsigned static long LastCheck;
  static boolean DisplayOff;
  if (Millis-LastCheck>250) {
    ButtonInterface(0, !DisplayOff);
    for(int ButtonScan= 0; ButtonScan<=3; ButtonScan++) {
      if (!digitalRead(ButtonScan+14)) {
        TimeStamp(1);
        fp("Button ");
        print(String(char(ButtonScan+65)), false);
        fpln(" was Pushed!");
        LastSleep= Millis; // Sleep Updates if button is pressed
        if (DisplayOff) {
          DisplayLight(1);
          DisplayOff= false;
          LCDInterface(0);
          ButtonInterface(0, true);
          TimeStamp(1);
          fpln("LCD woke up!");
        }
        else {
          LCD.clear();
          ButtonInterface(ButtonScan+1, true);
        }
      }
    }
    LastCheck= Millis;
    // Sleep Mode when past 60 Seconds
    if (Millis-LastSleep>60000&!DisplayOff) {
      TimeStamp(1);
      fpln("LCD going to sleep!");
      DisplayLight(0);
      LCD.clear();
      DisplayOff= true;
    }
    
  }
 
}

////////////////////// SERIAL DATA DECODE /////////////////////////
// http://arduino.cc/en/Tutorial/SerialEvent

String serialEvent() {
  while (Serial.available()&!stringComplete) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == ‘;’) {
      stringComplete = true;
    }
  }
}

////////////////////// CLOCK ///////////////////////////////////
// AdjustReset= 0 , Month = 1 , Day = 2 , Year = 3 , Hour = 4 , Minute = 5 , Second = 6
short Clock(int Type) {
  DateTime now = RTC1.now();
  // Adjust RTC Clock
  if ((Type==0|!RTC1.isrunning())) {
    RTC1.adjust(DateTime(__DATE__, __TIME__));
    fpln("Clock Message: Clock has started again!");
    print(String(Clock(1)), false); // Month
    fp("/");
    print(String(Clock(2)), false); // Day
    fp("/");
    print(String(Clock(3)), false); // Year
    fp(" ");
    print(String(Clock(4)), false); // Hour
    fp(":");
    print(String(Clock(5)), false); // Min
    fp(":");
    print(String(Clock(6)), true); // Sec
    
  }
  else if (Type==1) {return now.month();} // Month     1
  else if (Type==2) {return now.day();} // Day         2
  else if (Type==3) {return now.year();} // Year       3
  else if (Type==4) {return now.hour();} // Hour       4
  else if (Type==5) {return now.minute();} // Minute   5
  else if (Type==6) {return now.second();} // Second   6
  else if (Type==7) {return now.dayOfWeek();} // DayOfWeek   7
  else if (Type==8) { // Raw Time 8
    TimeStamp(1);
    fp("Unix Time: ");
    print(String(now.unixtime()), true);
    return now.unixtime();
  }
  // Invalid Function
  else {fpln("Clock Error: Invalid Function!");}
}

//////////////////////// Time Stamp Maker /////////////////////////// Edit: December 28, 2013
String TimeStampMake() {
  // Clock Converter PM/AM & Hour 12 Hour
  int Hour= Clock(4);
  String meridiem= "AM";
  if (Hour>=12) {meridiem= "PM";}
  if (Hour>12) {Hour= Hour-12;}
  if (!Hour) {Hour= 12;}
 
  // adding 0 in front ex. 01 02 03…
  String Transform;
  for (int Scan= 1; Scan<=6; Scan++) {
    // Makes ‘2013’ into ’13’
    if (Scan==3) {Transform+= String(Clock(3)).substring(2,4);}
    // Apply the 12 Hour
    else if (Scan==4) {
      if (int(Hour/10)) {Transform+= String(Hour);} else {Transform+= ‘0’+String(Hour);}
    }
    // making 0’s in front
    else if (int(Clock(Scan)/10)) {Transform+= String(Clock(Scan));}
    else {Transform+= ‘0’+String(Clock(Scan));}
    // Adds ‘:’ & ‘/’ & ‘ ‘
    if (Scan<=2) {Transform+= ‘/’;}
    else if (Scan<=3) {Transform+= ‘ ‘;}
    else if (Scan<=5) {Transform+= ‘:’;}
  }
  // Adds PM and AM to the end joy
  Transform+= meridiem;
 
  return Transform;
}

/////////////////////// TIMESTAMP /////////////////////////////////// Edit: December 28, 2013
// TimeStamp(String) String= INPUT,OUTPUT,LCD
// INPUT = 0 , OUTPUT = 1 , LCD = 2
void TimeStamp(int Function) {
  if (Function==0|Function==1) {
    print(TimeStampMake(), false);
  }
  // Input Type
  if (Function==0) { // INPUT
    fp("<<");
    print(inputString, true);
  }
  // Output Type
  else if (Function==1) { // OUTPUT
    fp(">>");
  }
  // LCD Type
  else if (Function==2) { // LCD
    printlcd(TimeStampMake().substring(0,14)+TimeStampMake().substring(17,19), false);
  }
  else {fpln("TimeStamp Error: Invalid Type!");} // Invalid Function
}

////////////////////// INTERNAL EEPROM MARKING /////////////////
// InternalEEPROM(String) String= SUM,WRITE,CLEAR
// SUM = 0 , WRITE = 1 , CLEAR = 2
int InternalEEPROM(int Task) {
  // TASK of Summing How many Markings
  if (Task==0) { // SUM
    int Counted=0;
    for (int Scan=0; Scan<1024; Scan++) {
      if (EEPROM.read(Scan)) {Counted++;}
    }
    TimeStamp(1);
    fp("Internal EEPROM sum to ");
    print(String(Counted), true);
    return Counted;
  }
 
  // TASK of Writting Add 1 Marking
  else if (Task==1) { // WRITE
    int Row=InternalEEPROM(0)+1;
    if (Row<=511&ExternalEEPROM(0, Row, "")!="Error") { // If is under 0-511
      EEPROM.write(Row,HIGH);
      TimeStamp(1);
      fp("Internal EEPROM set to ");
      print(String(Row), true);
    }
    else {
      TimeStamp(1);
      fpln("Internal EEPROM Error: cannot add anymore!");
    }
    return Row;
  }
 
  // TASK of Clear out All the markings
  else if (Task==2) { // CLEAR
    for (int Scan=0; Scan<1024; Scan++) {
      if (EEPROM.read(Scan)) {EEPROM.write(Scan,LOW);}
    }
    TimeStamp(1);
    fpln("Internal EEPROM cleared to 0");
    return InternalEEPROM(0);
  }
  // Invalid Function
  else {fpln("Internal EEPROM Marking Error: Invalid Type!");}
 
}

//////////////////////////// EEPROM MANAGAEMENT //////////////////////////// December 21, 2013 Modify Dec 23
// Read= 0 , Write= 1 & Message
#define EEPROM_ADDRESS 0x50
String ExternalEEPROM(int Func, long Row, char Message[66]) {
  // Test If EEPROM Is able to communicate
  Wire.beginTransmission(EEPROM_ADDRESS);
  if (Wire.endTransmission()!=0) {
    fpln("External EEPROM Error: Cannot find External EEPROM Device!");
    return "Error"; // Don’t Run at all if doesnt exist!
  }
  //  MATH LOGIC ARRAY SORTER
  int High= round((Row*64)/256);
  int Low= ((Row*64)-(High*256));
  print(String(Row), false);
  fp("  ");
  fp("High: ");
  print(String(High), false);
  fp("  ");
  fp("Low: ");
  print(String(Low+64), true);
  fp("    ");
 
  // READ FUNCTION
  if (Func==0) {
    String Words= "";
    Wire.beginTransmission(EEPROM_ADDRESS);
    Wire.write(byte(High)); // Max high 256
    Wire.write(byte(Low)); // Row to 256 Max
    Wire.endTransmission(); // END
    Wire.requestFrom(EEPROM_ADDRESS, 32);
    while(Wire.available()) {Words+= (char)Wire.read();}
    Words= Words.substring(0,30); // Cutt off tail null data
    
    Wire.beginTransmission(EEPROM_ADDRESS);
    Wire.write(byte(High)); // Max high 256
    Wire.write(byte(Low+32)); // Row to 256 Max
    Wire.endTransmission(); // END
    Wire.requestFrom(EEPROM_ADDRESS, 32);
    while(Wire.available()) {Words+= (char)Wire.read();}
    Words= Words.substring(0,60); // Cutt off tail null data
    
    print(Words, true);
    fp("Length: ");
    
    print(String(Words.length()), true);
    
    return Words;
  }
  // WRITE FUNCTION
  else if (Func==1) {
    Wire.beginTransmission(EEPROM_ADDRESS);
    Wire.write(byte(High)); // 0-255
    Wire.write(byte(Low)); // 0-255
    for(int DataSplitter= 0; DataSplitter<=31; DataSplitter++) {
      Wire.write((char)Message[DataSplitter]);
      print(String(Message[DataSplitter]), false);
    }
    //Wire.write(Message);
    Wire.endTransmission(); // END
    delay(5);
    Wire.beginTransmission(EEPROM_ADDRESS);
    Wire.write(byte(High)); // 0-255
    Wire.write(byte(Low+32)); // 0-255
    for(int DataSplitter= 32; DataSplitter<=63; DataSplitter++) {
      Wire.write((char)Message[DataSplitter]);
      print(String(Message[DataSplitter]), false);
    }
    //Wire.write(Message);
    Wire.endTransmission(); // END
    delay(5);
    
    fpln("Saved!");
    
    return Message;
  }
  else {fpln("External EEPROM Error: Invalid Function!");}
 
}

/////////////////////////// PASSWORD GENERATOR /////////////////////////////
String CreatePassword(int Length) {
  String Password="";
  int PasswordLength=0;
  randomSeed(Clock(8)*Millis);
  while (PasswordLength<Length) {
    PasswordLength++;
    if (round(random(0,10))<5) {
      Password+=(char)round(random(48,57));
    }
    else {
      Password+=(char)round(random(65,90));
    }
  }
  TimeStamp(1);
  fp("Password Generator>> (");
  print(Password, false);
  fpln(")");
  return Password;
}

///////////////////////// DISPLAY LIGHT ////////////////////////////////////
// Task: Power = 0
// Describe: On = 1 , Off = 0
void DisplayLight(int Task/*, int Describe*/) {
  //if (Task==0) {
    if (Task==1) { // ON LCD LIGHT
      int LEDBrightness=0;
      while (LEDBrightness<=255) {analogWrite(6,LEDBrightness),LEDBrightness+=1, delay(5);}
      TimeStamp(1);
      fpln("Display Enabled!");
    }
    else if (Task==0) { // OFF LCD LIGHT
      int LEDBrightness=255;
      while (LEDBrightness>=0) {analogWrite(6,LEDBrightness),LEDBrightness-=1, delay(5);}
      TimeStamp(1);
      fpln("Display Disabled!");
    }
  //}
  // Invalid Function
  else {fp("Display Light Error: Invalid Function!");}
}
///////////////////// Number to Char Converter Simplified ///////////////////////////// December 23, 2013
// Note: DigitPlace= 1000,100,10,0
int NumChar(int Number, int Digit) {
  return (Number/round(pow(10,Digit))%10); // Special Formula
}

/////////////////////// INTERNAL INPUT VOLTAGE ON THE CHIP ////////////////////////////// December 26, 2013
// http://code.google.com/p/tinkerit/wiki/SecretVoltmeter
long readVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}

// BACKUP  December 28, 2013
/* //////////////////////////////////////////////////////////////////////////////
EEPROM TRUTH TABLE
INTERNAL EEPROM: MIN= 1Bytes, MAX= 1024Bytes, TOTAL= 1024Byte
INTERNAL EEPROM USSAGE: EXTERNAL EEPROM CATEGORIZER USED IN 1-512Bytes
EXTERNAL EEPROM EEPROM: MAX= 32KBytes, MAX= 32768Bytes
EXTERNAL EEPROM EEPROM: MIN= 0Bit, MAX= 255Bit

*/ //////////////////////////////////////////////////////////////////////////////

/* //////////////////////////////////////////////////////////////////////////////
UPDATE LOG HISTORY
December 21, 2013  Worked on EXTERNAL EEPROM communication addressing (Uncomplete) [Ram Bug]
December 23, 2013  Logs was created, Opimizing RAM to PROGMEN & Adjusted Stuff 355L
December 23, 2013  Finished up External EEPROM and Added Number to Char Converter Simplified 353L
December 24, 2013  Added LCDInterface & ButtonInterface 555L
December 24, 2013  Made Pm/Am for TImeStamp + TImeStamp Optimized 600L
December 24, 2013  Notes External EEPROM: 31,32,60,61 are void spots & MenuType&Busy Buggy
December 25, 2013  Worked on Menu & Added Sleep Mode [Need Optimizing!] 958L
December 26, 2013  Added the watchdogs 1065L
December 26, 2013  Some Optimizing with ButtonInterface & Added Force Reset using watchdog 1096L

January 1, 2014    Removed stopping clock lib (DS1307 Library)

*/ //////////////////////////////////////////////////////////////////////////////

// FIRST GENERATION (January 25, 2014) >> CREATE THE CODE
// SECOND GENERATION (Novemember 15, 2014) >> OPTIMIZATION & FIX & IMPROVE
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/*-///////////////////// The Opitmization On Novemeber 15, 2014 //////////////////////////////////////////
Novemember 15, 2014   Saved 1K Byte of bytes in LCD Interfaces    30,858 Byes

*////////////////////////////////////////////////////////////////////////////////////////////////////////
[/code]

Congrats your on the buttom!

Leave a Reply

Your email address will not be published. Required fields are marked *