İçindekiler:

ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir: 5 Adım
ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir: 5 Adım

Video: ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir: 5 Adım

Video: ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir: 5 Adım
Video: ESP32 CAM İLE 100 TL YE IP KAMERA YAPMAK|IOT'A GİRİŞ|ESP32 CAM KULLANIMI 2024, Kasım
Anonim
ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir
ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir
ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir
ESP32 ile Daha İyi Bir DAC Nasıl Yapılır ve Test Edilir

ESP32'de 2 adet 8 bit Dijital - Analog Dönüştürücüler (DAC'ler) bulunur. Bu DAC'ler, 8 bit çözünürlükte belirli bir aralıkta (0-3.3V) isteğe bağlı voltajlar üretmemizi sağlar. Bu Eğitilebilir Kitapta, size bir DAC'nin nasıl oluşturulacağını ve performansını karakterize etmenin yanı sıra ESP32 DAC ile karşılaştırmayı göstereceğim. Bakacağım performans endeksleri şunları içeriyor:

  • Gürültü seviyesi
  • Bant genişliği
  • integral doğrusal olmama
  • diferansiyel doğrusal olmama

Bu endeksleri test etmek için ADS1115'i kullanacağım.

Tüm bu endekslere ilişkin değerlendirmenizin yalnızca referans cihazınız (bu durumda ADS115) kadar doğru olacağını belirtmek önemlidir. Örneğin, ADS115, voltaj ofseti ve kazancı söz konusu olduğunda 16 bit hassasiyete sahip değildir. Bu hatalar %0,1 kadar büyük olabilir. Mutlak doğruluk sınırlı endişe olduğunda birçok sistem için bu hatalar göz ardı edilebilir.

Gereçler

  • ADS1115
  • ESP32 Kurulu
  • ekmek tahtası
  • atlama telleri
  • 5 kOhm Direnç
  • 1 mikro-Farad seramik kondansatör

Adım 1: Breadboard'u Yerleştirme

Breadboard'u Yerleştirme
Breadboard'u Yerleştirme

Aşağıdaki pinleri bağlayın

ESP32 ve ADS1115 arasında

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA'sı

ADS1115'te

ADDR GND (ADS115)

DAC'yi yapmak

DAC yapmanın birçok yolu vardır. En basiti, bir direnç ve bir kapasitör ile bir PWM sinyalini düşük geçişli filtrelemektir. Buraya tampon olarak bir op-amp ekleyebilirdim ama işleri basit tutmak istedim. Bu tasarım, PWM'yi destekleyen herhangi bir mikrodenetleyici ile uygulanması basit ve ucuzdur. Burada tasarım teorisinden geçmeyeceğim (google PWM DAC).

Sadece GPIO255 KOhm direnç 1 microFarad Kapasitör gnd'yi bağlayın

Şimdi direncin kondansatörle buluştuğu noktadan ADS115'teki A0'a bir aktarma kablosu bağlayın.

Adım 2: Sinyali Gürültü Seviyesine Göre Değerlendirin

Sinyali Gürültü Seviyesine Göre Değerlendirin
Sinyali Gürültü Seviyesine Göre Değerlendirin

Gürültü seviyesini değerlendirmek için aşağıdaki komut dosyasını çalıştırmanız yeterlidir. Bunu değerlendirmek için DAC'yi sabit bir değerde bırakıyoruz ve voltajın zaman içinde nasıl salındığını ölçüyoruz.

DAC'nin tasarımı nedeniyle, PWM sinyali %50 görev döngüsündeyken gürültü en büyük olacaktır. Bu nedenle değerlendireceğimiz yer burasıdır. ESP32'yi de aynı sinyal seviyesinde değerlendireceğiz. Ayrıca ölçümü karşılaştırılabilir kılmak için ESP32 DAC'yi aynı düşük geçiş filtresiyle filtreleyeceğiz.

Benim için çıktı açıktı. PWM tasarımı >6dB daha iyi SNR'ye sahipti (2 kat daha iyi). Yeni DAC için net bir galibiyet. Hafif bir karışıklık, ADC'de SNR'yi kesinlikle artıran filtrelerin olmasıdır. Bu nedenle mutlak değerleri yorumlamak zor olabilir. İkinci dereceden bir filtre kullanmış olsaydım, durum böyle olmazdı.

Neyse kod aşağıda

#Dahil etmek

#Adafruit_ADS1115 reklamlarını dahil et; // adc için adafruit kitaplığı int16_t adc0; // void setup(void) { Serial.begin(115200); // Seri ads.setGain(GAIN_TWO); // 2x kazanç +/- 2.048V 1 bit =0.0625mV ads.begin(); // adc kayan nokta M = 0; // ilk ortalama kayan nokta Mp = 0; // önceki şamandıra anlamına gelir S = 0; // ilk Varyans kayan nokta Sp = 0; // önceki varyans const int reps = 500; // tekrar sayısı int n = 256; // örnek sayısı ledcSetup(0, 25000, 8); // pwm frekansı =25000 Hz'yi 8 bit çözünürlükte ayarla ledcAttachPin(25, 0); // pwm'yi pin 25'e ayarla ledcWrite(0, 128); // onu yarı görev döngüsüne ayarla(en büyük gürültü) gecikme(3000); // oturma süresini bekle float snrPWM[tekrar]; // PWM kayan nokta için snrs dizisi snrDAC[tekrar]; // DAC için snrs dizisi for (int i = 0; i < reps; i++) { // tekrarlar üzerinden döngü for (int k = 1; k < (n + 1); k++) { // örnekler üzerinden döngü adc0 = ads.readADC_SingleEnded(0); // okumaya başla M = Mp + (adc0 - Mp) / k; // yuvarlanan ortalamayı hesapla Mp = M; // önceki ortalamayı ayarla S = Sp + (adc0 - Mp) * (adc0 - M); // yuvarlanan varyansı hesapla Sp = S; // önceki farkı ayarla } // dB olarak snr snrPWM = 20 * log10(3.3 / (sqrt(S / n) *.0625 *.001)); // değerleri sıfırla M = 0; en = 0; S = 0; Sp = 0; } ledcDetachPin(25); // PWM'yi pin 25 dacWrite(25, 128)'den ayır; // DAC gecikmesine yaz(3000); // yerleşmek için bekle (int i = 0; i < reps; i++) { // PWM döngüsü ile aynı for (int k = 1; k < (n + 1); k++) { adc0 = ads.readADC_SingleEnded(0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; } snrDAC = 20 * log10(3.3 / (sqrt(S / n) *.0625 *.001)); M = 0; en = 0; S = 0; Sp = 0; } // (int i = 1; i < reps; i++) için SNR'leri bir grafik üzerinde çizin { Serial.print("PWM_SNR(dB):"); Serial.print(snrPWM); Seri.print(", "); Serial.print("ESP32_SNR(dB):"); Serial.println(snrDAC); } } geçersiz döngü(void) { }

Adım 3: İntegral Doğrusal Olmayanlık ve Diferansiyel Doğrusal Olmayanlık

İntegral Doğrusal Olmayanlık ve Diferansiyel Doğrusal Olmayanlık
İntegral Doğrusal Olmayanlık ve Diferansiyel Doğrusal Olmayanlık

İntegral doğrusal olmama, DAC çıkış voltajınız ile düz bir çizgi arasında kabaca ne kadar sapma olduğunun bir ölçüsüdür. Bu ne kadar büyükse o kadar kötü…

Diferansiyel doğrusal olmama, voltajda (bir koddan diğerine) gözlenen değişimin düz bir çizgiden beklenenden ne kadar saptığının kabaca bir ölçüsüdür.

Buradaki sonuçlar gerçekten ilginçti. Her şeyden önce, her ikisinde de 0,5 lsb'den daha az hata (8 bit çözünürlükte) vardır, bu da iyidir, ancak PWM çok daha iyi integral doğrusallığa sahiptir. Her ikisi de karşılaştırılabilir diferansiyel doğrusal olmayanlığa sahiptir, ancak ESP32 DAC'de bazı çok garip artışlar vardır. Dahası, PWM yönteminin hatalar için bir yapısı vardır. Esasen, alternatif bir şekilde doğru voltajı aşar ve altına düşürür.

Benim şüphem, bunun ESP32'de 8 bitlik bir PWM sinyalinin nasıl üretildiğine dair garip bir yuvarlama hatası.

Bunu düzeltmenin bir yolu, PWM ile iki bitişik kod (örneğin 128, 129) arasında hızla geçiş yapmaktır. Analog bir alçak geçiren filtre ile ortaya çıkan hataların ortalaması sıfır olacaktır. Bunu yazılımda simüle ettim ve gerçekten de tüm hatalar ortadan kayboldu. Artık PWM yöntemi, 16-bit'e kadar doğru olan doğrusallığa sahiptir!

Verileri oluşturacak kod aşağıdadır. Çıktı,.csv formatında seri monitörde olacaktır. Daha fazla işlem için bir metin dosyasına kopyalamanız yeterlidir.

#Dahil etmek

#Adafruit_ADS1115 reklamlarını dahil et; /* 16 bitlik sürüm için bunu kullanın */ int16_t adc0; void setup(void) { Serial.begin(115200); ads.setGain(GAIN_ONE); // 2x kazanç +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin(); ledcSetup(0, 25000, 8); ledcAttachPin(25, 0); Serial.println("Beklenen, Gözlemlenen"); ledcWrite(0, 2); gecikme(3000); for (int i = 2; i < 255; i++) { ledcWrite(0, i); gecikme(100); adc0 = ads.readADC_SingleEnded(0); beklenen kayan nokta = (i / 256,0 * 3.3) / 4.096 * 32767; Serial.print(beklenen); Seri.print(", "); Seri.println(adc0); } } geçersiz döngü(void) { }

4. Adım: Bant Genişliği

Bant genişliği
Bant genişliği

Bant genişliğini burada DAC çıkışının 3dB düştüğü frekans olarak tanımlayacağım. Bu bir sözleşmedir ve bir dereceye kadar keyfidir. Örneğin, 6dB noktasında, DAC yine de bir sinyal verecek ve bu sadece ~%50 genlik olacaktır.

Bunu ölçmek için, sinüs dalgalarını DAC'den ADC'ye artan bir frekansta geçiriyoruz ve standart sapmalarını ölçüyoruz. Şaşırtıcı olmayan bir şekilde, 3dB noktası 30Hz'de (1/(2*pi*5000*1e-6)).

ESP32 saniyede 1 Mega örnekleme yapabilir. Bu, ESP32 için pratik bir kazançtır. Genliği 100Hz bant genişliği test bölgesinde hiç azalmaz.

Aşağıdaki kod, PWM DAC bant genişliğini test edebilir.

#Dahil etmek

#Adafruit_ADS1115 reklamlarını dahil et; /* 16 bitlik sürüm için bunu kullanın */ int16_t adc0; int16_t adc1; void setup(void) { float M; kayan nokta Mp = 0; yüzer S = 0; yüzer Sp = 0; Seri.başla(115200); ads.setGain(GAIN_ONE); // 1x kazanç +/- 4.096V 1 bit = 2mV 0.125mV ads.begin(); ledcSetup(0, 25000, 8); ledcAttachPin(25, 0); gecikme (5000); Serial.println("Frekans, Genlik"); for (int i = 1; i < 100; i++) { unsigned uzun başlangıç = millis(); imzasız uzun T = millis(); Sp = 0; S = 0; M = 0; en = 0; int k = 1; yüzer norm; while ((T - başlangıç) < 1000) { int çıkış = 24 * sin(2 * PI * i * (T - başlangıç) / 1000.0) + 128; ledcWrite(0, çıkış); adc0 = ads.readADC_SingleEnded(0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis(); k++; } if (i == 1) { norm = sqrt(S / k); } Seri.print(i); Seri.print(", "); Serial.println(sqrt(S / k) / norm, 3); k = 0; } } geçersiz döngü(void) { }

Ve bu kod ESP32 bant genişliğini test edecek. Kondansatörü çıkardığınızdan emin olun, aksi takdirde sonuçlar her iki yöntem için de aynı olacaktır.

#Dahil etmek

#Adafruit_ADS1115 reklamlarını dahil et; /* 16 bitlik sürüm için bunu kullanın */ int16_t adc0; int16_t adc1; void setup(void) { float M; kayan nokta Mp = 0; yüzer S = 0; yüzer Sp = 0; Seri.başla(115200); ads.setGain(GAIN_ONE); // 1x kazanç +/- 4.096V 1 bit = 2mV 0.125mV ads.begin(); gecikme (5000); Serial.println("Frekans, Genlik"); for (int i = 1; i < 100; i++) { unsigned uzun başlangıç = millis(); imzasız uzun T = millis(); Sp = 0; S = 0; M = 0; en = 0; int k = 1; yüzer norm; while ((T - başlangıç) < 1000) { int çıkış = 24 * sin(2 * PI * i * (T - başlangıç) / 1000.0) + 128; dacWrite(25, çıktı); adc0 = ads.readADC_SingleEnded(0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis(); k++; } if (i == 1) { norm = sqrt(S / k); } Seri.print(i); Seri.print(", "); Serial.println(sqrt(S / k) / norm, 3); k = 0; } } geçersiz döngü(void) { }

Adım 5: Düşünceleri Kapatmak

Yeni DAC tasarımı, doğrusallık ve gürültü açısından kazanıyor, ancak bant genişliği konusunda kaybediyor. Uygulamanıza bağlı olarak bu endekslerden biri diğerinden daha önemli olabilir. Bu test prosedürleriyle, bu kararı objektif olarak verebilmelisiniz!

Ayrıca, burada PWM çıkışının düşük gürültülü olması ve olağanüstü doğrusallıkla PWM çıkışı ile çok daha yüksek çözünürlüklü bir DAC (belki de 16-bit hassasiyet) oluşturmanın mümkün olması gerektiğini belirtmeye değer olduğunu düşünüyorum. Bu biraz iş alacak. O zamana kadar sana veda ediyorum!

Önerilen: