Basit Elektronik Yük Devresi V3

Şönt gibi düşük değerli dirençlerde bağlantı noktası bile ölçüm değerini etkiler. Kalibrasyon şart.
 
ADC de bir lineerlik hatası var. Bu tip basit ADC lerde olur zaten.

Öncelikle R1 ve R2 gerilim bölücü dirençleri sök, soğumasını bekle. Sonra da tam olarak direnç değerlerini ölç ve bir kenara yaz. Cihaz 1 saat çalışsın, sonra da AREF i ölç ve bir kenara yaz.

Bir de şu anda kullandığın formülü de yaz. Daha önceki mesajlarda belki vardır bu bilgiler ama şu an için bir özet olması bakımından yeniden yazmakta fayda var. Formül ile olabilecek en yakın sonucu elde edelim.

Bunu elde edince, geri kalan hatayı da interpolasyon ile çözmen gerekecek. Mesela 10 farklı voltaj ölçümünü yapıp gerçek voltaj, hesaplanan voltaj tablosu yapacaksın. Sonra bu tabloya göre ölçülen değeri düzelteceksin. Ama önce yukarıdakileri halledelim. interpolasyonu sonra yaparız.

Tüm ölçümler aşağıdaki gibi.

R1: 17996
R2: 3229
AREF: 4995

MULTİMETREEKRAN
5.04V4.99V
7.546V7.51V
10V9.98V
12.437V12.39V
15.14V15.08V
17.5V17.43V
20.05V19.83V
22.5V21.99V
25.16V24.01

C++:
//Voltaj Değişkenleri ///////////////
const int voltajRead = A6;
int voltajDeger = 0;
const float R1 = 17996.0;
const float R2 = 3229.0;
float voltaj = 0.0;
float girisVoltaji = 0.0;
//////////////////////////////////////

// Voltaj Okuma Kodları /////////////////////////////////////////
  voltajDeger = analogRead(voltajRead);
  voltaj = (voltajDeger * 4.995) / 1023;
  girisVoltaji = voltaj * (R1 + R2) / R2;
///////////////////////////////////////////////////////////////
 
Tamam şimdi iş senin en favori kısmına geldi :gulus2: Yukarıda voltajı hesaplıyorsun ya, o voltajı bir düzeltme katsayısı ile çarpman lazım.

Multimetre değerlerini bir array içerisine koy

Kod:
float gercek_deger[] =
{
  5.04,
  7.546,
  *
  *
  *
};

ekran değerlerini de bir array içerisine koy

Kod:
float olculen_deger[] =
{
  4.99,
  7.51,
  *
  *
  *
};

Sonra da öyle bir algoritma yazacağız ki, verilen bir değeri ölçülen değerler tablosundan gerçek değer tablosuna ölçeklendirecek.
 
Böyle bir algoritmayı hemen chatgpt ye yazdırabilirsin, ama doğru çalışmazsa sarfedeceğin zaman, yeni yazmaktan daha uzun olabilir :) Ama mantığını anlaman için bana verdiği cevabı ekleyeyim buraya

1732710286617.png


Şu da ürettiği kod. Bana çok kalabalık geldi, ama dediğim gibi, olayın mantığını anlamak için kullan, aynen kopyama

C:
#include <stdio.h>

// Function to perform interpolation
float interpolate(float adc_table[], float real_table[], int size, float adc_value) {
    // Clamp adc_value to the bounds of adc_table
    if (adc_value <= adc_table[0]) {
        return real_table[0];
    } else if (adc_value >= adc_table[size - 1]) {
        return real_table[size - 1];
    }

    // Find the segment [i, i+1] containing adc_value
    int i;
    for (i = 0; i < size - 1; i++) {
        if (adc_table[i] <= adc_value && adc_value < adc_table[i + 1]) {
            break;
        }
    }

    // Perform linear interpolation
    float adc_low = adc_table[i];
    float adc_high = adc_table[i + 1];
    float real_low = real_table[i];
    float real_high = real_table[i + 1];

    float real_value = real_low + ((adc_value - adc_low) / (adc_high - adc_low)) * (real_high - real_low);
    return real_value;
}

int main() {
    // Example tables
    float adc_table[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
    float real_table[10] = {0.0, 0.95, 1.8, 2.7, 3.55, 4.4, 5.2, 6.1, 7.0, 7.9};

    // Test with a sample adc_value
    float adc_value = 3.25;
    float real_value = interpolate(adc_table, real_table, 10, adc_value);

    printf("ADC Value: %.2f, Real Value: %.2f\n", adc_value, real_value);
    return 0;
}
 
Böyle bir algoritmayı hemen chatgpt ye yazdırabilirsin, ama doğru çalışmazsa sarfedeceğin zaman, yeni yazmaktan daha uzun olabilir :) Ama mantığını anlaman için bana verdiği cevabı ekleyeyim buraya

38526 eklentisine bak

Şu da ürettiği kod. Bana çok kalabalık geldi, ama dediğim gibi, olayın mantığını anlamak için kullan, aynen kopyama

C:
#include <stdio.h>

// Function to perform interpolation
float interpolate(float adc_table[], float real_table[], int size, float adc_value) {
    // Clamp adc_value to the bounds of adc_table
    if (adc_value <= adc_table[0]) {
        return real_table[0];
    } else if (adc_value >= adc_table[size - 1]) {
        return real_table[size - 1];
    }

    // Find the segment [i, i+1] containing adc_value
    int i;
    for (i = 0; i < size - 1; i++) {
        if (adc_table[i] <= adc_value && adc_value < adc_table[i + 1]) {
            break;
        }
    }

    // Perform linear interpolation
    float adc_low = adc_table[i];
    float adc_high = adc_table[i + 1];
    float real_low = real_table[i];
    float real_high = real_table[i + 1];

    float real_value = real_low + ((adc_value - adc_low) / (adc_high - adc_low)) * (real_high - real_low);
    return real_value;
}

int main() {
    // Example tables
    float adc_table[10] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
    float real_table[10] = {0.0, 0.95, 1.8, 2.7, 3.55, 4.4, 5.2, 6.1, 7.0, 7.9};

    // Test with a sample adc_value
    float adc_value = 3.25;
    float real_value = interpolate(adc_table, real_table, 10, adc_value);

    printf("ADC Value: %.2f, Real Value: %.2f\n", adc_value, real_value);
    return 0;
}
Eve geçeyim bakacağım abi. Biraz dışarı çıkmam gerekti. Ben çıkmayalı çok şey değişmiş dışarıda. :katil2:
 
İyide burada herşey ingilizce ya. Zaten yarım beyinle tam işlem yapmaya çalışıyorum. Basmıyor kafa.
Değişken isimleri bir birine çok benzer, kafa karıştırıyor. Array'leri işlevsel olarak nasıl kullanacağımı öğrenemedim zamanında. Bir tek foreach'a sokup döndükçe gelen veriyi bir değişkene atıp kullanıyordum. Şuanda onu bile unutmuş durumdayım.
Kodu inceliyorum, şöyle yapmış, böyle yapmış derken for döngüsünden itibaren işler karışıyor. Tam olarak bu işi anlatan türkçe bir video bulabilir miyiz acaba?
interpolasyon olarak bir aratayım bakalım. Bunu öğrensem her alanda çok işime yarar aslında. Resmen yazılımsal olarak hata düzeltiyorsun. İleride PID kontrollü bir proje yapmak istiyorum. Orada da çok işe yarar.
 
Orada yapılan iş aslında üçgen benzerliğinden bir oran buluyorsun. O bulunan oranı da düzeltme faktörü olarak kullanıyorsun.

İstersen bu voltaj ölçüm işi üzerinde çalışırken Demonte güç kaynağı V3 üzerinde çalış, böylece ben de burada paralel test ederim. Veya elektronik yük için şimdilik bu voltaj akım ölçüm işini bir kenara bırak ve elektronik yükün kendisini sağlam ve çalışır hale getirelim.
 
Orada yapılan iş aslında üçgen benzerliğinden bir oran buluyorsun. O bulunan oranı da düzeltme faktörü olarak kullanıyorsun.

İstersen bu voltaj ölçüm işi üzerinde çalışırken Demonte güç kaynağı V3 üzerinde çalış, böylece ben de burada paralel test ederim. Veya elektronik yük için şimdilik bu voltaj akım ölçüm işini bir kenara bırak ve elektronik yükün kendisini sağlam ve çalışır hale getirelim.
Abi Elektronik yükle zaten bir işimiz kalmadı. Multimetre bağladığımız sürece istediğimiz gibi çalışıyor. Tek yapmamız gereken voltaj ve akımı doğru ölçüp ekrana yansıtmak. Bitirelim aradan çıksın istiyorum. Bu interpolasyon işini ha burada öğrenmişim ha güç kaynağında. Eninde sonunda lazım olacak. Yani bunu bırakıp güç kaynağına da geçsem, orada da bilmiyorum.

Sen güç kaynağının negatif voltaj olayına bir bak. Ben bu dizdiğim ikinci kartta da ölçüm yaptım. Negatif voltaj bunda da düşük. O arada bende şu interpolasyonu öğrenmeye çalışayım.
 
Daha elektronik yükte yapılması gereken bir sürü test var. Sana bir test ve iş planı vereyim :)

1) Stabil olarak çekilebilecek minimum akım nedir? Yani sürekli olarak değişmeyen, az çok sabit kalan minimum akım nedir?

2) Maksimum voltajı 30V olarak belirledik. Voltaj 30V u geçerse MCU nun çıkışı kesmesi lazım.

3) Maksimum voltajda çekilebilecek maksimum akım nedir? Yani MOSFET lerin sıcaklığının güvenli bir limitte sabit kaldığı maksimum akım nedir?

4) Bu güç limiti belirlendikten sonra, MCU'nun bu güç limitinin belli bir marjını geçtiği anda çıkışı kesmesi lazım.

5) MOSFET sıcaklık limiti aşılırsa çıkışın kesilmesi lazım.

6) Belli bir akım ayarlandığında, voltaj değişirse akım sabit kalıyor mu?

7) Voltajı potansiyometre ile sürekli değiştirirken akım sabit kalıyor mu?

8) Elektronik yükü 1A ayarlayıp akımı 3A yaparsan akım ayarlanan değere düzgün bir şekilde çıkıyor mu? Yoksa overshoot var mı? Varsa ne kadar?

9) Elektronik yükü 3A ayarlayıp akımı 1A yaparsan akım ayarlanan değere düzgün bir şekilde iniyor mu? Yoksa undershoot var mı? Varsa ne kadar?

Bu testlerin yapılıp yükün davranışının net olarak anlaşılması lazım. Ondan sonra artık buna güvenip her yerde rahatlıkla kullanırsın.
 
Daha elektronik yükte yapılması gereken bir sürü test var. Sana bir test ve iş planı vereyim :)

1) Stabil olarak çekilebilecek minimum akım nedir? Yani sürekli olarak değişmeyen, az çok sabit kalan minimum akım nedir?

2) Maksimum voltajı 30V olarak belirledik. Voltaj 30V u geçerse MCU nun çıkışı kesmesi lazım.

3) Maksimum voltajda çekilebilecek maksimum akım nedir? Yani MOSFET lerin sıcaklığının güvenli bir limitte sabit kaldığı maksimum akım nedir?

4) Bu güç limiti belirlendikten sonra, MCU'nun bu güç limitinin belli bir marjını geçtiği anda çıkışı kesmesi lazım.

5) MOSFET sıcaklık limiti aşılırsa çıkışın kesilmesi lazım.

6) Belli bir akım ayarlandığında, voltaj değişirse akım sabit kalıyor mu?

7) Voltajı potansiyometre ile sürekli değiştirirken akım sabit kalıyor mu?

8) Elektronik yükü 1A ayarlayıp akımı 3A yaparsan akım ayarlanan değere düzgün bir şekilde çıkıyor mu? Yoksa overshoot var mı? Varsa ne kadar?

9) Elektronik yükü 3A ayarlayıp akımı 1A yaparsan akım ayarlanan değere düzgün bir şekilde iniyor mu? Yoksa undershoot var mı? Varsa ne kadar?

Bu testlerin yapılıp yükün davranışının net olarak anlaşılması lazım. Ondan sonra artık buna güvenip her yerde rahatlıkla kullanırsın.
 
Son düzenleme:
Testlerin yapılması kolay yav. Gören de phase margin, loop stability testi yapacağını sanar :D
 
Abi ölçüm işlemini kodları düzenleyerek hallettim.
Çok yakın oranda doğru ölçüyorum artık voltajı.
Daha kesin sonuçlar için örnek sayısını çoğaltmam gerek ama arduinonun belleği yetmeyebilir. En son nano ile işimiz kalmadıktan sonra kalan bellek miktarını kullanarak örnek sayısını çoğaltırız.

interpolasyon fonksiyonunun ne yaptığını anladım ama işin matematik kısmı bende hala muamma.

C++:
// Referans ve ADC ölçümleri ///////////////////////////////////////
float adc_values[] = {5.01, 7.51, 9.98, 12.39, 15.08, 17.43, 19.83, 21.99, 24.01};  // ADC değerleri
float ref_values[] = {5.04, 7.546, 10, 12.437, 15.14, 17.5, 20.05, 22.50, 25.16};  // Multimetre ölçümleri
int num_points = 9;  // Veri noktalarının sayısı
////////////////////////////////////////////////////////////////////

// Interpolasyon fonksiyonu  ////////////////////////////////////////////////////////////////////
float interpolate(float adc_value) {
  for (int i = 0; i < num_points - 1; i++) {
    // Eğer adc_value iki nokta arasındaysa
    if (adc_value >= adc_values[i] && adc_value <= adc_values[i + 1]) {
      // Doğrusal interpolasyon
      float slope = (ref_values[i + 1] - ref_values[i]) / (adc_values[i + 1] - adc_values[i]);
      return ref_values[i] + slope * (adc_value - adc_values[i]);
    }
  }
  // Eğer aralık dışında bir değer alınırsa, sınır değerleri döndür
  if (adc_value < adc_values[0]) return ref_values[0];
  if (adc_value > adc_values[num_points - 1]) return ref_values[num_points - 1];
  return 0;  // Hata durumu
}
/////////////////////////////////////////////////////////////////////////////////////////////////

// Voltaj Okuma Kodları /////////////////////////////////////////
  voltajDeger = analogRead(voltajRead);
  voltaj = (voltajDeger * 4.995) / 1023;
  girisVoltaji = voltaj * (R1 + R2) / R2;
  float corrected_voltaj = interpolate(girisVoltaji);
///////////////////////////////////////////////////////////////

  display.print("Volt:");
  display.println(corrected_voltaj);
 
Özellikle düşük voltaj tarafına fazla örnek vermek lazım. 0.5 1.0 2.0 3.0 gibi. Aynı şekilde üst voltaj sınırına da. Lineerlik buralarda daha kötü oluyor.
 
Özellikle düşük voltaj tarafına fazla örnek vermek lazım. 0.5 1.0 2.0 3.0 gibi. Aynı şekilde üst voltaj sınırına da. Lineerlik buralarda daha kötü oluyor.
Olayı yazılımsal olarak anladım. Bundan sonrası kolay. ver örneği al reel değeri.
Şimdi bir şey dikkatimi çekti. 14.1V 1A akım çekmeye başladım güç kaynağından. Voltaj 13.47V'a düştü. Bu değer multimetrede de aynı, yük ekranında da aynı. O zaman sorun güç kaynağında oluyor değil mi?
 
Kablolarda voltaj düşüyor ondan daha az ölçüyorsun. Eğer güç kaynağının regülasyonu doğru çalışıyormu diye test etmek istiyorsan, ölçümü DOĞRUDAN pass transistörlerin emitter'inden yapman lazım.
 
Kablolarda voltaj düşüyor ondan daha az ölçüyorsun. Eğer güç kaynağının regülasyonu doğru çalışıyormu diye test etmek istiyorsan, ölçümü DOĞRUDAN pass transistörlerin emitter'inden yapman lazım.
Yok ben almıyım o zaman. :)
Güç kaynağının üzerindeki dijital multimetrede voltaj düşmüyor. Bende diyorum ki ne kadar hassas yapmışız, dijital multimetreden bile iyi ölçüyoruz :katil2:

Akımı nasıl ölçelim abi? Onda da interpolasyon kullanacağız herhalde ama ilk önce gelen verileri ölçeceğiz herhalde.
1.Aref, ki onu zaten biliyoruz artık.
2.Opamp çıkışı

Dün arkadaşlardan biri aşağıdaki kodu vermişti. Bu kod ile 24V da 1A çekerken;
Pensampermetre : 1A
Yük Ekranı : 780mA

C++:
 // Akım Okuma Kodları ////////////////////////////////////////
  akimDeger = analogRead(akimRead);
  voltajDususu = (akimDeger * 4.994) / 1023;
  akim = voltajDususu / 0.256;
  //////////////////////////////////////////////////////////////
 
Akım için tablo oluştururken mümkünse pensampermetreyi kullanma, voltaj ile aynı mantıkta kodu değiştirebilirsin.
 
Kalibrasyon için tablo oluştururken sık ölçüm yapıp bunları bir excel grafiğine aktarın. Daha sonra bunlar için ortalama bir eğilim çizgisi oluşturun. O çizginin görece fazla üstünde yada fazla altında kalan ölçümleri dikkate almayın. Kalibrasyonu da daha doğru verilerden oluşan bu tabloya göre yapın. Daha iyi sonuç elde edersiniz.
 
Olayı yazılımsal olarak anladım. Bundan sonrası kolay. ver örneği al reel değeri.
Şimdi bir şey dikkatimi çekti. 14.1V 1A akım çekmeye başladım güç kaynağından. Voltaj 13.47V'a düştü. Bu değer multimetrede de aynı, yük ekranında da aynı. O zaman sorun güç kaynağında oluyor değil mi?
Multimetreyi en düşük kademe V moduna alıp kablonun başı ile sonu arasındaki (aynı kablo üzerindeki (-) yada (+)) gerilim düşümünü ölçerseniz sebebini anlayacaksınız.
 

Çevrimiçi üyeler

Forum istatistikleri

Konular
7,115
Mesajlar
121,152
Üyeler
2,883
Son üye
alemrans

Son kaynaklar

Son profil mesajları

az bilgili çok meraklı
Prooffy wrote on semih_s's profile.
Merhaba, sizden DSO2C10 hakkında bilgi rica ettim. Yanıtlarsanız sevinirim...
Unal wrote on taydin's profile.
Timur Bey, Arduino kontrollü bir akü şarj cihazı yapmaya çalışıyorum. Aklımdaki fikri basit bir çizim olarak konu açmıştım. Özellikle sizin fikirlerinizi çok önemsiyorum.
hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Back
Top