Obsah:

Jak vytvořit a otestovat lepší DAC s ESP32: 5 kroků
Jak vytvořit a otestovat lepší DAC s ESP32: 5 kroků

Video: Jak vytvořit a otestovat lepší DAC s ESP32: 5 kroků

Video: Jak vytvořit a otestovat lepší DAC s ESP32: 5 kroků
Video: Output DC or AC Voltage using MCP4725 DAC with LCD and PWM to Voltage Converter with Arduino 2024, Červenec
Anonim
Jak vytvořit a otestovat lepší DAC s ESP32
Jak vytvořit a otestovat lepší DAC s ESP32
Jak vytvořit a otestovat lepší DAC s ESP32
Jak vytvořit a otestovat lepší DAC s ESP32

ESP32 má 2 8bitové převodníky digitálního signálu na analogový (DAC). Tyto DAC nám umožňují produkovat libovolné napětí v určitém rozsahu (0-3,3 V) s rozlišením 8 bitů. V tomto Instructable vám ukážu, jak vytvořit DAC a charakterizovat jeho výkon a porovnat jej s ESP32 DAC. Indexy výkonu, na které se podívám, zahrnují

  • Úrověn hluku
  • Šířka pásma
  • Integrální nelinearita
  • Diferenciální nelinearita

K otestování těchto indexů použiji ADS1115.

Je důležité si uvědomit, že vaše hodnocení všech těchto indexů bude pouze tak přesné jako vaše referenční zařízení (v tomto případě ADS115). Například ADS115 nemá 16bitovou přesnost, pokud jde o offset a zesílení napětí. Tyto chyby mohou být až 0,1%. U mnoha systémů lze tyto chyby ignorovat, pokud je absolutní přesnost omezená.

Zásoby

  • ADS1115
  • Deska ESP32
  • prkénko
  • propojovací vodiče
  • Rezistor 5 kOhm
  • 1 keramický kondenzátor micro-Farad

Krok 1: Rozložení Breadboardu

Rozložení prkénka
Rozložení prkénka

Připojte následující kolíky

Mezi ESP32 a ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Na ADS1115

ADDR GND (ADS115)

Výroba DAC

Existuje mnoho způsobů, jak vytvořit DAC. Nejjednodušší je filtrovat nízkoprůchodový signál PWM odporem a kondenzátorem. Mohl jsem sem přidat operační zesilovač jako vyrovnávací paměť, ale chtěl jsem, aby to bylo jednoduché. Tento design je jednoduchý a levný na implementaci s jakýmkoli mikrokontrolérem, který podporuje PWM. Nebudu zde procházet teorii designu (google PWM DAC).

Stačí připojit odpor GPIO255 KOhm 1 microFarad kondenzátor gnd

Nyní připojte propojovací vodič z bodu, kde se odpor setkává s kondenzátorem, k A0 na ADS115.

Krok 2: Vyhodnoťte úroveň šumu signálu

Vyhodnoťte úroveň signálu
Vyhodnoťte úroveň signálu

Chcete -li posoudit hladinu hluku, jednoduše spusťte níže uvedený skript. Abychom to posoudili, jednoduše necháme DAC na pevné hodnotě a změříme, jak napětí v průběhu času osciluje.

Vzhledem k konstrukci DAC bude šum největší, když je signál PWM při 50% pracovním cyklu. Proto to budeme posuzovat zde. Rovněž vyhodnotíme ESP32 na stejné úrovni signálu. Rovněž budeme filtrovat ESP32 DAC se stejným dolním průchodem, aby bylo měření srovnatelné.

Pro mě byl výstup jasný. Design PWM měl> 6 dB lepší SNR (to je 2krát lepší). Jasná výhra pro nový DAC. Mírným zmatkem je, že v ADC jsou zabudovány filtry, které zcela určitě vylepšují SNR. Proto může být obtížné interpretovat absolutní hodnoty. Pokud bych použil filtr druhého řádu, nebylo by to tak.

Každopádně kód je níže

#zahrnout

#include Adafruit_ADS1115 reklamy; // knihovna adafruit pro adc int16_t adc0; // neplatné nastavení (void) {Serial.begin (115200); // Spusťte sériové ads.setGain (GAIN_TWO); // 2x zisk +/- 2,048V 1 bit = 0,0625mV ads.begin (); // begin adc float M = 0; // počáteční průměrný plovák Mp = 0; // průměrný plovák S = 0; // počáteční odchylka variace Sp = 0; // předchozí odchylka const int opakování = 500; // počet opakování int n = 256; // počet vzorků ledcSetup (0, 25000, 8); // set pwm frequencyecny = 25000 Hz při rozlišení 8 bitů ledcAttachPin (25, 0); // nastavení pwm na pinu 25 ledcWrite (0, 128); // nastavení zpoždění na poloviční pracovní cyklus (největší hluk) (3000); // počkejte na ustálení času float snrPWM [opakování]; // pole snrs pro PWM float snrDAC [opakování]; // řada snrs pro DAC pro (int i = 0; i <opakování; i ++) {// opakování pro opakování pro (int k = 1; k <(n+1); k ++) {// smyčka nad vzorky adc0 = ads.readADC_SingleEnded (0); // získat čtení M = Mp + (adc0 - Mp) / k; // výpočet klouzavého průměru Mp = M; // nastavení předchozího průměru S = Sp + (adc0 - Mp) * (adc0 - M); // vypočítat valivý rozptyl Sp = S; // nastavit předchozí rozptyl} // snr v dB snrPWM = 20 * log10 (3,3 / (sqrt (S / n) *.0625 *.001)); // reset hodnot M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // odpoj PWM od pinu 25 dacWrite (25, 128); // zápis do zpoždění DAC (3000); // počkejte na vyrovnání (int i = 0; i <opakování; i ++) {// stejné jako smyčka PWM pro (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; Mp = 0; S = 0; Sp = 0; } // vykreslení SNR na jeden graf pro (int i = 1; i <opakování; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} prázdná smyčka (prázdná) {}

Krok 3: Integrální nelinearita a diferenciální nelinearita

Integrální nelinearita a diferenciální nelinearita
Integrální nelinearita a diferenciální nelinearita

Integrální nelinearita je měřítkem zhruba odchylky mezi výstupním napětím DAC a přímkou. Čím větší je toto, tím je to horší…

Diferenciální nelinearita je měřítkem zhruba toho, jak moc se pozorovaná změna napětí (z jednoho kódu do druhého) odchyluje od toho, co by se dalo očekávat od přímky.

Výsledky zde byly opravdu zajímavé. Za prvé, oba mají chybu menší než 0,5 lsb (při 8bitovém rozlišení), což je dobré, ale PWM má mnohem lepší integrovanou linearitu. Oba mají srovnatelnou diferenciální nelinearitu, ale ESP32 DAC má několik velmi podivných špiček. Metoda PWM má navíc strukturu chyb. V zásadě střídavě překračuje a překračuje správné napětí.

Moje podezření je, že je to nějaká podivná chyba zaokrouhlování v tom, jak je na ESP32 produkován 8bitový signál PWM.

Jedním ze způsobů, jak to napravit, je rychlé cyklování mezi dvěma sousedními kódy (např. 128, 129) s PWM. S analogovým dolním filtrem budou výsledné chyby průměrné až nula. Simuloval jsem to v softwaru a opravdu všechny chyby zmizely. Nyní má metoda PWM linearitu, která je přesná na 16 bitů!

Níže je uveden kód pro generování dat. Výstup bude na sériovém monitoru ve formátu.csv. Stačí jej zkopírovat do textového souboru pro další zpracování.

#zahrnout

#include Adafruit_ADS1115 reklamy; / * Použijte pro 16bitovou verzi */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x zisk +/- 2,048V 1 bit = 1mV 0,0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Očekávané, pozorované"); ledcWrite (0, 2); zpoždění (3000); pro (int i = 2; i <255; i ++) {ledcWrite (0, i); zpoždění (100); adc0 = ads.readADC_SingleEnded (0); float očekáván = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print (očekávané); Serial.print (","); Serial.println (adc0); }} prázdná smyčka (prázdná) {}

Krok 4: Šířka pásma

Šířka pásma
Šířka pásma

Šířku pásma zde definuji jako frekvenci, při které výstup DAC klesne o 3dB. Toto je konvence a do jisté míry svévolné. Například v bodě 6 dB bude DAC stále vysílat signál, který bude mít pouze ~ 50% amplitudy.

Abychom to změřili, jednoduše procházíme sinusovými vlnami s rostoucí frekvencí z DAC do ADC a měříme jejich standardní odchylku. Není překvapením, že bod 3dB je na 30 Hz (1/(2*pi*5000*1e-6)).

ESP32 zvládne 1 Mega vzorek za sekundu. Toto je výhra pro ESP32. Jeho amplituda se v testovací oblasti šířky pásma 100 Hz vůbec nerozpadá.

Níže uvedený kód může otestovat šířku pásma PWM DAC.

#zahrnout

#include Adafruit_ADS1115 reklamy; / * Použijte pro 16bitovou verzi */ int16_t adc0; int16_t adc1; void setup (void) {float M; float Mp = 0; float S = 0; float Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x zisk +/- 4,096V 1 bit = 2mV 0,125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); zpoždění (5000); Serial.println („Frekvence, Amplituda“); for (int i = 1; i <100; i ++) {unsigned long start = millis (); nepodepsané dlouhé T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plovoucí norma; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, out); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } if (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norm, 3); k = 0; }} prázdná smyčka (prázdná) {}

A tento kód otestuje šířku pásma ESP32. Ujistěte se, že jste odstranili kondenzátor, protože výsledky budou u obou metod stejné.

#zahrnout

#include Adafruit_ADS1115 reklamy; / * Použijte pro 16bitovou verzi */ int16_t adc0; int16_t adc1; void setup (void) {float M; float Mp = 0; float S = 0; float Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x zisk +/- 4,096V 1 bit = 2mV 0,125mV ads.begin (); zpoždění (5000); Serial.println („Frekvence, Amplituda“); for (int i = 1; i <100; i ++) {unsigned long start = millis (); nepodepsané dlouhé T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plovoucí norma; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, out); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } if (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norm, 3); k = 0; }} prázdná smyčka (prázdná) {}

Krok 5: Uzavření myšlenek

Nový design DAC vítězí na linearitě a šumu, ale ztrácí na šířce pásma. V závislosti na vaší aplikaci může být jeden z těchto indexů důležitější než druhý. S těmito testovacími postupy byste měli být schopni objektivně se rozhodnout!

Také si myslím, že stojí za to poukázat na to, že protože výstup PWM je nízkošumový, s výjimečnou linearitou by mělo být možné zkonstruovat DAC s mnohem vyšším rozlišením s výstupem PWM (možná dokonce 16bitová přesnost). To bude chtít trochu práce. Do té doby se s vámi loučím!

Doporučuje: