MCP4922 Otomatik DAC Kalibrasyonu

Gokrtl

Gökhan Kartal (TeknoDay)
Staff member
Katılım
27 Şubat 2019
Mesajlar
11,212
Güç kaynağımda yaptığımız istişareler sonucu MCP4922 DAC için bulduğumuz katsayı 133 idi.
Bu rakamla neyi çarparsak çarpalım bize çıkışta istediğimiz çıkışı neredeyse tam olarak veriyor.
Neredeyse diyorum çünkü bu rakamı sabit 133 olarak kullanınca 30V da 30.04V, değer aşağılara doğru düştükçe hata payı daha da artarak geliyor.
1V için 133 katsayısını kullandığımızda çıkış 1.20v oluyor.

Bende düşündüm elimde 4096 adım atabilen bir DAC varken neden bu hatalara boyun eğeyim?
Kat sayısını değiştirir istediğim sonuca tam olarak ulaşırım. Bunun için if - else yapısı kullanmaya karar verip 3.else kodundan sonra vaz geçtim.
Çünkü neredeyse 2 voltta bir kalibrasyon katsayısını değiştirmem gerekiyordu.

C++:
    if (voltaj <= 30.00 && voltaj >= 27.00) {
      voltaj = voltaj * 133.85;
      setDac(voltaj, 1); //Volt
      voltaj = voltaj / 133.85;
    }
    else if (voltaj < 27.00 && voltaj >= 25.00) {
      voltaj = voltaj * 133.75;
      setDac(voltaj, 1); //Volt
      voltaj = voltaj / 133.75;
    }
    else if (voltaj < 25.00 && voltaj >= 22.00) {
      voltaj = voltaj * 133.70;
      setDac(voltaj, 1); //Volt
      voltaj = voltaj / 133.70;
    }

Bunun daha pratik bir yolu olmalıydı. Aklımda for döngülerini, fonksiyonları döndürmeye başladım.
Sonra Timur abinin geçen gün konuşurken "otomatik kalibrasyon yapılabilir" dediğini hatırladım.
O zaman ben şöyle bir yol izlerim.

1- Keypadden girdiğin voltajı karşılaştırma için kullan. Misal 30V
2- Piconun ADC si ile Ana çıkışı oku ve 30v ile karşılaştır.
3- Çıkıştan okunan değer 30V'a eşit değilse DAC'a gönderilen değeri mesela 5 artır.

Bir bakıma PID kontrolü gibi yani. Değeri çıkışta sabit tutacağım.
Bunun için ilk önce başıma bela olan çıkışı okuma işini hassas bir şekilde çözmem gerek.
Yaptığım işlemleri buradan paylaşacağım.
 
Hmm burada başka bir sorun olması lazım. 12 bit DAC ile 1 mV çözünürlük elde ediyorsun. Bunu da opamp 7.5 ile çarpıyor, o halde senin çıkışta en fazla 7.5 mV sapma görmen lazım. Çıkış voltajı 1 V da olsa 30 V da olsa bu durum geçerli.
 
Hmm burada başka bir sorun olması lazım. 12 bit DAC ile 1 mV çözünürlük elde ediyorsun. Bunu da opamp 7.5 ile çarpıyor, o halde senin çıkışta en fazla 7.5 mV sapma görmen lazım. Çıkış voltajı 1 V da olsa 30 V da olsa bu durum geçerli.
Devre çok spesifik bir hal aldı abi.
Bu dediğin sorunun en başı gibi. Şimdi buraya geri dönsem yine beynim yanacak. Biliyorsun NREF kısmımız sorunlu.
Yan yana olsak çok güzel hareket ederdik ama uzaktan uzağa sana çok zor oluyor.
 
NREF sorunu buna sebep olmaz, 0 voita inmeni engeller. 1 volt adımlarla artırıp hata oranlarına bakalım.
 
@taydin abi çıkıştaki voltaj sabit, piconun adc sine gelen voltajda sabit ama videoda sağ alt karede adc nin ürettiği değer sürekli oynuyor.
Bu sabit olmayınca hassas okuma yapamıyorum. Bunu sabitlemenin bir yolu var mı?

 
NREF sorunu buna sebep olmaz, 0 voita inmeni engeller. 1 volt adımlarla artırıp hata oranlarına bakalım.

Abi DAC çıkışını tam olarak 1V'a ayarladım.

Bu durumdayken;
Opamp 3 numara 1V
Opamp 7 numara 38.52V
Opamp 4 numara -2.221V
Opamp 2 numara 1.003V
Opamp 6 numara 8.44V (Dirençten ve 1n4148 den geçtikten sonra ana çıkışa 7.49V olarak ulaşıyor.


DAC çıkışını tam olarak 2V'a ayarladım.

Bu durumdayken;
Opamp 3 numara 1.998V
Opamp 7 numara 38.13V
Opamp 4 numara -2.218V
Opamp 2 numara 2.004V
Opamp 6 numara 16V (Dirençten ve 1n4148 den geçtikten sonra ana çıkışa 14.96V olarak ulaşıyor.


DAC çıkışını tam olarak 3V'a ayarladım.

Bu durumdayken;
Opamp 3 numara 2.996V
Opamp 7 numara 38.02V
Opamp 4 numara -2.216V
Opamp 2 numara 3.004V
Opamp 6 numara 23.49V (Dirençten ve 1n4148 den geçtikten sonra ana çıkışa 22.44V olarak ulaşıyor.


DAC çıkışını tam olarak 4V'a ayarladım.

Bu durumdayken;
Opamp 3 numara 3.993V
Opamp 7 numara 38.30V
Opamp 4 numara -2.227V
Opamp 2 numara 3.003V
Opamp 6 numara 30.97V (Dirençten ve 1n4148 den geçtikten sonra ana çıkışa 29.90V olarak ulaşıyor.
 
Hmm şunu deneyebilirsin. DAC'tan sonraki 27 k lık direnç fazla geliyor olabilir. Onun yerine 1k tak bakalım.
 
Ölçülen rakamın sürekli değişmesi normal de, o kadar büyük değişim olması normal değil. Multimetre ile değiştiğini görüyor musun? Çıkışı 8 V yap mesela, sonra da multimetre ile çıkışı ölç. Değişimin sadece son hanede olması lazım. Senin ADC ile yaptığın ölçümde de tek değişimin son hanede ve ± 1 olması lazım.
 
Ölçümlerin geriye dönük belli bir sayısının ortalamasını da alabilirsin. Bir nevi FIR filtreden geçirmiş olursun. Aşağıda örnek bir program var. 5 elemanlı bir dizi var (array) ve bu diziye hem yeni eleman ekliyoruz hem de ortalamasını alıyoruz.

C:
#include <stdio.h>

double array[] = {0, 0, 0, 0, 0};

static double run_fir(double data)
{
   unsigned int num_elems = (sizeof(array) / sizeof(array[0]));

   double sum = 0;
   for (unsigned int i = 1; i <= num_elems; ++i)
   {
      double next = (i < num_elems) ? array[i + 1] : data;
      array[i] = next;
      sum += next;
   }

   return sum / num_elems;
}

int main()
{
   printf("fir = %f\n", run_fir(3));
   printf("fir = %f\n", run_fir(7));
   printf("fir = %f\n", run_fir(2));
   printf("fir = %f\n", run_fir(5));
   printf("fir = %f\n", run_fir(8));
   printf("fir = %f\n", run_fir(1));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
}

Programın çıktısı da aşağıdaki gibi.

Kod:
/home/ta/tmp/fir/cmake-build-debug/fir
fir = 0.600000
fir = 2.000000
fir = 2.400000
fir = 3.400000
fir = 5.000000
fir = 4.600000
fir = 4.400000
fir = 5.200000
fir = 5.400000
fir = 5.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000

Process finished with exit code 0
 
Ölçülen rakamın sürekli değişmesi normal de, o kadar büyük değişim olması normal değil. Multimetre ile değiştiğini görüyor musun? Çıkışı 8 V yap mesela, sonra da multimetre ile çıkışı ölç. Değişimin sadece son hanede olması lazım. Senin ADC ile yaptığın ölçümde de tek değişimin son hanede ve ± 1 olması lazım.
Bu sanırım attığım videonun cevabı.
Ana çıkışı ve piconun ADC pinini multimetre ile ölçtüğümde ± 1 bile oynama yok. Tam sabit.
Ama ADC pinden analogRead ile okuduğum değeri yazdırınca en düşük 1015, en yüksek 1020 arasında sürekli oynuyor.

Ölçümlerin geriye dönük belli bir sayısının ortalamasını da alabilirsin. Bir nevi FIR filtreden geçirmiş olursun. Aşağıda örnek bir program var. 5 elemanlı bir dizi var (array) ve bu diziye hem yeni eleman ekliyoruz hem de ortalamasını alıyoruz.

C:
#include <stdio.h>

double array[] = {0, 0, 0, 0, 0};

static double run_fir(double data)
{
   unsigned int num_elems = (sizeof(array) / sizeof(array[0]));

   double sum = 0;
   for (unsigned int i = 1; i <= num_elems; ++i)
   {
      double next = (i < num_elems) ? array[i + 1] : data;
      array[i] = next;
      sum += next;
   }

   return sum / num_elems;
}

int main()
{
   printf("fir = %f\n", run_fir(3));
   printf("fir = %f\n", run_fir(7));
   printf("fir = %f\n", run_fir(2));
   printf("fir = %f\n", run_fir(5));
   printf("fir = %f\n", run_fir(8));
   printf("fir = %f\n", run_fir(1));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
   printf("fir = %f\n", run_fir(6));
}

Programın çıktısı da aşağıdaki gibi.

Kod:
/home/ta/tmp/fir/cmake-build-debug/fir
fir = 0.600000
fir = 2.000000
fir = 2.400000
fir = 3.400000
fir = 5.000000
fir = 4.600000
fir = 4.400000
fir = 5.200000
fir = 5.400000
fir = 5.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000
fir = 6.000000

Process finished with exit code 0

Bu bilmediğim bir şey. Ben şöyşe birşey planladım.

1- Keypadden girdiğin sayıyı Vref değişkeninde tut.
2- Ana çıkışı analogRead ile oku.
3- Ana çıkış ! = Vref
4- voltaj = voltaj + 0.01;
5- setDac(voltaj, 1);

Tabi bu çok yüzeysel bir plan oldu. Büyükse, küçükse gibi operatörlerde kullanacağım.
Hem voltajı okumuş olacağım hem de DAC'ı kalibre etmiş olacağım.
 
Bu şekilde yaparsan osilasyona girme tehlikesi var. Osilasyon olmaması için çok yavaş ayarlamalar yapman lazım. Mesela 10 saniyede bir gibi.
 
Bu şekilde yaparsan osilasyona girme tehlikesi var. Osilasyon olmaması için çok yavaş ayarlamalar yapman lazım. Mesela 10 saniyede bir gibi.
10sn çok fazla ya. 10sn de bir 0.01 atarsak 30v'u bir kaç saat sonra alırız herhalde :katil2:
 
Aslında bizim 1v ile 30v arasında kullandığımız kat sayı 122 ile 134 aralığında. Bunu baz alarak ortalama bir rakam versek (mesela 128 gibi) ve bu değerden artırma - azaltma yapsak çok daha kısa bir döngüde ayar yapmış oluruz. Bu durumda yine osilasyon tehlikesi olur mu?
 
Osilasyon olma durumunu kafanda şöyle canlandır: Yolda sağdan yürüyorsun, karşıdan da birisi sağdan sana doğru yürüyor. Birbirinizi görüyorsunuz, sen sola gidiyorsun o da sola gidiyor sen sağa gidiyorsun o da sağa gidiyor. En sonunda bu osilasyondan nasıl kurtuluyorsun? Biriniz yerinde duruyor ve diğeri de ne yapması gerekiyorsa yapıyor :) Aynı durum güç kaynağında da oluyor.
 
Osilasyon olma durumunu kafanda şöyle canlandır: Yolda sağdan yürüyorsun, karşıdan da birisi sağdan sana doğru yürüyor. Birbirinizi görüyorsunuz, sen sola gidiyorsun o da sola gidiyor sen sağa gidiyorsun o da sağa gidiyor. En sonunda bu osilasyondan nasıl kurtuluyorsun? Biriniz yerinde duruyor ve diğeri de ne yapması gerekiyorsa yapıyor :) Aynı durum güç kaynağında da oluyor.
Anladım ama bu ortalama alma konusuda bana çok yabancı. Detaylı anlat dicem ama değerli bilgilerini bana verip zayi etmeni istemiyorum :katil2:

 
Anladım ama bu ortalama alma konusuda bana çok yabancı. Detaylı anlat dicem ama değerli bilgilerini bana verip zayi etmeni istemiyorum :katil2:

Bu projenin BENCE tek tek mesaj atarak değil canlı olarak incelenmesi gerek.
Bir discord buluşması ile anlık olarak gidilse daha çabuk çözülür gibi geliyor daha önce de vermiştim abi bu tavsiyeyi
 
Bu projenin BENCE tek tek mesaj atarak değil canlı olarak incelenmesi gerek.
Bir discord buluşması ile anlık olarak gidilse daha çabuk çözülür gibi geliyor daha önce de vermiştim abi bu tavsiyeyi
Bu aralar akşamları hep işte oluyorum Ahmet. Gece 00:00 gibi dönüyorum eve. Sadece gündüz bir kaç saat ayırabiliyorum. Birazda sıcaklar bunaltmaya başladı. Pc başında uzun süre sabit oturamıyorum. O yüzden devreye de odaklanamıyorum.
 
Bu aralar akşamları hep işte oluyorum Ahmet. Gece 00:00 gibi dönüyorum eve. Sadece gündüz bir kaç saat ayırabiliyorum. Birazda sıcaklar bunaltmaya başladı. Pc başında uzun süre sabit oturamıyorum. O yüzden devreye de odaklanamıyorum.
Kış en sevdiğim mevsim.
Giyiyorum 2 kat 1 de ceketimi soğusun hava önemli değil.

Yazın klima açsan çarpar, açmasan hararet sona vurur hiç sevmem.

Şuan 220v panodan söktüğüm fan ile serinliyorum ama izmirin en tepesindeyim ondan bana aşırı sıcak vurmuyor.
Bu fandan 4 tsne lazım sana Antalya sıcağında serinlemek için
 
Ben yama çözümlerden hiç hoşlanmıyorum. Bu otomatik kalibrasyonu ben sadece sistem açılırken bir kere yapılması amacıyla önermiştim. Ama sen bunu opamp devresi doğru çalışmadığı için yapmak istiyorsun. Geri beslemeli voltaj regülasyonunu opamp yapıyor zaten, bunu firmware yazılımı ile desteklemeye gerek yok. Eğer firmware'de geri beslemeli voltaj regülasyonu yapacaksan (ki bu ileri seviyede dijital kontrol teorisine girer) o zaman da harici opamp devresine gerek yok. Bence opamp regülasyonunu tam olarak çalışır hale getirelim. 27 k direnci deneyip bilgi ver bir fark yarattı mı.
 
Ben yama çözümlerden hiç hoşlanmıyorum. Bu otomatik kalibrasyonu ben sadece sistem açılırken bir kere yapılması amacıyla önermiştim. Ama sen bunu opamp devresi doğru çalışmadığı için yapmak istiyorsun. Geri beslemeli voltaj regülasyonunu opamp yapıyor zaten, bunu firmware yazılımı ile desteklemeye gerek yok. Eğer firmware'de geri beslemeli voltaj regülasyonu yapacaksan (ki bu ileri seviyede dijital kontrol teorisine girer) o zaman da harici opamp devresine gerek yok. Bence opamp regülasyonunu tam olarak çalışır hale getirelim. 27 k direnci deneyip bilgi ver bir fark yarattı mı.

Ben aslında ne yaptığımı bilmeden o şekilde kullanmak istedim. Yani mantıklı geldi çıkışı okuyup kalibre etmek. Bir taşla iki kuş vuracaktım. Ama ne kadar sağlıklı olacağını bilmiyorum tabi.

27k direnç aklımda abi. Yarın gündüz değiştirip deneyeceğim.
 

Forum istatistikleri

Konular
5,847
Mesajlar
99,735
Üyeler
2,482
Son üye
ilker29

Son kaynaklar

Son profil mesajları

gruptaki arkadaşlara selamlar. sıteyi bu gün fark ettim. Asansör için 2x7 segment LCD gösterge üretmek istiyorum. acaba bu sayfadaki arkadaşlardan destek alabilirmiyim. LCD nin mantık açılımı ektedir.
deneyci wrote on TA3UIS's profile.
Selam.
Amatör telsiz lisansı nasıl alınıyor?
Lisansı olmayanı forumlarına almıyorlar. :)
Bilgi alamıyoruz.
cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Back
Top