#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Encoder.h>
#include <EEPROM.h>
#include <Stepper.h>
// Inisialisasi LCD I2C dengan alamat 0x27 (sesuaikan jika berbeda)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Inisialisasi Rotary Encoder
Encoder encoder(2, 3);
const int encoderSwitchPin = 4;
const int executeButtonPin = 5;
long encoderPosition = -999;
int lastButtonState = HIGH;
int lastExecuteButtonState = HIGH;
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
// Alamat EEPROM untuk data 1 dan data 2
const int EEPROM_ADDR_DATA1 = 0;
const int EEPROM_ADDR_DATA2 = 10;
// Variabel menu
int currentMenu = 0;
int currentSubMenu = 0;
int menu1Selection = 0; // Untuk menyimpan pilihan Menu 1
float rotationValue = 0.0; // Menyimpan nilai sementara "Banyak Putaran"
char rotationDirectionTemp = 'C'; // Menyimpan arah putaran sementara
int speedValueTemp = 0; // Menyimpan kecepatan sementara
float rotationValues[2] = {0.0, 0.0}; // Menyimpan nilai "Banyak Putaran" untuk Data 1 dan Data 2
char rotationDirections[2] = {'C', 'C'}; // Menyimpan arah putaran untuk Data 1 dan Data 2 ('C' untuk CW, 'A' untuk CCW)
int speedValues[2] = {0, 0}; // Menyimpan kecepatan untuk Data 1 dan Data 2
void setup() {
pinMode(encoderSwitchPin, INPUT_PULLUP);
pinMode(executeButtonPin , INPUT_PULLUP);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Menu System");
Serial.begin(9600);
delay(2000);
lcd.clear();
updateLCD();
}
void loop() {
// Baca posisi rotary encoder
long newPosition = encoder.read();
if (newPosition != encoderPosition) {
encoderPosition = newPosition;
if (currentSubMenu == 0) {
// Navigasi menu utama
currentMenu = (newPosition / 4) % 4;
if (currentMenu < 0) currentMenu += 4;
} else if (currentSubMenu == 1) {
// Adjust nilai sub menu
switch (currentMenu) {
case 0:
menu1Selection = (newPosition / 4) % 2;
if (menu1Selection < 0) menu1Selection += 2;
break;
case 1:
rotationValue = ((newPosition / 4) % 1000) / 10.0;
if (rotationValue < 0) rotationValue += 100.0;
break;
case 2:
rotationDirectionTemp = ((newPosition / 4) % 2) ? 'A' : 'C';
break;
case 3:
speedValueTemp = (newPosition / 4) % 100;
if (speedValueTemp < 0) speedValueTemp += 100;
break;
}
} else if (currentSubMenu == 2) {
// Pilih data untuk disimpan
menu1Selection = (newPosition / 4) % 2;
if (menu1Selection < 0) menu1Selection += 2;
}
updateLCD();
}
// Baca tombol rotary encoder
int buttonState = digitalRead(encoderSwitchPin);
if (buttonState == LOW && lastButtonState == HIGH) {
// Tombol ditekan
if (currentSubMenu == 0) {
currentSubMenu = 1;
if (currentMenu == 0) {
encoder.write(0);
}
} else if (currentSubMenu == 1) {
if (currentMenu == 0) {
// Restore data dan print ke serial
restoreData(menu1Selection);
currentSubMenu = 3;
} else {
currentSubMenu = 2;
}
} else {
if (currentMenu == 1) {
rotationValues[menu1Selection] = rotationValue;
} else if (currentMenu == 2) {
rotationDirections[menu1Selection] = rotationDirectionTemp;
} else if (currentMenu == 3) {
speedValues[menu1Selection] = speedValueTemp;
}
saveData(menu1Selection);
printSaveData(menu1Selection);
currentSubMenu = 0;
encoder.write(0);
}
updateLCD();
}
lastButtonState = buttonState;
// Baca tombol eksekusi stepper
int executeButtonState = digitalRead(executeButtonPin);
if (executeButtonState == LOW && lastExecuteButtonState == HIGH) {
// Tombol eksekusi ditekan
Serial.println("ditekan");
executeStepper(menu1Selection);
if (currentMenu == 0 && currentSubMenu == 0) {
// Eksekusi stepper setelah restore data
Serial.println("dilepas");
}
}
lastExecuteButtonState = executeButtonState;
delay(100);
}
void updateLCD() {
lcd.clear();
if (currentSubMenu == 0) {
// Menu utama
lcd.setCursor(0, 0);
switch (currentMenu) {
case 0:
lcd.print("1.Data Tersimpan");
break;
case 1:
lcd.print("2.Banyak Putaran");
break;
case 2:
lcd.print("3.Arah Putaran");
break;
case 3:
lcd.print("4.Kecepatan");
break;
}
lcd.setCursor(0, 1);
lcd.print("Press to Enter");
} else if (currentSubMenu == 1) {
// Sub menu edit
switch (currentMenu) {
case 0:
lcd.setCursor(0, 0);
lcd.print("1. Data Tersimpan");
lcd.setCursor(0, 1);
lcd.print("1.1 Data ");
lcd.print(menu1Selection + 1);
break;
case 1:
lcd.setCursor(0, 0);
lcd.print("2. Banyak Putaran");
lcd.setCursor(0, 1);
lcd.print(rotationValue, 1);
break;
case 2:
lcd.setCursor(0, 0);
lcd.print("3. Arah Putaran");
lcd.setCursor(0, 1);
lcd.print(rotationDirectionTemp == 'C' ? "CW" : "CCW");
break;
case 3:
lcd.setCursor(0, 0);
lcd.print("4. Kecepatan");
lcd.setCursor(0, 1);
lcd.print(speedValueTemp);
lcd.print("%");
break;
}
} else if (currentSubMenu == 2) {
// Menu simpan data
lcd.setCursor(0, 0);
lcd.print("Simpan ke");
lcd.setCursor(0, 1);
lcd.print("Data ");
lcd.print(menu1Selection + 1);
} else if (currentSubMenu == 3) {
// Menu data tersimpan
lcd.setCursor(0, 0);
lcd.print("Data ");
lcd.print(menu1Selection + 1);
lcd.print(" = ");
// Tampilkan data sesuai pilihan
lcd.print("Rot:");
lcd.print(rotationValues[menu1Selection], 1);
lcd.setCursor(0, 1);
lcd.print("Dir:");
lcd.print(rotationDirections[menu1Selection] == 'C' ? "CW" : "CCW");
lcd.print(" ");
lcd.print("Spd:");
lcd.print(speedValues[menu1Selection]);
lcd.print("%");
}
}
void saveData(int dataSelection) {
int addr = (dataSelection == 0) ? EEPROM_ADDR_DATA1 : EEPROM_ADDR_DATA2;
EEPROM.put(addr, rotationValues[dataSelection]);
EEPROM.put(addr + sizeof(float), rotationDirections[dataSelection]);
EEPROM.put(addr + sizeof(float) + sizeof(char), speedValues[dataSelection]);
}
void restoreData(int dataSelection) {
int addr = (dataSelection == 0) ? EEPROM_ADDR_DATA1 : EEPROM_ADDR_DATA2;
EEPROM.get(addr, rotationValues[dataSelection]);
EEPROM.get(addr + sizeof(float), rotationDirections[dataSelection]);
EEPROM.get(addr + sizeof(float) + sizeof(char), speedValues[dataSelection]);
// Print data ke serial
Serial.print("submenu = ");
Serial.print(currentSubMenu );
Serial.print("Data ");
Serial.print(dataSelection + 1);
Serial.print(": Banyak Putaran = ");
Serial.print(rotationValues[dataSelection], 1);
Serial.print(", Arah Putaran = ");
Serial.print(rotationDirections[dataSelection] == 'C' ? "CW" : "CCW");
Serial.print(", Kecepatan = ");
Serial.print(speedValues[dataSelection]);
Serial.println("%");
}
void printSaveData(int dataSelection) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Data ");
lcd.print(dataSelection + 1);
lcd.setCursor(0, 1);
lcd.print("Saved");
delay(2000);
updateLCD();
}
void executeStepper(int dataSelection) {
// Menentukan arah putaran
if (rotationDirections[dataSelection] == 'C') {
myStepper.setSpeed(map(speedValues[dataSelection], 1, 100, 10, 1000)); // Map kecepatan dari 1-100% ke 10-1000 RPM
} else {
myStepper.setSpeed(map(speedValues[dataSelection], 1, 100, 10, 1000)); // Map kecepatan dari 1-100% ke 10-1000 RPM
myStepper.step(-rotationValues[dataSelection] * stepsPerRevolution); // Langkah negatif untuk arah CCW
return;
}
// Menggerakkan stepper berdasarkan banyak putaran
long steps = rotationValues[dataSelection] * stepsPerRevolution; // 1 putaran = stepsPerRevolution langkah
myStepper.step(steps);
}
// #include <Stepper.h>
// #include <LiquidCrystal_I2C.h>
// LiquidCrystal_I2C lcd(0x27, 16, 2);
// #define ENCODER_CLK 2
// #define ENCODER_DT 3
// #define ENCODER_SW 4
// int putaran = 0;
// int speed = 0;
// bool arah = 0;
// int menu = 0;
// int menu1 = 0;
// int menu2 = 0;
// int counter = 0;
// int counter1 = 0;
// int counter2 = 0;
// int count = 0;
// int count1 = 0;
// int count2 = 0;
// int save = 0;
// bool lastButtonState = HIGH; // Status tombol sebelumnya
// const int stepsPerRevolution = 28; // change this to fit the number of steps per revolution
// // for your motor
// // initialize the stepper library on pins 8 through 11:
// Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
// void setup() {
// // set the speed at 60 rpm:
// myStepper.setSpeed(100);
// // initialize the serial port:
// Serial.begin(9600);
// // Initialize LCD
// lcd.init();
// lcd.backlight();
// // Initialize encoder pins
// pinMode(ENCODER_CLK, INPUT);
// pinMode(ENCODER_DT, INPUT);
// pinMode(ENCODER_SW, INPUT_PULLUP);
// attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
// }
// void readEncoder() {
// int dtValue = digitalRead(ENCODER_DT);
// if (dtValue == HIGH) {
// if (menu == 0 && menu1 != 0){
// counter++; // Clockwise
// if (counter >=3) {counter = 3;}
// } else if(menu1 == 1){
// counter1++; // Clockwise
// if (counter1 >=2) {counter1 = 2;}
// } else if(menu2 == 1){
// counter2++; // Clockwise
// if (counter2 >=3) {counter2 = 3;}
// }
// }
// if (dtValue == LOW) {
// if (menu == 0){
// counter--; // Counterclockwise
// if (counter <=-3) {counter = -3;}
// } else if(menu1 == 1){
// counter1--; // Counterclockwise
// if (counter1 <=-2) {counter1 = -2;}
// } else if(menu2 == 1){
// counter2--; // Counterclockwise
// if (counter2 <=-3) {counter2 = -3;}
// }
// }
// }
// void loop() {
// bool currentButtonState = digitalRead(ENCODER_SW);
// if (lastButtonState == HIGH && currentButtonState == LOW) {
// count++;
// if (count == 1){
// count1++;
// }
// }
// lastButtonState = currentButtonState; // Update status tombol sebelumnya
// if (menu == 0 ){
// if (counter == 0){
// lcd.setCursor(0, 0);
// lcd.print("Data Tersimpan :");
// menu1 = 1;
// if (menu1 == 1){
// if (digitalRead(ENCODER_SW) == LOW) {
// lcd.setCursor(0, 1);
// lcd.print("1.Data 1");
// }
// if (counter1 == 1 || counter1 == -1){
// lcd.setCursor(0, 1);
// lcd.print("2.Data 2");
// }
// }
// // menu1 = 1;
// // if (menu1 == 1){
// // if (count == 1){
// // if (counter1 == 1 || counter1 == -1){
// // lcd.setCursor(0, 1);
// // lcd.print("1.");
// // if (count1 == 1){
// // lcd.setCursor(0, 1);
// // lcd.print("1.Data 1");
// // save = 1;
// // count = 0;
// // count1 = 0;
// // counter1 = 0;
// // }
// // } else if (counter1 == 2 || counter == -2){
// // lcd.setCursor(0, 1);
// // lcd.print("2.");
// // }
// // }
// // }
// } else if (counter == 1 || counter == -1){
// lcd.setCursor(0, 0);
// lcd.print(" Atur X Putaran ");
// } else if (counter == 2 || counter == -2){
// lcd.setCursor(0, 0);
// lcd.print(" Atur Kecepatan ");
// } else if (counter == 3 || counter == -3){
// lcd.setCursor(0, 0);
// lcd.print(" Atur Arah Putar ");
// }
// }
// // step one revolution in one direction:
// // Serial.println("clockwise");
// // myStepper.step(stepsPerRevolution);
// // delay(500);
// // step one revolution in the other direction:
// // Serial.println("counterclockwise");
// // myStepper.step(-stepsPerRevolution);
// // delay(500);
// }