Obsah:
- Zásoby
- Krok 1: Rozložení Breadboardu
- Krok 2: Vyhodnoťte úroveň šumu signálu
- Krok 3: Integrální nelinearita a diferenciální nelinearita
- Krok 4: Šířka pásma
- Krok 5: Uzavření myšlenek
Video: Jak vytvořit a otestovat lepší DAC s ESP32: 5 kroků
2024 Autor: John Day | [email protected]. Naposledy změněno: 2024-01-30 08:19
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
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
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 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
Šíř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:
Jak vytvořit zaváděcí jednotku Linux (a jak ji používat): 10 kroků
Jak vytvořit zaváděcí jednotku Linux (a jak ji používat): Toto je jednoduchý úvod, jak začít s Linuxem, konkrétně Ubuntu
Lepší projekty s použitím desek plošných spojů: 6 kroků
Lepší projekty s využitím desek plošných spojů: Pokud jste strávili čas prací na elektronických projektech, víte, jak zábavné a vzrušující to může být. Není nic vzrušujícího, než vidět, jak se váš okruh ožívá přímo před vašima očima. Je to ještě vzrušující, když se váš projekt změní na
Jak vytvořit více rozhovorů ESP prostřednictvím ESP-NOW pomocí ESP32 a ESP8266: 8 kroků
Jak vytvořit více rozhovorů ESP prostřednictvím ESP-NYNÍ pomocí ESP32 a ESP8266: Na mém probíhajícím projektu potřebuji více ESP, abychom spolu mohli mluvit bez routeru. K tomu použiji ESP-NOW k bezdrátové komunikaci mezi sebou bez routeru na ESP
Bezpečnější lepší: Zvýšení bezpečnosti nádraží: 7 kroků
Bezpečnější lepší: Zvýšení bezpečnosti vlakových stanic: Mnoho dnešních nádraží není bezpečných kvůli nedostatku zabezpečení, závor a varování před přijíždějícím vlakem. Viděli jsme, že je potřeba to opravit. Abychom tento problém vyřešili, vytvořili jsme bezpečnější lepší. Použili jsme vibrační senzory, pohybové senzory a
Jak vytvořit autonomního robota hrajícího basketbal pomocí IRobota Vytvořit jako základ: 7 kroků (s obrázky)
Jak vytvořit autonomního robota hrajícího basketbal pomocí IRobota Vytvořit jako základ: Toto je můj příspěvek k výzvě iRobot Create. Nejtěžší na celém tomto procesu pro mě bylo rozhodnout, co bude robot dělat. Chtěl jsem předvést skvělé funkce Create a zároveň přidat trochu robo vkusu. Všechny moje