Obsah:

Ako vytvoriť a otestovať lepší DAC s ESP32: 5 krokov
Ako vytvoriť a otestovať lepší DAC s ESP32: 5 krokov
Anonim
Ako vytvoriť a otestovať lepší DAC s ESP32
Ako vytvoriť a otestovať lepší DAC s ESP32
Ako vytvoriť a otestovať lepší DAC pomocou ESP32
Ako vytvoriť a otestovať lepší DAC pomocou ESP32

ESP32 má 2 8-bitové digitálne analógové prevodníky (DAC). Tieto DAC nám umožňujú produkovať ľubovoľné napätie v určitom rozsahu (0-3,3 V) s rozlíšením 8 bitov. V tomto návode vám ukážem, ako zostaviť DAC a charakterizovať jeho výkon a tiež ho porovnať s ESP32 DAC. Indexy výkonnosti, na ktoré sa pozriem, zahŕňajú

  • Úroveň hluku
  • Šírka pásma
  • Integrálna nelinearita
  • Diferenciálna nelinearita

Na testovanie týchto indexov použijem ADS1115.

Je dôležité si uvedomiť, že vaše hodnotenie všetkých týchto indexov bude len také presné ako vaše referenčné zariadenie (v tomto prípade ADS115). Napríklad ADS115 nemá 16-bitovú presnosť, pokiaľ ide o posun napätia a zosilnenie. Tieto chyby môžu byť až 0,1%. V prípade mnohých systémov je možné tieto chyby ignorovať, ak je absolútna presnosť obmedzená.

Zásoby

  • ADS1115
  • Doska ESP32
  • breadboard
  • prepojovacie vodiče
  • Rezistor 5 kOhm
  • 1 keramický kondenzátor micro-Farad

Krok 1: Položenie Breadboardu

Položenie Breadboardu
Položenie Breadboardu

Pripojte nasledujúce kolíky

Medzi ESP32 a ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Na ADS1115

ADDR GND (ADS115)

Výroba DAC

Existuje mnoho spôsobov, ako vytvoriť DAC. Najjednoduchšie je filtrovať signál PWM s nízkym priechodom odporom a kondenzátorom. Mohol som sem pridať operačný zosilňovač ako vyrovnávaciu pamäť, ale chcel som, aby to bolo jednoduché. Tento dizajn je jednoduchý a lacný na implementáciu pomocou akéhokoľvek mikrokontroléra, ktorý podporuje PWM. Nejdem tu rozoberať teóriu dizajnu (google PWM DAC).

Stačí pripojiť odpor GPIO255 KOhm 1 microFarad kondenzátor gnd

Teraz pripojte prepojovací vodič z bodu, kde sa odpor stretáva s kondenzátorom, k A0 na ADS115.

Krok 2: Posúďte signál k úrovni šumu

Posúďte signál k úrovni šumu
Posúďte signál k úrovni šumu

Na vyhodnotenie hladiny hluku jednoducho spustite nasledujúci skript. Aby sme to posúdili, jednoducho necháme DAC na pevnej hodnote a zmeráme, ako napätie v priebehu času osciluje.

Vzhľadom na konštrukciu DAC bude šum najväčší, keď je signál PWM pri 50% pracovnom cykle. Preto to budeme hodnotiť práve tu. Tiež budeme hodnotiť ESP32 na rovnakej úrovni signálu. Tiež budeme filtrovať ESP32 DAC s rovnakým dolnopriepustným filtrom, aby bolo meranie porovnateľné.

Pre mňa bol výstup jasný. Konštrukcia PWM mala> 6 dB lepšie SNR (to je 2 krát lepšie). Jasná výhra pre nový DAC. Miernym zmätkom je, že v ADC sú zabudované filtre, ktoré rozhodne zlepšujú SNR. Preto môže byť ťažké interpretovať absolútne hodnoty. Ak by som použil filter druhého rádu, nebolo by to tak.

Každopádne kód je nižšie

#zahrnúť

#include Adafruit_ADS1115 reklamy; // knižnica adafruit pre adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Spustenie sériového ads.setGain (GAIN_TWO); // 2x zisk +/- 2,048V 1 bit = 0,0625mV ads.begin (); // begin adc float M = 0; // počiatočný priemer float Mp = 0; // previouos priemer float S = 0; // počiatočný odchýlkový rozptyl Sp = 0; // predchádzajúca odchýlka const int reps = 500; // počet opakovaní int n = 256; // počet vzoriek ledcSetup (0, 25000, 8); // nastavenie frekvencie pwm = 25 000 Hz pri 8 bitovom rozlíšení ledcAttachPin (25, 0); // nastavenie pwm na pin 25 ledcWrite (0, 128); // nastavenie oneskorenia na polovicu pracovného cyklu (najväčší hluk) (3000); // čakanie na čas vyrovnania float snrPWM [opakovania]; // pole snrs pre PWM float snrDAC [opakovania]; // rad snrs pre DAC pre (int i = 0; i <opakovanie; i ++) {// opakovanie pre opakovanie pre (int k = 1; k <(n+1); k ++) {// slučka nad vzorkami adc0 = ads.readADC_SingleEnded (0); // prečítanie M = Mp + (adc0 - Mp) / k; // vypočítajte valivý priemer Mp = M; // nastavenie predchádzajúceho priemeru S = Sp + (adc0 - Mp) * (adc0 - M); // vypočítajte valivý rozptyl Sp = S; // nastavenie predchádzajúcej odchýlky} // snr v dB snrPWM = 20 * log10 (3,3 / (sqrt (S / n) *.0625 *.001)); // vynulovanie hodnôt M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // odpoj PWM od pinu 25 dacWrite (25, 128); // zápis do oneskorenia DAC (3000); // čakať na vyrovnanie sa (int i = 0; i <opakovania; i ++) {// rovnaké ako slučka PWM pre (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 * 0,001)); M = 0; Mp = 0; S = 0; Sp = 0; } // vykreslenie SNR na jeden graf pre (int i = 1; i <opakovania; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} prázdna slučka (prázdna) {}

Krok 3: Integrálna nelinearita a diferenciálna nelinearita

Integrálna nelinearita a diferenciálna nelinearita
Integrálna nelinearita a diferenciálna nelinearita

Integrovaná nelinearita je mierou zhruba odchýlky medzi vašim výstupným napätím DAC a priamkou. Čím je to väčšie, tým je to horšie …

Diferenciálna nelinearita je mierou zhruba toho, ako veľmi sa pozorovaná zmena napätia (z jedného kódu do druhého) líši od toho, čo by sa dalo očakávať od priamky.

Výsledky tu boli skutočne zaujímavé. Po prvé, obe majú chybu menšiu ako 0,5 lsb (pri 8-bitovom rozlíšení), čo je dobré, ale PWM má oveľa lepšiu integrálnu linearitu. Oba majú porovnateľnú diferenciálnu nelinearitu, ale ESP32 DAC má niekoľko veľmi podivných špičiek. Metóda PWM má navyše štruktúru chýb. V zásade striedavo strieda a prekračuje správne napätie.

Moje podozrenie je, že je to zvláštna chyba zaokrúhľovania v tom, ako sa na ESP32 vytvára 8-bitový signál PWM.

Jeden zo spôsobov, ako to napraviť, je rýchly cyklus medzi dvoma susednými kódmi (napr. 128, 129) s PWM. Pri analógovom dolnopriepustnom filtri budú výsledné chyby priemerné až nula. Simuloval som to v softvéri a skutočne všetky chyby zmizli. Metóda PWM má teraz linearitu presnú na 16 bitov!

Ktokoľvek kód na generovanie údajov je uvedený nižšie. Výstup bude na sériovom monitore vo formáte.csv. Stačí ho skopírovať do textového súboru na ďalšie spracovanie.

#zahrnúť

#include Adafruit_ADS1115 reklamy; / * Použite to pre 16-bitovú verziu */ 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čakávané, pozorované"); ledcWrite (0, 2); oneskorenie (3000); pre (int i = 2; i <255; i ++) {ledcWrite (0, i); oneskorenie (100); adc0 = ads.readADC_SingleEnded (0); očakávaný plavák = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print (očakáva sa); Serial.print (","); Serial.println (adc0); }} prázdna slučka (prázdna) {}

Krok 4: Šírka pásma

Šírka pásma
Šírka pásma

Šírku pásma tu definujem ako frekvenciu, pri ktorej výstup DAC klesne o 3dB. Toto je konvencia a do istej miery svojvoľná. Napríklad v bode 6 dB bude DAC stále vydávať signál, ktorý bude mať iba ~ 50% amplitúdy.

Aby sme to mohli zmerať, jednoducho prechádzame sínusovými vlnami so zvyšujúcou sa frekvenciou z DAC do ADC a meriame ich štandardnú odchýlku. Nie je prekvapením, že bod 3dB je na 30 Hz (1/(2*pi*5000*1e-6)).

ESP32 môže robiť 1 megapixel za sekundu. Toto je praktická výhra pre ESP32. Jeho amplitúda sa v testovacej oblasti šírky pásma 100 Hz vôbec nerozpadá.

Nasledujúci kód môže testovať šírku pásma PWM DAC.

#zahrnúť

#include Adafruit_ADS1115 reklamy; / * Použite to pre 16-bitovú verziu */ int16_t adc0; int16_t adc1; void setup (void) {float M; plavák Mp = 0; plavák S = 0; plavák 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); oneskorenie (5 000); Serial.println („Frekvencia, amplitúda“); for (int i = 1; i <100; i ++) {unsigned long start = millis (); nepodpísané dlhé T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plávajúca norma; while ((T - štart) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000,0) + 128; ledcWrite (0, von); 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 (","); Sériové číslo. Println (sqrt (S / k) / norma, 3); k = 0; }} prázdna slučka (prázdna) {}

A tento kód testuje šírku pásma ESP32. Uistite sa, že ste vybrali kondenzátor, pretože výsledky budú pre obe metódy rovnaké.

#zahrnúť

#include Adafruit_ADS1115 reklamy; / * Použite to pre 16-bitovú verziu */ int16_t adc0; int16_t adc1; void setup (void) {float M; plavák Mp = 0; plavák S = 0; plavák Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x zisk +/- 4,096V 1 bit = 2mV 0,125mV ads.begin (); oneskorenie (5 000); Serial.println („Frekvencia, amplitúda“); for (int i = 1; i <100; i ++) {unsigned long start = millis (); nepodpísané dlhé T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plávajúca norma; while ((T - štart) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000,0) + 128; dacWrite (25, von); 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 (","); Sériové číslo. Println (sqrt (S / k) / norma, 3); k = 0; }} prázdna slučka (prázdna) {}

Krok 5: Zatváranie myšlienok

Nový dizajn DAC víťazí na linearite a hluku, ale stráca na šírke pásma. V závislosti od vašej aplikácie môže byť jeden z týchto indexov dôležitejší ako druhý. S týmito testovacími postupmi by ste mali byť schopní objektívne sa rozhodnúť!

Tiež si myslím, že stojí za to poukázať na to, že pretože výstup PWM je nízky šum, s výnimočnou linearitou by malo byť možné zostrojiť DAC s oveľa vyšším rozlíšením s výstupom PWM (možno dokonca 16-bitová presnosť). To bude chcieť trochu práce. Dovtedy vám dávam zbohom!

Odporúča: