MCP4922 Otomatik DAC Kalibrasyonu

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
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.
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
NREF sorunu buna sebep olmaz, 0 voita inmeni engeller. 1 volt adımlarla artırıp hata oranlarına bakalım.
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
@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ı?

 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Hmm şunu deneyebilirsin. DAC'tan sonraki 27 k lık direnç fazla geliyor olabilir. Onun yerine 1k tak bakalım.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Ö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.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Ö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
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
Ö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.
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
Bu şekilde yaparsan osilasyona girme tehlikesi var. Osilasyon olmaması için çok yavaş ayarlamalar yapman lazım. Mesela 10 saniyede bir gibi.
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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:
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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?
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
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.
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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:

 

Ahmet

Kıdemli Üye
Katılım
31 Mayıs 2021
Mesajlar
2,597
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
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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.
 

Ahmet

Kıdemli Üye
Katılım
31 Mayıs 2021
Mesajlar
2,597
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
 

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
13,798
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ı.
 

Gokrtl

Gökhan Kartal
Staff member
Katılım
27 Şubat 2019
Mesajlar
7,855
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.
 
Top