/*
 * Program sistem pencahayaan kandang ayam dengan metode fuzzy logic mamdani
 * Rizky Pratama Rusdiana
 * 2212191024
 * Tugas Instrumentasi Cerdas
 */
 
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


typedef struct suhu{
  float dingin,
        agakDingin,
        sejuk,
        agakPanas,
        panas;
} suhu;


typedef struct cahaya{
  float gelap,
        agakGelap,
        remang2,
        agakTerang,
        terang;
} cahaya;


typedef struct lampu{
  float padam = 5;
  float redup = 25;
  float normal = 50;
  float sedang = 75;
  float terang = 100;        
} lampu;


// Fungsi Minimum & Maximum //
float minimum(float a, float b) {
  return a < b ? a : b;
}

float maximum(float a, float b) {
  return a > b ? a : b;
}

// Fungsi Pembentukan Membership Function //
float trapmf(float a, float b, float c, float d, float x) {
  return maximum(minimum(minimum(((x - a)/(b - a)),((d - x)/(d - c))), 1), 0);
}


float bobot1,
      bobot2,
      bobot3,
      bobot4,
      bobot5,
      bobot6,
      bobot7,
      bobot8,
      bobot9,
      bobot10,
      bobot11,
      bobot12,
      bobot13,
      bobot14,
      bobot15,
      bobot16,
      bobot17,
      bobot18,
      bobot19,
      bobot20,
      bobot21,
      bobot22,
      bobot23,
      bobot24,
      bobot25;


float inSuhu = 0;
float inCahaya = 0;
float rataBobot = 0;
float sumrataBobot = 0;
float out = 0;
float suhu_x, cahaya_x;


suhu Suhu;
cahaya Cahaya;
lampu Lampu;



void setup() {
  Serial.begin(9600);
  
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Fuzzy Mamdani");
  lcd.setCursor(0, 1);
  lcd.print("Rizky Pratama");
  delay(500);
}


void loop() {
  fuzzyMamdani();
  
  inSuhu = analogRead(A0);
  inCahaya = analogRead(A1);
  suhu_x = map(inSuhu, 0, 1023, 5, 45);
  cahaya_x = map(inCahaya, 0, 1023, 0, 400);

  lcd.setCursor(0, 0);
  lcd.print("In1:");
  lcd.setCursor(4, 0);
  lcd.print(suhu_x);
  lcd.setCursor(9, 0);
  lcd.print("In2;");
  lcd.setCursor(13, 0);
  lcd.print(cahaya_x);
  lcd.setCursor(0, 1);
  lcd.print("Warning;");
  lcd.setCursor(8, 1);
  lcd.print(out);
  delay(500);
  lcd.clear();
  Serial.print("out = ");
  Serial.println(rataBobot);
  Serial.print("out2 = ");
  Serial.println(sumrataBobot);
}


void fuzzyMamdani(){
  Suhu.dingin = trapmf(5, 5, 10, 15, suhu_x);
  Suhu.agakDingin = trapmf(10, 15, 20, 25, suhu_x);
  Suhu.sejuk = trapmf(20, 25, 25, 30, suhu_x);
  Suhu.agakPanas = trapmf(25, 30, 35, 40, suhu_x);
  Suhu.panas = trapmf(35, 40, 45, 45, suhu_x);

  Cahaya.gelap = trapmf(0, 0, 50, 100, cahaya_x);
  Cahaya.agakGelap = trapmf(50, 100, 150, 200, cahaya_x);
  Cahaya.remang2 = trapmf(150, 200, 200, 250, cahaya_x);
  Cahaya.agakTerang = trapmf(200, 250, 300, 350, cahaya_x);
  Cahaya.terang = trapmf(300, 350, 400, 400, cahaya_x);

  bobot1 = 0;
  bobot2 = 0;
  bobot3 = 0;
  bobot4 = 0;
  bobot5 = 0;
  bobot6 = 0;
  bobot7 = 0;
  bobot8 = 0;
  bobot9 = 0;
  bobot10 = 0;
  bobot11 = 0;
  bobot12 = 0;
  bobot13 = 0;
  bobot14 = 0;
  bobot15 = 0;
  bobot16 = 0;
  bobot17 = 0;
  bobot18 = 0;
  bobot19 = 0;
  bobot20 = 0;
  bobot21 = 0;
  bobot22 = 0;
  bobot23 = 0;
  bobot24 = 0;
  bobot25 = 0;

//********** Fungsi Implikasi ************//
//********** Cahaya Gelap ************//
  if(Suhu.dingin > 0 && Cahaya.gelap > 0){
    bobot1 = minimum(Suhu.dingin, Cahaya.gelap);
  }
  if(Suhu.agakDingin > 0 && Cahaya.gelap > 0){
    bobot2 = minimum(Suhu.agakDingin, Cahaya.gelap);
  }
  if(Suhu.sejuk > 0 && Cahaya.gelap > 0){
    bobot3 = minimum(Suhu.sejuk, Cahaya.gelap);
  }
  if(Suhu.agakPanas > 0 && Cahaya.gelap > 0){
    bobot4 = minimum(Suhu.agakPanas, Cahaya.gelap);
  }
  if(Suhu.panas > 0 && Cahaya.gelap > 0){
    bobot5 = minimum(Suhu.panas, Cahaya.gelap);
  }


//********** Cahaya Agak Gelap ************//
  if(Suhu.dingin > 0 && Cahaya.agakGelap > 0){
    bobot6 = minimum(Suhu.dingin, Cahaya.agakGelap);
  }
  if(Suhu.agakDingin > 0 && Cahaya.agakGelap > 0){
    bobot7 = minimum(Suhu.panas, Cahaya.agakGelap);
  }
  if(Suhu.sejuk > 0 && Cahaya.agakGelap > 0){
    bobot8 = minimum(Suhu.sejuk, Cahaya.agakGelap);
  }
  if(Suhu.agakPanas > 0 && Cahaya.agakGelap > 0){
    bobot9 = minimum(Suhu.agakPanas, Cahaya.agakGelap);
  }
  if(Suhu.panas > 0 && Cahaya.agakGelap > 0){
    bobot10 = minimum(Suhu.panas, Cahaya.agakGelap);
  }


//********** Cahaya Remang-Remang ************//
  if(Suhu.dingin > 0 && Cahaya.remang2 > 0){
    bobot11 = minimum(Suhu.dingin, Cahaya.remang2);
  }
  if(Suhu.agakDingin > 0 && Cahaya.remang2 > 0){
    bobot12 = minimum(Suhu.agakDingin, Cahaya.remang2);
  }
  if(Suhu.sejuk > 0 && Cahaya.remang2 > 0){
    bobot13 = minimum(Suhu.sejuk, Cahaya.remang2);
  }
  if(Suhu.agakPanas > 0 && Cahaya.remang2 > 0){
    bobot14 = minimum(Suhu.agakPanas, Cahaya.remang2);
  }
  if(Suhu.panas > 0 && Cahaya.remang2 > 0){
    bobot15 = minimum(Suhu.panas, Cahaya.remang2);
  }


//********** Cahaya Agak Terang ************//
  if(Suhu.dingin > 0 && Cahaya.agakTerang > 0){
    bobot16 = minimum(Suhu.dingin, Cahaya.agakTerang);
  }
  if(Suhu.agakDingin > 0 && Cahaya.agakTerang > 0){
    bobot17 = minimum(Suhu.agakDingin, Cahaya.agakTerang);
  }
  if(Suhu.sejuk > 0 && Cahaya.agakTerang > 0){
    bobot18 = minimum(Suhu.sejuk, Cahaya.agakTerang);
  }
  if(Suhu.agakPanas > 0 && Cahaya.agakTerang > 0){
    bobot19 = minimum(Suhu.agakPanas, Cahaya.agakTerang);
  }
  if(Suhu.panas > 0 && Cahaya.agakTerang > 0){
    bobot20 = minimum(Suhu.panas, Cahaya.agakTerang);
  }


//********** Cahaya Terang ************//
  if(Suhu.dingin > 0 && Cahaya.terang > 0){
    bobot21 = minimum(Suhu.dingin, Cahaya.terang);
  }
  if(Suhu.agakDingin > 0 && Cahaya.terang > 0){
    bobot22 = minimum(Suhu.agakDingin, Cahaya.terang);
  }
  if(Suhu.sejuk > 0 && Cahaya.terang > 0){
    bobot23 = minimum(Suhu.sejuk, Cahaya.terang);
  }
  if(Suhu.agakPanas > 0 && Cahaya.terang > 0){
    bobot24 = minimum(Suhu.agakPanas, Cahaya.terang);
  }
  if(Suhu.panas > 0 && Cahaya.terang > 0){
    bobot25 = minimum(Suhu.panas, Cahaya.terang);
  }
  

//************** Defuzzifikasi ***************//
  rataBobot = (bobot1 * Lampu.terang)+(bobot2 * Lampu.terang)+
              (bobot3 * Lampu.terang)+(bobot4 * Lampu.normal)+
              (bobot5 * Lampu.redup)+(bobot6 * Lampu.terang)+
              (bobot7 * Lampu.terang)+(bobot8 * Lampu.sedang)+
              (bobot9 * Lampu.redup)+(bobot10 * Lampu.redup)+
              (bobot11 * Lampu.terang)+(bobot12 * Lampu.sedang)+
              (bobot13 * Lampu.sedang)+(bobot14 * Lampu.redup)+
              (bobot15 * Lampu.redup)+(bobot16 * Lampu.sedang)+
              (bobot17 * Lampu.sedang)+(bobot18 * Lampu.normal)+
              (bobot19 * Lampu.redup)+(bobot20 * Lampu.padam)+
              (bobot21 * Lampu.sedang)+(bobot22 * Lampu.sedang)+
              (bobot23 * Lampu.normal)+(bobot24 * Lampu.padam)+
              (bobot25 * Lampu.padam);
  sumrataBobot = bobot1 + bobot2 + bobot3 + bobot4 + bobot5 + bobot6 +
                  bobot7 + bobot8 + bobot9 + bobot10 + bobot11 + bobot12 +
                  bobot13 + bobot14 + bobot15 + bobot16 + bobot17 + bobot18 + 
                  bobot19 + bobot20 + bobot21 + bobot22 + bobot23 + bobot24 + 
                  bobot25;
  out = rataBobot / sumrataBobot;
}