RP–05 · Raspberry Pi başlangıç projesi

Web Üzerinden LED Kontrolü (Flask)

Nesnelerin İnterneti'ne (IoT) ilk adım: Raspberry Pi'yi bir web sunucusuna dönüştürüp aynı ağdaki telefonunuzdan veya bilgisayarınızdan LED'leri açıp kapatacağız. Üstelik Pi açıldığında sunucunun kendiliğinden başlamasını da sağlayacağız.

SeviyeBaşlangıç
Süre45 dk
Malzeme8 çeşit
FlaskWeb sunucusuRouteHTML şablonuIP adresisystemd

Proje hakkında

Flask, Python ile web uygulaması yazmayı sağlayan küçük ve anlaşılır bir kütüphanedir. Birkaç satır kodla Raspberry Pi'niz, ağdaki diğer cihazların tarayıcıdan bağlanabildiği bir web sunucusuna dönüşür. Tarayıcıdan gelen her istek bir Python fonksiyonunu çalıştırır; bu fonksiyon da gpiozero ile LED'i kontrol eder.

Projeyi tamamladığınızda telefonunuzdan "Aç" düğmesine dokunduğunuzda masadaki LED yanacak. Aynı yapıyla röle modülü üzerinden lamba, fan veya bir robotun motorlarını da kontrol edebilirsiniz; akıllı ev sistemlerinin temeli budur.

  • Flask ile basit bir web sunucusu kurmayı
  • Route (adres) tanımlayıp parametre almayı
  • HTML şablonu içinde Python değişkenlerini göstermeyi
  • Programı systemd ile açılışta otomatik başlatmayı

Malzeme listesi

Projeyi tamamlamak için aşağıdaki 8 çeşit malzemeye ihtiyacınız var. Raspberry Pi'niz hazırsa geri kalan parçaların çoğu elektronik başlangıç setlerinde bulunur.

Raspberry Pi 4 veya 5 1 adet

Raspberry Pi OS (Bookworm veya üstü) kurulu olmalı. Pi 3B+ ile de çalışır.

microSD kart 1 adet

En az 16 GB, Raspberry Pi OS yüklü.

Resmi güç adaptörü 1 adet

Pi 5 için 5V 5A USB-C, Pi 4 için 5V 3A USB-C.

Breadboard 1 adet

Yarım boy (400 delik) yeterlidir.

5 mm LED (kırmızı ve yeşil) 2 adet

330 Ω direnç 2 adet

Her LED için bir direnç.

Jumper kablo (dişi-erkek) 3 adet

Telefon veya bilgisayar 1 adet

Raspberry Pi ile aynı Wi-Fi ağına bağlı olmalı.

Devre bağlantıları

Bağlantıları Raspberry Pi kapalıyken ve güç kablosu çıkarılmışken yapın. Her satırda önce GPIO (BCM) numarası, ardından kart üzerindeki fiziksel pin numarası yazar; çizgi rengi önerilen kablo rengidir.

Kırmızı LED anotGPIO17 · pin 11330 Ω direnç üzerinden
Yeşil LED anotGPIO27 · pin 13330 Ω direnç üzerinden
İki LED'in katotlarıGND · pin 9Ortak − hattı üzerinden
Raspberry Pi'nin ağdaki adresini öğrenmek için terminale hostname -I yazın. Çıkan ilk değer (örneğin 192.168.1.42) tarayıcıya yazacağınız adrestir. Modem Pi'ye her açılışta farklı adres verebilir; sabit adres için modem ayarlarından IP rezervasyonu yapabilirsiniz.

Adım adım kurulum

  1. LED'leri bağlayın

    Pi kapalıyken kırmızı LED'i pin 11'e, yeşil LED'i pin 13'e direnç üzerinden bağlayın; kısa bacakları pin 9'a (GND) gitsin.

  2. Flask'ı kontrol edin

    Pi'yi açıp terminale python3 -c "import flask" yazın. Hata alırsanız sudo apt install -y python3-flask ile kurun.

  3. Proje klasörü oluşturun

    mkdir ~/ledweb komutuyla bir klasör açın ve aşağıdaki kodu bu klasöre app.py adıyla kaydedin.

  4. Sunucuyu başlatın

    cd ~/ledweb ve ardından python3 app.py yazın. Ekranda Running on http://… satırları görünecek.

  5. IP adresini öğrenin

    Yeni bir terminal penceresinde hostname -I komutuyla Pi'nin adresini öğrenin.

  6. Telefondan bağlanın

    Telefon Pi ile aynı Wi-Fi'dayken tarayıcıya http://PI_ADRESI:5000 yazın (örneğin http://192.168.1.42:5000). Aç / Kapat düğmeleriyle LED'leri kontrol edin.

  7. Açılışta otomatik başlatın

    Her şey çalışıyorsa son iki kod bloğuyla bir systemd servisi oluşturun. Artık Pi her açıldığında sunucu kendiliğinden başlar.

Python kodu

Kodları Thonny editörüne yapıştırıp .py uzantısıyla kaydedin ve Run düğmesine basın ya da terminalden python3 dosya_adi.py komutuyla çalıştırın. Programı durdurmak için Ctrl+C tuşlarını kullanın.

Flask web sunucusu ve LED kontrol sayfası.

app.pyPython
# Web Üzerinden LED Kontrolü
# RobotikHocasi.com

from flask import Flask, redirect, url_for, render_template_string
from gpiozero import LED

app = Flask(__name__)

ledler = {
    "kirmizi": LED(17),
    "yesil": LED(27),
}

SAYFA = """
<!doctype html>
<html lang="tr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Pi LED Kontrol</title>
  <style>
    body { font-family: sans-serif; text-align: center; padding: 30px; background: #F5F7FC; }
    .kart { background: #fff; border-radius: 16px; padding: 16px; margin: 14px auto; max-width: 360px; }
    a { display: inline-block; margin: 6px; padding: 14px 24px; border-radius: 12px;
        color: #fff; text-decoration: none; font-weight: bold; }
    .ac { background: #14B8A6; }
    .kapa { background: #FF5D5D; }
  </style>
</head>
<body>
  <h1>Raspberry Pi LED Kontrol</h1>
  {% for ad, led in ledler.items() %}
    <div class="kart">
      <h2>{{ ad|capitalize }}: {{ "ACIK" if led.is_lit else "KAPALI" }}</h2>
      <a class="ac" href="/{{ ad }}/ac">Ac</a>
      <a class="kapa" href="/{{ ad }}/kapa">Kapat</a>
    </div>
  {% endfor %}
</body>
</html>
"""

@app.route("/")
def anasayfa():
    return render_template_string(SAYFA, ledler=ledler)

@app.route("/<ad>/<islem>")
def kontrol(ad, islem):
    led = ledler.get(ad)
    if led is None:
        return "Boyle bir LED yok", 404
    if islem == "ac":
        led.on()
    elif islem == "kapa":
        led.off()
    return redirect(url_for("anasayfa"))

if __name__ == "__main__":
    # 0.0.0.0: ağdaki diğer cihazlar da bağlanabilsin
    app.run(host="0.0.0.0", port=5000, debug=False)

Bonus: Sunucuyu açılışta otomatik başlatan systemd servis dosyası. "pi" yazan yerleri kendi kullanıcı adınızla değiştirin.

ledweb.serviceTerminal
# Bu içeriği şu dosyaya kaydedin:
# sudo nano /etc/systemd/system/ledweb.service

[Unit]
Description=Raspberry Pi LED web kontrol
After=network-online.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/ledweb/app.py
WorkingDirectory=/home/pi/ledweb
User=pi
Restart=on-failure

[Install]
WantedBy=multi-user.target

Servisi etkinleştirme ve durumunu kontrol etme komutları.

terminalTerminal
# Servisi tanıt, etkinleştir ve hemen başlat
sudo systemctl daemon-reload
sudo systemctl enable --now ledweb

# Çalışıyor mu? (çıkmak için q)
sudo systemctl status ledweb

# Kodu değiştirdikten sonra yeniden başlatmak için
sudo systemctl restart ledweb

Kod açıklaması

app = Flask(__name__)

Bir Flask uygulaması oluşturur. Tüm adresler (route) bu nesneye bağlanır.

@app.route("/<ad>/<islem>")

Adresin içindeki parçaları fonksiyona parametre olarak verir. /kirmizi/ac adresi ad="kirmizi", islem="ac" olarak gelir.

render_template_string(SAYFA, ledler=ledler)

HTML şablonunu işler. {% for %} döngüsü ve {{ }} içindeki ifadeler Python verileriyle doldurulur.

led.is_lit

LED'in o an yanıp yanmadığını True veya False olarak verir. Sayfadaki AÇIK / KAPALI yazısı buradan gelir.

redirect(url_for("anasayfa"))

İşlemden sonra tarayıcıyı ana sayfaya geri gönderir; böylece güncel durum hemen görünür.

host="0.0.0.0", debug=False

0.0.0.0 sunucunun ağdaki tüm cihazlara açık olmasını sağlar. debug=True, Flask'ın kodu iki kez yüklemesine ve GPIO pin çakışmasına yol açtığı için kapalı tutulur.

Nasıl çalışır?

Telefonunuzun tarayıcısına http://192.168.1.42:5000/kirmizi/ac yazdığınızda tarayıcı, ağ üzerinden Raspberry Pi'nin 5000 numaralı portuna bir HTTP isteği gönderir. Flask bu adresi tanımlı route'larla karşılaştırır, eşleşen kontrol() fonksiyonunu çalıştırır ve fonksiyon gpiozero ile GPIO17'yi açar. Ardından tarayıcıya ana sayfaya dönmesini söyleyen bir yanıt gönderir.

systemd, Linux'ta arka plan programlarını yöneten sistemdir. Servis dosyası, programın hangi komutla, hangi klasörde ve hangi kullanıcıyla çalışacağını tanımlar. Restart=on-failure satırı sayesinde program bir hata nedeniyle kapanırsa systemd onu otomatik olarak yeniden başlatır.

Sorun giderme

Telefondan sayfa açılmıyor
Telefon ile Pi'nin aynı Wi-Fi ağında olduğundan emin olun. Adrese :5000 port numarasını eklemeyi unutmayın. Misafir ağları cihazların birbirini görmesini engelleyebilir.
Pin already in use / GPIO busy hatası
app.py zaten başka bir terminalde veya servis olarak çalışıyor. sudo systemctl stop ledweb ile servisi durdurup tekrar deneyin.
Address already in use hatası
5000 numaralı portu başka bir program kullanıyor. Önceki sunucuyu kapatın ya da kodda port=5001 yazın.
Servis başlamıyor
sudo systemctl status ledweb çıktısındaki hataya bakın. En sık neden, dosya yollarındaki kullanıcı adının yanlış olmasıdır.

Geliştirme fikirleri

Projeyi tamamladıysanız, aşağıdaki fikirlerle bir adım öteye taşıyabilirsiniz.

Parlaklık kaydırıcısı

PWMLED ve bir HTML range kaydırıcısıyla LED parlaklığını web'den ayarlayın.

Sıcaklık paneli

DS18B20 projesindeki ölçümü aynı sayfada canlı olarak gösterin.

Röle ile gerçek cihaz

Röle modülüyle masa lambası kontrol edin. 220V ile mutlaka bir yetişkin gözetiminde çalışın.

Robot kumandası

İleri, geri, sağ, sol düğmeleriyle motor sürücüye bağlı bir robot aracı telefondan yönetin.

Sık sorulan sorular

Bu sayfaya internetten (ev dışından) erişebilir miyim?
Teknik olarak mümkündür, ancak modemde port açmak Pi'nizi internete açık hale getirir ve güvenlik riski oluşturur. Bu proje yalnızca ev ağında kullanım içindir. Uzaktan erişim gerekiyorsa VPN gibi güvenli yöntemler araştırın.
Neden debug=True kullanmıyoruz?
Flask'ın debug modu, kodu izlemek için programı iki kez başlatır. Bu durumda aynı GPIO pinini iki süreç kullanmaya çalışır ve "pin in use" hatası oluşur.
Butonlar neden link (a etiketi) şeklinde?
Başlangıç için en basit yöntem budur. Gerçek projelerde durum değiştiren işlemler için HTML formu ve POST isteği kullanmak daha doğru bir uygulamadır.

Bir sonraki projeye hazır mısınız?

Raspberry Pi serisindeki 5 projeyi tamamladığınızda GPIO, kamera, sensör verisi ve web sunucusu ile çalışmanın temellerini öğrenmiş olursunuz.

Raspberry Pi projelerine dön