#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
#define CALIBRATION_FACTOR 107

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Set the LCD I2C address

#include <Keypad.h> //include keypad library - first you must install library (library link in the video description)
const byte rows = 4; //number of the keypad's rows and columns
const byte cols = 4;
char keyMap [rows] [cols] = { //define the cymbols on the buttons of the keypad

  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'.', '0', '#', 'D'}
};

byte rowPins [rows] = {12, 11, 10, 9};
byte colPins [cols] = {8,7,6,5};

Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);

#include <HX711.h>
byte pinDt = 2; // DOUT
byte pinSck = 4; // SCK
HX711 scale; 

bool show_Weighing = false;

float data;
float data2;
float units;

void setup() {

  Serial.begin(9600);
//  bluetooth.begin(115200);
  Serial.println();
  lcd.begin(16, 2);
  lcd.backlight();
  lcd.init();
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("TIMBANGAN");
  lcd.setCursor(4,1);
  lcd.print("DIGITAL");
  Serial.println("TIMBANGAN DIGITAL");

  scale.begin(pinDt, pinSck);
  scale.set_scale(CALIBRATION_FACTOR);
  scale.tare();
  // show_Weighing = true;
  
}

void loop()
{

static char userinput[11];
static int count = 0;
int number;

  char key = myKeypad.getKey();

  if (key != NO_KEY)
  {
    lcd.print(key);
    Serial.println(key);
  }

 
  switch (key)
  {
    case NO_KEY:
      break;
      
      case 'A':
      
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("A.prep");
      lcd.setCursor(0,1);
      lcd.print("B.input");
      lcd.setCursor(8,0);
      lcd.print("C.Cal");
      lcd.setCursor(8,1);
      lcd.print("D.tare");

//      Serial.println("A.prep");
//      Serial.println("B.input");
//      Serial.println("C.Cal");
//      Serial.println("D.tare");
      
      show_Weighing = false;

      break;

    case 'B':

      show_Weighing = false;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("Press a number:"));
//Serial.println("Press a number:");
// clear the current user input
      lcd.setCursor(0, 1);
      memset(userinput, 0, sizeof(userinput));
      number=(userinput, 0, sizeof(userinput));
      // reset the counter
      count = 0;
      break;
      
    case 'C':           //Get number from memory and print to LCD
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("Number: "));
      lcd.setCursor(0, 1);
      lcd.print(userinput);//print the stored number
      
      Serial.print(F("Number: "));
      Serial.println(userinput);
      delay(1000);
      
      data = atof (userinput);
      if (scale.is_ready()) {
          scale.set_scale(data);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Weight: ");
          lcd.setCursor(0, 1);
          lcd.print(scale.get_units(2),0);
          lcd.print("  g");

          Serial.print("Weight: ");
          Serial.print(scale.get_units(2),0);
          Serial.println("  g");
      }
       
        for (byte i = 7; i > 0; i--) {
          lcd.setCursor(0, 0);
          lcd.print("Weight: ");
          lcd.setCursor(0, 1);
          lcd.print(scale.get_units(2));
          
          Serial.print("Weight: ");
          Serial.print(scale.get_units(2),0);
                    
          EEPROM.write(0, scale.get_units(2));
          delay(1000);
        }

        data2 = EEPROM.read(0);
        lcd.clear();
        lcd.setCursor(1, 0);
        lcd.print("Hitung Beban");
        Serial.println("Hitung Beban");
        delay (2000);
        
        if (scale.is_ready()) {
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Calibration");
            // Serial.println("Calibration MODE");
            scale.set_scale(data2);

            Serial.println("Calibration");
 
            delay(1000);
            show_Weighing = true;
          }
      break;
     
     case 'D':
        scale.tare();
        delay(100);
        break;

      case '#':
        show_Weighing = true;
         delay(100);
        break;
      
    default:
      // if not 10 characters yet
      if (count < 10)
      {
        // add key to userinput array and increment counter
        userinput[count++] = key;
      }
      break;
  }

   if(Serial.available()) {
    char inChar = (char)Serial.read();  // Accommodates incoming characters from serial communication.
    Serial.println(inChar);

    if (inChar == 'A') {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("A.prep");
      lcd.setCursor(0,1);
      lcd.print("B.input");
      lcd.setCursor(8,0);
      lcd.print("C.Cal");
      lcd.setCursor(8,1);
      lcd.print("D.tare");

      show_Weighing = false;
    }

    if (inChar == 'B') {
      show_Weighing = false;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("Press a number:"));
//Serial.println("Press a number:");
// clear the current user input
      lcd.setCursor(0, 1);
      memset(userinput, 0, sizeof(userinput));
      number=(userinput, 0, sizeof(userinput));
      // reset the counter
      count = 0;

    }

    if (inChar == 'C') {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("Number: "));
      lcd.setCursor(0, 1);
      lcd.print(userinput);//print the stored number
      
      Serial.print(F("Number: "));
      Serial.println(userinput);
      delay(1000);
      
      data = atof (userinput);
      if (scale.is_ready()) {
          scale.set_scale(data);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Weight: ");
          lcd.setCursor(0, 1);
          lcd.print(scale.get_units(2),0);
          lcd.print("  g");

          Serial.print("Weight: ");
          Serial.print(scale.get_units(2),0);
          Serial.println("  g");
      }
       
        for (byte i = 7; i > 0; i--) {
          lcd.setCursor(0, 0);
          lcd.print("Weight: ");
          lcd.setCursor(0, 1);
          lcd.print(scale.get_units(2));
          
          Serial.print("Weight: ");
          Serial.print(scale.get_units(2),0);
                    
          EEPROM.write(0, scale.get_units(2));
          delay(1000);
        }

        data2 = EEPROM.read(0);
        lcd.clear();
        lcd.setCursor(1, 0);
        lcd.print("Hitung Beban");
        Serial.println("Hitung Beban");
        delay (2000);
        
        if (scale.is_ready()) {
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Calibration");
            // Serial.println("Calibration MODE");
            scale.set_scale(data2);

            Serial.println("Calibration");
 
            delay(1000);
            show_Weighing = true;
          }
    }

    if (inChar == 'D') {
    scale.tare();
    delay(100);
    }

    if (inChar == '#') {
    show_Weighing = true;
  }

   }
  if (show_Weighing == true) {
    if (scale.is_ready()) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Weight: ");
    lcd.setCursor(0, 1);
    lcd.print(units, 0);
    lcd.print(" g");

    Serial.print("Weight: ");
    Serial.print(units,0);
    Serial.println("  g");
          
    units = scale.get_units(10),0;
     if (units < 0)
     { units = 0;}
     
      delay (200);
       }
      }
}