back to top

Raspberry Pi Pico Projeleri: GPS Takip, Hırsız Alarmı ve WiFi RGB LED ile 3 Farklı Atölye Deneyi

Raspberry Pi Pico W, uygun fiyatı ve Wi-Fi özelliği ile maker dünyasında oyunun kurallarını değiştirdi. Yazımızda, Pico W’nun gücünü kullanarak yapabileceğiniz üç farklı ve etkileyici projeyi adım adım inceleyeceğiz. 

Hazırsan, malzemelerimizi hazırlayıp kodlamaya başlayalım.

  • GPS takip sistemi – Konum bilgisini OLED ekranda gösteren taşınabilir modül
  • Hareket algılayan hırsız alarmı – PIR sensör ve buzzer ile anında uyarı veren sistem
  • WiFi kontrollü RGB LED şerit – Telefon tarayıcısından renk değiştirebileceğiniz akıllı ışık

Raspberry Pi Pico Projeleri için Kullandığımız Malzemeler

Tüm projelerin kalbinde mikrodenetleyici olarak:

Sensörler ve Modüller:

Aydınlatma:

WS2812B Adreslenebilir RGB Şerit LED (IP65)

Devre Elemanları:

Unutmayın! Kaliteli bağlantı elemanları ve sensörler kullanmak projenizin kararlılığı için önemlidir.

Proje 1 – Raspberry Pi Pico ile GPS Takip Sistemi

İnternet olmayan bir yerde bile konumunuzu bilmek ister misiniz? 

İlk projemizde Raspberry Pi Pico W, NEO-8M GPS modülü ve OLED ekran kullanarak:

  • Anlık enlem / boylam değerlerini,
  • Kaç adet uyduya bağlandığını,  

küçük bir ekranda gösteren taşınabilir bir GPS takip cihazı yapıyoruz. Bu proje;

  • Drone / RC araç takip
  • Basit konum logger’ı
  • Dış mekân projelerine giriş için şahane bir başlangıç noktasıdır.

Hangi malzemeler gerekiyor?

  • Lehimli Raspberry Pi Pico W
  • Ublox GY-GPSV3 NEO-8M M8N Antenli GPS Modülü
  • 0.96 inç I2C OLED Ekran – SSD1306
  • Jumper kablolar (M-M ve F-F)

Gps Takip Cihazı Projesinin Devre Şeması

GPS modülleri genellikle UART protokolü ile haberleşir.

GPS → Raspberry Pi Pico bağlantıları:

  • GPS VCC: Pico VSYS (5V) pinine bağlanır (Çoğu GPS modülü 5V sever).
  • GPS TX Pico RX (GP1): Veri okumak için.
  • GPS RX  → Pico TX (GP0): Konfigürasyon için.
  • GND → GND

OLED Ekran: I2C protokolü kullanır:

OLED → Raspberry Pi Pico bağlantıları:

  • VCC → 3V3
  • GND → GND
  • SCL → GP5 (I2C SCL)
  • SDA → GP4 (I2C SDA)

Tüm GND’lerin ortak olduğundan emin olursanız,projenin tek seferde çalıştığını gözlemleyebilirsiniz.

Kodlama Mantığı Nasıl Çalışıyor?

Projemizde MicroPython ile:

  1. I2C üzerinden OLED’i,
  2. UART üzerinden GPS modülünü başlatıyoruz.
  3. GPS modülü sürekli olarak NMEA formatında veri paketleri yollar. Kodumuzda $GNGGA paketini yakalayarak uydu bağlantısını (Fix durumunu), $GNRMC paketini yakalayarak ise koordinatları çözümlüyoruz:
    • Uydu sayısı
    • Enlem / boylam bilgisini çekiyoruz.
  4. Dönüştürme: Ham GPS verisi (derece dakika) formatındadır, kodumuzdaki convert_to_decimal fonksiyonu bunu Google Maps’te kullanabileceğiniz ondalık formata çevirir.

Derece + dakika formatındaki konumu ondalık dereceye çevirip OLED’e yazıyoruz.

ssd1306.py: Ekranı kullanmak için bu kütüphane dosyasını Pico’nuzun içine kaydetmeniz gereklidir.


from machine import Pin, I2C, UART
import ssd1306
import time

# ---------- OLED ----------
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

# ---------- GPS UART ----------
uart = UART(
    0,
    baudrate=9600,
    tx=Pin(0),
    rx=Pin(1),
    timeout=100,
    rxbuf=1024
)

# ---------- Yardımcı Fonksiyon ----------
def convert_to_decimal(raw, direction):
    if raw == "":
        return None
    value = float(raw)
    degrees = int(value / 100)
    minutes = value - (degrees * 100)
    decimal = degrees + minutes / 60
    if direction in ["S", "W"]:
        decimal = -decimal
    return decimal

# ---------- OLED Temiz ----------
def oled_msg(lines):
    oled.fill(0)
    for i, line in enumerate(lines):
        oled.text(line, 0, i * 10)
    oled.show()

oled_msg(["GPS Baslatiliyor..."])
print("GPS Baslatiliyor...")
time.sleep(2)

lat = lon = None
sats = 0
fix = False

# ---------- ANA DÖNGÜ ----------
while True:
    if uart.any():
        line = uart.readline()
        if not line:
            continue

        try:
            line = line.decode("utf-8").strip()
        except:
            continue

        # ---------- GGA (Fix + Uydu) ----------
        if line.startswith("$GNGGA"):
            parts = line.split(",")
            fix = parts[6] == "1"
            sats = parts[7]

        # ---------- RMC (Konum) ----------
        if line.startswith("$GNRMC"):
            parts = line.split(",")
            if parts[2] == "A":
                lat = convert_to_decimal(parts[3], parts[4])
                lon = convert_to_decimal(parts[5], parts[6])

        # ---------- EKRAN + TERMİNAL ----------
        if fix and lat and lon:
            oled_msg([
                "GPS FIX OK",
                f"LAT: {lat:.5f}",
                f"LON: {lon:.5f}",
                f"SAT: {sats}"
            ])

            print("GPS FIX OK")
            print("LAT:", lat)
            print("LON:", lon)
            print("UYDU:", sats)
            print("-" * 30)

        else:
            oled_msg([
                "GPS Araniyor...",
                "Uydu: " + str(sats)
            ])
            print("GPS veri bekleniyor...")

    time.sleep(0.3)

Raspberry Pi Pico gps takip cihazı projesini biraz daha ileri taşımak istersen, koordinatları seri porttan bilgisayara kaydedip basit bir GPS logger da yapabilirsin.

SSD1306 OLED için MicroPython kütüphanesi (ssd1306.py)

GPS projesinde kullandığımız OLED ekranın çalışması için aşağıdaki dosyayı ssd1306.py adıyla Pico’ya yüklemen gerekiyor. Bu, MicroPython’un klasik SSD1306 sürücüsü:


# MicroPython SSD1306 OLED driver, I2C and SPI interfaces

from micropython import const
import framebuf


# register definitions
SET_CONTRAST        = const(0x81)
SET_ENTIRE_ON       = const(0xa4)
SET_NORM_INV        = const(0xa6)
SET_DISP            = const(0xae)
SET_MEM_ADDR        = const(0x20)
SET_COL_ADDR        = const(0x21)
SET_PAGE_ADDR       = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP       = const(0xa0)
SET_MUX_RATIO       = const(0xa8)
SET_COM_OUT_DIR     = const(0xc0)
SET_DISP_OFFSET     = const(0xd3)
SET_COM_PIN_CFG     = const(0xda)
SET_DISP_CLK_DIV    = const(0xd5)
SET_PRECHARGE       = const(0xd9)
SET_VCOM_DESEL      = const(0xdb)
SET_CHARGE_PUMP     = const(0x8d)


class SSD1306:
    def __init__(self, width, height, external_vcc, color=framebuf.MONO_VLSB):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        fb = framebuf.FrameBuffer(self.buffer, self.width, self.height, color)
        self.framebuf = fb
        # Provide methods for accessing FrameBuffer graphics primitives. This is a
        # workround because inheritance from a native class is currently unsupported.
        # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
        self.fill = fb.fill
        self.pixel = fb.pixel
        self.hline = fb.hline
        self.vline = fb.vline
        self.line = fb.line
        self.rect = fb.rect
        self.fill_rect = fb.fill_rect
        self.text = fb.text
        self.scroll = fb.scroll
        self.blit = fb.blit
        self.init_display()

    def init_display(self):
        for cmd in (
            SET_DISP | 0x00, # off
            # address setting
            SET_MEM_ADDR, 0x00, # horizontal
            # resolution and layout
            SET_DISP_START_LINE | 0x00,
            SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
            SET_MUX_RATIO, self.height - 1,
            SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
            SET_DISP_OFFSET, 0x00,
            SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
            # timing and driving scheme
            SET_DISP_CLK_DIV, 0x80,
            SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
            SET_VCOM_DESEL, 0x30, # 0.83*Vcc
            # display
            SET_CONTRAST, 0xff, # maximum
            SET_ENTIRE_ON, # output follows RAM contents
            SET_NORM_INV, # not inverted
            # charge pump
            SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01): # on
            self.write_cmd(cmd)
        self.fill(0)
        self.show()

    def poweroff(self):
        self.write_cmd(SET_DISP | 0x00)

    def poweron(self):
        self.write_cmd(SET_DISP | 0x01)

    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)

    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))

    def show(self):
        x0 = 0
        x1 = self.width - 1
        if self.width == 64:
            # displays with width of 64 pixels are shifted by 32
            x0 += 32
            x1 += 32
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(x0)
        self.write_cmd(x1)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(self.pages - 1)
        self.write_data(self.buffer)


class SSD1306_I2C(SSD1306):
    def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False, color=framebuf.MONO_VLSB):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        super().__init__(width, height, external_vcc, color)

    def write_cmd(self, cmd):
        self.temp[0] = 0x80 # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)

    def write_data(self, buf):
        self.i2c.writeto(self.addr, b'\x40' + buf)


class SSD1306_SPI(SSD1306):
    def __init__(self, width, height, spi, dc, res, cs, external_vcc=False, color=framebuf.MONO_VLSB):
        self.rate = 10 * 1024 * 1024
        dc.init(dc.OUT, value=0)
        res.init(res.OUT, value=0)
        cs.init(cs.OUT, value=1)
        self.spi = spi
        self.dc = dc
        self.res = res
        self.cs = cs
        import time
        self.res(1)
        time.sleep_ms(1)
        self.res(0)
        time.sleep_ms(10)
        self.res(1)
        super().__init__(width, height, external_vcc, color)

    def write_cmd(self, cmd):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(0)
        self.cs(0)
        self.spi.write(bytearray([cmd]))
        self.cs(1)

    def write_data(self, buf):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs(1)
        self.dc(1)
        self.cs(0)
        self.spi.write(buf)
        self.cs(1)

Proje 2 – Raspberry Pi Pico ile Hareket Algılayan Hırsız Alarmı

İkinci Raspberry pi Pico projesinde PIR hareket sensörü ile odada hareket algılandığında:

  • Buzzer’dan uyarı sesi veriyoruz,
  • Terminale “Hareket ALGILANDI!” mesajı yazdırıyoruz.

Yaptığımız alarm, çocuk odası, koridor, atölye kapısı gibi ufak alanlar için temel bir güvenlik modülü görevi görüyor.

Hangi Malzemeler Gerekiyor?

  • Lehimli Raspberry Pi Pico W
  • HC-SR501 Ayarlanabilir IR Hareket Algılama Sensörü – PIR
  • Ses Kartı – Buzzer Kartı
  • Jumper kablolar

Hırsız Alarmı Projesinin Devre Bağlantıları

3 proje içerisinde kurulumu en basit devre budur. Görseldeki şemaya göre:

PIR Sensör → Pico bağlantıları:

  • VCC → VSYS (Pin 39) veya VBUS
  • GND → GND
  • OUT → GP15 (istersen farklı GPIO da kullanabilirsin)

Buzzer → Pico bağlantıları:

  • VCC → 3V3 OUT (Pin 36)
  • GND → GND
  • SIG → GP14

Yine tüm GND hatları ortak.

Kodların Mantığı Ne?

PIR sensör hareket algıladığında çıkış pinini “1” (High) yapar. Döngümüz sürekli bu pini kontrol eder:

  1. PIR çıkışını dijital giriş olarak okuyoruz.
  2. Değer 1 olduğunda hareket var, 0 olduğunda hareket yok kabul ediyoruz.

Hareket algılandığında buzzer’ı aktif edip kısa bir “bip” serisi çalıyoruz.

from machine import Pin
import time

# Pin tanımları
pir = Pin(15, Pin.IN)      # PIR sensör OUT -> GP15
buzzer = Pin(14, Pin.OUT)  # Buzzer SIG -> GP14

print("PIR sensör başlatılıyor...")
time.sleep(5)  # Sensörün kalibre olması için bekleme
print("Hazır! Hareket bekleniyor...")

while True:
    
    if pir.value() == 1:
        print("Hareket ALGILANDI!")
        
        # Buzzer bip sesi
        buzzer.value(1)
        time.sleep(0.3)
        buzzer.value(1)
        time.sleep(0.3)
        
    else:
        print("Hareket yok")
        buzzer.value(0)
        time.sleep(0.3)

PIR sensörlerin üzerinde hassasiyet ve zaman ayarı yapan iki adet potansiyometre bulunur. Bunları çevirerek sensörün ne kadar uzaktan algılayacağını ayarlayabilirsiniz.

İpucu: Buzzer’ın yanına bir WS2812B LED ekleyip alarm anında kırmızı yanmasını sağlayarak bu raspberry pi pico projesini daha da görsel hale getirebilirsin.

Proje 3 – Raspberry Pi Pico W ile WiFi Kontrollü RGB LED Şerit

Üçüncü ve en eğlenceli kısmımız: telefon tarayıcısından kontrol edilebilen akıllı RGB şerit LED sistemi.

Son projemizde:

  • Pico W’nun “W” (Wireless) özelliğini kullanarak WiFi ağına bağlanıyor,
  • İçinde mini bir web sunucu çalıştırıyor,
  • Telefonundan açtığın sayfada “KIRMIZI / YEŞİL / MAVİ / KAPAT” butonlarıyla WS2812B şerit LED’in rengini gerçek zamanlı değiştiriyorsun.

Yani bu raspberry pi pico projeleri setinin bu parçası, odanıza düşük maliyetli bir akıllı ışık sistemi kazandırıyor.

Hangi malzemeler kullanılıyor?

  • Lehimli Raspberry Pi Pico W
  • WS2812B Adreslenebilir RGB Şerit Led – IP65 Su geçirmez – 5m
  • 1000 uF 6.3 V Elektrolit Kondansatör
  • 1000 uF 10 V Elektrolit Kondansatör
  • 1/4 W 330 R Direnç Paketi – 10 Adet
  • Harici 5V LED adaptörü
  • Jumper kablolar

Devre Bağlantıları Nasıl Kuruluyor?

Dikkat etmeniz gereken en önemli nokta güç beslemesidir. LED şeritler fazla akım çektiği için harici bir adaptör kullanmak ve Pico ile ortak GND (Toprak) hattı oluşturmak gerekir.

WS2812B Şerit LED → Güç & Pico

  • Pico GP15: LED’in Data (DIN) girişine bağlanır (Araya 330R direnç koymak veri hattını korur).
  • Kondansatör: LED şeridinin güç girişlerine (5V ve GND arasına) bağlanarak voltaj dalgalanmalarını engeller.
  • Güç: LED’ler harici adaptörden, Pico USB’den beslenir.

Pico W, LED’leri sadece kontrol sinyali ile sürüyor; asıl akım harici adaptörden geliyor.

Web Arayüzü ve MicroPython Kodu Nasıl Çalışıyor?

Raspberry Pi Pico W ile WiFİ kontrollü RGB LED şerit  projesinde adımlar şöyle:

  1. Pico W, belirtilen SSID ve şifreyle WiFi ağına bağlanıyor.
  2. Bağlanınca aldığı IP adresini seri porttan yazdırıyor.
    1. portta basit bir HTTP server açıyor.
  3. Tarayıcıdan IP’ye girdiğinde HTML bir sayfa dönüyor; butonlara tıkladığında /red, /green, /blue, /off gibi endpoint’lere istek atılıyor.

Her endpoint, set_color() fonksiyonu ile LED’lerin rengini güncelliyor.

import network
import socket
import time
from machine import Pin
import neopixel

# ================== LED AYARLARI ==================
LED_PIN = 15
LED_COUNT = 15   # şerit varsa artırabilirsin
np = neopixel.NeoPixel(Pin(LED_PIN), LED_COUNT)

def set_color(r, g, b):
    for i in range(LED_COUNT):
        np[i] = (r, g, b)
    np.write()

# ================== WIFI AYARLARI ==================
SSID = ""
PASSWORD = ""

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)

print("WiFi baglaniyor...")
while not wlan.isconnected():
    time.sleep(0.5)

ip = wlan.ifconfig()[0]
print("Baglandi! IP:", ip)

# ================== HTML SAYFA ==================
html = """\
HTTP/1.1 200 OK

<!DOCTYPE html>
<html>
<head>
<title>Pico W LED Kontrol</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align: center; background:#111; color:white; }
button {
  width: 120px;
  height: 50px;
  font-size: 18px;
  margin: 10px;
  border: none;
  border-radius: 8px;
}
.red { background:red; }
.green { background:green; }
.blue { background:blue; }
.off { background:gray; }
</style>
</head>
<body>
<h2>Pico W LED Kontrol</h2>
<a href="/red"><button class="red">KIRMIZI</button></a><br>
<a href="/green"><button class="green">YESIL</button></a><br>
<a href="/blue"><button class="blue">MAVI</button></a><br>
<a href="/off"><button class="off">KAPAT</button></a>
</body>
</html>
"""

# ================== WEB SERVER ==================
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)

print("Web sunucu hazir!")
print("Tarayicidan gir:", ip)

while True:
    conn, addr = s.accept()
    request = conn.recv(1024).decode()
    print("Istek:", request)

    if "/red" in request:
        set_color(255, 0, 0)
    elif "/green" in request:
        set_color(0, 255, 0)
    elif "/blue" in request:
        set_color(0, 0, 255)
    elif "/off" in request:
        set_color(0, 0, 0)

    conn.send(html)
    conn.close()

Böylece raspberry pi pico projesinde telefonun tarayıcısı senin uzaktan kumandan haline geliyor.

YouTube Videomuzu İzleyin

Üç projeyi adım adım görmek isteyenler için tüm kurulum, bağlantı ve testleri anlattığımız detaylı bir video da hazır:

Raspberry Pi Pico W ile neler yapabileceğinizi gördünüz, ama bu sadece buzdağının görünen yüzü! Artık top sizde. Kodları alın, değiştirin, bozun ve tekrar yapın. Belki GPS modülünü bir drone’a takarsınız ya da alarm sistemini odanıza habersiz girenleri yakalamak için kullanırsınız. Sınır sadece hayal gücünüz!

Yaptığınız projeleri bizimle paylaşmayı ve aklınıza takılan o çılgın soruları yorumlarda sormayı unutmayın!

Son Çıkan Yazılar

CEVAP VER

Lütfen yorumunuzu giriniz!
Lütfen isminizi buraya giriniz