// Maulana Anjari Anggorokasih
// 21/477748/TK/52619
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width,  (pixels)
#define SCREEN_HEIGHT 64 // OLED display height, (pixels)
#define CHAR_LENGTH 50
// pins
// Keypad Rows declared
const int r1 = 13;
const int r2 = 12;
const int r3 = 14;
const int r4 = 27;
// Keypad coulombs declared
const int c1 = 26;
const int c2 = 25;
const int c3 = 33;
const int c4 = 32;

char str[CHAR_LENGTH]; // storing character before print to display
int position = 0; // cursor position
bool capslock = false;

// declare an SSD1306 display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  // initialize OLED display with address 0x3C for 128x64
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }

  delay(2000);         // wait two seconds for initializing
  oled.clearDisplay(); // clear display

  oled.setTextSize(1.5);
  oled.setTextColor(WHITE);
  oled.setCursor(0, 0);
  oled.println("Keypad Program");
  oled.setCursor(0, 10);
  oled.println("NIU: 477748");
  oled.setCursor(0, 20);
  oled.println("Type something...");
  oled.display();

  //Keypad rows declared as output
  pinMode(r1, OUTPUT); pinMode(r2, OUTPUT);
  pinMode(r3, OUTPUT); pinMode(r4, OUTPUT);
  //Keypad columns declared as input
  pinMode(c1, INPUT_PULLUP); pinMode(c2, INPUT_PULLUP);
  pinMode(c3, INPUT_PULLUP); pinMode(c4, INPUT_PULLUP);

}

void loop() {
  char a = 'a';
  while (a != 'c') {
    // "low" indicates that the row or column is suppressed
    // row 1 is pressed and column 1 is pressed
    digitalWrite(r1, LOW); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c1) == LOW) {
      str[position] = '1'; printToDisplay();
      if (digitalRead(c1) == LOW) {
        str[position] = (capslock ? 'A' : 'a'); printToDisplay();
        if (digitalRead(c1) == LOW) {
          str[position] = (capslock ? 'B' : 'b'); printToDisplay();
          if (digitalRead(c1) == LOW) {
            str[position] = (capslock ? 'C' : 'c'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;

    }
    // row 1 is pressed and column 2 is pressed
    digitalWrite(r1, LOW); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c2) == LOW) {
      str[position] = '2'; printToDisplay();
      if (digitalRead(c2) == LOW) {
        str[position] = (capslock ? 'D' : 'd'); printToDisplay();
        if (digitalRead(c2) == LOW) {
          str[position] = (capslock ? 'E' : 'e'); printToDisplay();
          if (digitalRead(c2) == LOW) {
            str[position] = (capslock ? 'F' : 'f'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;

    }
    // row 1 is pressed and column 3 is pressed
    digitalWrite(r1, LOW); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c3) == LOW) {
      str[position] = '3'; printToDisplay();
      if (digitalRead(c3) == LOW) {
        str[position] = (capslock ? 'G' : 'g'); printToDisplay();
        if (digitalRead(c3) == LOW) {
          str[position] = (capslock ? 'H' : 'h'); printToDisplay();
          if (digitalRead(c3) == LOW) {
            str[position] = (capslock ? 'I' : 'i'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 1 is pressed and column 4 is pressed (Backspace)
    digitalWrite(r1, LOW); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c4) == LOW) {
      if (position >= 1) {
        position--;
        str[position] = '\0';
      }
      printToDisplay();
    }
    // row 2 is pressed and column 1 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, LOW);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c1) == LOW) {
      str[position] = '4'; printToDisplay();
      if (digitalRead(c1) == LOW) {
        str[position] = (capslock ? 'J' : 'j'); printToDisplay();
        if (digitalRead(c1) == LOW) {
          str[position] = (capslock ? 'K' : 'k'); printToDisplay();
          if (digitalRead(c1) == LOW) {
            str[position] = (capslock ? 'L' : 'l'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 2 is pressed and column 2 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, LOW);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c2) == LOW) {
      str[position] = '5'; printToDisplay();
      if (digitalRead(c2) == LOW) {
        str[position] = (capslock ? 'M' : 'm'); printToDisplay();
        if (digitalRead(c2) == LOW) {
          str[position] = (capslock ? 'N' : 'n'); printToDisplay();
          if (digitalRead(c2) == LOW) {
            str[position] = (capslock ? 'O' : 'o'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 2 is pressed and column 3 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, LOW);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c3) == LOW) {
      str[position] = '6'; printToDisplay();
      if (digitalRead(c3) == LOW) {
        str[position] = (capslock ? 'P' : 'p'); printToDisplay();
        if (digitalRead(c3) == LOW) {
          str[position] = (capslock ? 'Q' : 'q'); printToDisplay();
          if (digitalRead(c3) == LOW) {
            str[position] = (capslock ? 'R' : 'r'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 2 is pressed and column 4 is pressed (Capslock)
    digitalWrite(r1, HIGH); digitalWrite(r2, LOW);
    digitalWrite(r3, HIGH); digitalWrite(r4, HIGH);

    if (digitalRead(c4) == LOW) {
      if (capslock == false) {
        capslock = true;
        oled.clearDisplay();
        oled.setTextSize(2);
        oled.setTextColor(WHITE);
        oled.setCursor(0, 10);
        oled.println("CAPSLOCK : ON");
        oled.display();
        delay(500);
      } else {
        capslock = false;
        oled.clearDisplay();
        oled.setTextSize(2);
        oled.setTextColor(WHITE);
        oled.setCursor(0, 10);
        oled.println("CAPSLOCK : OFF");
        oled.display();
        delay(500);
      }
    }
    // row 3 is pressed and column 1 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, LOW); digitalWrite(r4, HIGH);

    if (digitalRead(c1) == LOW) {
      str[position] = '7'; printToDisplay();
      if (digitalRead(c1) == LOW) {
        str[position] = (capslock ? 'S' : 's'); printToDisplay();
        if (digitalRead(c1) == LOW) {
          str[position] = (capslock ? 'T' : 't'); printToDisplay();
          if (digitalRead(c1) == LOW) {
            str[position] = (capslock ? 'U' : 'u'); printToDisplay();
          }
        }
      }
      a = 'c'   ;
      position++;
    }
    // row 3 is pressed and column 2 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, LOW); digitalWrite(r4, HIGH);

    if (digitalRead(c2) == LOW) {
      str[position] = '8'; printToDisplay();
      if (digitalRead(c2) == LOW) {
        str[position] = (capslock ? 'V' : 'v'); printToDisplay();
        if (digitalRead(c2) == LOW) {
          str[position] = (capslock ? 'W' : 'w'); printToDisplay();
          if (digitalRead(c2) == LOW) {
            str[position] = (capslock ? 'X' : 'x'); printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 3 is pressed and column 3 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, LOW); digitalWrite(r4, HIGH);

    if (digitalRead(c3) == LOW) {
      str[position] = '9'; printToDisplay();
      if (digitalRead(c3) == LOW) {
        str[position] = (capslock ? 'Y' : 'y'); printToDisplay();
        if (digitalRead(c3) == LOW) {
          str[position] = (capslock ? 'Z' : 'z'); printToDisplay();
        }
      }
      a = 'c';
      position++;
    }
    // row 3 is pressed and column 4 is pressed (Enter)
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, LOW); digitalWrite(r4, HIGH);

    if (digitalRead(c4) == LOW) {
      str[position] = '\n';
      position++;
      printToDisplay();
    }
    // row 4 is pressed and column 1 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, LOW);

    if (digitalRead(c1) == LOW) {
      str[position] = '*'; printToDisplay();
      if (digitalRead(c1) == LOW) {
        str[position] = '('; printToDisplay();
        if (digitalRead(c1) == LOW) {
          str[position] = ')'; printToDisplay();
          if (digitalRead(c1) == LOW) {
            str[position] = '-'; printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 4 is pressed and column 2 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, LOW);

    if (digitalRead(c2) == LOW) {
      str[position] = '0'; printToDisplay();
      if (digitalRead(c2) == LOW) {
        str[position] = '&'; printToDisplay();
        if (digitalRead(c2) == LOW) {
          str[position] = '|'; printToDisplay();
          if (digitalRead(c2) == LOW) {
            str[position] = '!'; printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 4 is pressed and column 3 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, LOW);

    if (digitalRead(c3) == LOW) {
      str[position] = '#'; printToDisplay();
      if (digitalRead(c3) == LOW) {
        str[position] = '%'; printToDisplay();
        if (digitalRead(c3) == LOW) {
          str[position] = '^'; printToDisplay();
          if (digitalRead(c3) == LOW) {
            str[position] = '&'; printToDisplay();
          }
        }
      }
      a = 'c';
      position++;
    }
    // row 4 is pressed and column 4 is pressed
    digitalWrite(r1, HIGH); digitalWrite(r2, HIGH);
    digitalWrite(r3, HIGH); digitalWrite(r4, LOW);

    if (digitalRead(c4) == LOW) {
      str[position] = ' ';
      position++;
      printToDisplay();
    }
  }
}

void printToDisplay() {
  oled.clearDisplay();
  oled.setTextSize(2);
  oled.setTextColor(WHITE);
  oled.setCursor(0, 0);
  oled.println(str);
  oled.display();
  delay(500);
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
keypad1:R1
keypad1:R2
keypad1:R3
keypad1:R4
keypad1:C1
keypad1:C2
keypad1:C3
keypad1:C4
oled1:GND
oled1:VCC
oled1:SCL
oled1:SDA