#include wire.h
#include liquidcrystal_i2c.h
#include servo.h
// LCD Ayarları
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pin Tanımları
const int baslangicButonuPin = 2;
const int copUltrasonikEchoPin = 3;
const int copUltrasonikTrigPin = 4;
const int copKapakServoPin = 5;
const int buzzerPin = 6;
const int irSensorPin = 7;
const int lambaKontrolPin = 8;
const int boyunServoPin = 9;
const int motorBaslatmaPin = 10;
const int motorYonKontrolPin = 11;
const int kirmiziLedPin = 12;
const int maviLedPin = 13;
const int isikSensorPin = A0;
const int irSagPin = A1;
const int irSolPin = A2;
const int rfGirisPin = A3;
//A4 ve A5 pinleri LCD ekran I2C için kullanılıyor.
// Motor Kontrol Ayarları
const unsigned long ileriSurmeSuresi = 5000;
const unsigned long geriSurmeSuresi = 200;
const unsigned long dugmeSiciramaEngellemeSuresi = 50;
unsigned long motorHareketBaslangicZamani = 0;
unsigned long sonButonBasmaZamani = 0;
//Göz haeket fonksiyonları
unsigned long gozKirpmaBaslangic = 3;
unsigned long gozKirpmaSure = random(50, 451); // İlk rastgele aralık
int gozKirpmaSayac = 0;
int toplamGozKirpma = 6; // Kaç defa kırpacak?
bool gozAcik = true;
bool gozAnimasyonBasladi = false;
int gozDurum = 0; // 0: Hazır, 1: Animasyon Başladı
// Göz Durumları
enum GozDurumu { GOZ_ORTA, GOZ_SOL, GOZ_SAG };
GozDurumu aktifGoz = GOZ_ORTA; // Başlangıçta ortada baksın
// Genel Değişkenler
volatile bool sistemAktif = false;
// Servo Nesneleri
Servo copKapakServo;
Servo boyunServo;
// Boyun Hareketi Değişkenleri
unsigned long boyunHareketZamanlayici = 0;
const unsigned long boyunHareketAraligi = 15000;
byte boyunPozisyonIndex = 0;
int boyunPozisyonlari[] = {60, 120, 90}; // Boyun pozisyonları (sağ, sol, orta)
// Yumuşak Geçiş Değişkenleri
int hedefBoyunAci = 90;
int suankiBoyunAci = 90;
unsigned long oncekiBoyunHareketZamani = 0;
const long boyunHareketAdimAraligi = 5; // Hareket adımları arasındaki milisaniye
// Melodi Ayarları
//Birinci Notalar
int melodi1Notlari[] = {440, 554, 659}; // A4, C#5, E5
int melodi1Sureleri[] = {200, 200, 400};
byte melodi1Boyutu = 3;
//İkinci Notalar
int melodi2Notlari[] = {
440, 523, 587, 659};
int melodi2Sureleri[] = {
125, 125, 125, 250};
byte melodi2Boyutu = 4;unsigned long oncekiNotaZamani = 0;
byte notaIndex = 0;
bool melodiCaliniyor = false;
//Polis çakar Işığı Başlangıç
const long cakarAraligi = 40;
const byte tekrarSayisi = 5; // Tekrar sayısını burada tanımlıyoruz
unsigned long oncekiCakarZamani = 0;
byte cakarAdimi = 0;
byte tekrarSayaci = 0;
bool cakarAktif = false;
void setup() {
Serial.begin(9600);
// LCD Başlatma
lcd.init();
lcd.backlight(); // LCD arka ışığını aç
lcd.setCursor(0, 0);
// Pin Modları
pinMode(baslangicButonuPin, INPUT_PULLUP);
pinMode(copUltrasonikTrigPin, OUTPUT);
pinMode(copUltrasonikEchoPin, INPUT);
copKapakServo.attach(copKapakServoPin);
copKapakServo.write(0); // Başlangıçta kapalı
pinMode(buzzerPin, OUTPUT);
pinMode(irSensorPin, INPUT);
pinMode(lambaKontrolPin, OUTPUT);
boyunServo.attach(boyunServoPin);
boyunServo.write(suankiBoyunAci); // Başlangıç pozisyonu
pinMode(motorBaslatmaPin, OUTPUT);
pinMode(motorYonKontrolPin, OUTPUT);
pinMode(kirmiziLedPin, OUTPUT);
pinMode(maviLedPin, OUTPUT);
pinMode(isikSensorPin, INPUT);
pinMode(irSagPin, INPUT);
pinMode(irSolPin, INPUT);
pinMode(rfGirisPin, INPUT);
digitalWrite(motorBaslatmaPin, LOW);
digitalWrite(motorYonKontrolPin, LOW);
// Interrupt (Sistem Açma/Kapama Butonu)
attachInterrupt(digitalPinToInterrupt(baslangicButonuPin), toggleSistem, FALLING);
// Karşılama mesajı (Öğrenciler için daha açıklayıcı)
melodiCal(2); // Sistem başladı melodi çal..
lcd.setCursor(0, 0);
lcd.print("MERHABA!!!");
lcd.setCursor(0, 1);
lcd.print("BEN i-BOR :)");
delay(2000);
lcd.clear();
// Bilgi mesajı (Öğrenciler için daha açıklayıcı)
lcd.setCursor(0, 0);
lcd.print("HAZIRSAK LUTFEN");
lcd.setCursor(0, 1);
lcd.print("C TUSUNA BAS!!");
delay(2000);
lcd.clear();
}
void loop() {
if (!sistemAktif) {
return; // Sistem aktif değilse hiçbir işlem yapma
}
butonlariOku();
motorKontrol();
// Seri Monitör Bilgileri (Öğrenciler için takip kolaylığı)
Serial.print("Isik: "); Serial.println(analogRead(isikSensorPin));
Serial.print("Sag IR: "); Serial.println(digitalRead(irSagPin));
Serial.print("Sol IR: "); Serial.println(digitalRead(irSolPin));
// Boyun Hareketi Kontrolü
boyunHareketiKontrol();
// Göz Hareketi Kontrolü
gozHareketKontrol();
// Çöp Kutusu Kontrolü
copKutusuKontrol();
// Işık Kontrolü
isikKontrol();
// delay(1250); // Daha kısa gecikme daha hızlı tepki
}
// ------ FONKSİYONLAR ------
// Sistem Açma/Kapama Fonksiyonu
void toggleSistem() {
static unsigned long sonBasmaZamani = 0;
if (millis() - sonBasmaZamani > 200) {
sistemAktif = !sistemAktif;
sonBasmaZamani = millis();
Serial.println(sistemAktif ? "Sistem AKTIF" : "Sistem PASIF");
if (!sistemAktif) {
polisCakarIsigi(false); // Sistem kapanınca çakarları kapat
noTone(buzzerPin); // Sistem kapanınca melodiyi durdur
}
}
}
void gozkirp(int adet, int bekleme) {
for (int i = 0; i < adet; i++) {
lcd.noDisplay();
delay(bekleme);
lcd.display();
delay(bekleme);
}
}
void sagabak() {
if (!gozAnimasyonBasladi) {
// İlk seferde gözü çiziyoruz
for (int i = 4; i < 8; i++) {
lcd.setCursor(i, 0);
lcd.write(255);
lcd.setCursor(i, 1);
lcd.write(255);
}
for (int i = 12; i < 16; i++) {
lcd.setCursor(i, 0);
lcd.write(255);
lcd.setCursor(i, 1);
lcd.write(255);
}
gozKirpmaBaslangic = millis();
gozKirpmaSayac = 0;
gozAnimasyonBasladi = true;
gozAcik = true;
}
if (gozAnimasyonBasladi) {
if (millis() - gozKirpmaBaslangic >= gozKirpmaSure) {
gozKirpmaBaslangic = millis();
gozKirpmaSure = random(50, 451); // Her kırpmada yeni rastgele süre
if (gozAcik) {
lcd.noDisplay();
gozAcik = false;
} else {
lcd.display();
gozAcik = true;
gozKirpmaSayac++;
}
if (gozKirpmaSayac >= toplamGozKirpma) {
lcd.display();
lcd.clear();
gozAnimasyonBasladi = false;
}
}
}
}
void solabak() {
if (!gozAnimasyonBasladi) {
for (int i = 0; i < 4; i++) {
lcd.setCursor(i, 0);
lcd.write(255);
lcd.setCursor(i, 1);
lcd.write(255);
}
for (int i = 8; i < 12; i++) {
lcd.setCursor(i, 0);
lcd.write(255);
lcd.setCursor(i, 1);
lcd.write(255);
}
gozKirpmaBaslangic = millis();
gozKirpmaSayac = 0;
gozAnimasyonBasladi = true;
gozAcik = true;
}
if (gozAnimasyonBasladi) {
if (millis() - gozKirpmaBaslangic >= gozKirpmaSure) {
gozKirpmaBaslangic = millis();
gozKirpmaSure = random(50, 451); // Her kırpmada yeni rastgele süre
if (gozAcik) {
lcd.noDisplay();
gozAcik = false;
} else {
lcd.display();
gozAcik = true;
gozKirpmaSayac++;
}
if (gozKirpmaSayac >= toplamGozKirpma) {
lcd.display();
lcd.clear();
gozAnimasyonBasladi = false;
}
}
}
}
void ortabak() {
if (!gozAnimasyonBasladi) {
for (int i = 2; i < 6; i++) {
lcd.setCursor(i, 0);
lcd.write(255);
lcd.setCursor(i, 1);
lcd.write(255);
}
for (int i = 10; i < 14; i++) {
lcd.setCursor(i, 0);
lcd.write(255);
lcd.setCursor(i, 1);
lcd.write(255);
}
gozKirpmaBaslangic = millis();
gozKirpmaSayac = 0;
gozAnimasyonBasladi = true;
gozAcik = true;
}
if (gozAnimasyonBasladi) {
if (millis() - gozKirpmaBaslangic >= gozKirpmaSure) {
gozKirpmaBaslangic = millis();
gozKirpmaSure = random(50, 451); // Her kırpmada yeni rastgele süre
if (gozAcik) {
lcd.noDisplay();
gozAcik = false;
} else {
lcd.display();
gozAcik = true;
gozKirpmaSayac++;
}
if (gozKirpmaSayac >= toplamGozKirpma) {
lcd.display();
lcd.clear();
gozAnimasyonBasladi = false;
}
}
}
}
// Gözlerin kontrolü
void gozHareketKontrol() {
switch (aktifGoz) {
case GOZ_ORTA:
ortabak();
break;
case GOZ_SOL:
solabak();
break;
case GOZ_SAG:
sagabak(); // millis uyumlu, engellemeyen
break;
}
}
// Boyun Hareketi Kontrol (ir ve Döngüsel) - YUMUŞATILMIŞ
void boyunHareketiKontrol() {
unsigned long suan = millis();
bool irSagAktif = (digitalRead(irSagPin) == LOW);
bool irSolAktif = (digitalRead(irSolPin) == LOW);
if (irSagAktif) {
hedefBoyunAci = boyunPozisyonlari[0]; // Sağa bak hedefi ayarla
aktifGoz = 1; // GOZ_SAG olarak tanımladıysanız onu kullanın
melodiCal(1); // Yaklaşan var melodi çal.. (burada veya loop içinde başka bir yerde çağrılabilir)
polisCakarIsigi(true); //(burada veya loop içinde başka bir yerde çağrılabilir)
boyunHareketZamanlayici = suan;
boyunPozisyonIndex = 0;
} else if (irSolAktif) {
hedefBoyunAci = boyunPozisyonlari[1]; // Sola bak hedefi ayarla
aktifGoz = 2; // GOZ_SOL olarak tanımladıysanız onu kullanın
melodiCal(1);
polisCakarIsigi(true);
boyunHareketZamanlayici = suan;
boyunPozisyonIndex = 1;
} else {
aktifGoz = 0; // GOZ_ORTA olarak tanımladıysanız onu kullanın
// polisCakarIsigi(false);
if (suan - boyunHareketZamanlayici >= boyunHareketAraligi) {
boyunHareketZamanlayici = suan;
boyunPozisyonIndex = (boyunPozisyonIndex + 1) % 3;
hedefBoyunAci = boyunPozisyonlari[boyunPozisyonIndex]; // Döngüsel hareket hedefi ayarla
}
}
// Hedef açıya doğru yumuşak geçiş
if (suan - oncekiBoyunHareketZamani >= boyunHareketAdimAraligi) {
oncekiBoyunHareketZamani = suan;
if (suankiBoyunAci < hedefBoyunAci) {
suankiBoyunAci++;
boyunServo.write(suankiBoyunAci);
} else if (suankiBoyunAci > hedefBoyunAci) {
suankiBoyunAci--;
boyunServo.write(suankiBoyunAci);
}
}
}
// Işık Sensörü Kontrol Fonksiyonu
void isikKontrol() {
int isikSeviyesi = analogRead(isikSensorPin);
digitalWrite(lambaKontrolPin, isikSeviyesi < 70 ? HIGH : LOW);
Serial.print("Gece Modu: "); Serial.println(isikSeviyesi > 70 ? "AKTIF" : "PASIF");
}
// Mesafe Ölçme Fonksiyonu (Ultrasonik Sensör)
int mesafeOlc() {
digitalWrite(copUltrasonikTrigPin, LOW);
delayMicroseconds(2);
digitalWrite(copUltrasonikTrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(copUltrasonikTrigPin, LOW);
return pulseIn(copUltrasonikEchoPin, HIGH) * 0.034 / 2;
}
// Çöp Kutusu Kontrol Fonksiyonu
void copKutusuKontrol() {
int mesafe = mesafeOlc();
static bool kapakAcik = false;
static unsigned long kapakKapanmaZamani = 0;
Serial.print("Cop Mesafesi: "); Serial.println(mesafe);
//20 cm yaklaştığında çöpü aç
if (mesafe < 20 && !kapakAcik) {
copKapakServo.write(90);
kapakAcik = true;
kapakKapanmaZamani = millis();
Serial.println("KAPAK ACILDI");
melodiCal(2); // Çöp kutusu açılınca melodi
lcd.clear();
lcd.print("Tesekkur Ederim!!!");
lcd.setCursor(0, 1);
lcd.print("Sevgiler :)");
delay(4000); // Öğrenciler için mesajı görme süresi (isteğe bağlı)
lcd.clear();
}
if (kapakAcik && millis() - kapakKapanmaZamani > 3000) {
copKapakServo.write(0);
kapakAcik = false;
//Serial.println("KAPAK KAPANDI");
}
}
// Motor Kontrol Fonksiyonu
void motorKontrol() {
if (digitalRead(motorBaslatmaPin) == HIGH) { // Motor başlatma pini yüksekse
if (digitalRead(motorYonKontrolPin) == HIGH) { // Yön pini yüksekse (geri)
if (millis() - motorHareketBaslangicZamani >= geriSurmeSuresi) {
durdur();
Serial.println("Geri süresi doldu!");
}
} else { // Yön pini düşükse (ileri)
if (millis() - motorHareketBaslangicZamani >= ileriSurmeSuresi) {
durdur();
Serial.println("İleri süresi doldu!");
}
}
}
}
// RF Butonlarını Okuma Fonksiyonu
void butonlariOku() {
// IR Sensörü (ÖNCELİK - Tehlikeyi Algıla!)
if (digitalRead(irSensorPin) == LOW) {
durdur();
geri();
return;
}
// Düğme sıçramalarını engellemek için bekle
if (millis() - sonButonBasmaZamani < dugmeSiciramaEngellemeSuresi) return;
int rfDegeri = analogRead(rfGirisPin);
Serial.print("RF Değeri: "); Serial.println(rfDegeri);
if (rfDegeri >= 230 && rfDegeri < 260) {
ileri();
sonButonBasmaZamani = millis();
} else if (rfDegeri >= 200 && rfDegeri < 229) {
geri();
sonButonBasmaZamani = millis();
} else if (rfDegeri >= 20 && rfDegeri < 50) {
durdur();
sonButonBasmaZamani = millis();
}
}
// İleri Hareket Fonksiyonu
void ileri() {
digitalWrite(motorBaslatmaPin, HIGH);
digitalWrite(motorYonKontrolPin, LOW);
motorHareketBaslangicZamani = millis();
Serial.println("İLERİ HAREKET!");
}
// Geri Hareket Fonksiyonu
void geri() {
digitalWrite(motorYonKontrolPin, HIGH);
digitalWrite(motorBaslatmaPin, HIGH);
motorHareketBaslangicZamani = millis();
Serial.println("GERİ ÇEKİLİYOR!");
}
// Motor Durdurma Fonksiyonu
void durdur() {
digitalWrite(motorBaslatmaPin, LOW);
digitalWrite(motorYonKontrolPin, LOW);
motorHareketBaslangicZamani = 0;
Serial.println("DURDURULDU!");
}
void melodiCal(int melodiSecimi) {
int *notalar;
int *sureler;
byte boyut;
if (melodiSecimi == 1) {
notalar = melodi1Notlari;
sureler = melodi1Sureleri;
boyut = melodi1Boyutu;
} else if (melodiSecimi == 2) {
notalar = melodi2Notlari;
sureler = melodi2Sureleri;
boyut = melodi2Boyutu;
} else {
noTone(buzzerPin); // Geçersiz seçimde sesi kapat
return;
}
unsigned long suan = millis();
static unsigned long oncekiNotaZamani = 0;
static byte notaIndex = 0;
static bool melodiCaliniyor = false;
static int aktifMelodi = 0;
if (melodiSecimi != aktifMelodi) { // Yeni melodi seçildiyse sıfırla
melodiCaliniyor = false;
notaIndex = 0;
aktifMelodi = melodiSecimi;
}
if (boyut > 0) {
if (!melodiCaliniyor) {
melodiCaliniyor = true;
oncekiNotaZamani = suan;
tone(buzzerPin, notalar[notaIndex], sureler[notaIndex]);
} else {
if (suan - oncekiNotaZamani >= sureler[notaIndex]) {
notaIndex++;
if (notaIndex < boyut) {
oncekiNotaZamani = suan;
tone(buzzerPin, notalar[notaIndex], sureler[notaIndex]);
} else {
noTone(buzzerPin);
melodiCaliniyor = false;
notaIndex = 0;
aktifMelodi = 0; // Çalma bitti, aktif melodi sıfırla
}
}
}
} else {
noTone(buzzerPin);
melodiCaliniyor = false;
notaIndex = 0;
aktifMelodi = 0;
}
}
// Polis Çakar Işığı Kontrol Fonksiyonu
// Polis Çakar Işığı Kontrol Fonksiyonu (Engellemeyen, Tek Fonksiyon, Tekrarlı)
void polisCakarIsigi(bool aktif) {
unsigned long suan = millis();
if (aktif) {
if (!cakarAktif) {
cakarAktif = true;
oncekiCakarZamani = suan;
cakarAdimi = 0;
tekrarSayaci = 0; // Tekrar sayacını başlat
}
if (cakarAktif) {
if (suan - oncekiCakarZamani >= cakarAraligi) {
oncekiCakarZamani = suan;
switch (cakarAdimi) {
case 0: digitalWrite(kirmiziLedPin, HIGH); break;
case 1: digitalWrite(kirmiziLedPin, LOW); break;
case 2: digitalWrite(kirmiziLedPin, HIGH); break;
case 3: digitalWrite(kirmiziLedPin, LOW); break;
case 4: digitalWrite(kirmiziLedPin, HIGH); break;
case 5: digitalWrite(kirmiziLedPin, LOW); break; // Kırmızı tamamlandı
case 6: digitalWrite(maviLedPin, HIGH); break;
case 7: digitalWrite(maviLedPin, LOW); break;
case 8: digitalWrite(maviLedPin, HIGH); break;
case 9: digitalWrite(maviLedPin, LOW); break;
case 10: digitalWrite(maviLedPin, HIGH); break;
case 11: digitalWrite(maviLedPin, LOW); break;
case 12: digitalWrite(maviLedPin, HIGH); break;
case 13: digitalWrite(maviLedPin, LOW); break; // Mavi tamamlandı
case 14: // Bir tekrar tamamlandı
tekrarSayaci++;
if (tekrarSayaci < tekrarSayisi) {
cakarAdimi = 0; // Yeni tekrar başlat
} else {
cakarAktif = false; // Tüm tekrarlar tamamlandı
}
break;
}
cakarAdimi++;
}
}
} else {
cakarAktif = false;
digitalWrite(kirmiziLedPin, LOW);
digitalWrite(maviLedPin, LOW);
cakarAdimi = 0;
tekrarSayaci = 0;
}
}