#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include "pitches.h"

const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};

//Pin connected to ST_CP (Storage Clock / Latch) of 74HC595
int latchPin = 4;
//Pin connected to SH_CP (Shift Clock) of 74HC595
int clockPin = 3;
////Pin connected to DS / SER (Data/Serial Input) of 74HC595
int dataPin = 5;

// Pin used for the button
int toneButton = A5;

// Whatever the button has been pressed
bool buttonPressed = false;

// Pin used for the piezo buzzer
int buzzerPin = 2;

// The number incoming to toneOut/shiftOut as well as the previous one
int incomingNum = 0;
int incomingNum_last = 0;

// the inputted number as a string and its converted binary value as a string
String inputNum;
String inputBin;

// The current and previous states of the button

int buttonState = LOW;
int lastButtonState = LOW;


// previous time since last button press
unsigned long lastDebounceTime = 0;

// delay (in ms) before button press can be registered again
unsigned long debounceDelay = 50;

// the notes for the high note to indicate a 1 and low note to indicate a 0 as set by pitches.h
int highNote = NOTE_C4;
int lowNote = NOTE_C2;

String typedString ="";
int typedInt = 0;

uint8_t colPins[COLS] = { 9, 8, 7, 6 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 13, 12, 11, 10 }; // Pins connected to R1, R2, R3, R4

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

#define I2C_ADDR    0x27
#define LCD_COLUMNS 16
#define LCD_LINES   2

LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);



void setup() {
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(toneButton, INPUT);
  pinMode(buzzerPin, OUTPUT);

  // Cleaning up serial monitor and announcing program has initalized and going to loop
  for(int a = 0; a < 25; a++) {
    Serial.println("");
  }

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Please enter #");
  lcd.setCursor(0,1);
  lcd.print("from 0 to 255");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,0);

}





void loop() {
  char key = keypad.getKey();
  typedInt = typedString.toInt();

  if (key != NO_KEY && isDigit(key)) {
    typedString += key;
    lcd.print(key);
  }

  if(key == '#') {
    typedInt = typedString.toInt();
    Serial.println(typedInt);
  }

  if(key == '*') {
    lcd.clear();
    lcd.home();
    typedString = "";
  }
/*
  if (key == '#' && typedString.toInt() <= 255 && typedString.toInt() >= 0)
  {
    Serial.println(typedString.toInt());
    lcd.print(typedString);
    delay(2000);
    lcd.clear();
    lcd.home();
  }

*/

  if (key == '#' && typedInt > 255) {
    Serial.println("Invalid number please try again!");
    lcd.clear();
    lcd.home();
    lcd.print("INVALID!");
    delay(2000);
    lcd.clear();
    lcd.home();
    lcd.print("0 - 255 ONLY!");
    delay(2000);
    lcd.clear();
    lcd.home();

  }
  
}

void toneOut(int tonePin, uint8_t bitOrder, uint8_t val, int delayTime)
{
  if (bitOrder == LSBFIRST) {
    for (int i = 0; i < 8; i++)  {

      Serial.print(bitRead(val, i));
      delay(delayTime);
      if (bitRead(val, i) == 0) {
        tone(tonePin, lowNote);
        delay(delayTime);
        noTone(tonePin);
      } else {
        tone(tonePin, highNote);
        delay(delayTime);
        noTone(tonePin);
      }


    }
  } else {
    for (int i = 7; i >= 0; i--)  {

      Serial.print(bitRead(val, i));
      delay(delayTime);
      if (bitRead(val, i) == 0) {
        tone(tonePin, lowNote);
        delay(delayTime);
        noTone(tonePin);
      } else {
        tone(tonePin, highNote);
        delay(delayTime);
        noTone(tonePin);
      }
    }}}
   
$abcdeabcde151015202530fghijfghij
74HC595