Ana Sayfa · Akademi · Robotik ve Kodlama · Arduino · Kod Yapısını Fonksiyonlara Bölmek

Kod Yapısını Fonksiyonlara Bölmek

Uzun loop'u okunabilir fonksiyonlara bölerek düzenli ve test edilebilir kod yazmayı öğren.

DERS PUSULASI

Bu sayfayı ne için kullanacaksın?

Ana fikir

Uzun ve karışık bir loop() fonksiyonunu küçük, adı anlamlı fonksiyonlara bölerek kodu daha okunabilir, tekrar kullanılabilir ve test edilebilir hâle getiririz.

Üretilecek kanıt

Yukarıdaki "sonra" örneğini kendi projene uyarla. Bu kez uyarı mantığını üç kademeye ayır ve showAlert() fonksiyonunu geliştir. Hedef davranış: Mesafe 20 cm'den büyükse: LED sönük, ses yok (güvenli). Mesafe 10–20 cm arasıysa: LED yanık, ses yok (dikkat). Mesafe 10 cm'den küçükse: LED yanık ve buzzer ötüyor (tehlike). readDistance() fonksiyonuna hiç dokunma.…

Kontrol tuzağı

Fonksiyon türünü yanlış yazmak readDistance() bir sayı döndürüyorsa başına void yazarsan derleyici (compiler) hata verir. Değer döndüren fonksiyonun türü int , long gibi olmalı; döndürmeyen fonksiyon void olur. return'ü unutmak Başına int yazıp içine return koymazsan fonksiyon söz verdiği değeri geri vermez. "Bir…

Sonraki bağlantı

Proje: Akıllı Park Sensörü — Bu derste yazdığın readDistance() ve showAlert() fonksiyonlarını bir araya getirip, yaklaştıkça hızlanan gerçek bir park sensörü kuracağız.

Modül kaynakları: Python Tutorial · Arduino Learn

SeviyeBaşlangıç
Yaş10–16
Süre30–45 dk
Ön koşulKütüphaneler
İçerikStandart ders · 1.514 kelime
Son güncelleme

Bir cümlelik özet

Uzun ve karışık bir loop() fonksiyonunu küçük, adı anlamlı fonksiyonlara bölerek kodu daha okunabilir, tekrar kullanılabilir ve test edilebilir hâle getiririz.

Neden önemli?

Bir Arduino projesi büyüdükçe loop() fonksiyonu şişer. Sensör okuma, hesaplama, LED yakma, buzzer çaldırma ve seri porta yazma; hepsi alt alta dizilir. Bir süre sonra kendi kodunu okumak bile zorlaşır. "Bu satır ne yapıyordu?" diye üstünde dakikalarca düşünürsün.

Python dersinde fonksiyon fikrini görmüştük: bir işi bir kez tanımlar, sonra adıyla çağırırdık. Arduino'nun dili (C/C++) de tam olarak aynı fikri kullanır. readDistance() yazdığında, o işin nasıl yapıldığını bilmene gerek kalmaz; adına bakıp ne yaptığını anlarsın.

Bunu günlük hayattan iki örnekle düşünebilirsin:

Fonksiyonlara bölmek de kodun için tam olarak bu bölmeleri açmaktır.

Fonksiyon nedir, nasıl yazılır?

Bir fonksiyon, bir işi yapan ve ona bir ad verdiğimiz kod parçasıdır. Onu bir kez yazar, istediğimiz kadar çağırırız.

Arduino'da zaten iki fonksiyon kullanıyorsun: setup() bir kez çalışır, loop() sürekli tekrar eder. Şimdi kendi fonksiyonlarımızı ekleyeceğiz.

En basit fonksiyon

Aşağıdaki fonksiyon bir iş yapar ama geriye bir değer döndürmez. Bu yüzden başına void yazarız (Türkçesi "boş", yani "geri dönen değer yok").

void beepOnce() {
  tone(4, 1000);   // 4 numaralı pime 1000 Hz ses ver
  delay(200);
  noTone(4);       // sesi durdur
}

Bu fonksiyonu loop() içinde tek satırla çağırırsın: beepOnce();. Kod okunurken "burada bir kez bip çalıyor" demek yeter; detaylar fonksiyonun içinde saklı kalır.

return: geriye değer döndürmek

Bazı fonksiyonlar bir iş yapıp sonucu geri verir. Python'da return kullanıyorduk; C/C++ de aynı kelimeyi kullanır. Geri dönen değerin türünü fonksiyonun başına yazarız. Tam sayı döndüren bir fonksiyonun başına int, uzun tam sayı için long yazarız.

int readTemperature() {
  int raw = analogRead(A0);        // sensörü oku
  int celsius = raw / 4;           // basit bir dönüşüm örneği
  return celsius;                  // sonucu geri döndür
}

Artık int t = readTemperature(); yazarak sıcaklığı bir değişkene alabilirsin. Fonksiyonun içindeki return, "işim bitti, işte cevabım" demektir.

Önce: her şey loop içinde

Şimdi gerçek bir örneğe bakalım. Bir mesafe sensörü (HC-SR04), bir LED ve bir buzzer var. Amaç: bir nesne 10 santimetreden yakına gelince LED yansın ve buzzer ötsün. Bir sonraki dersteki park sensörünün tam kalbi budur.

İlk denemede çoğu kişi her şeyi loop() içine yazar:

const int trigPin = 9;
const int echoPin = 10;
const int ledPin = 3;
const int buzzerPin = 4;

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
}

loop() ise şöyle uzar:

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH);
  int distance = duration / 58;      // mikrosaniyeyi cm'ye çevir
  Serial.println(distance);
  if (distance < 10) {
    digitalWrite(ledPin, HIGH);
    tone(buzzerPin, 1000);
  } else {
    digitalWrite(ledPin, LOW);
    noTone(buzzerPin);
  }
  delay(100);
}

Bu kod çalışır. Ama loop() iki ayrı işi birbirine karıştırıyor: sensörü *okumak* ve uyarıyı *göstermek*. İkisi tek yığın hâlinde duruyor.

Sonra: işleri fonksiyonlara ayırmak

Şimdi aynı işi ikiye bölelim. Bir fonksiyon sadece sensörü okuyup mesafeyi döndürsün; bir fonksiyon da sadece uyarıyı göstersin. setup() aynı kalır.

Önce okuma işi. Bu fonksiyon bir int değer döndürür:

int readDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH);
  return duration / 58;              // cm cinsinden mesafeyi döndür
}

Sonra uyarı işi. Bu fonksiyon dışarıdan bir mesafe alır (parametre) ve geriye değer döndürmediği için void'dur:

void showAlert(int distance) {
  if (distance < 10) {
    digitalWrite(ledPin, HIGH);
    tone(buzzerPin, 1000);
  } else {
    digitalWrite(ledPin, LOW);
    noTone(buzzerPin);
  }
}

Artık loop() inanılmaz sadeleşir. Tek bakışta ne yaptığını okuyabilirsin:

void loop() {
  int distance = readDistance();     // oku
  Serial.println(distance);
  showAlert(distance);               // uyar
  delay(100);
}

Mantık birebir aynı; hiçbir satır kayboldu değil. Sadece iki iş iki kutuya girdi. Yarın buzzer yerine ekran eklemek istersen, sadece showAlert() içini değiştirirsin; okuma kısmına dokunmazsın.

Mini uygulama

Yukarıdaki "sonra" örneğini kendi projene uyarla. Bu kez uyarı mantığını üç kademeye ayır ve showAlert() fonksiyonunu geliştir.

Hedef davranış:

readDistance() fonksiyonuna hiç dokunma. Sadece showAlert() içindeki if yapısını genişlet. Test etmek için elini sensöre yavaşça yaklaştır ve seri ekrandaki (Serial Monitor) sayıya bakarak üç durumun da doğru çalıştığını gör.

İpucu: else if kullanarak orta kademeyi ekleyebilirsin.

Uygulama laboratuvarı: Kod Yapısını Fonksiyonlara Bölmek

Kod Yapısını Fonksiyonlara Bölmek konusunu kalıcı hâle getirmenin en iyi yolu, kavramı küçük ve ölçülebilir bir göreve dönüştürmektir. Bu çalışmada Fonksiyon nedir, nasıl yazılır? ile return: geriye değer döndürmek arasındaki ilişkiyi kullanarak bağlantı şeması, derlenebilen Arduino kodu, seri monitör kaydı ve test sonucu hazırlayacaksın. Amaç yalnız sonucun çalışması değil; hangi kararı neden verdiğini, neyi test ettiğini ve hangi durumda tasarımı değiştireceğini açıklayabilmektir.

Görev senaryosu

Şu senaryoyu ele al: çizgiyi algılayan iki sensörün değerlerini seri monitörde karşılaştırma. Dersin ana hedefi “Uzun loop'u okunabilir fonksiyonlara bölerek düzenli ve test edilebilir kod yazmayı öğren” olduğuna göre önce problemi tek cümleyle tanımla. Ardından sistemin alacağı girdiyi, uygulayacağı işlemi ve üreteceği çıktıyı ayrı ayrı yaz. Bilmediğin bir ayrıntı varsa onu varsayım olarak işaretle; varsayımı gerçek bilgi gibi kullanma.

  1. Planla: Başlangıç durumunu, beklenen sonucu ve kullanacağın kavramları yaz.
  2. En küçük sürümü kur: Yalnız temel davranışı çalıştır; süsleme ve ek özellikleri sonraya bırak.
  3. Üç test hazırla: Normal bir durum, sınırda bir durum ve hatalı ya da beklenmeyen bir durum seç.
  4. Sonucu kaydet: Beklenen ile gerçekleşeni yan yana yaz; fark varsa olası nedeni belirt.
  5. Tek değişiklik yap: Aynı anda birçok şeyi değiştirmek yerine bir kararı düzeltip testi yeniden çalıştır.

Başarı ölçütleri

“Kod Yapısını Fonksiyonlara Bölmek” çalışmasını bitirdiğinde ürünü bir arkadaşına yalnız bölüm başlıklarıyla anlat. Arkadaşın çizgiyi algılayan iki sensörün değerlerini seri monitörde karşılaştırma senaryosundaki adımları ve karar nedenlerini takip edebiliyorsa anlatım yeterince açıktır. Anlaşılmayan noktayı daha fazla terim ekleyerek değil, Fonksiyon nedir, nasıl yazılır? ve return: geriye değer döndürmek ilişkisini daha küçük adımlara bölerek düzelt.

Sık yapılan hatalar

Fonksiyon türünü yanlış yazmak

readDistance() bir sayı döndürüyorsa başına void yazarsan derleyici (compiler) hata verir. Değer döndüren fonksiyonun türü int, long gibi olmalı; döndürmeyen fonksiyon void olur.

return'ü unutmak

Başına int yazıp içine return koymazsan fonksiyon söz verdiği değeri geri vermez. "Bir cevap döndüreceğim" dedin ama döndürmedin.

pinMode'u setup dışına koymak

pinMode() çağrılarını fonksiyonların içine dağıtma. Kurulum bir kez yapılır; yeri setup()'tır. Aksi hâlde loop() her turda gereksiz yere pinleri yeniden ayarlar.

Fonksiyona kötü ad vermek

sensor2() veya yap() gibi adlar hiçbir şey anlatmaz. readDistance() ve showAlert() gibi, işi anlatan adlar seç. İyi ad, yorum satırına olan ihtiyacı azaltır.

Güvenlik notu

Bu ders yalnızca düşük gerilimli parçalar kullanır: Arduino'yu USB kablosuyla ya da uygun bir pil paketiyle besle. Şebeke (priz) elektriğiyle çalışma.

Ders özeti

Kontrol soruları

  1. void ile başlayan bir fonksiyon ile int ile başlayan bir fonksiyon arasındaki fark nedir?
  2. return duration / 58; satırındaki return ne işe yarar?
  3. Uzun bir loop() fonksiyonunu neden küçük fonksiyonlara böleriz? Bir sebep yaz.
  4. showAlert(int distance) yazarken parantez içindeki int distance neyi ifade eder?
  5. pinMode() çağrılarının doğru yeri setup() mı yoksa loop() mu? Neden?

Cevaplar

  1. void fonksiyon bir iş yapar ama geriye değer döndürmez; int fonksiyon bir tam sayı hesaplayıp return ile geri verir.
  2. Fonksiyonun işini bitirdiğini belirtir ve hesaplanan mesafeyi (santimetre olarak) çağıran yere geri gönderir.
  3. Kodun okunması ve test edilmesi kolaylaşır; her iş ayrı bir kutuda durduğu için birini değiştirmek diğerini etkilemez. (Tekrar kullanım da geçerli bir cevaptır.)
  4. Fonksiyona dışarıdan verilen bir parametredir; çağıran kişi bir mesafe değeri gönderir ve fonksiyon o değeri distance adıyla kullanır.
  5. setup(). Pin ayarları kurulum işidir ve bir kez yapılması yeterlidir; loop()'a koymak her turda gereksiz tekrar demektir.

Kaynak ve doğrulama notu

“Kod Yapısını Fonksiyonlara Bölmek” dersi için doğrulama odağı Fonksiyon nedir, nasıl yazılır? ile return: geriye değer döndürmek arasındaki ilişkinin örnekler üzerinde tutarlı çalışmasıdır. Arduino uyumlu kartlarda pin, gerilim ve akım sınırları modele göre değişebilir. Kod derlense bile devre güvenli olmayabileceğinden, motor ve servo gibi yükler uygun sürücü ve harici besleme ile kullanılmalıdır.

Sonraki ders

Proje: Akıllı Park Sensörü — Bu derste yazdığın readDistance() ve showAlert() fonksiyonlarını bir araya getirip, yaklaştıkça hızlanan gerçek bir park sensörü kuracağız.

Quiz’i BaşlatArduino bölümüne dön
SORU HAVUZU

Bu dersi 10 soruyla pekiştir

Bu ders için 20 soruluk bir havuz hazırlandı. Her başlangıçta 10 soru ve seçenekler yeniden karıştırılır.