#include <Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ENCODER_CLK 2
#define ENCODER_DT  3
#define ENCODER_SW  4

#define BUTTON2 8
#define BUTTON3 9

#define ECHO_PIN 6
#define TRIG_PIN 7

int servoPin = 11;
int servoPos = 90;
Servo servo1;

int previous1Time = millis();
int previous2Time = millis();
int previous3Time = millis();

OneWire oneWire(10);
DallasTemperature sensor(&oneWire);

volatile int lastClkState = HIGH;
volatile int lastDtState = HIGH;

volatile int lastButton1State = HIGH;
volatile int lastButton2State = HIGH;
volatile int lastButton3State = HIGH;

void setup() {
  Serial.begin(115200);
  sensor.begin();

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  pinMode(ENCODER_SW, INPUT_PULLUP); // Enable internal pull-up resistor for the switch
  pinMode(BUTTON2, INPUT_PULLUP);
  pinMode(BUTTON3, INPUT_PULLUP);
  servo1.attach(servoPin);

  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), clkISR, FALLING);
}

void loop() {
  servo1.write(servoPos);

  int button1State = digitalRead(ENCODER_SW);
  int button2State = digitalRead(BUTTON2);
  int button3State = digitalRead(BUTTON3);

  if (button1State != lastButton1State && button1State == LOW && ((millis()-previous1Time) > 50)) {
    servoPos = 90; // Reset servo position when button is pressed
    previous1Time = millis();
  }
  
  if (button2State != lastButton2State && button2State == LOW && ((millis()-previous2Time) > 50)) {
    float distance = readDistanceCM();
    Serial.print("Measured distance: ");
    Serial.println(readDistanceCM());
    previous2Time = millis();
  }
  
  if (button3State != lastButton3State && button3State == LOW && ((millis()-previous3Time) > 50)) {
    sensor.requestTemperatures();
    Serial.print("Temperature is: ");
    Serial.println(sensor.getTempCByIndex(0));
    previous3Time = millis();
  }

  lastButton1State = button1State;
  lastButton2State = button2State;
  lastButton3State = button3State;

}

void clkISR() {
  int dtState = digitalRead(ENCODER_DT);
  
  if (dtState == HIGH) {
    Serial.println("Rotated clockwise ⏩");
    if (servoPos < 180) {
      servoPos += 10;
    }
  } else {
    Serial.println("Rotated counterclockwise ⏪");
    if (servoPos > 0) {
      servoPos -= 10;
    }
  }
  servo1.write(servoPos);
}

float readDistanceCM() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  int duration = pulseIn(ECHO_PIN, HIGH);
  return duration * 0.0344 / 2;
}