🚀 C# ile Programlamaya Giriş: Kodlamaya İlk Adımını At, Kendi Projelerini Geliştirmeye Başla!
00ANASAYFA 01YAZILAR 02EĞİTİM 03ELEKTRİK_ENERJİ 04OTOMOTİV_MÜHENDİSLİĞİ 05ARAÇLAR 06LAB 07SÖZLÜK 08ETİKETLER ♡OKUMA LİSTEM ⌕ARA
TRENG

Mini proje: sensör ölçüm kaydı ve istatistik

Öğrendiklerini birleştir: struct, sınıf, vector, STL algoritmaları ve lambda ile sıcaklık kayıt programı.

Kursun sonuna geldin. Şimdi öğrendiğin parçaları tek bir programda birleştirelim: bir sıcaklık sensöründen gelen ölçümleri saklayan, istatistiğini çıkaran ve eşik aşımını uyaran küçük bir veri kaydedici. Gerçek bir mühendislik aracının iskeleti bu.

Tasarım

  • Olcum yapısı: ölçümün dakikası ve sıcaklığı.
  • Kayit sınıfı: ölçümleri vektörde tutar; ortalama, en küçük, en büyük, standart sapma ve eşik üstü sayısını verir.
  • main: örnek verileri ekler, tabloyu ve istatistikleri yazdırır.

Hesap yöntemlerini kısaca hatırlayalım. Ortalama, toplamın eleman sayısına bölünmesidir. Standart sapma ise verinin ortalamadan ne kadar saçıldığını söyler: her ölçümün ortalamadan farkının karesini al, bunların ortalamasını bul, karekökünü çek. Bu programda tüm veriyi kapsayan "popülasyon" standart sapmasını kullanıyoruz.

Kod

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <vector>

struct Olcum {
    int dakika;
    double sicaklik;
};

class Kayit {
public:
    void ekle(int dakika, double sicaklik) {
        veri_.push_back(Olcum{dakika, sicaklik});
    }

    bool bos() const { return veri_.empty(); }

    double ortalama() const {
        double toplam = std::accumulate(
            veri_.begin(), veri_.end(), 0.0,
            [](double t, const Olcum& o) { return t + o.sicaklik; });
        return toplam / veri_.size();
    }

    double standartSapma() const {
        double m = ortalama();
        double kareler = 0.0;
        for (const auto& o : veri_) {
            kareler += (o.sicaklik - m) * (o.sicaklik - m);
        }
        return std::sqrt(kareler / veri_.size());
    }

    double enKucuk() const {
        auto it = std::min_element(
            veri_.begin(), veri_.end(),
            [](const Olcum& a, const Olcum& b) { return a.sicaklik < b.sicaklik; });
        return it->sicaklik;
    }

    double enBuyuk() const {
        auto it = std::max_element(
            veri_.begin(), veri_.end(),
            [](const Olcum& a, const Olcum& b) { return a.sicaklik < b.sicaklik; });
        return it->sicaklik;
    }

    int esikUstu(double esik) const {
        return static_cast<int>(std::count_if(
            veri_.begin(), veri_.end(),
            [esik](const Olcum& o) { return o.sicaklik > esik; }));
    }

    void tabloYazdir() const {
        std::cout << std::setw(6) << "dak" << std::setw(10) << "sicaklik" << '\n';
        for (const auto& o : veri_) {
            std::cout << std::setw(6) << o.dakika
                      << std::setw(10) << o.sicaklik << '\n';
        }
    }

private:
    std::vector<Olcum> veri_;
};

int main() {
    Kayit kayit;
    kayit.ekle(0, 22.5);
    kayit.ekle(5, 23.0);
    kayit.ekle(10, 21.5);
    kayit.ekle(15, 24.0);
    kayit.ekle(20, 22.0);

    if (kayit.bos()) {
        std::cout << "Veri yok.\n";
        return 1;
    }

    const double esik = 23.5;
    std::cout << std::fixed << std::setprecision(2);
    kayit.tabloYazdir();
    std::cout << '\n';
    std::cout << "Ortalama : " << kayit.ortalama() << '\n';
    std::cout << "En kucuk : " << kayit.enKucuk() << '\n';
    std::cout << "En buyuk : " << kayit.enBuyuk() << '\n';
    std::cout << "Std sapma: " << kayit.standartSapma() << '\n';

    int asim = kayit.esikUstu(esik);
    std::cout << "Esik (" << esik << ") ustu: " << asim << " olcum\n";
    if (asim > 0) {
        std::cout << "UYARI: sicaklik esigi asildi!\n";
    }
    return 0;
}
   dak  sicaklik
     0     22.50
     5     23.00
    10     21.50
    15     24.00
    20     22.00

Ortalama : 22.60
En kucuk : 21.50
En buyuk : 24.00
Std sapma: 0.86
Esik (23.50) ustu: 1 olcum
UYARI: sicaklik esigi asildi!

Hesabı elle doğrulayalım

Toplam 113.0, eleman sayısı 5, ortalama 22.6. Ortalamadan farklar: -0.1, 0.4, -1.1, 1.4, -0.6. Kareleri: 0.01, 0.16, 1.21, 1.96, 0.36; toplamı 3.70. Bölü 5 yapınca 0.74, karekökü yaklaşık 0.86. Program bu sonuçla örtüşüyor. Kendi yazdığın hesap kodunu elle yapılmış küçük bir örnekle doğrulamak, mühendislikte altın kuraldır.

Neleri nerede kullandık?

  • Sınıf ve kapsülleme: veri_ private; dışarıdan yalnızca arayüz metotları var.
  • const metotlar: İstatistik metotları kaydı değiştirmiyor.
  • STL: accumulate, min_element, max_element, count_if.
  • Lambda: Karşılaştırma ve eşik kuralları yerinde yazıldı; [esik] ile dış değişken yakalandı.
  • const referans: Döngüde const auto& ile kopyalama olmadı.
  • Doğrulama: Boş kayıtta bölme yapmadan çıkış.

Gerçek bir cihazda ekle metodu ADC'den okuduğun değeri alırdı ve veri bir ring buffer'da (dairesel arabellek) tutulurdu. Böylece bellek hiç büyümez, en eski ölçüm yenisiyle ezilir. Sabit boyutlu bir std::array ile bu tasarımı yapmak, gömülü dünyaya doğru atacağın ilk adımdır.

Bu programda ortalama() boş kayıtta sıfıra böler. main bunu önceden kontrol ediyor, ama sınıfı başka biri kullanırsa unutabilir. Sağlam kodda metotların kendisi boş durumu ele almalı (ör. istisna fırlatmak ya da std::optional dönmek).

Kendin dene

  1. Programı std::cin ile okuyacak şekilde genişlet: kullanıcı dakika ve sıcaklık girsin, dakika -1 girilince bitsin.
  2. Ölçümleri sıcaklığa göre büyükten küçüğe sıralayıp ilk üçünü yazdıran bir metot ekle.
  3. Ölçümleri dosyaya yazan (std::ofstream, başlık <fstream>) bir metot ekle.
  4. Sensör ADC değerini gerilime ve sıcaklığa çeviren bir fonksiyon yaz (ör. 10 mV/°C veren LM35 sensörü için sıcaklık = gerilim * 100).
  5. Meydan okuma: Son 3 ölçümün hareketli ortalamasını hesaplayan metot yaz.

Sırada ne var?

Bu kursla C++'ın temelini bitirdin. Devamında şunlara bakabilirsin: kalıtım ve sanal fonksiyonlar (polimorfizm), şablonlar (template), istisnalar (try/catch), dosya işlemleri, çoklu iş parçacığı ve CMake ile proje yönetimi. Gömülü yönüne gitmek istersen STM32 ya da ESP32 geliştirme kartı alıp ilk LED yakma programını C++ ile yazmak harika bir sonraki adımdır.

// Mini sınav

Bir seçeneğe tıkla; doğru mu yanlış mı, anında ve nedeniyle birlikte göreceksin.

1. Bu programda standart sapma neyi ölçer?
2. Kayit sınıfında veri_ üyesinin private yapılmasının faydası nedir?
3. Boş bir kayıtta ortalama() çağrılırsa ne olur?

Bitirdiğinde işaretle: ilerlemen kaydolur, +20 XP kazanırsın.

// Final sınavı ve sertifika

Derslerden rastgele 20 soru, 30 dakika, geçme notu %70. Geçersen adına doğrulanabilir (QR kodlu) bir başarı sertifikası düzenlenir.

Final sınavına gir

İpucu: ← → tuşlarıyla dersler arasında gezinebilirsin.