2027 yazı için yazılım stajı arıyorum.CV indir

← Tüm projeler

AgriSense-AI

Uçtan uca IoT projesi

Rol
Sistem Mimarı
Süre
2026-03 – 2026-04
Takım
2

An end-to-end IoT system for soil nutrient analysis and plant health monitoring, integrated with LoRaWAN connectivity and LLM-powered expert insights for precision agriculture.

Problem

Tarımda toprak dengesizliği neredeyse her zaman geç fark edilir — bitki gözle görülür şekilde strese girdikten sonra. O noktada zarar çoktan oluşmuştur, müdahale hem daha pahalı hem de daha az etkilidir. Kök bölgesinin sağlıklı olup olmadığını dört değer belirler: nem, sıcaklık, pH ve elektriksel iletkenlik (EC). Üstelik bu dördü birbirinden bağımsız değildir: sulama nemi düzeltirken EC'yi seyreltir, pH kayması ise EC ideal görünse bile besin alımını engeller.

Mevcut çözümlerin her biri farklı bir noktada tıkanıyor. Manuel ölçüm anlık bir fotoğraftır; birinin tarlaya gitmesi gerekir ve kimse bunu saat başı yapmaz. Laboratuvar analizi doğrudur ama günler sürer. Ticari telemetri sistemleri pahalıdır ve genellikle her düğüm için ayrı hücresel kapsama ve abonelik ister — ne şebeke elektriği ne de güvenilir sinyali olan bir tarla için gerçekçi değildir.

Daha az göze çarpan ikinci bir problem daha var: veri mevcut olsa bile eyleme dönüşmüyor. "EC 1450 µS/cm, pH 6,2, nem %38" satırı, toprak bilimci olmayan bir üretici için hiçbir şey ifade etmez. Buradaki boşluk sadece ölçüm değil, yorumlama boşluğudur.

Bu yüzden sistemin aynı anda üç şeyi çözmesi gerekiyordu: sürekli ve otomatik ölçüm yapmak, veriyi düğüm başına internet gerektirmeden düşük güçle uzun mesafeye taşımak ve ham sayıları sade dille bir öneriye dönüştürmek.

Çözüm ve mimari

Sistem, her biri tek bir sorumluluğu olan dört katmandan oluşan uçtan uca bir hattır.

Sensör düğümü (tarla). IP68 4'ü 1 arada toprak sensörü, bir LilyGO T-Beam (ESP32 + SX1276) tarafından RS485 / Modbus RTU üzerinden okunur. Firmware, Arduino component'li ESP-IDF ile yazıldı; böylece setup() / loop() yapısı korunurken derleme idf.py ile yapılabiliyor. Sensör ile ESP32 arasında bir MAX485 çevirici var: UART1 GPIO 13/14 üzerinde, GPIO 4 ise ModbusMaster'ın preTransmission / postTransmission callback'leri aracılığıyla DE/RE yön pinini sürüyor. Düğüm her 60 saniyede bir 0x0000 adresinden başlayan dört holding register'ı okuyup nem, sıcaklık, EC ve pH değerlerine ölçekliyor. Okuma başarısızsa paket hiç gönderilmiyor — hatalı veri hatta hiç girmiyor.

LoRa hattı. Ölçüm, bilinçli olarak kısa tutulmuş bir JSON yüküne ({"h":..,"t":..,"ec":..,"ph":..}) paketlenip 868 MHz (EU bandı), SF9, 125 kHz bant genişliği, 0x12 sync word ve CRC açık şekilde gönderiliyor. Kısa anahtar isimleri burada önemli: LoRa çerçeve sınırı 255 byte ve her byte hem havada kalma süresi hem de güç demek.

Gateway. İkinci T-Beam sürekli dinlemede. Alım callback'i kesme (interrupt) bağlamında çalıştığı için yalnızca gelen baytları tampona kopyalayıp bir bayrak kaldırıyor; asıl HTTP işi loop() içinde, korumalı bir kopya üzerinden yapılıyor. Gateway WiFi bağlantısını otomatik yeniden bağlanmayla ayakta tutuyor ve her paketi x-api-key başlığıyla HTTPS POST /api/readings olarak iletiyor. Kimlik bilgileri depoda durmuyor: tools/gen_secrets_h.py, derleme sırasında gateway/.env dosyasını okuyup secrets.h üretiyor.

Backend ve yapay zekâ. Node.js + Express + Prisma + PostgreSQL; iki tablo var: readings ve alerts (cascade ilişkili). Yazma işlemleri API anahtarıyla korunuyor, okuma uçları ise CORS allowlist üzerinden panele açık. Her okumada analiz servisi dört değeri katı bir JSON sözleşmesiyle LLM'e gönderiyor: hasAlert, severity, message. Dönen cevap veri tabanı sözlüğüne eşleniyor (high → critical, medium → warning, low → info). En önemlisi, LLM opsiyonel kabul edilmiş: anahtar yoksa, API hata verirse veya cevap geçerli JSON değilse servis null dönüyor ve fiziksel olarak uç değerler için deterministik bir kural kontrolü yine de uyarı üretiyor (pH < 4,5 veya > 8,5; sıcaklık < 5 veya > 42 °C; EC < 50 veya > 5000). Sistem körleşmiyor, yalnızca sadeleşiyor.

Web paneli. TypeScript ve Tailwind ile yazılmış Next.js (App Router) panosu: agronomik eşiklere göre renklenen dört değer kartı (pH 6–7, EC 200–2000 µS/cm, 15–30 °C, %20–70 nem), 24 saat / 1 hafta / 1 ay aralıklı dört Recharts trend grafiği, bir yapay zekâ durum özeti kartı ve severity'e göre filtrelenebilen uyarı listesi. Veri, sensör aralığıyla uyumlu olarak 60 saniyede bir yenileniyor.

Mimari
flowchart TD
    subgraph FIELD["Field / Tarla"]
        S["4-in-1 Soil Sensor<br/>pH · EC · Humidity · Temperature<br/>IP68"]
        M["MAX485 Converter<br/>RS485 to UART TTL"]
        N["T-Beam 1 — Sensor Node<br/>ESP32 + SX1276<br/>ESP-IDF + Arduino component"]
    end

    subgraph LINK["Long Range Link / Uzun Menzil"]
        G["T-Beam 2 — Gateway<br/>LoRa RX + WiFi STA<br/>ISR buffer, POST in loop"]
    end

    subgraph SERVER["Backend / Sunucu"]
        API["Express API<br/>POST /api/readings<br/>GET /api/readings, /latest, /alerts"]
        DB[("PostgreSQL + Prisma<br/>readings · alerts")]
        LLM["LLM Analysis Service<br/>Groq primary, OpenAI fallback"]
        RULE["Rule-based Fallback<br/>extreme value check"]
    end

    subgraph PANEL["Web Panel"]
        UI["Next.js Dashboard<br/>cards · charts · alerts<br/>60 s auto refresh"]
    end

    S -->|"Modbus RTU · 9600 8N1 · slave 1"| M
    M -->|"UART1 GPIO 13/14 · DE-RE GPIO 4"| N
    N -->|"LoRa 868 MHz · SF9 · BW 125 kHz · sync 0x12 · CRC"| G
    G -->|"HTTPS POST · x-api-key · JSON h,t,ec,ph"| API
    API -->|"persist reading"| DB
    API -->|"4 values"| LLM
    LLM -->|"hasAlert · severity · message"| API
    LLM -.->|"key missing, API error or bad JSON"| RULE
    RULE -->|"warning alert"| DB
    API -->|"store alert"| DB
    UI -->|"GET every 60 s"| API
    API -->|"readings + alerts + AI summary"| UI

Canlı gömme

  • .
  • .
  • .

Sonuç

Hat uçtan uca çalışıyor: toprakta ölçülen bir değer, yaklaşık bir ölçüm döngüsü içinde yorumlanmış hâlde web panosunda görünüyor. Somut olarak tamamlanan sistem şunları sunuyor: Modbus RTU üzerinden 60 saniyede bir dört toprak parametresini okuyan bir tarla düğümü; sensörün kendisinde ne hücresel abonelik ne de internet gerektiren 868 MHz noktadan noktaya LoRa hattı; WiFi kopmalarını atlatıp dinlemeye devam eden bir gateway; PostgreSQL destekli dört uçlu bir REST API; dört sayıyı iki cümlelik bir öneriye çeviren LLM katmanı; ve "şu an sağlıklı mı, sırada ne yapmalıyım" sorusunu tek ekranda yanıtlayan bir pano.

İki tasarım kararı diğer her şeyden daha belirleyici çıktı. Birincisi, yapay zekâ katmanının taşıyıcı değil opsiyonel olması: LLM anahtarı, ağ ya da kota gittiğinde uyarı üretimi çalışmaya devam ediyor — sistemi çalışır hâlde bırakmayı dürüstçe mümkün kılan şey bu. İkincisi katman yalıtımı: gateway düz HTTP JSON konuştuğu için, sunucu tarafının tamamı radyo hattı güvenilir hâle gelmeden çok önce bir webhook ucuna karşı geliştirilip test edilebildi; panel de hiç donanıma dokunmadan API üzerinden geliştirilebildi.

Bilinen sınırlar, açıkça. LoRa hattı noktadan noktaya; tam bir LoRaWAN network server değil. Dolayısıyla OTAA join, cihaz başına oturum anahtarı ve çok düğümlü adresleme yok; RF paketleri kimlik doğrulamasız ve tek filtre eşleşen sync word. Backend geçmiş sorgularını 200 satırla sınırlıyor, bu yüzden 30 günlük grafik 24 saatlik olandan daha kaba. LLM her "son okuma" isteğinde çağrılıyor; bu hem maliyet hem gecikme demek — eşik ön filtresi (yalnızca bir değer normal bandın dışına çıktığında çağırmak) en bariz sonraki adım. Pil ve güneş paneli davranışı uzun süreli saha kullanımında doğrulanmadı.

Sonraki adımlar: eşiğe bağlı LLM çağrıları ve cevap önbellekleme, kritik uyarılarda mobil/push bildirim, cihaz doğrulamalı gerçek bir LoRaWAN yığını, paket içinde cihaz kimliğiyle çok düğüm desteği ve yeni sensör tipleri.

Bağlantılar