#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <HX711.h>
#include <ESP32Servo.h>
// Inisialisasi LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C LCD bisa bervariasi (0x27 atau 0x3F)
// Servo setup
#define SERVO_PIN 15
Servo servoMotor;
int servoOpenAngle = 0;
int servoCloseAngle = 90;
// Konfigurasi keypad 4x4
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {23, 19, 18, 5}; // Pin GPIO untuk baris
byte colPins[COLS] = {17, 16, 4, 2}; // Pin GPIO untuk kolom
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Inisialisasi HX711 untuk loadcell
#define DT 25 // Data pin HX711
#define SCK 26 // Clock pin HX711
HX711 scale;
float target = 0; // Variabel target berat
bool loadcellActive = false;
// Faktor kalibrasi yang dihitung berdasarkan perbandingan antara berat sebenarnya dan yang terukur
float calibrationFactor = 4.2; // 0.8 kg / 2.41 kg
void setup() {
Serial.begin(115200); // Debugging
servoMotor.attach(SERVO_PIN);
servoMotor.write(servoCloseAngle); // Start with closed position
Serial.println("Servo Initialized");
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("ATM BERAS");
lcd.setCursor(0,1);
lcd.print("Al-Mu'minun");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan KG:");
// Inisialisasi HX711
scale.begin(DT, SCK);
scale.set_scale(calibrationFactor); // Set nilai kalibrasi awal yang mendekati
scale.tare(); // Kalibrasi awal (menghilangkan berat beban awal)
}
void loop() {
static String inputBuffer = "";
char key = keypad.getKey();
if (!loadcellActive) {
if (key) {
if (key >= '0' && key <= '9') {
// Menambahkan angka ke buffer input
inputBuffer += key;
lcd.setCursor(0, 1);
lcd.print(inputBuffer);
} else if (key == '#') {
// Konfirmasi input target
target = inputBuffer.toFloat();
inputBuffer = "";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mengambil ");
lcd.print(target);
lcd.print("kg");
loadcellActive = true;
} else if (key == '*') {
// Reset input
inputBuffer = "";
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
} else {
// Membaca berat terukur dan mengalikan dengan faktor kalibrasi
float weight = scale.get_units()/100;
servoMotor.write(servoOpenAngle); // membuka servo
Serial.println("Servo terbuka");
lcd.setCursor(0, 1);
lcd.print(weight, 2);
lcd.print(" kg ");
if (weight >= target) {
servoMotor.write(servoCloseAngle); // menutup servo
Serial.println("Servo tertutup");
loadcellActive = false;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Silakan Ambil");
lcd.setCursor(0, 1);
lcd.print(target);
lcd.print(" kg ");
delay(5000); // Tampilkan "Berhasil" selama 5 detik
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan KG:");
}
}
}