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!