#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT22
#define BUZZER_PIN 15
#define LED_PIN 25
// Ekran ve Sensör Tanımlamaları
DHT dht(DHTPIN, DHTTYPE);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
// ==========================================
// 1. APPLE WATCH TARZI SAYFA VE MENÜ SİSTEMİ
// ==========================================
/*
Mersil Ekran Modları (Sayfalar):
0: ANA EKRAN (Saat, Sıcaklık, Yapay Zeka Durumu)
1: UYGULAMA MENÜSÜ (Apple Watch Grid Ekranı)
2: SES KAYDETME UYGULAMASI (Voice Memos)
3: NABIZ UYGULAMASI (Heart Rate)
4: SİSTEM AYARLARI (Settings)
*/
int aktifSayfa = 0;
int seciliUygulama = 0; // Menü içindeki imleç pozisyonu (0: Ses, 1: Mesaj, 2: Nabız, 3: Ayar)
// Ses Kayıt Uygulaması Değişkenleri
bool sesKaydediliyor = false;
unsigned long kayitBaslangicZamani = 0;
int kayitSaniyesi = 0;
// Mersil Çekirdek Hafızası
String aiMesaj = "Mersil Watch OS Hazir!";
String aiDurum = "STANDBY";
float sonSicaklik = 0.0;
float sonNem = 0.0;
unsigned long oncekiZaman = 0;
const long sensorGuncellemeAraligi = 2000;
void setup() {
Serial.begin(115200);
Wire.setSDA(4);
Wire.setSCL(5);
Wire.begin();
dht.begin();
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
for(;;);
}
acilisAnimasyonu();
}
void acilisAnimasyonu() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(30, 15);
display.print("MERSIL");
display.setCursor(45, 40);
display.print("v5.5");
display.display();
tone(BUZZER_PIN, 1500, 200);
delay(1500);
}
// ==========================================
// 2. GELİŞMİŞ EKRAN ÇİZİM MOTORU (UI)
// ==========================================
void ekraniGuncelle() {
display.clearDisplay();
// Üst Durum Çubuğu (Tüm sayfalarda sabit, saat hissi verir)
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(2, 2);
display.print("10:34"); // Sabit Saat simülasyonu
display.setCursor(95, 2);
display.print("%100"); // Batarya göstergesi
display.drawLine(0, 11, 128, 11, SSD1306_WHITE);
// AKTİF SAYFAYA GÖRE EKRANI ÇİZ
switch(aktifSayfa) {
// --- SAYFA 0: ANA EKRAN ---
case 0:
display.setCursor(4, 16);
display.setTextSize(1);
display.print("MERSIL WATCH");
// Sensör Verileri Bölümü
display.setCursor(4, 28);
display.print("Sly: "); display.print(sonSicaklik, 1); display.print("C");
display.setCursor(4, 38);
display.print("Nem: %"); display.print(sonNem, 0);
// Alt Bilgi Çubuğu
display.drawLine(0, 51, 128, 51, SSD1306_WHITE);
display.setCursor(4, 54);
display.print("AI: "); display.print(aiDurum);
break;
// --- SAYFA 1: UYGULAMA MENÜSÜ (APPLE WATCH GRID) ---
case 1:
display.setCursor(4, 14);
display.print("--- UYGULAMALAR ---");
// 1. Ses Kayıt Uygulaması Kutusu
display.drawRect(4, 26, 56, 22, SSD1306_WHITE);
if(seciliUygulama == 0) display.fillRect(6, 28, 52, 18, SSD1306_WHITE);
display.setTextColor(seciliUygulama == 0 ? SSD1306_BLACK : SSD1306_WHITE);
display.setCursor(8, 32); display.print("[ ] SES");
// 2. Nabız Uygulaması Kutusu
display.drawRect(68, 26, 56, 22, SSD1306_WHITE);
if(seciliUygulama == 1) display.fillRect(70, 28, 52, 18, SSD1306_WHITE);
display.setTextColor(seciliUygulama == 1 ? SSD1306_BLACK : SSD1306_WHITE);
display.setCursor(72, 32); display.print("<3 NABIZ");
// Menü Navigasyon İpucu (Alt Kısım)
display.setTextColor(SSD1306_WHITE);
display.setCursor(4, 54);
display.print("Secmek icin 'gir' yaz");
break;
// --- SAYFA 2: SES KAYDETME UYGULAMASI (VOICE MEMOS) ---
case 2:
display.setCursor(4, 15);
display.print("[VOICE RECORDER]");
if(sesKaydediliyor) {
// Mikrofondan kayıt yapılıyor simülasyonu
display.setCursor(4, 32);
display.print("• KAYDEDILIYOR...");
display.setCursor(4, 45);
display.print("Sure: "); display.print(kayitSaniyesi); display.print(" sn");
// Yanıp sönen kırmızı LED efekti (Fiziksel pin tetikleme)
digitalWrite(LED_PIN, (millis() / 500) % 2);
} else {
display.setCursor(4, 32);
display.print("Hazir. Baslatmak icin");
display.setCursor(4, 42);
display.print("'basla' komutu ver.");
digitalWrite(LED_PIN, LOW);
}
display.setCursor(4, 54);
display.print("Geri gitmek icin 'geri'");
break;
// --- SAYFA 3: NABIZ UYGULAMASI ---
case 3:
display.setCursor(4, 15);
display.print("[HEART RATE]");
display.setCursor(4, 32);
display.print("Nabiz: 78 BPM");
display.setCursor(4, 42);
display.print("Durum: Mukemmel");
display.setCursor(4, 54);
display.print("Geri gitmek icin 'geri'");
break;
}
display.display();
}
// ==========================================
// 3. AKILLI SAAT NAVİGASYON VE KOMUT MOTORU
// ==========================================
void gelenMesajiIsle(String mesaj) {
mesaj.toLowerCase();
mesaj.trim();
// --- KÜRESEL GERİ KOMUTU ---
if (mesaj == "geri") {
tone(BUZZER_PIN, 600, 100);
if (aktifSayfa > 1) {
aktifSayfa = 1; // Uygulamanın içindeysek menüye dön
} else if (aktifSayfa == 1) {
aktifSayfa = 0; // Menüdeysek ana ekrana dön
}
sesKaydediliyor = false;
digitalWrite(LED_PIN, LOW);
ekraniGuncelle();
return;
}
// --- SAYFA TABANLI KONTROL MANTIĞI ---
// A. ANA EKRANDAYKEN (Sayfa 0)
if (aktifSayfa == 0) {
if (mesaj == "sag" || mesaj == "menu" || mesaj == "kaydir") {
aktifSayfa = 1; // Menüyü aç (Apple Watch Grid)
tone(BUZZER_PIN, 900, 100);
}
}
// B. UYGULAMA MENÜSÜNDEYKEN (Sayfa 1)
else if (aktifSayfa == 1) {
if (mesaj == "sag" || mesaj == "sol" || mesaj == "degis") {
// Menüdeki uygulamalar arası geçiş yap (0: Ses, 1: Nabız)
seciliUygulama = (seciliUygulama == 0) ? 1 : 0;
tone(BUZZER_PIN, 800, 50);
}
else if (mesaj == "gir" || mesaj == "sec" || mesaj == "ok") {
tone(BUZZER_PIN, 1200, 150);
if (seciliUygulama == 0) aktifSayfa = 2; // Ses Kayıt Uygulamasına gir
else if (seciliUygulama == 1) aktifSayfa = 3; // Nabız Uygulamasına gir
}
}
// C. SES KAYIT UYGULAMASINDAYKEN (Sayfa 2)
else if (aktifSayfa == 2) {
if (mesaj == "basla" || mesaj == "kaydet") {
if (!sesKaydediliyor) {
sesKaydediliyor = true;
kayitBaslangicZamani = millis();
kayitSaniyesi = 0;
tone(BUZZER_PIN, 1000, 300);
}
}
else if (mesaj == "dur" || mesaj == "bitir") {
if (sesKaydediliyor) {
sesKaydediliyor = false;
digitalWrite(LED_PIN, LOW);
tone(BUZZER_PIN, 700, 400);
// Python terminaline kayıt bitti bilgisini uçur
Serial.println("Mersil: Ses kaydi basariyla tamamlandi!");
}
}
}
ekraniGuncelle();
}
// ==========================================
// 4. ANA DÖNGÜ (MAIN LOOP)
// ==========================================
void loop() {
unsigned long suAn = millis();
// 1. Sensörleri ve Ekranı Arka Planda Güncelle (İşlemciyi dondurmaz)
if (suAn - oncekiZaman >= sensorGuncellemeAraligi) {
oncekiZaman = suAn;
float yeniNem = dht.readHumidity();
float yeniSicaklik = dht.readTemperature();
if (!isnan(yeniNem) && !isnan(yeniSicaklik)) {
sonNem = yeniNem;
sonSicaklik = yeniSicaklik;
}
// Uygulama içinde aktif bir kayıt yoksa ekranı otomatik tazele
if (!sesKaydediliyor) {
ekraniGuncelle();
}
}
// 2. Ses Kayıt Uygulaması İçin Saniye Sayacı (Aktifken çalışır)
if (aktifSayfa == 2 && sesKaydediliyor) {
// Her 1 saniyede bir sayacı artır ve ekranı anlık tazele
if (suAn - kayitBaslangicZamani >= 1000) {
kayitSaniyesi++;
kayitBaslangicZamani = suAn;
ekraniGuncelle();
}
}
// 3. Seri Port (Python / Wokwi Konsol Köprüsü) Dinleme Hattı
if (Serial.available() > 0) {
String gelenVeri = Serial.readStringUntil('\n');
if (gelenVeri.length() > 0) {
gelenMesajiIsle(gelenVeri);
}
}
}
// ==========================================
// KODUN SONU - MERSIL SMARTWATCH OS TAMAMLANDI!
// ==========================================