// UTS SISTEM KENDALI CERDAS
// RIO ARDIANSYAH
// 221113006
// TEKNIK ELEKTRO

const int trigPin = 7; // deklarasi pin 7 untuk trig sensor ultrasonik
const int echoPin = 6; // deklarasi pin 6 untuk echo sensor ultrasonik

float a[1];//inisiasi ukuran array untuk nilai slope
float b[1];//inisiasi ukuran array hasil nilai intercept

float slope; // deklarasi nilai slope
float intercept; // deklarasi nilai intercept

void setup() {
  
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // data maping sensor ultrasonik diambil dari sensor ultrasonik tanpa perhitungan
  // nilai x sebagai data PWM 
  float x[] = {118,1524,2688,3800,4970,6317,7423,9240,10875,12045,13216,14504,16315,17656,19474};
  // nilai y sebagai data jarak yang terbaca sensor ultrasonik
  float y[] = {2,26,46,65,85,108,127,158,186,206,226,248,279,302,333};

  // ukuran data yang digunakan
  int n = sizeof(x) / sizeof(x[0]);

  // deklarasi slope intercept dan juga pembuatan fungsi untuk menghitung regresi linear
  float slope, intercept;
  linearRegression(x, y, n, slope, intercept);

  // tampilan slope dan intercept
  Serial.print("Slope: ");
  Serial.println(slope, 4);
  Serial.print("Intercept: ");
  Serial.println(intercept, 4);
  a[0]=slope; // memasukkan data perhitungan slope ke dalam array a
  b[0]=intercept; // memasukkan data perhitungan intercept ke dalam array b
}

void loop() {
// looping perhitungan jarak sensor ultrasonik
  long duration, distance;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // pembacaan data PWM 
  duration = pulseIn(echoPin, HIGH);

  // menghitung jarak dengan menggunakan data perhitungan regresi linear (slope dan intercept)
  distance = duration * a[0]+ b[0];

  // tampilan jarak sensor utrasonik
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(1000);
}

// fungsi perhitungan regresi linier
void linearRegression(float x[], float y[], int n, float &slope, float &intercept) {
  float sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;

  for (int i = 0; i < n; i++) {
    sumX += x[i];
    sumY += y[i];
    sumXY += x[i] * y[i];
    sumX2 += x[i] * x[i];
  }

  slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
  intercept = (sumY - slope * sumX) / n;
}