#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#define BUTTON_PIN 12  // Pin tombol
#define SERVO_PIN 15   // Pin servo
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Servo setup
Servo servoMotor;
int servoOpenAngle = 90;
int servoCloseAngle = 0;
// Variables
bool isButtonPressed = false;
float weightInput = 0; // Desired weight in grams
unsigned long lastButtonPress = 0; // For debouncing button press
void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  servoMotor.attach(SERVO_PIN);
  Serial.begin(115200); // Debugging
  // Initialize LCD
  lcd.begin(16, 2);
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("ATM BERAS");
  Serial.println("LCD Initialized");
  // Initialize Servo
  servoMotor.attach(SERVO_PIN);
  servoMotor.write(servoCloseAngle); // Start with closed position
  Serial.println("Servo Initialized");
  // Initialize Pushbutton
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  Serial.println("Button Initialized");
  // Wait for system boot
  delay(2000);
  lcd.clear();
}
void loop() {
  // Check pushbutton as RFID simulation with debounce
  if (digitalRead(BUTTON_PIN) == LOW && (millis() - lastButtonPress) > 500) {
    lastButtonPress = millis();
    if (!isButtonPressed) {
      isButtonPressed = true;
      Serial.println("Button Pressed");
      startProcess();
    }
  } else if (digitalRead(BUTTON_PIN) == HIGH) {
    isButtonPressed = false;
  }
}
void startProcess() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Masukan Gram:");
  Serial.println("Masukan Gramasi");
  
  // Input jumlah gramasi melalui serial
  weightInput = getWeightFromSerial();
  if (weightInput > 0) {
    lcd.setCursor(0, 1);
    lcd.print(String(weightInput) + "g");
    delay(2000);
    dispenseRice(weightInput);
  } else {
    lcd.clear();
    lcd.print("Input Invalid");
    delay(2000);
  }
}
float getWeightFromSerial() {
  String input = "";
  lcd.setCursor(0, 1);
  Serial.println("Masukkan berat dalam gram:");
  while (true) {
    if (Serial.available()) {
      char key = Serial.read();
      if (key == '\n') break; // End input with enter
      input += key;
      lcd.print(key); // Tampilkan karakter pada LCD
    }
  }
  return input.toFloat();
}
void dispenseRice(float targetWeight) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Proses...");
  servoMotor.write(servoOpenAngle); // Open servo
  delay(1000); // Simulate the dispensing action for 1 second
  while (true) {
    // Simulate weight sensing (replace with actual sensor logic if available)
    float currentWeight = targetWeight; // For testing, it's set to target weight
    lcd.setCursor(0, 1);
    lcd.print("Weight: " + String(currentWeight, 1) + "g");
    if (currentWeight >= targetWeight) {
      servoMotor.write(servoCloseAngle); // Close servo
      delay(500);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Selesai");
      lcd.setCursor(0, 1);
      lcd.print("Beras: " + String(targetWeight) + "g");
      delay(3000);
      break;
    }
  }
}