Arduino etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Arduino etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

28 Ekim 2025 Salı

C Dilinde Hata Durumları Nasıl Yönetilmelidir? Debouncer Yapısı Nedir?

C Dilinde Hata Durumları Nasıl Yönetilmelidir? Debouncer Yapısı Nedir?

Merhaba! 😊 Bu yazıda iki kritik konuyu pratik bir mühendislik akışıyla ele alacağız: (1) C dilinde hata yönetimi ve (2) mekanik buton/switch girişleri için debouncer (zıplama önleme). Amaç; üretim ortamında güvenilir, izlenebilir ve bakımı kolay bir kod tabanı kurarken giriş sinyallerini de kararlı, tek olaya indirgenmiş şekilde üst katmana aktarmak. Yazının sonunda err_t hata kodları, cleanup/goto, assert + log halkası, Watchdog/safe-state ve SysTick tabanlı debouncer için hazır kopyala–yapıştır C kodları bulacaksınız. 🚀

İçindekiler

Neden Hata Yönetimi ve Debounce?

Gömülü sistemler sahada gürültü, kenar durumlar, zaman aşımları ve kullanıcı etkileşimi gibi belirsizlikler altında çalışır. İyi tasarlanmamış bir hata akışı sistemin kilitlenmesine, veri kaybına veya güvenlik risklerine yol açabilir. Benzer şekilde debounce yapılmadığında tek basış birden fazla olay gibi algılanır; menüler sapıtır, sayaçlar şaşar. İyi haber: Aşağıdaki yapıları bir kere kurduğunuzda yeni projelere şablon gibi taşıyabilirsiniz. ✅

Hata Türleri ve Tepki Matrisi

TürÖrnekÖncelikÖnerilen Tepki
Geçici (Transient) I2C NACK, tek seferlik CRC hatası Orta Tekrar dene, geri basınç (backoff), telemetri kaydı
Kalıcı (Persistent) Sensör kopuk, donanım arızası Yüksek Güvenli mod (safe-state), kullanıcı/servis bildirimi
Programatik (Bug) Null pointer, sınır taşması Çok yüksek Geliştirmede assert, üretimde kontrollü kurtarma/yeniden başlatma

C’de Hata Mimarisinin Omurgası: err_t + Makrolar

Modüller arası anlaşılır ve tutarlı bir dil kurmak için tek bir hata başlığı kullanın. Fonksiyonlar ERR_OK ile döner; başarısızlıklarda anlamlı kodlar kullanılır. Aşağıdaki şablon doğrudan kopyalanabilir.

/* error.h */
#ifndef ERROR_H
#define ERROR_H
#include <stdint.h>

typedef enum {
  ERR_OK = 0,
  ERR_TIMEOUT,
  ERR_PARAM,
  ERR_IO,
  ERR_BUSY,
  ERR_NO_MEM,
  ERR_RANGE,
  ERR_STATE,
  ERR_CRC,
  ERR_UNKNOWN
} err_t;

/* Hızlı dönüş ve tek çıkış noktası için yardımcılar */
#define RET_IF_FAIL(expr)        do { err_t _e = (expr); if (_e != ERR_OK) return _e; } while (0)
#define GOTO_IF_FAIL(expr,label) do { err = (expr);     if (err != ERR_OK) goto label; } while (0)

#endif /* ERROR_H */

Kaynak Yönetimi için cleanup/goto Kalıbı

Çoklu tahsis (buffer, periferal) yapan fonksiyonlarda tek çıkış noktası sızıntıları önler ve okunabilirliği artırır.

/* demo_cleanup.c */
#include "error.h"
#include <stdlib.h>

typedef struct Buf { uint8_t *p; size_t n; } Buf;

static err_t buf_alloc(Buf *b, size_t n){
  if (!b || n==0) return ERR_PARAM;
  b->p = (uint8_t*)malloc(n);
  if (!b->p)     return ERR_NO_MEM;
  b->n = n;
  return ERR_OK;
}
static void buf_free(Buf *b){
  if (b && b->p){ free(b->p); b->p=NULL; b->n=0; }
}

err_t do_job(size_t a, size_t b){
  err_t err = ERR_OK;
  Buf x={0}, y={0};

  GOTO_IF_FAIL(buf_alloc(&x, a), cleanup);
  GOTO_IF_FAIL(buf_alloc(&y, b), cleanup);

  /* ... iş mantığı ... */
  if (a < b){ err = ERR_RANGE; goto cleanup; }

cleanup:
  buf_free(&y);
  buf_free(&x);
  return err;
}

Geliştirmede assert, Sahada Log Halkası

assert geliştirme sırasında hatalı varsayımları erken patlatır. Üretimde ya kapatılır ya da yumuşatılır. Sahada hata analizi için ring buffer ile zaman damgalı olay kaydı çok işe yarar.

/* errlog.h / errlog.c */
#include <stdatomic.h>
typedef struct {
  uint32_t ts_ms;
  uint16_t code;  /* err_t veya modül kodu */
  uint16_t info;  /* ek veri (ör. hangi buton, hangi sensör) */
} error_event_t;

#define ERRLOG_SIZE 64
static error_event_t g_errlog[ERRLOG_SIZE];
static atomic_uint   g_wr = 0;

void errlog_push(uint32_t ts_ms, uint16_t code, uint16_t info){
  unsigned i = atomic_fetch_add(&g_wr, 1u) % ERRLOG_SIZE;
  g_errlog[i].ts_ms = ts_ms;
  g_errlog[i].code  = code;
  g_errlog[i].info  = info;
}

ISR, Watchdog ve Safe-State Stratejisi

  • ISR kısa olmalı: Ağır işi ana döngüye bırak; ISR sadece flag/kuyruk yazar.
  • Watchdog besleme: Tüm görevler “bitti” sinyali vermeden besleme yok; tek noktadan yönet.
  • Safe-state: Kritik hatada röleleri bırak, PWM’i kes, çıkışları güvenli seviyeye çek, kullanıcıyı uyar.

Debouncer Nedir? Neden Gerekli?

Mekanik buton/switch’ler bas-bırak sırasında 1–20 ms boyunca çok hızlı aç/kapa zıplama (bounce) üretir. Yazılımsal debouncer, bu gürültülü sinyali tek ve kararlı olaya dönüştürür; sayıcılar ve menüler güvenilir çalışır.

Debounce Yöntemleri (Delay, Counter, Majority, FSM)

1) Basit Gecikme (bloklayıcı – öğretici)

  • Değişim algılanınca delay ile bekle, sonra tekrar oku.
  • Eksiler: Ölçeklenmez, ISR/ana döngüyü kilitler.

2) Counter (Sayısal İntegratör) – Üretim için hafif ve sağlam

typedef struct {
  uint8_t stable;   /* onaylı seviye (0/1) */
  uint8_t cnt;      /* ms sayacı */
  uint8_t thr_ms;   /* debounce eşiği (örn 10-20 ms) */
  uint8_t event;    /* 1: durum değişti kenarı */
} debounce_t;

static inline void debounce_step(debounce_t *d, uint8_t raw){
  d->event = 0;
  if (raw == d->stable){ d->cnt = 0; return; }
  if (d->cnt < d->thr_ms){
    if (++d->cnt == d->thr_ms){
      d->stable = raw;
      d->event  = 1; /* kenar olayı */
    }
  }
}

3) Majority (Kaydırmalı Pencere) – Gürültü bağışıklığı yüksek

#define WIN 8u
typedef struct { uint8_t q[WIN]; uint8_t i; uint8_t stable; uint8_t event; } db_win_t;

static inline void db_win_step(db_win_t *d, uint8_t raw){
  d->q[d->i++ % WIN] = raw; d->event = 0;
  uint8_t sum=0; for (uint8_t k=0;k<WIN;k++) sum += d->q[k];
  uint8_t maj = (sum >= (WIN/2 + 1)) ? 1u : 0u;
  if (maj != d->stable){ d->stable = maj; d->event = 1; }
}

4) FSM (Single/Long/Double Press gibi zengin olaylar)

typedef enum { DB_IDLE, DB_BOUNCE, DB_PRESSED } db_state_t;
typedef enum { EV_NONE=0, EV_PRESS, EV_RELEASE, EV_LONG } db_event_t;

typedef struct {
  db_state_t st;
  uint16_t   t_ms;
  uint16_t   db_ms;    /* 10-20 ms */
  uint16_t   long_ms;  /* 600-800 ms */
} db_fsm_t;

static db_event_t db_fsm_step(db_fsm_t *d, uint8_t raw, uint16_t dt){
  d->t_ms += dt;
  switch (d->st){
    case DB_IDLE:
      if (raw){ d->st=DB_BOUNCE; d->t_ms=0; }
      break;
    case DB_BOUNCE:
      if (!raw){ d->st=DB_IDLE; }
      else if (d->t_ms >= d->db_ms){ d->st=DB_PRESSED; d->t_ms=0; return EV_PRESS; }
      break;
    case DB_PRESSED:
      if (!raw){ d->st=DB_IDLE; return EV_RELEASE; }
      else if (d->t_ms >= d->long_ms){ d->t_ms=0; return EV_LONG; }
      break;
  }
  return EV_NONE;
}

STM32 HAL ile 1 ms SysTick Tabanlı Çoklu Buton Debounce

HAL_SYSTICK_Callback() içinde sadece zaman işareti üretip asıl işlemi ana döngüde yapmak daha temiz ve güvenlidir.

/* debounce_stm32.c */
#include "stm32f1xx_hal.h" /* ailenize göre değiştirin */
#include <stdint.h>

#define BTN_COUNT 4

typedef struct { uint8_t stable, cnt, thr_ms, event; } debounce_t;

static volatile uint8_t g_tick1ms = 0;
static debounce_t g_btn[BTN_COUNT];

void HAL_SYSTICK_Callback(void){ g_tick1ms = 1; }

static inline uint8_t btn_raw_read(int i){
  /* Projenize göre uyarlayın; aktif-düşük butonlarda tersleyin */
  switch (i){
    case 0: return (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET);
    case 1: return (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET);
    case 2: return (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET);
    case 3: return (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_SET);
    default: return 0;
  }
}

static inline void debounce_step_one(debounce_t *d, uint8_t raw){
  d->event = 0;
  if (raw == d->stable){ d->cnt = 0; }
  else {
    if (d->cnt < d->thr_ms){
      if (++d->cnt == d->thr_ms){
        d->stable = raw;
        d->event  = 1;
      }
    }
  }
}

static void debounce_step_all(void){
  for (int i=0;i<BTN_COUNT;i++){
    debounce_step_one(&g_btn[i], btn_raw_read(i));
  }
}

/* Kenar olaylarını üst katmana bildir */
static void on_button_edge(int idx, uint8_t level){
  /* Basıldı/bırakıldı: uygulamanıza göre doldurun */
  (void)idx; (void)level;
}

int main(void){
  HAL_Init(); /* RCC, GPIO vb. başlatmalarınızı yapın */

  for (int i=0;i<BTN_COUNT;i++){
    g_btn[i].stable = 0;  /* aktif-düşük ise 1/0 normalize edin */
    g_btn[i].cnt    = 0;
    g_btn[i].thr_ms = 15; /* 10–20 ms tipik */
    g_btn[i].event  = 0;
  }

  for (;;){
    if (g_tick1ms){
      g_tick1ms = 0;
      debounce_step_all();
      for (int i=0;i<BTN_COUNT;i++){
        if (g_btn[i].event){
          on_button_edge(i, g_btn[i].stable);
        }
      }
    }
    /* Diğer non-blocking işler */
  }
}

Hata Yönetimi + Debouncer Entegrasyon Örneği

Bir butona basıldığında EEPROM yazımı tetiklensin; hata olursa log’a düşüp uyarı LED’i yansın:

#include "error.h"

/* Donanım/sürücü katmanı: uygulamanızda sağlayın */
extern err_t eeprom_write_page(uint32_t addr, const void *buf, size_t n);
extern void  led_error_on(void);
extern void  errlog_push(uint32_t ts_ms, uint16_t code, uint16_t info);

static void on_button_edge_safe(int idx, uint8_t level){
  if (idx==0 && level==1){ /* buton 0 basıldı */
    uint32_t data = 0x12345678u;
    err_t e = eeprom_write_page(0x0000u, &data, sizeof(data));
    if (e != ERR_OK){
      /* Zaman damgasını sisteminizden (HAL_GetTick vb.) alın */
      errlog_push(/*ts*/0u, (uint16_t)e, /*info*/idx);
      led_error_on();
    }
  }
}

Yaygın Hatalar ve İpuçları

  • ISR’da debounce yapmak: Kesme süresini uzatır, jitter üretir. Ana döngüde yapın.
  • Bloklayıcı HAL_Delay: Demo’da çalışır; gerçek zamanlı işlerde işleri kilitler.
  • Keyfi eşik değerleri: Osiloskopla ölçüp 10–20 ms bandında gerçekçi seçin.
  • Watchdog’u kör beslemek: “Tüm görevler bitti” şartı sağlanmadan besleme yapmayın.
  • Dağınık hata kodları: Tüm modüller tek error.h üzerinden konuşsun.

Kontrol Listesi

  • [ ] Projede tek bir err_t başlığı var
  • [ ] cleanup/goto ile tek çıkış noktası sağlandı
  • [ ] Zaman damgalı log halkası aktif
  • [ ] ISR’lar kısa; ana döngü non-blocking
  • [ ] Debounce eşiği ölçüme dayalı
  • [ ] PRESS/RELEASE/LONG olayları tasarlandı (gerekirse)
  • [ ] Watchdog besleme politikası yazılı

🔖 Terimler Sözlüğü

TerimAçıklama
err_tFonksiyonların döndürdüğü, enum tabanlı hata tipi.
cleanup/gotoKaynakları tek noktada serbest bırakma kalıbı.
assertGeliştirmede hatalı varsayımı anında yakalar.
Ring bufferBaşa saran sabit boyutlu kayıt tamponu.
ISRKesme rutinleri; kısa ve deterministik olmalı.
WatchdogSistem takıldığında reset atarak toparlar.
DebounceGürültülü mekanik girişin kararlı olaya indirgenmesi.
FSMSonlu durum makinesi; olay tabanlı durum geçişi.

📌 Ekstra Kaynaklar

🎨 Görsel Önerisi

Not: Aşağıdaki prompt ve alt metin HTML’in dışındadır (bu yazının içinde sadece bilgilendirme amaçlı listelenmiştir).


Görsel üretim promptu: - “Clean technical illustration: left side shows a noisy mechanical button waveform turning into a stable debounced signal (counter/FSM hint); right side depicts a C error-handling flow (err_t enums → cleanup/goto → safe-state + watchdog). Minimal, vector, white background, high contrast.” Alt metin (alt text) önerisi: - “Debouncer ile gürültülü buton sinyalinin tek olaya indirgenmesi ve C’de err_t + cleanup/goto hata yönetimi akışını anlatan teknik çizim.”

4 Eylül 2025 Perşembe

C Dilinde Exponential Moving Average (EMA) Filter Nedir, Nasıl Uygulanır?

C Dilinde Exponential Moving Average (EMA) Filter Nedir, Nasıl Uygulanır?

Merhaba! 😊 Bugünkü yazımızda hem elektronikçiler hem de yazılımcılar için oldukça faydalı olan Exponential Moving Average (EMA) filtresini inceleyeceğiz. Özellikle gürültülü sensör verilerini yumuşatmak ve daha kararlı ölçümler elde etmek isteyenler için C dilinde bu filtrenin nasıl uygulanacağını adım adım göstereceğim.

Dalgalı sensör verisi ve EMA filtresi ile yumuşatılmış verinin karşılaştırmalı grafiği

Exponential Moving Average (EMA) Filtresi Nedir?

EMA filtresi, geçmiş verilerle birlikte yeni gelen verileri ağırlıklı bir şekilde birleştirerek daha pürüzsüz bir çıkış sinyali elde etmemizi sağlar. Burada “exponential” (üstel) ifadesi, yeni veriye daha fazla, eski verilere ise giderek azalan ağırlık verilmesi anlamına gelir.

Matematiksel Tanım

EMA filtresi şu formülle ifade edilir:

EMA(n) = α * YeniVeri(n) + (1 - α) * EMA(n-1)
  • EMA(n): Şu anki filtrelenmiş değer
  • YeniVeri(n): Şu anki ölçüm/sensör değeri
  • EMA(n-1): Bir önceki filtrelenmiş değer
  • α (alfa): 0 ile 1 arasında bir katsayı, filtre hassasiyetini belirler

Neden EMA Kullanılır?

Birçok uygulamada ham veriler çok fazla gürültü içerir. Örneğin:

  • ADC ile ölçülen sıcaklık sensör verileri
  • Jiroskop veya ivmeölçer (IMU) verileri
  • Motor akım ve voltaj ölçümleri

Bu gibi durumlarda, veriyi doğrudan kullanmak yerine EMA filtresi ile yumuşatmak daha anlamlıdır. Böylece:

  • Veri dalgalanmaları azalır ✅
  • Trendler daha net görülür 📈
  • Kod tarafında basit bir algoritma ile uygulanır ⚡

EMA ile Basit Moving Average (SMA) Arasındaki Fark

Sıklıkla EMA ile Simple Moving Average (SMA) karşılaştırılır. SMA’da belirli sayıda eski veri toplanır ve ortalaması alınır. EMA ise:

  • Eski verileri saklamaz (daha az RAM kullanır)
  • Daha az işlem gücü gerektirir
  • Son veriye daha fazla ağırlık verdiği için daha hızlı tepki verir
Özellik SMA EMA
Hafıza Kullanımı Yüksek (N veri tutar) Düşük (tek değer tutar)
Tepki Hızı Daha yavaş Daha hızlı
Hesaplama Yükü Toplama + Bölme Çarpma + Toplama

C Dilinde EMA Filtresi Nasıl Uygulanır?

Temel Kod Örneği

#include <stdio.h>

float EMA_Filter(float new_value, float alpha) {
    static float ema = 0; // Başlangıç değeri
    ema = (alpha * new_value) + ((1 - alpha) * ema);
    return ema;
}

int main() {
    float sensor_data[] = {10, 12, 15, 14, 13, 20, 18};
    int data_size = sizeof(sensor_data) / sizeof(sensor_data[0]);
    float alpha = 0.2; // Filtre hassasiyeti

    for(int i = 0; i < data_size; i++) {
        float filtered = EMA_Filter(sensor_data[i], alpha);
        printf("Ham Veri: %.2f  ->  Filtrelenmiş: %.2f\n", sensor_data[i], filtered);
    }
    return 0;
}

Yukarıdaki örnekte:

  • alpha = 0.2 seçildi. Bu durumda yeni veri %20 etkili olurken, geçmiş veri %80 oranında korunur.
  • static float ema, fonksiyon çağrıları arasında eski değeri saklar.
  • Her ölçüm geldiğinde filtre otomatik güncellenir.

α (Alpha) Değeri Nasıl Seçilir?

Alpha değeri filtrenin hızlı mı, yavaş mı tepki vereceğini belirler:

  • α ≈ 0.1 → Daha yavaş, daha yumuşak filtre (gürültüyü azaltır, ama gecikme artar)
  • α ≈ 0.5 → Orta hassasiyet, hem hızlı hem dengeli
  • α ≈ 0.9 → Çok hızlı tepki, ama gürültü daha az bastırılır

Pratikte, sensör tipine ve uygulamaya göre α ayarlanır.

Gerçek Hayat Örneği

Bir sıcaklık sensörü saniyede 100 ölçüm yapıyor ve her ölçümde ±2°C gürültü var. Eğer ham veriyi doğrudan kullanırsak ekranda sürekli dalgalanan değerler görürüz. Ancak EMA filtresi kullanıldığında:

  • Ekranda daha stabil bir sıcaklık değeri görünür 🌡️
  • Küçük dalgalanmalar ortadan kalkar
  • Değişimler daha akıcı yansır

Avantajlar ve Dezavantajlar

Avantajları

  • Kolay implementasyon (tek satır formül yeterli)
  • Düşük hafıza ve işlem gücü ihtiyacı
  • Gerçek zamanlı sistemler için ideal

Dezavantajları

  • Trend değişimlerine gecikmeli tepki verir
  • Alpha değeri doğru seçilmezse ya çok gürültülü ya da çok yavaş tepki verebilir

Sonuç

Exponential Moving Average (EMA) filtresi, sensör verilerini yumuşatmak için C dilinde kolayca uygulanabilecek güçlü bir yöntemdir. Hafif, hızlı ve esnek olması sayesinde hem gömülü sistemlerde hem de masaüstü uygulamalarında yaygın olarak kullanılır. Uygulamanıza göre doğru α değerini seçerek siz de daha kararlı ve güvenilir sonuçlar elde edebilirsiniz 🚀.


🔖 Terimler Sözlüğü

Terim Açıklama
EMA Exponential Moving Average – Üstel hareketli ortalama filtresi
α (Alpha) Filtrenin yeni veriye verdiği ağırlık (0–1 arasında)
SMA Simple Moving Average – Basit hareketli ortalama filtresi
ADC Analog-Dijital Çevirici

📌 Ekstra Kaynaklar

9 Haziran 2025 Pazartesi

C Dilinde Moving Average Filter (Hareketli Ortalama Filtresi) Nedir, Nasıl Uygulanır?

Hareketli Ortalama Filtresi (Moving Average Filter), sinyal işleme ve veri analizi alanlarında en çok tercih edilen basit ve etkili filtrelerden biridir. Gürültülü verilerin pürüzsüzleştirilmesi, ani değişimlerin yumuşatılması ve sensör okumalarının stabilize edilmesi gibi birçok uygulama alanında kullanılır. Özellikle gömülü sistemlerde, mikrodenetleyicilerde ve gerçek zamanlı uygulamalarda, C dili ile kolayca uygulanabilir olması sayesinde oldukça popülerdir.

Hareketli Ortalama Filtresi Nedir?

Kısaca, hareketli ortalama filtresi, belirli bir pencere (örneğin N örnek) içerisindeki verilerin aritmetik ortalamasını alarak yeni bir çıktı üretir. Böylece, kısa süreli gürültüler ve ani değişimler filtrelenmiş olur.

Matematiksel olarak:
Y[n] = (X[n] + X[n-1] + ... + X[n-(N-1)]) / N
Burada:

  • Y[n]: Filtrelenmiş çıktı

  • X[n]: En yeni giriş değeri

  • N: Pencere boyutu (window size)


Avantajları ve Dezavantajları

Avantajlar:

  • Basit ve hızlı algoritma

  • Bellek ve işlemci gereksinimi düşük

  • Gerçek zamanlı uygulamalara uygun

Dezavantajlar:

  • Ani değişimleri geciktirir (faz kayması)

  • Büyük pencerelerde tepki yavaştır

  • Herkese uyan tek boyutlu çözüm değildir; pencere boyutu dikkatle seçilmelidir


C Dilinde Moving Average Filter Nasıl Uygulanır?

Aşağıda, hareketli ortalama filtresinin C dilinde farklı şekillerde uygulanışı anlatılmaktadır.

1. Temel Uygulama: Döngüyle Ortalama Alma

Kullanımı:

Eksisi:

Her yeni örnekte tüm pencereyi toplar, bu da işlemciyi yorar.


2. Kayan Pencere ile Optimizasyon (Dairesel Buffer Kullanımı)

Dairesel (circular) buffer ve kayan toplam yaklaşımıyla işlem yükü azaltılabilir.

Kullanımı:

Avantajı:

  • Her örnek için sadece iki toplama/çıkarma işlemi gerekir.

  • Özellikle gömülü sistemlerde çok daha hızlıdır.


3. Uygulama Alanları

  • Sensör verilerinin düzeltilmesi (ör. sıcaklık, ivmeölçer)

  • Finansal zaman serilerinde veri yumuşatma

  • Gürültülü sinyal filtreleme (ör. ADC verisi)

  • Otomotivde, tıbbi cihazlarda, endüstriyel kontrol sistemlerinde


Pencere Boyutu (Window Size) Nasıl Seçilmeli?

  • Küçük pencere (örn. 3–5): Ani değişimlere daha duyarlı, az gecikme.

  • Büyük pencere (örn. 20–50): Daha yumuşak sonuç, daha fazla gecikme.

Kullanım amacınıza ve verinizin doğasına göre pencere boyutunu dikkatli seçmelisiniz.


Kodun Tamamı: Basit Moving Average Filter Kütüphanesi

Sonuç

Hareketli ortalama filtresi, basitliği ve etkililiğiyle öne çıkan bir filtreleme yöntemidir. C dilinde uygulanması da oldukça kolaydır. Kodunuzu ve pencere boyutunuzu ihtiyacınıza göre optimize ederek, birçok gerçek zamanlı uygulamada başarılı sonuçlar elde edebilirsiniz.

Sen de uygulaman için yukarıdaki örnekleri kolayca entegre edebilirsin!

26 Şubat 2024 Pazartesi

ESP32 ile Kristal veya Osilatör Kullanmadan RMII Üzerinden Ethernet Haberleşmesi ve İpuçları

İnternette gördüğüm ESP32 ve ethernet uygulamalarının çoğunda ethernet chipine kristal takarak uygulama çalıştırılmış. Bunun sinyal kalitesi açısından faydası olabilir ancak tek çözüm bu değil. ESP32 modüllerinden de ethernet için gerekli clock çıkışını alabilirsiniz.

Bunun için örnek devrede de gösterildiği gibi ESP32 ile ethernet chipinin clock uçlarını birleştirmek yeterli. Burada frekans 50 MHz mertebesinde olduğu için mümkün oldukça yakın olması önemli.

Benim yaptığım uygulamadan hat boyu yaklaşık 44 mm ve 2 adet via kullanılıyor. Buna rağmen sorunsuz bir şekilde sistemin çalıştığını gördüm.



ESP32 clock çıkışı için GPIO0, GPIO16, GPIO17 pinleri kullanılabilir.


Arduino arayüzünde varsayılan olarak clock ESP32'ye girecek şekilde tanımlanmıştır. Ethernet clock çıkışını tanımlamak için aşağıdaki satır kullanılabilir. Bu begin fonksiyonu üzerinden ethernet chipi, clock yönü ve pini seçilebilir.

ETH.begin(0,-1,23,18,ETH_PHY_LAN8720,ETH_CLOCK_GPIO17_OUT);

Kaynaklar;

  • https://docs.espressif.com/projects/esp-idf/en/release-v3.1/api-reference/ethernet/esp_eth.html
  • https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32d_esp32-wroom-32u_datasheet_en.pdf

C Dilinde Hata Durumları Nasıl Yönetilmelidir? Debouncer Yapısı Nedir?

C Dilinde Hata Durumları Nasıl Yönetilmelidir? Debouncer Yapısı Nedir? Merhaba! 😊 Bu yazıda iki kritik konuyu pratik bir mühendislik akış...