#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Encoder & Output
#define ENCODER_A 2
#define ENCODER_B 3
#define SigmaAuto 5
#define RelayOut 8
// Tombol Navigasi Menu
#define BTN_MENU 6
#define BTN_ENTER 7
#define BTN_UP 9
#define BTN_DOWN 10
// LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Variabel penghitungan encoder
volatile long pulseCount = 0;
bool isCounting = false;
bool isLimitReached = false;
bool lastSigmaAutoState = HIGH;
// Variabel pengaturan (bisa diubah dari menu)
int ppr = 120;
float wheelCirc = 100.0;
int maxLength = 2000;
// Variabel menu
int settingIndex = 0;
bool editMode = false;
unsigned long menuActiveTime = 0;
const unsigned long menuTimeout = 5000; // Waktu diam 10 detik untuk keluar dari menu
bool menuActive = false;
void readEncoder() {
if (!isCounting || isLimitReached) return;
if (digitalRead(ENCODER_A) == HIGH) {
if (digitalRead(ENCODER_B) == HIGH) {
pulseCount++;
} else {
pulseCount--;
}
}
}
void setup() {
Serial.begin(115200);
// Pin setup
pinMode(ENCODER_A, INPUT);
pinMode(ENCODER_B, INPUT);
pinMode(SigmaAuto, INPUT);
pinMode(RelayOut, OUTPUT);
pinMode(BTN_MENU, INPUT_PULLUP);
pinMode(BTN_ENTER, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_A), readEncoder, CHANGE);
// LCD setup
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Program Load...");
lcd.setCursor(0, 1);
lcd.print("by Jikun MTC SKF");
delay(3000);
lcd.clear();
Serial.println("Program dimulai...");
}
bool readButton(int pin) {
static unsigned long lastPress[11] = {0}; // 11 = max pin checked
if (digitalRead(pin) == LOW && millis() - lastPress[pin] > 200) {
lastPress[pin] = millis();
return true;
}
return false;
}
void showMenu() {
lcd.clear();
lcd.setCursor(0, 0);
switch (settingIndex) {
case 0: lcd.print("Set PPR: "); lcd.print(ppr); break;
case 1: lcd.print("Set Wheel: "); lcd.print(wheelCirc); break;
case 2: lcd.print("Set MaxLen: "); lcd.print(maxLength); break;
}
lcd.setCursor(0, 1);
lcd.print(editMode ? "<Edit Mode>" : "<View Mode>");
menuActive = true;
menuActiveTime = millis(); // Reset waktu aktivitas menu
}
void loop() {
static unsigned long lastPrintTime = 0;
// === Menu Navigasi ===
if (readButton(BTN_MENU)) {
settingIndex = (settingIndex + 1) % 3;
editMode = false;
showMenu();
lastPrintTime = millis();
return;
}
if (readButton(BTN_ENTER)) {
editMode = !editMode;
showMenu();
lastPrintTime = millis();
return;
}
if (editMode) {
if (readButton(BTN_UP)) {
if (settingIndex == 0) ppr += 10;
if (settingIndex == 1) wheelCirc += 1.0;
if (settingIndex == 2) maxLength += 100;
showMenu();
lastPrintTime = millis();
return;
}
if (readButton(BTN_DOWN)) {
if (settingIndex == 0 && ppr > 10) ppr -= 10;
if (settingIndex == 1 && wheelCirc > 1) wheelCirc -= 1.0;
if (settingIndex == 2 && maxLength > 100) maxLength -= 100;
showMenu();
lastPrintTime = millis();
return;
}
}
// === Fungsi utama selama SigmaAuto aktif ===
bool SigmaAutoState = digitalRead(SigmaAuto);
if (!SigmaAutoState && lastSigmaAutoState) {
Serial.println("SigmaAuto OFF: Reset panjang ke 0 mm");
pulseCount = 0;
isLimitReached = false;
isCounting = false;
digitalWrite(RelayOut, LOW);
}
if (SigmaAutoState && !lastSigmaAutoState) {
Serial.println("SigmaAuto ON: Hitungan dimulai...");
isCounting = true;
}
lastSigmaAutoState = SigmaAutoState;
int length_mm = (int)((pulseCount / (float)ppr) * wheelCirc);
if (length_mm >= maxLength && !isLimitReached) {
isLimitReached = true;
isCounting = false;
digitalWrite(RelayOut, HIGH);
Serial.println("Mencapai batas panjang, RelayOut ON!");
}
// === Update LCD setiap 500ms (jika tidak di menu) ===
if (millis() - lastPrintTime > 500 && !menuActive) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SigmaAuto: ");
lcd.print(SigmaAutoState ? "ON " : "OFF");
lcd.setCursor(0, 1);
lcd.print("P: ");
lcd.print(length_mm);
lcd.print(" mm");
Serial.print("SigmaAuto: ");
Serial.print(SigmaAutoState ? "ON" : "OFF");
Serial.print(" | Pulse: ");
Serial.print(pulseCount);
Serial.print(" | Panjang: ");
Serial.print(length_mm);
Serial.println(" mm");
lastPrintTime = millis();
}
// === Timeout menu otomatis keluar jika tidak ada input selama 10 detik ===
if (menuActive && millis() - menuActiveTime > menuTimeout) {
menuActive = false;
editMode = false;
lcd.clear();
}
delay(50);
}