Arduino'da Fonksiyon Kullanımı ve Temiz Kod Düzeni

👤 Yazar: ozcan 📅 Tarih: 24.05.2026 14:10 👁️ Görüntüleme: 14

Projeleriniz Koda Boğulmasın: Arduino'da Fonksiyon Kullanımı ve Temiz Kod Düzeni

Arduino ile projelere ilk başladığımızda, yazdığımız her satırı, her if şartını ve sensör okumasını doğrudan void loop() fonksiyonunun içine eklemeye meyilli oluruz. Proje küçükken bu durum sorun yaratmaz. Ancak devreye yeni sensörler, ekranlar ve motorlar eklendikçe void loop() yüzlerce satır süren, nerede hata yapıldığını bulmanın imkansız olduğu bir "kod çorbasına" dönüşür.

Yazılım dünyasında buna Spagetti Kod denir. Projelerimizi profesyonel, okunabilir ve kolayca geliştirilebilir hale getirmenin yolu ise kodlarımızı Fonksiyonlara (Functions) bölmektir.

Fonksiyon Nedir? Neden Kullanmalıyız?

Fonksiyon, program içinde belirli bir görevi yerine getiren, bağımsız ve tekrar kullanılabilir kod bloklarıdır.

Kod organizasyonunda fonksiyon kullanmanın bize sağladığı 3 büyük avantaj vardır:

  1. Okunabilirlik: void loop() içerisine baktığınızda karmaşık matematiksel formüller yerine sicaklikOku(); gibi ne yapıldığı anlaşılan temiz kelimeler görürsünüz.
  2. Tekrar Kullanılabilirlik (Don't Repeat Yourself - DRY): Bir LED'i projenin 5 farklı yerinde farklı şartlarda kırpıştırmanız gerekiyorsa, aynı 10 satırlık kodu 5 kez kopyalamak yerine, bir kez ledKirpis(int pin) fonksiyonu yazar ve ihtiyaç duyduğunuzda tek satırla çağırırsınız.
  3. Kolay Hata Ayıklama (Debugging): Eğer ekrana yazı gelmiyorsa, tüm kodu incelemek yerine sadece ekranaYazdir() fonksiyonunun içine bakarsınız.


Kötü Kod Tasarımı (Spagetti Kod) vs. İyi Kod Tasarımı (Temiz Mimari)

Gelin, bir LDR sensöründen veri okuyup, bu veriyi ekrana yazdıran ve duruma göre bir motoru çalıştıran projenin iki farklı yazım şeklini karşılaştıralım.

❌ Kaçınmamız Gereken Yöntem (Her şey loop içinde)

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
}

void loop() {
  // Sensör Okuma Bölümü
  int isikDegeri = analogRead(A0);
  float voltaj = isikDegeri * (5.0 / 1023.0);
  
  // Ekrana Yazdırma Bölümü
  Serial.print("Isik: ");
  Serial.print(isikDegeri);
  Serial.print(" | Voltaj: ");
  Serial.println(voltaj);
  
  // Motor Kontrol Bölümü
  if(isikDegeri < 300) {
    analogWrite(9, 255);
  } else {
    analogWrite(9, 0);
  }
  delay(1000);
}

Doğru ve Temiz Yöntem (Fonksiyonel Mimari)

Aynı kodu fonksiyonlara bölerek yazdığımızda void loop() kısmının ne kadar sadeleştiğine ve kodun nasıl kendi kendini açıklar hale geldiğine dikkat edin:

const int motorPin = 9;
const int ldrPin = A0;

void setup() {
  Serial.begin(9600);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  // Loop içi adeta bir kitap dizini gibi temiz ve anlaşılır
  int isik = ldrVerisiOku();
  seriPortaYazdir(isik);
  motoruKontrolEt(isik);
  
  delay(1000);
}

// 1. Değer Döndüren Fonksiyon (int türünde veri üretir)
int ldrVerisiOku() {
  int hamVeri = analogRead(ldrPin);
  return hamVeri; // Okunan değeri çağıran yere gönderir
}

// 2. Parametre Alan Fonksiyon (Dışarıdan veri alır, işlem yapar ama geriye veri döndürmez -> void)
void seriPortaYazdir(int deger) {
  float voltaj = deger * (5.0 / 1023.0);
  Serial.print("Isik Seviyesi: ");
  Serial.print(deger);
  Serial.print(" | Voltaj: ");
  Serial.println(voltaj);
}

// 3. Mantıksal Karar Fonksiyonu
void motoruKontrolEt(int isikSeviyesi) {
  if (isikSeviyesi < 300) {
    digitalWrite(motorPin, HIGH); // Karanlıksa motoru çalıştır
  } else {
    digitalWrite(motorPin, LOW);  // Aydınlıksa motoru durdur
  }
}

Fonksiyon Yazarken Dikkat Edilmesi Gereken 3 Kural

  1. Tek Bir Görev (Single Responsibility): Bir fonksiyon sadece ismiyle müsemma tek bir işi yapmalıdır. Örneğin sicaklikOku() fonksiyonunun içinde hem sensör okunup hem de motor çalıştırılmamalıdır. Motor kontrolü başka bir fonksiyonun işi olmalıdır.
  2. Doğru Geri Dönüş Tipi: Eğer fonksiyon bir hesaplama yapıp size bir sayı verecekse tipini int veya float yapmalısınız (Örn: float sensorHesapla()). Eğer sadece bir işlem yapıp (LED yakmak, ekrana basmak gibi) geriye bir değer vermeyecekse tipi mutlaka void olmalıdır.
  3. Anlamlı İsimlendirmeler: Fonksiyon isimleri genellikle bir eylem belirtmelidir. data() yerine veriOku(), motor() yerine motoruDurdur() gibi isimlendirmeler kodun okunmasını doğrudan artırır.

Özet

Büyük ve profesyonel projelerin sırrı, karmaşık problemleri küçük ve yönetilebilir parçalara ayırmaktır. Kodunuzda fonksiyon yapısını kullanmaya başladığınızda, hem projelerinizi başkalarının anlaması kolaylaşacak hem de aylar sonra kodunuza geri döndüğünüzde "Ben burada ne yazmıştım?" karmaşasından kurtulacaksınız.

Siz projelerinizde fonksiyonel mimariyi kullanıyor musunuz, yoksa her şeyi loop içine yazanlardan mısınız? Yaşadığınız deneyimleri yorumlarda paylaşın!

💬 Yorumlar

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Bir Yorum Bırakın

Güvenlik Kontrolü:

Yenidir.com
Sayfa Başı
Yenidir CMS V0.1