A twist to the computer that landed man on the moon. More information can be found at http://hackaday.io/project/294-Open-Source-DSKY

Dependencies:   DS1302 keypad mbed

Hardware

main.cpp

Committer:
VivaPenguinos
Date:
2014-07-21
Revision:
4:99535d368a9f
Parent:
3:29cff763ae36
Child:
5:5f08974ef8bb

File content as of revision 4:99535d368a9f:

/* Introduction
MBED DSKY
This is a personal project used developed by penguinos to mix old school technology with a modern twist.
Version 0.04: July. 5 2014
    - DS1302 Added
    - Shift Register Variable has been added
    - void Button_Sort(int sort); is now int Button_Sort(int sort);
        Button sort has 90% of all the variables in there.
    - Void shifting out no longer takes 8 bits but rather 4 bits. (Makes things easier to compute)
    - Added Concatenation Functionality
    - Added NO_Lights Functionality
    - Added R_GET Functionality
    - Test Light Program working
    - GET Program Working
    - GET Configuration Working
    
    
Notable Credits:
NASA! - Release of technical documentations regarding the AGC and DSKY
Ron Burkley and Contributers of "Virtual AGC — AGS — LVDC — Gemini" - Providing Technical documentations, Source Code, explanations,
    and refrences on other sites to make this project successful

Warning: This may contain author's crude language, and random thoughts.

Pin Usage:

Real Time Clock
    SCLK    PTC5
    IO      PTC4
    CE      PTC3
Keypad
    Row0    PTD4
    Row1    PTA12
    Row2    PTD3
    Row3    PTA5
    Col1    PTA13
    Col2    PTD5
    Col3    PTD0
    Col4    PTD2
Shift Registers
    Latch   PTC6
    Clock   PTC10
    Data    PTC11
    
Shift Registers Data:
Because the project contains 11 shift registers, All data must be properly formatted before shifting out. each shift register controls 2 7 segments.
R1_A                                           [P_A | P_B]
R1_B                   
R1_C                    [V_A | V_B]            [N_A | N_B]
R1_D                    
R1_E                    [R3_E | R3_D | R3_C | R3_B | R3_A]
R2_A
R2_B                    [R2_E | R2_D | R2_C | R2_B | R2_A]
R2_C
R2_D                    [R1_E | R1_D | R1_C | R1_B | R1_A]
R2_E
R3_A
R3_B
R3_C
R3_D
R3_E
V_A
V_B
N_A
N_B
P_A
P_B
 */
 
// For RTC 
#define SCLK    PTC5
#define IO      PTC4
#define CE      PTC3

// Comment Line if DS1302 is already running
#define INITIAL_RUN

using namespace std;
#include "mbed.h"
#include "Keypad.h" // Keypad
#include "DS1302.h" // RTC for DS1032
    
DS1302 clk(SCLK, IO, CE); //DS1302 clk(SCLK, IO, PTC3);

//Declare Variables
// int shift = 0; // Shift Data
// In the Arduino Version it uses a String. Will use an Int instead to see if this works on Mbed
int Verb_Number1 = 0;
int Verb_Number2 = 0;
int Noun_Number1 = 0;
int Noun_Number2 = 0;
int Enter_Number1 = 0;
int Enter_Number2 = 0;
int Verb; // DSKY Verb
int Noun; // DSkY Noun
int Enter; // DSKY Enter

// For shift register use. Refer to shift register data for additional information.
int R1_A = 0x0f;
int R1_B = 0x0f;                   
int R1_C = 0x0f;
int R1_D = 0x0f;                    
int R1_E = 0x0f;
int R2_A = 0x0f;
int R2_B = 0x0f;
int R2_C = 0x0f;
int R2_D = 0x0f;
int R2_E = 0x0f;
int R3_A = 0x0f;
int R3_B = 0x0f;
int R3_C = 0x0f;
int R3_D = 0x0f;
int R3_E = 0x0f;
int V_A = 0x0f;
int V_B = 0x0f;
int N_A = 0x0f;
int N_B = 0x0f;
int P_A = 0x0f;
int P_B = 0x0f;

// For GET use. Refer to R3_GET, R2_GET, and R1_GET
int RA = 0;
int RB = 0;
int RC = 0;
int RD = 0;
int RE = 0;
int RVA = 0x0f;
int RVB = 0x0f;
int RVC = 0x0f;
int RVD = 0x0f;
int RVE = 0x0f;
int R_Position = 1;
int R1_Position = 1;
int R2_Position = 1;
int R3_Position = 1;
int GET_Config_Time = 0;

// Keypad
char Keytable[] = { '1', '2', '3', '+', // R0
                    '4', '5', '6', '-', // R1
                    '7', '8', '9', 'E', // R2
                    'V', '0', 'N', 'R', // R3
                  };
                //  C0   C1   C2   C3

// RTC Variables
int TIME_VALUE = 1397702161;
int Time_Difference = 0%60;

// Button State
int32_t Index = -1; // Button
int     State;

// Function Declaration
void Verb_Button();
void Noun_Button();
void Enter_Button();
void compare();
int Button_Sort(int sort); // Function that sorts Verb Values
void blinkAll(int amount, int delay);// Function that Blinks all LED
void Shift(); // Function that shifts all data
void R_GET(int R); // Grab inputs for the Rows
int R_Concatenate(int C); // Used for concatenating information
void NO_Light(int L); // Configures shift registers to 0
//void ShiftingOut(char myDataOut);

// Program Names
void Ground_Elapse_Time();  // Ground Elapse Time
void Test_Lights();         // Test Lights
void GET_Config();          // Configures Ground Elapse Time

// Pin modes for each pins
DigitalOut LatchPin(PTC6); //Pin for ST_CP of 74HC595 Pin # 12
DigitalOut ClockPin(PTC10); //Pin for SH_CP of 74HC595 Pin # 11
DigitalOut DataPin(PTC11);  //Pin for to DS of 74HC595 Pin # 14

DigitalOut myled(LED1);
Serial pc(USBTX, USBRX); // tx, rx Serial Output to PC Enabling this WILL consume resources. Use only for debug

unsigned concatenate(unsigned x, unsigned y);

uint32_t cbAfterInput(uint32_t index)
{
    Index = index;
    return 0;
}

int main()
{
    pc.printf("Initialization...\n");
    wait(1);
    pc.printf("Testing shift registers.\n");
    blinkAll(4,1);
    pc.printf("Shift Register: PASS \n");
    wait(1);
    pc.printf("Energizing keypad\n");
    State = 1;
    //             r0   r1   r2   r3   c0   c1   c2   c3
    Keypad keypad(PTD4, PTA12, PTD3, PTA5, PTA13, PTD5, PTD0, PTD2, 20);
    keypad.attach(&cbAfterInput);
    keypad.start();  // energize the columns c0-c3 of the keypad
    pc.printf("Keypad: PASS \n");
    pc.printf("Initialize RTC Clock. \n");
    #ifdef INITIAL_RUN
    clk.set_time(TIME_VALUE);
    #endif
    //char storedByte = clk.recallByte(0);
    //clk.storeByte(0, storedByte + 1);
    pc.printf("RTC: PASS \n");
    pc.printf("Welcome to DSKY!\n");
    while (1) {
        __wfi();
        if (Index >-1) {
            pc.printf("Interrupted");
            pc.printf("Index:%d => Key:%c\r\n", Index, Keytable[Index]);
            if (Index == 12) { // Index 12 = Verb Button
                Verb_Button(); // Goes to Verb_Button
            }
            if (Index == 14) { // Index 14 = Noun Button
                Noun_Button(); // Goes to Noun_Button
            }
            if (Index == 11) { // Index 11 = Enter Button
                Enter_Button(); // Goes to Enter_Button
            }
            Index = -1;
        }
        // Debug use only
        //pc.printf("%c", Keytable[Verb_Number1]);
        //pc.printf("%c", Keytable[Verb_Number2]);
        //pc.printf("%c", Keytable[Noun_Number1]);
        //pc.printf("%c", Keytable[Noun_Number2]);
    }
}

/* This function is used when the Verb Button has been pressed. Take the inputs of the button twice and determine if the buttons are integers.
If other buttons are pressed send it to their perspective locations.
*/
void Verb_Button(){
        Verbz: // Don't Ask
        // All Variables for Verb, Noun and Enter are zeroed out
        Verb_Number1    = 0;
        Verb_Number2    = 0;
        Noun_Number1    = 0;
        Noun_Number2    = 0;
        Enter_Number1   = 0;
        Enter_Number2   = 0;
        pc.printf("Please enter a Verb Number");          
        __wfi();
        Verb_Number1 = Index;
        if (Verb_Number1 == 12){ // This is section is used on atleast one of the two Verb_Number variabels to prevent a Nestled If within if within if.
            goto Verbz; // Line 110
        } else {
            V_A = Button_Sort(Verb_Number1);
            Shift();
        }
        //pc.printf("%c", Verb_Number1);
        //pc.printf("%c", Keytable[Index]);
        __wfi();
        Verb_Number2 = Index;
        V_B = Button_Sort(Verb_Number2);
        Shift();
        //pc.printf("%c", Verb_Number2);
        //pc.printf("%c", Verb_Number1);
        //pc.printf("%c\n", Verb_Number2);
}

/* This Function is used when the Verb Button has been Pressed. Take the inputs of the button twice and determine if the buttons are integers.
If other buttons are pressed send it to their perspective locations.
*/
void Noun_Button()
{
    Nounz:
    pc.printf("Please enter a Noun Number");
    __wfi();
    Noun_Number1 = Index;
    if (Noun_Number1 == 14) {// This is section is used on atleast one of the two Noun_Number variabels to prevent a Nestled If within if within if.
        goto Nounz;
        }
    else{
        N_A = Button_Sort(Noun_Number1);
        Shift();
        }
    __wfi();
    Noun_Number2 = Index;
    N_B = Button_Sort(Noun_Number2);
    Shift();
}

/* This function is used wen the Enter button has been pressed. This function is a special circumstance since it will be checking both the Verb and Noun variables before entering variable to Enter.
*/
void Enter_Button()
{
    Enterz:
    pc.printf("Checking Whether there is a variable stored in Noun or Verb 35\n");
    if (Noun_Number1 == 0 && Noun_Number2 == 0 && Verb_Number1 != 2 && Verb_Number2 != 5){
        pc.printf("Please enter a Enter Number");
        __wfi();
        Enter_Number1 = Index;
        if (Enter_Number1 == 11) { // This section is used on atleast one of the two Enter_Number variable to prevent a nestled if within if within if.
            goto Enterz;
            }
        else{
            Button_Sort(Enter_Number1);
            }
        __wfi();
        Enter_Number2 = Index;
        Button_Sort(Enter_Number2);
    }
    else {// (Noun_Number1 != 0 && Noun_Number2 != 0){ 
        pc.printf("Check completed, Executing");
        Index = -1;
        compare();
    }
    
}

// This function is used to sort the button press for Verb and Noun.
int Button_Sort(int Sort)
{
    if (Sort == 0){ // Index 0 - Char 1
        return 0x01;
        }
    else if (Sort == 1) { // Index 1 - Char 2
        return 0x02;
        }
    else if (Sort == 2) { // Index 2 - Char 3
        return 0x03;
        }
    else if (Sort == 3) { // Index 3 - Char + comparing the array number NOT what value in the array it is. Actual Array value is +
        pc.printf("+");
        }
    else if (Sort == 4) { // Index 4 - Char 4
        return 0x04;
        }
    else if (Sort == 5) { // Index 5 - Char 5
        return 0x05;
        }
    else if (Sort == 6) { // Index 6 - Char 6
        return 0x06;
        }
    else if (Sort == 7) { // Index 7 - Char - comparing the array number NOT what value in the array it is. Actual Array value is -
        pc.printf("-");
        }
    else if (Sort == 8) { // Index 8 - Char 7
        return 0x07;
        }
    else if (Sort == 9) { // Index 9 - Char 8
        return 0x08;
        }
    else if (Sort == 10) { // Index 10 - Char 9
        return 0x09;
        }
    else if (Sort == 12){ // Index 12 - Char V comparing the array number NOT what value in the array it is. Actual Array value is V
        Verb_Button();
        }    
    else if (Sort == 13) { // Index 13 - Char 0
        return 0x00;
        }
    else if (Sort == 14) { // Index 14 - Char N comparing the array number NOT what value in the array it is. Actual Array value is N
        Noun_Button();
        }          
    else if (Sort == 15) { //comparing the array number NOT what value in the array it is. Actual Array value is R
        pc.printf("R");
        }
    return 0;
}

// Compares the button to what program the DSKY should be running. This section will be inefficent until I can improve on my programming skills :]
void compare()
{
    if (Verb_Number1 == 0 && Verb_Number2 == 6 && Noun_Number1 == 2 && Noun_Number2 == 6 && Enter_Number1 == 0 && Enter_Number2 == 0) {// Verb 16, Noun 36, Enter 00
        // Configure GET
        pc.printf("Display GET");
        Ground_Elapse_Time();
    } else if (Verb_Number1 == 2 && Verb_Number2 == 5 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 35 Noun 00 Enter 00
        // Test Lights
        pc.printf("Testing Lights");
        Test_Lights();
    } else if (Verb_Number1 == 1 && Verb_Number2 == 5 && Noun_Number1 == 2 && Noun_Number2 == 6 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 25, Noun 36, Enter 00
        // GET COnfiguration
        pc.printf("GET configuration");
        GET_Config();
    } else if (Verb == 37 && Enter == 00) {
        // Idle Program
    }
}

void ShiftingOut(int myDataOut)
{
    // This shifts 8 bits out to the MSB first, The the rising edge of the clock, while clock idles low.
    // Internal Fucntions
    DataPin = 0;
    ClockPin = 0;
    int i= 0;
    int pinState;
    // Clears Everything within shift registers
    DataPin = 0;
    ClockPin = 0;

    for (i=3; i>= 0; i--) {
        ClockPin = 0;

        // Value passed to my data out
        if ( myDataOut & (1<<i)) {
            pinState = 1;
            myled = 1;
            //pc.printf("1");
        } else {
            pinState = 0;
            myled = 0;
            //pc.printf("0");
        }
        DataPin = pinState;
        ClockPin = 1;
        DataPin = 0;
    }
    //pc.printf("\n");
    ClockPin = 0;
    DataPin = 1;
}

// This function is used for shifting all Shift_X variables into the 7 segment display.
void Shift()
{
    LatchPin = 0;
    ShiftingOut(P_B);
    ShiftingOut(P_A);
    ShiftingOut(V_B);
    ShiftingOut(V_A);
    ShiftingOut(N_B);
    ShiftingOut(N_A);
    ShiftingOut(R3_E);
    ShiftingOut(R3_D);
    ShiftingOut(R3_C);
    ShiftingOut(R3_B);
    ShiftingOut(R3_A);
    ShiftingOut(R2_E);
    ShiftingOut(R2_D);
    ShiftingOut(R2_C);
    ShiftingOut(R2_B);
    ShiftingOut(R2_A);
    ShiftingOut(R1_E);
    ShiftingOut(R1_D);
    ShiftingOut(R1_C);
    ShiftingOut(R1_B);
    ShiftingOut(R1_A);
    LatchPin = 1;
}

//blinks the whole registered based on the number of times you want to blink with a certain delay
void blinkAll(int amount, int delay)
{
    LatchPin = 0; // Before shift
    //ShiftingOut(0);
    //ShiftingOut(0);
    LatchPin = 1; // Done shift
    wait(0.2);
    for (int x = 0; x < amount; x++) {
        LatchPin = 0;
        pc.printf("sending\n");
        for (int s = 0; s < 22; s++) 
        {
            ShiftingOut(0x08);
        }
        LatchPin = 1;
        wait(delay);
        LatchPin = 0;
            for (int s = 0; s < 22; s++)
            {
            ShiftingOut(0xf);
            }
        LatchPin = 1;
        wait(delay);
    }
}

// The Ground Elapse Time is refrence to range zero or the last integeral before liftoff.
// Page CM-9
// 00XXX    h
// 000XX    min
// 0XX.XX   s (Code current does not follow this format)
void Ground_Elapse_Time()
{
    NO_Light(7); // Clears all the 7 Segment first.
    // Displays V16N36 on the 7 segments
    V_A = 0x01;
    V_B = 0x06;
    N_A = 0x03;
    N_B = 0x06;
    Shift();
    int GET_FLAG = 1;
    while(GET_FLAG == 1) {
        int minute = 0;
        int Seconds = 0;
        int Hours = 0;
        int minutemod = 0; // Minute Modulo
        int R1D = 0x00;
        int R1E = 0x00;
        int R2D = 0x00;
        int R2E = 0x00;
        int R3D = 0x00;
        int R3E = 0x00;
        time_t seconds = clk.time(NULL);
        pc.printf ("S = %d\n", seconds);
        Time_Difference = (seconds + GET_Config_Time) - TIME_VALUE;
        printf("TIME=%d \n", Time_Difference);  // Displays time elapsed based on seconds elapsed.
        Hours = Time_Difference/3600;   // Divide seconds by 3600 seconds
        Seconds = Time_Difference%60;   // Get the remainder of time difference after 60 seconds
        minute = Time_Difference/60;    // Divide the seconds by 3600
                                    // Comments:                                                            7 Segments Location
        minutemod = minute%60;      // Get the remainder of the minutemod after 60 seconds
        R3D = (Hours%60)/10;        // Get the modulo of the hour variable then divde by 10 to get single digit     [][][][x][]
        R3E = Hours%10;             // Get the modulo of the Hours variable by 10 to get single digit               [][][][][x]
        R2D = minutemod/10;         // Divide the minute variable by 10 to get single digit                         [][][][x][]
        R2E = minute%10;            // Get the remainder of the minute variable to get single digit                 [][][][][x]
        R1D = Seconds/10;           // Divide the seconds variable by 10 to get single digit                        [][][][x][]
        R1E = Time_Difference%10;   // Get the remainder of the Time_Difference to get single digit                 [][][][][x]
        // Debug Use:
        // pc.printf("%d \n", minute);
        // pc.printf("%o \n", R2E);
        // pc.printf("%o \n", R2D);
        R3_E = R3E;
        R3_D = R3D;
        R1_E = R1E;
        R1_D = R1D;
        R2_E = R2E;
        R2_D = R2D;
        Shift();
        //pc.printf("%i \n",(Time_Difference%10) + ((Time_Difference/10)<<4)); // Decimal to BCD
        //printf("Time as a basic string = %s\r", ctime(&seconds));
        if (Index >-1) {
        GET_FLAG = 0;
        pc.printf("Interrupted");
        pc.printf("Index:%d => Key:%c\r\n", Index, Keytable[Index]);
            if (Index == 12) { // Index 12 = Verb Button
                Verb_Button(); // Goes to Verb_Button
                GET_FLAG = 0;
                break;
            } else if (Index == 14) { // Index 14 = Noun Button
                Noun_Button(); // Goes to Noun_Button
                GET_FLAG = 0;
                break;
            } else if (Index == 11) { // Index 11 = Enter Button
                Enter_Button(); // Goes to Enter_Button
                GET_FLAG = 0;
                break;
            }
            Index = -1;
            GET_FLAG = 0;
            break;
        }
        wait(1);
    }
}

// This function tells the shift registers to not display anything on the 7 segments. The integer L is used to specificy which area to zero.
// 1 = Row 1
// 2 = Row 2
// 3 = Row 3
// 4 = Verb
// 5 = Nouns
// 6 = Program Number
// 7 = All lights off
void NO_Light(int L)
{

    switch(L) {
        case 1:
            R1_A = 0x0f;
            R1_B = 0x0f;
            R1_C = 0x0f;
            R1_D = 0x0f;
            R1_E = 0x0f;
            Shift();
        case 2:
            R2_A = 0x0f;
            R2_B = 0x0f;
            R2_C = 0x0f;
            R2_D = 0x0f;
            R2_E = 0x0f;
            Shift();
        case 3:
            R3_A = 0x0f;
            R3_B = 0x0f;
            R3_C = 0x0f;
            R3_D = 0x0f;
            R3_E = 0x0f;
            Shift();
        case 4:
            V_A = 0x0f;
            V_B = 0x0f;
            Shift();
        case 5:
            N_A = 0x0f;
            N_B = 0x0f;
            Shift();
        case 6:
            P_A = 0x0f;
            P_B = 0x0f;
            Shift();
        case 7:
            R1_A = 0x0f;
            R1_B = 0x0f;
            R1_C = 0x0f;
            R1_D = 0x0f;
            R1_E = 0x0f;
            R2_A = 0x0f;
            R2_B = 0x0f;
            R2_C = 0x0f;
            R2_D = 0x0f;
            R2_E = 0x0f;
            R3_A = 0x0f;
            R3_B = 0x0f;
            R3_C = 0x0f;
            R3_D = 0x0f;
            R3_E = 0x0f;
            V_A = 0x0f;
            V_B = 0x0f;
            N_A = 0x0f;
            N_B = 0x0f;
            P_A = 0x0f;
            P_B = 0x0f;
            Shift();
    }
}
    
// Test lights is to make sure all the 7 segments and indicator lights worked prior to lift-off.
void Test_Lights()
{
    for(int x = 0; x < 7; x++) {
        R1_A = 0x08;
        R1_B = 0x08;
        R1_C = 0x08;
        R1_D = 0x08;
        R1_E = 0x08;
        R2_A = 0x08;
        R2_B = 0x08;
        R2_C = 0x08;
        R2_D = 0x08;
        R2_E = 0x08;
        R3_A = 0x08;
        R3_B = 0x08;
        R3_C = 0x08;
        R3_D = 0x08;
        R3_E = 0x08;
        V_A = 0x08;
        V_B = 0x08;
        N_A = 0x08;
        N_B = 0x08;
        P_A = 0x08;
        P_B = 0x08;
        Shift();
        wait(1);
        V_A = 0x0f;
        V_B = 0x0f;
        N_A = 0x0f;
        N_B = 0x0f;
        Shift();
        wait(1);
    }    
}

// This configs the Ground Elapse Time
// This portion of code converts the value retrived into seconds and replaces the value in the RTC module.
// Process:
// V25N36
//      Displays V21N36
// +-00XXX 750 hours max (equates to 31.25 days) Longest Apollo mission was only 12 hours, 13 hours. So 750 Hours is more than enough.
//      Displays V22N36
// +-000XX 60 Minutes Max
//      Displays V23N36
// +-0XXXX 60 Seconds Max, Currently follows 000XX will change in future revisions
void GET_Config()
{
    int GET_Hours   = 0;
    int GET_Minute  = 0;
    int GET_Seconds = 0;
    // Configures Hours, Minutes, and Seconds for RTC
    NO_Light(3);
    do {
        NO_Light(3);
        pc.printf("Debug");
        R_GET(3);
        V_A = 0x02;
        V_B = 0x01;
        N_A = 0x03;
        N_B = 0x06;
        R_GET(3);
        Shift();
        wait(.5);
        R_GET(3);
        V_A = 0x0f;
        V_B = 0x0f;
        N_A = 0x0f;
        N_B = 0x0f;
        R_GET(3);
        Shift();
        wait(.5);
    } while (R3_Position != 6);
    R_Position = 1;
    RVA = 0x0f;
    RVB = 0x0f;
    RVC = 0x0f;
    RVD = 0x0f;
    RVE = 0x0f;
    do {
        pc.printf("Debug R2");
        R_GET(2);
        V_A = 0x02;
        V_B = 0x02;
        N_A = 0x03;
        N_B = 0x06;
        R_GET(2);
        Shift();
        wait(.5);
        R_GET(2);
        V_A = 0x0f;
        V_B = 0x0f;
        N_A = 0x0f;
        N_B = 0x0f;
        R_GET(2);
        Shift();
        wait(.5);
    } while(R2_Position != 6);
    R_Position = 1;
    RVA = 0x0f;
    RVB = 0x0f;
    RVC = 0x0f;
    RVD = 0x0f;
    RVE = 0x0f;
    do {
        pc.printf("Debug R1");
        R_GET(1);
        V_A = 0x02;
        V_B = 0x03;
        N_A = 0x03;
        N_B = 0x06;
        R_GET(1);
        Shift();
        wait(.5);
        R_GET(1);
        V_A = 0x0f;
        V_B = 0x0f;
        N_A = 0x0f;
        N_B = 0x0f;
        R_GET(1);
        Shift();
        wait(.5);
    } while(R1_Position != 6);
    R_Position = 1;
    RVA = 0x0f;
    RVB = 0x0f;
    RVC = 0x0f;
    RVD = 0x0f;
    RVE = 0x0f;
    
    // The Actual Configuration of GET
    // Concatenate the values from each row based on it's value
    GET_Hours   = R_Concatenate(3);
    GET_Minute  = R_Concatenate(2);
    GET_Seconds = R_Concatenate(1);
    
    // Checks if value exceeds the Hours, Minute, and Seconds
    if (GET_Hours > 750 or GET_Minute > 60 or GET_Seconds > 60) {
        pc.printf("Error! Check your Hours, Minute, and Seconds Value");
        R3_Position = 1;
        GET_Config();
    } else {
        pc.printf("Pass!, Going to configure RTC Now");
        GET_Config_Time =  GET_Hours * 3600;
        GET_Config_Time += GET_Minute * 60;
        GET_Config_Time += GET_Seconds;
        pc.printf("Time Conversion is %d", GET_Config_Time);
    }
    
    // Reconfigures the timee so the values can be resetted.
    #ifdef INITIAL_RUN
    clk.set_time(TIME_VALUE);
    #endif
    
    // Debug Use Only
    //pc.printf("%d\n", GET_Hours);
    //pc.printf("%d\n", GET_Minute);
    //pc.printf("%d\n", GET_Seconds);
    Ground_Elapse_Time();
 }
 
 // This is used to concatenate Row 3, Useful for when verifying inputs.
 int R_Concatenate(int C) {
     
     // Used for concatenation only
     int RAB       = 0;
     int RCD       = 0;
     int RABCD     = 0;
     int RABCDE    = 0;
     
     // Actual Physical Interaces, Row Physical
     int RPA    = 0;
     int RPB    = 0;
     int RPC    = 0;
     int RPD    = 0;
     int RPE    = 0;  
     
     // This if Statement compares which rows to concatenate then replaces the variables with the correct one.
    if (C == 3) {
        RPA = R3_A;
        RPB = R3_B;
        RPC = R3_C;
        RPD = R3_D;
        RPE = R3_E;
    }
    if (C == 2) {
        RPA = R2_A;
        RPB = R3_B;
        RPC = R2_C;
        RPD = R2_D;
        RPE = R2_E;
    }
    if (C == 1) {
        RPA = R1_A;
        RPB = R1_B;
        RPC = R1_C;
        RPD = R1_D;
        RPE = R1_E;
    }
     RAB = concatenate(RPA, RPB);        // R3A + R3B
     RCD = concatenate(RPC, RPD);        // R3C + R3D
     RABCD = concatenate(RAB, RCD);      // R3AB + R3CD
     RABCDE = concatenate(RABCD, RPE);    // R3ABCD = R3E
     //Debug Use:
     //pc.printf("%d\n", RAB);
     //pc.printf("%d\n", RCD);
     //pc.printf("%d\n", RABCD);
     //pc.printf("%d\n", RABCDE);
     return RABCDE;
}
     
 
 // Concatenate two Integers. Credits to Mooing Duck. http://stackoverflow.com/questions/12700497/how-to-concatenate-two-integers-in-c
 // Decided not modify the code to do 5 at a time since I can use it to concatenate the Verb, Noun, and Program Number.
 unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while(y >= pow)
        pow *= 10;
    return x * pow + y;        
}
 
void R_GET(int R)
{
    if (R == 3) {
        R3_A = RVA;
        R3_B = RVB;
        R3_C = RVC;
        R3_D = RVD;
        R3_E = RVE;
        R3_Position = R_Position;
    }
    if (R == 2) {
        R2_A = RVA;
        R2_B = RVB;
        R2_C = RVC;
        R2_D = RVD;
        R2_E = RVE;
        R2_Position = R_Position;
    }
    if (R == 1) {
        R1_A = RVA;
        R1_B = RVB;
        R1_C = RVC;
        R1_D = RVD;
        R1_E = RVE;
        R1_Position = R_Position;
    }
    
    switch (R_Position){
        case 1:
            if (Index >-1) {
                pc.printf("RA\n");
                RA = Button_Sort(Index);
                RVA = RA;
                Shift();
                Index = -1;
                R_Position = 2;
            }
        case 2:
            if (Index >-1) {
                pc.printf("RB\n");
                RB = Button_Sort(Index);
                RVB = RB;
                Shift();
                Index = -1;
                R_Position = 3;
            }
        case 3:
            if (Index >-1) {
                pc.printf("RC\n");
                RC = Button_Sort(Index);
                RVC = RC;
                Shift();
                Index = -1;
                R_Position = 4;
            }
        case 4:
            if (Index >-1) {
                pc.printf("RD\n");
                RD = Button_Sort(Index);
                RVD = RD;
                Shift();
                Index = -1;
                R_Position = 5;
            }
        case 5:
            if (Index >-1) {
                pc.printf("RE\n");
                RE = Button_Sort(Index);
                RVE = RE;
                Shift();
                Index = -1;
                R_Position = 6;
            }
    }
                

}