#include <Servo.h>
#include <ModbusRtu.h>
uint16_t au16data[16] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1
};
Modbus slave(1, 0, 0);

#define START 2       // SSR1
#define COOLING 3     // SSR2
#define AGITATOR 4    // SSR3
#define LAMP 5        // SSR4

#define buttonSTART 6         //button for START
#define buttonCOOLING 7       //button for COOLING
#define buttonAGITATOR 8      //button for AGITATOR
#define buttonLAMP 9          //button for LAMP

int STARTState = LOW;         //track the state of START
int COOLINGState = LOW;       //track the state of COOLING
int AGITATORState = LOW;      //track the state of AGITATOR
int LAMPState = LOW;          //track the state of LAMP

#define potValve A4
#define potAirflow A5

#define airflow 11            //Servo pin airflow
Servo Airflow_Digital10;

#define valve 10               //Servo pin valve
Servo Valve_Digital9;


void setup() {
  Serial.begin(9600);
  slave.begin(9600); // Perbaikan pada inisialisasi Modbus
  
  pinMode(START, OUTPUT);     //SSR1
  pinMode(COOLING, OUTPUT);   //SSR2
  pinMode(AGITATOR, OUTPUT);  //SSR3
  pinMode(LAMP, OUTPUT);      //SSR4

  pinMode(buttonSTART, INPUT_PULLUP);     //button for START
  pinMode(buttonCOOLING, INPUT_PULLUP);   //button for COOLING
  pinMode(buttonAGITATOR, INPUT_PULLUP);  //button for AGITATOR
  pinMode(buttonLAMP, INPUT_PULLUP);      //button for LAMP

  pinMode(potAirflow, INPUT);   //Potensio airFlow
  pinMode(potValve, INPUT);     //potensio valve

  pinMode(airflow, OUTPUT);     //PWM servo
  pinMode(valve, OUTPUT);       //PWM servo

  Airflow_Digital10.attach(airflow);
  Valve_Digital9.attach(valve);

  digitalWrite(START, LOW);
  digitalWrite(COOLING, LOW);
  digitalWrite(AGITATOR, LOW);
  digitalWrite(LAMP, LOW);
}

void loop() {
  slave.poll(au16data, 16);

  //START
  int buttonStateSTART = digitalRead(buttonSTART);
  if (buttonStateSTART != STARTState) {
    STARTState = buttonStateSTART;
    if (STARTState == HIGH) {
      au16data[8] = 99;
    } else {
      au16data[8] = 1;
    }
  }
  for (int i = 1; i <= 99; i++) {
    if (i <= au16data[8]) {
      digitalWrite(START, HIGH);
    }
    else {
      digitalWrite(START, LOW);
    }
  }

  // COOLING & AGITATOR
  int buttonStateAGITATOR = digitalRead(buttonAGITATOR);
  int buttonStateCOOLING = digitalRead(buttonCOOLING);
  // Mengatur COOLING dan AGITATOR berdasarkan kondisi tombol
  if (buttonStateCOOLING == 1 && buttonStateAGITATOR == 1) {
    digitalWrite(COOLING, 1);
    digitalWrite(AGITATOR, 1);
  } else if (buttonStateAGITATOR == 1 && buttonStateCOOLING == 0) {
    digitalWrite(AGITATOR, 1);
    digitalWrite(COOLING, 0);
  } else if (buttonStateAGITATOR == 0 && buttonStateCOOLING == 1) {
    digitalWrite(AGITATOR, 0);
    digitalWrite(COOLING, 1);
  } else if (buttonStateAGITATOR == 0 && buttonStateCOOLING == 0) {
    digitalWrite(AGITATOR, 1);
    digitalWrite(COOLING, 0);
  } else {
    digitalWrite(AGITATOR, 0);
    digitalWrite(COOLING, 0);
  }
  // Perbarui status COOLING hanya jika ada perubahan pada tombol
  if (buttonStateCOOLING != COOLINGState) {
    COOLINGState = buttonStateCOOLING;
    au16data[12] = (COOLINGState == 1) ? 99 : 1;
  }
  // Mengatur COOLING dan AGITATOR berdasarkan nilai au16data[12]
  for (int i = 1; i <= 99; i++) {
    digitalWrite(COOLING, i <= au16data[12]);
    if (buttonStateAGITATOR == 1) {
      digitalWrite(AGITATOR, i <= au16data[12]);
    } else if (buttonStateAGITATOR == 0 && buttonStateCOOLING == 1) {
      digitalWrite(AGITATOR, 0);
    } else if (buttonStateAGITATOR == 0 && buttonStateCOOLING == 0) {
      if (au16data[12] <= 1) {
        digitalWrite(AGITATOR, 1);
      } else {
        digitalWrite(AGITATOR, 0);
      }
    }
  }

  // LAMP
  int buttonStateLAMP = digitalRead(buttonLAMP);
  if (buttonStateLAMP != LAMPState) {
    LAMPState = buttonStateLAMP;
    if (LAMPState == HIGH) {
      au16data[13] = 99;
    } else {
      au16data[13] = 1;
    }
  }
  for (int i = 1; i <= 99; i++) {
    if (i <= au16data[13]) {
      digitalWrite(LAMP, HIGH);
    }
    else {
      digitalWrite(LAMP, LOW);
    }
  }

/*  // VALVE
  int potValue1 = analogRead(potValve);
  int averageValue1 = map (potValue1, 0, 1023, 80, 65 );
  int sliderValue1 = map(au16data[4], -38, 100, 145, 15);
  averageValue1 = constrain(averageValue1, 0, 80);
  sliderValue1 = constrain(sliderValue1, 0, 145);
  int combinedValue1;
  // Konstanta untuk menghaluskan pergerakan servo
  const float smoothingFactor1 = 0.3;
  static float smoothedValue1 = 0.0;
  if (averageValue1 < sliderValue1) {
    combinedValue1 = averageValue1;
  } else {
    combinedValue1 = sliderValue1;
  }
  // Menggunakan filter rata-rata bergerak eksponensial
  smoothedValue1 = smoothingFactor1 * combinedValue1 + (1.0 - smoothingFactor1) * smoothedValue1;
  Valve_Digital9.write(smoothedValue1);
  //delay(10);
*/

  // VALVE
  int potValue1 = analogRead(potValve);
  int sliderValue1 = map(au16data[4], 100, -40, -48, 206);
  int combinedValue1 = max(map(potValue1, 0, 1023, 91, 0), sliderValue1);
  Valve_Digital9.write(map(combinedValue1, 0, 211, 0, 180));

  // AIRFLOW
  int potValue = analogRead(potAirflow);
  int sliderValue = map(au16data[5], -40, 100, -94, 131);
  int combinedValue = max(map(potValue, 0, 1023, 0, 91), sliderValue);
  Airflow_Digital10.write(map(combinedValue, 0, 180, 0, 180));



au16data[3] =   244;
au16data[6] =   150;     

}