// 2209106055
// Muhammad Hamzah


const int BUTTON_UP_PIN = 4;    
const int BUTTON_DOWN_PIN = 5;  
const int POT_PIN = 1;          
const int MOTOR_PIN = 13;   

const int PWM_FREQ = 5000;      
const int PWM_RESOLUTION = 8;

int currentSpeed = 0;          
int speedLimit = 255;          

void setup() {
  Serial.begin(115200);
  Serial.println("Simulasi Kontrol Motor DC (ESP32-S3)");


  pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
  pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);

  ledcAttach(MOTOR_PIN, PWM_FREQ, PWM_RESOLUTION); 

  ledcWrite(MOTOR_PIN, currentSpeed);
}

void loop() {
  unsigned long lastDebounceTimeUp = 0;
  unsigned long lastDebounceTimeDown = 0;
  unsigned long debounceDelay = 50;
  int lastButtonStateUp = LOW;
  int lastButtonStateDown = LOW;
  int currentButtonStateUp;
  int currentButtonStateDown;

  int potValue = analogRead(POT_PIN);
  // ESP32-S3 ADC biasanya 12-bit (0-4095), map ke resolusi PWM (0-255)
  speedLimit = map(potValue, 0, 4095, 0, 255);

  currentButtonStateUp = digitalRead(BUTTON_UP_PIN);
  if (currentButtonStateUp != lastButtonStateUp) {
    lastDebounceTimeUp = millis(); 
  }
  if ((millis() - lastDebounceTimeUp) > debounceDelay) {

    if (currentButtonStateUp == LOW) { // Tombol ditekan (karena pakai pull-up internal)
      currentSpeed += 5;
      if (currentSpeed > speedLimit) {
        currentSpeed = speedLimit; // Batasi dengan speedLimit
      }
    }
  }
  lastButtonStateUp = currentButtonStateUp; // Simpan state terakhir

  currentButtonStateDown = digitalRead(BUTTON_DOWN_PIN);
  if (currentButtonStateDown != lastButtonStateDown) {
    lastDebounceTimeDown = millis(); // Reset timer debounce
  }
  if ((millis() - lastDebounceTimeDown) > debounceDelay) {

    if (currentButtonStateDown == LOW) { // Tombol ditekan
      currentSpeed -= 5;
      if (currentSpeed < 0) {
        currentSpeed = 0;
      }
    
  }
  }
  lastButtonStateDown = currentButtonStateDown; // Simpan state terakhir



  ledcWrite(MOTOR_PIN, currentSpeed);

  int simulatedRPM = map(currentSpeed, 0, 255, 0, 1000);

  static unsigned long lastPrintTime = 0;
  if (millis() - lastPrintTime > 250) { 
    Serial.print("Current Speed (PWM): ");
    Serial.print(currentSpeed);
    Serial.print(" | Speed Limit (PWM): ");
    Serial.print(speedLimit);
    Serial.print(" | Simulated RPM: ");
    Serial.println(simulatedRPM);
    lastPrintTime = millis();
  }
  delay(100);
}