3.12. ADC ile analog okuma

Şimdiye kadar kamera dijital sinyaller okuyordu – bir pin ya 0 ya da 1 olur, bir anahtar ya açık ya kapalıdır. Gerçek dünyadaki sensörlerden gelen sinyallerin çoğu analogdur: belirli bir aralıkta yumuşakça değişen sürekli bir voltaj. Bir fotorezistör, ortam parlaklığı değiştikçe raylar arasındaki her voltaj değerini tarar. Bir sıcaklık sensörünün çıkışı, oda ısındıkça birkaç milivolt kayar. Bir mikrofonun çıkışı, çevresindeki sesle birlikte yükselir ve alçalır.

Bir analog-dijital dönüştürücü (ADC) bu köprüyü kurar. Bir pin üzerindeki voltajı örnekler ve Python’ın diğer herhangi bir değer gibi okuyabileceği bir tam sayı döndürür.

3.12.1. Nicemleme

Dijital bir değer, sürekli bir voltajı tam olarak gösteremez. ADC’nin işi nicemlemektir – her örneği sabit bir düzey kümesinin en yakınına yuvarlamak. N bitlik bir ADC, 2^N düzeye sahiptir; 12 bitlik bir dönüştürücü, giriş aralığına yayılmış 4096 düzeye sahiptir.

Zamana karşı çizilmiş, basamaklı bir dijital yaklaşımla üst üste bindirilmiş yumuşak bir analog eğri. Kesik yatay çizgiler nicemleme düzeylerini gösterir; basamaklı eğri, her örnekleme noktasında analog sinyale en yakın olan düzeye yuvarlanır.

Nicemleme: analog sinyalin her örneği (düz çizgi), sonlu bir dijital düzey kümesinden birine yuvarlanır (basamaklı kesik çizgi).

İki komşu düzey arasındaki voltaj, ADC’nin adım boyutudur; bundan daha küçük olan her şey yuvarlamada kaybolur. 3,3 V aralığında 12 bitlik bir ADC, yaklaşık 3.3 / 4096 0.8 mV adım boyutuna sahiptir – bu, çoğu sinyalin yazılımda fiilen sürekli görünmesini sağlayacak kadar incedir.

3.12.2. machine.ADC sınıfı

machine.ADC, tek bir analog giriş kanalını sarmalar. Okumak istediğiniz pin ile oluşturun, ardından read_u16() metodunu çağırın:

from machine import ADC

adc = ADC("P6")
value = adc.read_u16()
print(value)

read_u16() her zaman 0 ile 65535 arasında işaretsiz 16 bitlik bir tam sayı döndürür. Yerel ADC çözünürlüğü karta göre değişir (STM32’de 12 bit, başka yerlerde porta özgü); sonuç 16 bite sola hizalanır, böylece donanım ayrıntısı Python’a sızmaz – 65535 değeri, yongadan bağımsız olarak tam ölçektir.

Tam ölçeğe karşılık gelen giriş olan referans voltajı, karta bağlıdır. Kameranızdaki değer için OpenMV Kartları belgesine bakın. Referansın üzerindeki her şey tam ölçek olarak okunur (ve mutlak maksimum giriş voltajını aşarsa pini hasara uğratabilir).

3.12.2.1. Sayımları voltaja dönüştürme

Sayımlardan voltaja eşleme doğrusaldır ve tam ölçek sayımları tam olarak Vref değerine eşlenir:

voltage = counts × Vref / 65535

Kodda:

VREF = 3.3  # cam-dependent; see the quickref
counts = adc.read_u16()
voltage = counts * VREF / 65535
print(voltage, "V")

3.12.3. Voltaj bölücüler

Bir voltaj rayı ile toprak arasında seri bağlı iki direnç bir voltaj bölücü oluşturur. Aralarındaki düğüm, iki direncin oranıyla belirlenen bir voltajda durur:

Bir voltaj bölücü. Üstteki Vin, R1 üzerinden V_out olarak alınan bir düğüme bağlanır; bu düğüm de R2 üzerinden toprağa bağlanır.

Bir voltaj bölücü: seri bağlı R1 ve R2, Vin değerini V_out değerine düşürür.

V_out = Vin × R2 / (R1 + R2)

Eşit dirençler ray voltajının yarısını verir; R1 değerinden çok daha küçük bir R2, alma noktasını toprağa yaklaştırır; çok daha büyük bir R2 ise raya yaklaştırır.

Formül, V_out üzerinden başka hiçbir şeyin kayda değer akım çekmediğini varsayar. Bir ADC pini yüksek empedanslıdır (megaohm, nanoamper) ve bunu kolayca sağlar, dolayısıyla bir ADC’yi besleyen bir bölücü formülün öngördüğü gibi davranır.

3.12.4. Potansiyometreler

Bir potansiyometre, tam olarak bir voltaj bölücü olan tek bir fiziksel bileşendir; alma noktasını iki uç arasında hareket ettiren kayan bir sürgüye (wiper) sahiptir. Düğmeyi çevirmek, toplamlarını (potun toplam direncini) sabit tutarken R1 ve R2 değerlerini birlikte değiştirir.

3,3 V ile toprak arasına bağlanmış bir potansiyometre. Sürgü, bir ADC pinine bağlanır.

ADC için manuel bir voltaj kaynağı olarak bağlanmış bir potansiyometre: bir ucunda 3,3 V, diğer ucunda toprak, sürgü ise pine bağlı.

Pot, ADC’yi denemek için tipik giriş aygıtıdır. Bir ucunu 3.3 V değerine, diğerini toprağa ve sürgüyü ADC destekli bir pine bağlayın; düğmeyi çevirmek sürgüyü raylar arasındaki her voltaj boyunca tarar.

import time
from machine import ADC

pot = ADC("P6")
VREF = 3.3

while True:
    counts = pot.read_u16()
    voltage = counts * VREF / 65535
    print(voltage, "V")
    time.sleep_ms(100)

3.12.5. Bir bölücüyle daha yüksek voltajları okuma

Vref değerinin üzerindeki bir voltaj, ADC’yi tam ölçeğe sabitler ve mutlak maksimum değeri aşarsa girişe hasar verebilir. Daha yüksek bir kaynağı okumak için – bir pil, Vref değerinin ötesine uzanan bir sensör çıkışı – pine ulaşmadan önce sabit bir voltaj bölücüyle aşağı ölçekleyin:

Yüksek bir V_in değerini bir ADC pinine düşüren bir voltaj bölücü. R1, V_in değerinden bir bağlantı noktasına iner; bu nokta yatay olarak ADC pinine bağlanır; R2 ise bağlantı noktasından toprağa devam eder.

Yüksek voltajlı bir kaynağı ADC’ye uygun hale getirmek için ölçekleme: R1 ve R2, alma noktası ADC pinini besleyen sabit bir voltaj bölücü oluşturur.

R1 ve R2 değerlerini, beklediğiniz en yüksek giriş voltajında bölünmüş voltaj ADC’nin aralığı içinde kalacak şekilde seçin:

V_adc = V_in × R2 / (R1 + R2)

Maksimum V_in = 12 V ve 3,3 V referans için R2 / (R1 + R2) oranı en fazla 3.3 / 12 0.275 olmalıdır. Biraz pay bırakan yaygın bir seçim R1 = 33 , R2 = 10 değerleridir. Oran 10 / 43 0.233 olduğundan V_adc en fazla yaklaşık 12 × 0.233 2.79 V değerine ulaşır – Vref değerinin güvenli bir şekilde altında.

Bir ADC okumasından orijinal V_in değerini geri elde etmek için bölücü formülünü tersine çevirin:

V_in = V_adc × (R1 + R2) / R2

Kodda:

from machine import ADC

R1 = 33_000
R2 = 10_000
VREF = 3.3

adc = ADC("P6")

counts = adc.read_u16()
v_adc = counts * VREF / 65535
v_in = v_adc * (R1 + R2) / R2
print(v_in, "V")

Birkaç pratik not:

  • Bölücü sürekli olarak V_in / (R1 + R2) akımı çeker. R1 + R2 = 43 ve V_in = 12 V ile bu yaklaşık 280 µA’dır – genellikle ihmal edilebilir, ancak kaynak pille çalışıyorsa boşta tüketimi azaltmak için daha büyük dirençler (100 kΩ ila 1 MΩ) düşünün.

  • Direnç toleransı (genellikle ±%1 veya ±%5) doğrudan ölçüm doğruluğunu etkiler. İki ±%5 direnç, geri elde edilen V_in değerine en kötü durumda kabaca ±%10 hata verebilir.

  • Bölücünün kaynak empedansı, herhangi bir kaçak kapasitansla birleşerek girişi alçak geçiren bir filtreden geçirir. Hızlı değişen sinyaller için bu önemlidir; bir pil voltajı kontrolü için ise önemli değildir.