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

AREF | Arduino ADC Referans Değerini Değiştirme

    Arduino ile ADC ölçümlerinde hep 5V kullanıldığı dikkatinizi çekmiştir. İşin aslı AVR 'nin bize sunduğu analog reference voltage değişikliğini Arduino ile de yapmak mümkün. Bu değişiklik için 3 farklı seçeneğimiz var, birincisi herkesin bildiği 5V olarak kullanmak (DEFAULT), ikinci seçenek AVR çip üzerinde gömülü halde gelen 1.1V 'luk referans voltajı(INTERNAL), diğeri de AREF pini üzerinden harici bir değeri analog referans olarak belirleyebiliyor olmamız(EXTERNAL).

    Peki analog referans değerini neden değiştirmeye ihtiyaç duyarız? ADC kaç bit oluşuyla bağlantılı olarak referans voltajını 2^n (2 üzeri n) sayısına böler, ADC kanalındaki ölçülmek istenen gerilim ile bu bölmeden elde ettiği aralıklardan hangisine uygunsa o dönüşümü sayısal olarak çıkartır. Bu arduino UNO için 10 bitlik bir değerdir. Referans voltajımız 5v ise, her adımımız yaklaşık olarak 5mV olacaktır:

5V/1024 = 0.0048828125

0.0048828125 / 2 = 0.00244140625

Bunun anlamı da ADC için 0.5 LSB 'lik  bir kuantalama hatası olduğuna göre ölçtüğümüz her değer için yaklaşık yine 2.5mV 'luk hata payımız var demektir. Eğer ki ölçeceğimiz gerilim, bulunduğu noktada ASLA 1.1V 'u aşmıyorsa, bu durumda referans voltajını 1.1 'a değiştirmek hata payımızı 1/5 oranında düşürür ve daha az hatalı bir sonuç okumamızı sağlar:

1V/1024 = 0.0009765625

0.0009765625 / 2 = 0.00048828125



Eğer ki 1.1 V yeterli değilse ve 5v da uygulamanız için fazlaysa ve hassasiyetin önem arzettiği noktada kendi analog referans voltajınızı üretip (bir voltaj bölücü yardımıyla mesela) AREF pinine bağlayabilirsiniz, bu durumda AREF pinine uyguladığınız voltajı 1024 'e bölerek hesaplamalarınızı yapabilirsiniz:    

ADC = (Vin*1024) / AREF

bizim durumumuz için ADC bilinen Vin hesaplanmak istenen olduğu için :

Vin = (ADC * AREF)/1024 

olacaktır. Burada

Vin : okunmak istenen voltajı

ADC : dönüşüm sonunda elde edilen ADC değerini

AREF : analog referans voltajını

1024 ise 2^10, 'dan ADC 'nin 10 bit olması dolayısıyla elde edilen sabittir. 12 bit bir ADC 'miz olsaydı bu sabit 4096 olacaktı.



Gelelim uygulamaya ve detaylara; normal şartlar altında ADMUX registerinin 7 ve 6. bitleri [REFS1:0] bu ayarlamayı yapmamızı sağlıyor, ancak siz Arduino kodu içerisinde bu register ile bu ayarlamayı yaptıktan sonra analogRead fonksyionunu kullanıyorsanız, -bu fonksiyon her çağırıldığında AREF i default olarak 5V 'a ayarlıyor- yaptığınız bu değişikliği fonksiyon tekrar değiştirmiş olacak ve kullanamıyor olacaksınız. Bu noktada ya dönüşümü kendiniz yazmaçları kullanarak yapacaksınız ya da yine arduino wiring_analog.c dosyasında yer alan analogReference fonksiyonunu ADC okumanızı yapmadan önce kullanacaksınız.

Arduino Analog Referans Voltajını 1.1V a ayarlamak için analogRead fonksiyonundan hemen önce:

  analogReference(INTERNAL);

External ayarlamak için:

  analogReference(EXTERNAL);

5V ' a ayarlamak için

  analogReference(DEFAULT);

şeklinde kullanabilirsiniz. Hatırlatmakta fayda var bu fonksiyon analog referans voltajını değiştirdikten sonra tüm adc okumaları bu ayar üzerinden yapılır, eğer ki başka bir kanalda 5V kullanırken bir diğer kanalde 1.1V kullanmak isterseniz, her okumadan önce mutlaka bu fonksiyonla referans voltajını ayarlamanız gerekiyor. Bir diğer önemli konu da INTERNAL olarak set ettiğinizde AREF pinine herhangi bir voltaj uygulamadığınızdan emin olmanızdır.

EXTERNAL olarak ayarladığınızda da söylememiş olmayalım diye yazıyorum, AREF pinine uygulayacağınız voltaj 5v ' geçmemelidir. Yani oraya 20V uygulayıp 0-20V arası ölçüm yapayım diyemiyorsunuz, böyle bir ihtiyacınız varsa : Arduino İle Yüksek Voltaj Ölçme konusunu okumanızı öneririm.





Arduino ile Yüksek Voltaj Ölçme | SMPS DC Bara Ölçümü

    Arduino ile 5v 'tan daha yüksek bir voltajı ölçmek için; ya da herhangi bir mikro denetleyici için analog referans değerinin üzerindeki bir gerilimi ölçmek istediğimizde linkteki yazıda anlattığım gerilim bölücüleri kullanırız. Henüz okumadıysanız, okuyup buraya geri dönmenizi tavsiye ederim. Örnek olsun diye 9V 'luk bir pili ölçmeye çalışalım, bu aynı zamanda en fazla 9V dc çıkışı olan farklı bir kaynak da olabilir.

Arduino ile daha yüksek voltaj ölçme



    Burada teorik olarak yaptığımız şey en fazla 5v olan arduino ölçme kapasitesini 9V a çıkartmaktır. Dirençleri seçerken GND 'ye bağlı olan 5 in kaç katıysa (4) kaynağın + sına bağlı olan direncin de 4'ün o katı olduğuna dikkat edin.. Toplamda dirençlerimizin GND ve arduino analog pin arasında olan üzerinde 5V diğer direnç üzerinde de 4v olmasını istiyoruz, 12V ölçüyor olsaydık ikinci direnç 4'ün değil 7'nin 4 katı olacaktı, 9 da 4, 12 'de 7 nerden geldi? Kaynak voltajı - 5v (arduino adc max) 'tan geldi. Basitçe üstteki direnç 5x, alttaki direnç 4x olmalı, 9v 'luk bir kaynak için. Bulunabilirliği göz önüne alarak 20 ve 16 yı seçmiş bulunduk.


Arduino ile voltaj okuma konusunu okumadıysanız, şimdi okumanın tam zamanı. Gelelim oradan ne farkımız var noktasına, artık ADC 'den okuduğumuz veriyi 5v üzerinden değil, gerilim bölücünün çarpanı üzerinden değerlendirmemiz gerekiyor, gerilim bölücü en basit haliyle; kaynaktaki voltaj değerini bir şeye ('x') bölmüş ve A0 noktasındaki gerilimi elde etmiş. Bizim örneğimiz için şöyle olacak:

    9V / x = 5V    => 9v/5v = x    => x = 1.8 

biz de tam tersi yol izleyerek yani ADC den okuduğumuz voltaj değerini bu çarpan ile çarparak kaynak voltajına ulaşmış olacağız. Başka türlü hesaplanabilir miydi? 

    (R1 + R 2) / R2  (R2 gnd ye bağlı olan direnç)
    (20 + 16) / 20    => 1.8

yani maksimum direncin "toplam direnç" R2 ye oranıyla, maksimum gerilimin orta ucta oluşan ADC gerilimine oranı aynı. Koda bakacak olursak, işin matematiği dışında değişen bir şey yok :

// C++ code
//
void setup()
{
 Serial.begin(115200);
}

void loop()
{
  int ADC_Value = analogRead(A0);
  float vOnDivider = ADC_Value * 5.0 /1023;
  Serial.print(vOnDivider);
  float vOnSource = vOnDivider *1.8f;
  Serial.print(" ");
  Serial.println(vOnSource);
}

aslına bakarsanız ölçeceğimiz maksimum gerilimi 1023 e bölüp devam etsek de olurdu. Dikkat ederseniz, vOnDivider değerini yani 5 'i 1.8 le çarpıyoruz o da 9 ediyor 😁


Haydi biraz yükselip bir SMPS devresinde giriş voltajı olan 220v AC den doğrultularak elde edilmiş DC Bara denen voltajı ölçmek istiyor olalım; 220v * √(2) = 312V DC ölçeceğiz yani, bu durumda R2 miz 5x ken R1 'imizin de 312-5 'ten 307x olması lazım. Bu noktada voltaj yükseldiği için devrenin güç değerlerini de işin içine katmak gerekecek. Önce ne direnç kullanabiliriz ona bakalım, 307 k direnç arasak bulur muyuz, bulabiliriz belki ama, 307 bizim için alt limit, bu da ne demek 220v olaki yükselirse, bizim A0 da 5v u geçecektir o yüzden daha yüksek bir direnç kullanmak daha güvenli olacaktır. Maksimumda kaça kadar çıkabilsin noktasını düşünürsek 250v AC için 354v dc demek, 355 diyelim düz hesapla; 5x e 350x kullanabiliriz, yani 5k kullanacaksak diğerini 350k k kullanmamız gerekecek.
Devreden geçen akımı hesaplayalım :

I = V / Rtop    => 355V / 355K  = 1mA

350K direnç üzerinde 350V oluşacak, gücü hesaplarsak;

P = I * V    => 0.001 * 350 = 0.350w 

burada bir sıkıntı var,  nedir? piyasadan alacağımız dirençler 1/4w yani 0.25w, biz bu direnç için 0.350w harcar diyoruz, yani bizim dirence elveda bu noktada; ne yapmalıyız, ya daha yüksek güçlü bir direnç almalıyız ya da direnç sayısını artırarak dirençlerin güç tüketimlerini de dağıtabiliriz, 350K yerine iki tane 175K seri kullansak; direnç başına 0.175w güç tüketimi söz konusu olacak bu işimize yarar, ya da K lardan çıkıp M lere geçeceğiz ki devrenin akımı daha da düşsün, R2 yi 20 K 'ya çıkartalım, bu durumda R1 in de 345*4 'ten 1380K olması lazım, olmadı, olabilen ne var 1.5M ohm olabilir. Bu durumda toplam direncimiz 1520k oldu, orta noktada 5v maksimum için artık kaynakta 380V a kadar ölçüm yapabiliyor olacağız. Güç değerimiz kurtarıyor mu peki?

devre akımı; 380V/ 1520K = 250µA
1.5M direnç için güç tüketimi : "380-5" => 375V*0.25mA = 0.093w.

 Umarım mevzu net olarak anlaşılmıştır, dirençlerle alakalı daha fazla detay isterseniz Direnç Parametreleri konusunu okumanızı öneririm, kafanıza takılan herhangi bir şeyi lütfen yorumlarda sormaktan çekinmeyin!

Herkese kolay gelsin!


Arduino ile voltaj okuma | Arduino ile voltmetre | Arduino ADC örnek Kod

 

Arduino ile voltaj okuma

    Arduino güç özellikleri konusunda detaylıca anlattığımız üzere, Arduino UNO için konuşuyorsak; mikro denetleyicimizin anlamlandırabildiği maksimum potansiyel fark +5V 'tur. Bunun konumuzu ilgilendiren kısmı da standart olarak bir Arduino UNO ile ölçebileceğimiz en fazla potansiyel farkın 5V olmasıdır. Daha yüksek seviyelerdeki voltajların Arduino ile ölçülebilmesi için ek elemanlara ve devrelere ihtiyaç duyulmaktadır, ileride bu konuyla ilgili yazı yayınlarsam linkini buralarda paylaşıyor olurum. Voltaj Bölücü Devresi şimdilik size yardımcı olacaktır. Gerekli hesapları yapıp Vout için maksimumda 5v gelecek şekilde dirençlerinizi seçip devrenizi tasarlayabilirsiniz. Bu yazı Arduino UNO ile daha önce hiç voltaj ölçmemiş, nasıl ölçüldüğü konusunda fikri olmayan okuyucularımızı hedef almaktadır :) 

       Arduino ADC ölçümlerinde yalnızca 0-5V arası DC gerilim ölçülebilir!

    Devre şemamız görseldeki gibi, biraz anlatmamız gerekirse, potansiyometremizin dış uçlarından birini 5V pinine diğerini de GND pinine bağlıyoruz, yerleri farkeder mi? aslına bakarsanız hiç farketmez, peki ne gibi bir değişikliğe sebep olur? şöyle : şekilde gördüğünüz potansiyometrenin kadranı Kırmızıya yakın bu durumda orta pinden çıkan voltaj 5v 'a yakın olur, yaani saat yönünde çevirdikçe voltajımız 0 dan 5V ' a doğru yükselir. Tam tersi bağlamış olsaydık olay tam olarak ters şekilde gerçekleşiyor olacaktı. Potansiyometrenin de buradaki fonksiyonu anlaşılmıştır diye tahmin ediyorum, bizim için 0v ile 5v arasını kademelendirmiş oluyor. Sağdaki pini 5V 'a değil de hemen yanındaki 3.3v 'a bağlamış olsaydık, A0 pinine bağlı olan terminalinde 0 v ile 3.3v arasında bir voltaj değişimine şahit olacaktık. Soldakini 3.3V 'a sağdakini 5V 'a bağlasaydık ne olurdu ki? 😲 cevabı bilenleri yorumlarda görmek isteriz :) Potansiyometremiz 1K - 10 K -100K vs olabilir, sorun yok.

    Harici bir kaynaktaki voltajı ölçmek için kaynağın GND 'sini Arduino kartın GND 'sine, + ucunu da kullanmak istediğiniz analog pine bağlayıp ölçüm yapabilirsiniz. Tekrar etmek gerekirse yalnızca 0-5v arası DC!

Kod kısmına gelecek olursak kurgumuz şöyle olsun A0 pinindeki voltajı okuyup Arduino Serial Ekran 'a belirli zaman aralıklarıyla yazdıralım. Aşağıdaki kod kurgumuzu tam olarak gerçekleştirecektir :

void setup()
{
  Serial.begin(115200);
}
void loop()
{
  int adcVal = analogRead(0);
  float voltage = adcVal * 5.0f / 1023.0f;
  Serial.println(voltage);
  delay(10);
}

gördüğünüz üzere gayet basit bir kod, açıklamaya çalışalım dilimiz döndüğünce:

Serial.begin(115200); seri iletişimi 115200 hızında başlatmayı hedefler

int adcVal = analogRead(0); satırı konumuzun göz bebeği, adcVal adında int tipinde bir değişken oluşturup,analogRead(0) fonksiyonuyla A0 pinindeki voltajın okunmasını sağlamış oluyoruz, neden int? çünkü Arduino UNO için ADC çeviricisi 10 bittir. Bunun anlamı nedir? 10 haneli binary sayı tutabilir. Yaani 2^10 değeri için maksimum seviyedir diyebiliriz. Bu da bizim numerik 10 sisteminde 1023 e denk gelir, uint8_t char gibi 8 bitlik tamsayı değişkenlerine sığmaz demeye çalışıyorum. Özetle anlamlandırabildiği maksimum voltaj olan 5V 'u bizim için sayısal olarak 1023 değeriyle ifade eder. Bir sonraki satırdaki matematik kafanıza oturmuş olmalı bu noktada!

float voltage = adcVal * 5.0f/ 1023.0f; satırıyla okumuş olduğumuz adc değerini voltaja çeviriyoruz, basit bir dil ile 5.0V u 1023 ise adcVal neye denk gelir? doğrusal denkleminin cevabını arıyoruz, klasik içler dışlar meselesi. 5 i 1023 e bölerek 1 adc değerinin ne ettiğini hesaplamış oluyoruz, bu değeri de okunan adc değeri ile çarpınca voltaj tipinde bir değer elde etmiş oluyoruz, bu kadar basic. Bu bölmedeki .0f ler nerden geliyor diyenleri C++ Intreger Literal konusunu okumaya davet ediyoruz.. He bir de neden float? çünkü biraz detay istiyoruz yani voltaj seviyesini en azından virgülden sonra iki hane de olsa görelim değil mi.

Serial.println(voltage); ile nihai voltaj değerimizi seri ekrana yazıdırıyoruz, ln olması yazdırdıktan sonra bir sonraki satıra geçişi sağlıyor, print de yazabilirsiniz, o zaman yan yana yazıyor olur, inanmıyorsanız deneyin :)

delay(10); ile 10ms lik bir gecikme ekliyoruz, 100 olabilir 1000 olabilir keyfinize göre ayarlayın.

Artık Seri Ekranda değerleri görebilirsiniz, aynı zamanda Serial Plotter ile çizim halini de görebilirsiniz. Tinkercad gibi simulasyonlarda bu çizim çok düzgün bir şekilde çıkarken, gerçek bir uygulamada çok da düzgün çıkmayabilir, hiç dokunmadığınız halde oynamalar düşmeler çıkmalar, sakallar görülebilir, bunları da atlamanın yöntemleri var ancak bu yazıda değil de daha sonra yazar ve paylaşıyor oluruz. 

250ms lik beklemelerle benim tinkercad ile aldığım çıktı şu şekilde :

Arduino voltaj ölçme

Tinkercad Simulasyonu için tıklayınız!

Detaylıca anlatmaya çalıştım, yine de kafanıza takılan herşeyi yorumlarda sorabilirsiniz!

Okuduğumuz voltaj değerini bir ekrana yazdırmak istersek diye ekran kullanımıyla alakalı yazıların linkleri : 

16x2 LCD Arduino ile 4 bit Paralel modda sürülmesi

Arduino ADC Referans Voltajı Değiştirme konusunu okuyarak, daha hassas ölçümleri nasıl yapabileceğinizi öğrenebilirsiniz.

Herkese kolay gelsin!

Türksat Saat Kanalı ve IRIG-B Time Code

Türksat Saat Kanalından Saat Bilgisi Nasıl Alınır? Uyduda kanalları dolaşırken, şu Türksat Saat kanalı hep dikkatimi çekmiştir. Özellikle  S...