Bulanık mantık yeni nesil denetim mekanizmalarında çokça kullanılan bir kontrol mekanizmasıdır.Matematiksel mekanizmaların karmaşıklaşmasından dolayı tercihimizi dilsel olarak ifadelerle ayarlanmış aralıklara sahip bulanık mantıktan yana kullanmamız doğru olacaktır.
Bulanıklaştırma, giriş değişkenleri ile çıkış değişkenlerinin dilsel ifadelere dönüştürülme işlemidir. Bu nedenle ilk yapılacak olan giriş ve çıkış değişkenlerinin belirlenmesi, klima sistemi için giriş değişkenleri olarak; ortam sıcaklığı, hedef sıcaklık seçilmiştir ve çıkış değişkenleri olarak; klima çıkışı seçilmiştir. Daha sonra bulunan giriş ve çıkış değişkenlerine dilsel ifadeler verilmek suretiyle üyelik derecelerinin tespiti yapılır.
Projenin Çalışma Mantığı
Ortam sıcaklığı ve hedef(referans) sıcaklıkları bulanık mantık girişlerimizdir. Klimanın çıkışı ise bulanık mantık çıkışımızdır. Ortam ve hedef sıcaklığı dilsel ifadelere dönüştürerek üyelik fonksiyonu oluşturuyoruz. Bunları biz 5 tane üyelik fonksiyonlarıyla oluşturduk. Bunlar Çok soğuk, Soğuk , Konforlu, Sıcak , Çok Sıcak ve aynı şekilde çıkışımızı da 5 tane üyelik fonksiyonlarıyla ifade ediyoruz. Bunlar Çok Düşük, Düşük,Normal , Yüksek , Çok Yüksek Daha sonra 2 girişimiz olduğundan ve birinde 3 diğerinde 5 tane üyelik fonksiyonundan oluştuğu için 5*5=25 tane kuralımızın olması gerekiyor.
/* Bulanık Mantık Sıcaklık Nem */
#include "DHT.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 16, 2);
#define DHTPIN 2 // Sıcaklık Nem Sensörü Sinyal Pini
#define DHTTYPE DHT11 // Kütüphane Değişkeni
const int fansogut=9;
const int enablesogut=3;
const int fanisit=10;
const int enableisit=5;
int fanhiz;
int fanhiz2;
int mavi=13;
int kirmizi=12;
DHT dht(DHTPIN, DHTTYPE); // Sıcaklık Nem Kütüphanesi
void setup() {
Serial.begin(9600); // Seri iletişim Bağlantısı
Serial.println("Bulanik Mantik");
pinMode(fansogut,OUTPUT);
pinMode(enablesogut, OUTPUT);
pinMode(fanisit,OUTPUT);
pinMode(enableisit, OUTPUT);
pinMode(mavi, OUTPUT);
pinMode(kirmizi, OUTPUT);
dht.begin();
lcd.begin();
lcd.backlight();
}
void loop() {
float h = dht.readHumidity(); // Sensör Nem Okuma
float t = dht.readTemperature(); // Sensör Sıcaklık Okuma
if (isnan(t) || isnan(h)) // Sensörden veri gelmezse okuma hatası
{
Serial.println("DHT Hatası");
}
else
{
// Değişkenleri tanımlıyoruz
float Kapali[3] = {0};
float OrtaHalli[3] = {0};
float AzHizli[5] = {0};
float TamHizli[4] = {0};
float CokSoguk = 0;
float Soguk = 0;
float Konforlu = 0;
float Sicak = 0;
float CokSicak = 0;
float CokDusuk = 0;
float Dusuk = 0;
float Normal = 0;
float Yuksek = 0;
float CokYuksek = 0;
float Kapali_max = 0;
float Yavas_max = 0;
float OrtaHalli_max = 0;
float AzHizli_max = 0;
float TamHizli_max = 0;
// Sıcaklık Üyelik Fonksiyonu
CokSoguk = ucgen(t, 10, 13, 17);
Soguk = ucgen(t, 13, 17, 24);
Konforlu = ucgen(t, 17, 24, 29);
Sicak = ucgen(t, 24, 29, 31);
CokSicak = ucgen(t, 29, 31, 32);
// Nem Üyelik Fonksiyonu
CokDusuk = ucgen(h, 10, 25, 40);
Dusuk = ucgen(h, 25, 40, 55);
Normal = ucgen(h, 40, 55, 70);
Yuksek = ucgen(h, 55, 70, 85);
CokYuksek = ucgen(h, 70, 85, 100);
lcd.setCursor(0,0);
lcd.print("S:");
lcd.print(t);
lcd.setCursor(9,0);
lcd.print("N:");
lcd.print(h);
if ( t <= 24) {
//Kural Tablosu 1
AzHizli[0] = AND(CokDusuk, CokSoguk);
OrtaHalli[0] = AND(CokDusuk, Soguk);
Kapali[0] = AND(CokDusuk, Konforlu);
//Kural Tablosu 2
AzHizli[1] = AND(Dusuk, CokSoguk);
AzHizli[2] = AND(Dusuk, Soguk);
Kapali[1] = AND(Dusuk, Konforlu);
//Kural Tablosu 3
TamHizli[0] = AND(Normal, CokSoguk);
AzHizli[3] = AND(Normal, Soguk);
Kapali[2] = AND(Normal, Konforlu);
//Kural Tablosu 4
TamHizli[1] = AND(Yuksek, CokSoguk);
AzHizli[4] = AND(Yuksek, Soguk);
OrtaHalli[1] = AND(Yuksek, Konforlu);
//Kural Tablosu 5
TamHizli[2] = AND(CokYuksek, CokSoguk);
TamHizli[3] = AND(CokYuksek, Soguk);
OrtaHalli[2] = AND(CokYuksek, Konforlu);
// maksimum değerleri belirme
Kapali_max = DiziMax(Kapali, 3);
OrtaHalli_max = DiziMax(OrtaHalli, 3);
AzHizli_max = DiziMax(AzHizli, 5);
TamHizli_max = DiziMax(TamHizli, 4);
// Ağırlık Ortalaması Hesaplama
float cikis = (Kapali_max*0 + OrtaHalli_max*40 + AzHizli_max*70 + TamHizli_max*100);
cikis /= (Kapali_max+ OrtaHalli_max+ AzHizli_max+ TamHizli_max);
lcd.setCursor(0,1);
lcd.print("IsitF:");
lcd.print(cikis);
fanhiz = ((cikis/100)*255);
analogWrite(enableisit,fanhiz);
digitalWrite(fanisit,HIGH);
digitalWrite(kirmizi,HIGH);
digitalWrite(mavi,LOW);
}
else {
//Kural Tablosu 1
AzHizli[0] = AND(CokDusuk, CokSicak);
OrtaHalli[0] = AND(CokDusuk, Sicak);
Kapali[0] = AND(CokDusuk, Konforlu);
//Kural Tablosu 2
AzHizli[1] = AND(Dusuk, CokSicak);
AzHizli[2] = AND(Dusuk, Sicak);
Kapali[1] = AND(Dusuk, Konforlu);
//Kural Tablosu 3
TamHizli[0] = AND(Normal, CokSicak);
AzHizli[3] = AND(Normal, Sicak);
Kapali[2] = AND(Normal, Konforlu);
//Kural Tablosu 4
TamHizli[1] = AND(Yuksek, CokSicak);
AzHizli[4] = AND(Yuksek, Sicak);
OrtaHalli[1] = AND(Yuksek, Konforlu);
//Kural Tablosu 5
TamHizli[2] = AND(CokYuksek, CokSicak);
TamHizli[3] = AND(CokYuksek, Sicak);
OrtaHalli[2] = AND(CokYuksek, Konforlu);
// maksimum değerleri belirme
Kapali_max = DiziMax(Kapali, 3);
OrtaHalli_max = DiziMax(OrtaHalli, 3);
AzHizli_max = DiziMax(AzHizli, 5);
TamHizli_max = DiziMax(TamHizli, 4);
// Ağırlık Ortalaması Hesaplama
float cikis2 = (Kapali_max*0 + OrtaHalli_max*40 + AzHizli_max*70 + TamHizli_max*100);
cikis2 /= (Kapali_max+ OrtaHalli_max+ AzHizli_max+ TamHizli_max);
lcd.setCursor(0,1);
lcd.print("SogutF:");
lcd.print(cikis2);
fanhiz2 = ((cikis2/100)*255);
analogWrite(enablesogut,fanhiz2);
digitalWrite(fansogut,HIGH);
digitalWrite(kirmizi,LOW);
digitalWrite(mavi,HIGH);
}
delay(1000);
}
}
// Dizideki Maksimum Değeri Bul
float DiziMax(float a[], int b) {
float max = a[0];
for (int i = 1; i < b; i++) { if (a[i] > max)
max = a[i];
}
return max;
}
float AND(float a, float b) {
if (a < b) {
return a;
} else {
return b;
}
}
float ucgen(float x,float a, float b, float c){
float f;
if(x<=a)
f=0;
else if((a<=x)&&(x<=b))
f=(x-a)/(b-a);
else if((b<=x)&&(x<=c))
f=(c-x)/(c-b);
else if(c<=x)
f=0;
return f;
}
İncelemeler
Henüz inceleme yapılmadı.