Sisällysluettelo:
- Tarvikkeet
- Vaihe 1: Leipälevyn asettaminen
- Vaihe 2: Arvioi signaali melutasolle
- Vaihe 3: Integraalinen epälineaarisuus ja differentiaalinen epälineaarisuus
- Vaihe 4: Kaistanleveys
- Vaihe 5: Ajatuksien sulkeminen
Video: Kuinka tehdä ja testata parempi DAC ESP32: 5 -vaiheilla
2024 Kirjoittaja: John Day | [email protected]. Viimeksi muokattu: 2024-01-30 08:59
ESP32: ssa on 2 8-bittistä digitaalista analogiamuunninta (DAC). Näiden DAC-laitteiden avulla voimme tuottaa mielivaltaisia jännitteitä tietyllä alueella (0-3,3 V) 8 bitin tarkkuudella. Tässä Instructable -ohjelmassa näytän sinulle, kuinka rakentaa DAC ja luonnehtia sen suorituskykyä sekä verrata sitä ESP32 DAC -laitteeseen. Suoritusindeksit, joita tarkastelen, sisältävät
- Melutaso
- Kaistanleveys
- Integraalinen epälineaarisuus
- Erilainen epälineaarisuus
Näiden indeksien testaamiseen käytän ADS1115: tä.
On tärkeää huomata, että arvio kaikista näistä indekseistä on vain yhtä tarkka kuin vertailulaitteesi (tässä tapauksessa ADS115). Esimerkiksi ADS115: llä ei ole 16-bittistä tarkkuutta jännitteen siirtymän ja vahvistuksen suhteen. Nämä virheet voivat olla jopa 0,1%. Monissa järjestelmissä nämä virheet voidaan jättää huomiotta, kun absoluuttinen tarkkuus on vähäistä.
Tarvikkeet
- ADS1115
- ESP32 -levy
- leipälauta
- hyppyjohtimet
- 5 kOhm vastus
- 1 keraaminen mikro-Farad-kondensaattori
Vaihe 1: Leipälevyn asettaminen
Johda seuraavat nastat
ESP32: n ja ADS1115: n välillä
3v3 VDD
GND GND
GPIO22 SCL
GPIO21 SDA
ADS1115
ADDR GND (ADS115)
DAC: n tekeminen
On monia tapoja tehdä DAC. Yksinkertaisin on alipäästösuodattaa PWM-signaali vastuksella ja kondensaattorilla. Olisin voinut lisätä op-vahvistimen tänne puskuriksi, mutta halusin pitää asiat yksinkertaisina. Tämä malli on yksinkertainen ja halpa toteuttaa millä tahansa PWM: ää tukevalla mikro -ohjaimella. En aio käydä läpi suunnitteluteoriaa täällä (google PWM DAC).
Liitä vain GPIO255 Kohmin vastus 1 microFarad -kondensaattori gnd
Kytke nyt hyppyjohdin pisteestä, jossa vastus kohtaa kondensaattorin, ADS115: n A0 -liittimeen.
Vaihe 2: Arvioi signaali melutasolle
Voit mitata melutason yksinkertaisesti suorittamalla alla olevan komentosarjan. Tämän arvioimiseksi jätämme DAC: n kiinteään arvoon ja mittaamme jännitteen värähtelyn ajan mittaan.
DAC: n rakenteen vuoksi melu on suurin, kun PWM -signaali on 50%: n toimintajaksolla. Siksi arvioimme sitä tässä. Arvioimme myös ESP32: n samalla signaalitasolla. Suodatamme myös ESP32 DAC: n samalla alipäästösuodattimella, jotta mittaus olisi vertailukelpoinen.
Minulle lähtö oli selvä. PWM -suunnittelussa oli> 6 dB parempi SNR (joka on 2 kertaa parempi). Selvä voitto uudelle DAC: lle. Pieni hämmennys on se, että ADC: hen on rakennettu suodattimia, jotka ehdottomasti parantavat SNR: ää. Joten absoluuttisia arvoja voi olla vaikea tulkita. Jos olisin käyttänyt toisen asteen suodatinta, näin ei olisi.
Joka tapauksessa koodi on alla
#sisältää
#Sisällytä Adafruit_ADS1115 -mainokset; // adafruit -kirjasto adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Aloita sarjamainokset.setGain (GAIN_TWO); // 2x vahvistus +/- 2.048V 1 bitti = 0.0625mV ads.begin (); // aloita adc float M = 0; // alku keskimääräinen float Mp = 0; // edeltävä keskimääräinen kelluva S = 0; // alkuperäinen varianssi float Sp = 0; // edellinen varianssi const int toistot = 500; // toistojen lukumäärä int n = 256; // näytteiden lukumäärä ledcSetup (0, 25000, 8); // aseta pwm frequecny = 25000 Hz 8 bitin resoluutiolla ledcAttachPin (25, 0); // aseta pwm nastaan 25 ledcWrite (0, 128); // aseta se puoleen käyttöjaksoon (suurin melu) viive (3000); // odota asettumisaikaa float snrPWM [reps]; // taulukko snrs PWM -kellulle snrDAC [toistot]; // matriisi snrs for DAC for (int i = 0; i <reps; i ++) {// silmukka toistojen kohdalla (int k = 1; k <(n+1); k ++) {// silmukka näytteiden yli adc0 = ads.readADC_SingleEnded (0); // saada lukema M = Mp + (adc0 - Mp) / k; // laske liukuva keskiarvo Mp = M; // aseta edellinen keskiarvo S = Sp + (adc0 - Mp) * (adc0 - M); // laske vierintävarianssi Sp = S; // aseta edellinen varianssi} // snr dB: ssä snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // nollaa arvot M = 0; Sp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // irrota PWM nastasta 25 dacWrite (25, 128); // kirjoittaa DAC -viiveeseen (3000); // odota tyytyä (int i = 0; i <reps; i ++) {// sama kuin PWM -silmukka (int k = 1; k <(n+1); k ++) {adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Sp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; } snrDAC = 20 * log10 (3,3 / (neliö (S / n) *.0625 *.001)); M = 0; Sp = 0; S = 0; Sp = 0; } // piirtää SNR: t yhteen kuvaajaan kohteelle (int i = 1; i <toistoa; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Sarja.println (snrDAC ); }} void loop (void) {}
Vaihe 3: Integraalinen epälineaarisuus ja differentiaalinen epälineaarisuus
Integroitu epälineaarisuus on mitta siitä, kuinka paljon poikkeamaa DAC -lähtöjännitteen ja suoran välillä on. Mitä isompi tämä, sitä huonompi…
Ero -epälineaarisuus mittaa suunnilleen kuinka paljon havaittu jännitteen muutos (koodista toiseen) poikkeaa siitä, mitä suoralta odotettaisiin.
Tulokset täällä olivat todella mielenkiintoisia. Ensinnäkin molemmilla on alle 0,5 lsb virhe (8-bittisellä resoluutiolla), mikä on hyvä, mutta PWM: llä on paljon parempi integraalinen lineaarisuus. Molemmilla on vertailukelpoinen differentiaalinen epälineaarisuus, mutta ESP32 DAC: ssa on joitain hyvin outoja piikkejä. Lisäksi PWM -menetelmällä on jonkinlainen rakenne virheille. Pohjimmiltaan se ylittää ja alittaa oikean jännitteen vuorotellen.
Epäilen, että tämä on outo pyöristysvirhe siinä, miten 8-bittinen PWM-signaali tuotetaan ESP32: ssa.
Yksi tapa korjata tämä on selata nopeasti kahden vierekkäisen koodin (esim. 128, 129) välillä PWM: n kanssa. Analogisella alipäästösuodattimella syntyvät virheet keskimäärin nollaan. Simuloin tätä ohjelmistossa ja todellakin kaikki virheet katosivat. Nyt PWM-menetelmällä on lineaarisuus, joka on tarkka 16-bitille!
Alla on koodi, jolla tiedot luodaan. Lähtö tulee olemaan sarjamonitorissa.csv -muodossa. Kopioi se tekstitiedostoon jatkokäsittelyä varten.
#sisältää
#Sisällytä Adafruit_ADS1115 -mainokset; / * Käytä tätä 16-bittisessä versiossa */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x vahvistus +/- 2.048V 1 bitti = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Odotettu, havaittu"); ledcWrite (0, 2); viive (3000); for (int i = 2; i <255; i ++) {ledcWrite (0, i); viive (100); adc0 = ads.readADC_SingleEnded (0); float odotettu = (i / 256,0 * 3,3) / 4,096 * 32767; Sarjajälki (odotettu); Serial.print (","); Sarja.println (adc0); }} void loop (void) {}
Vaihe 4: Kaistanleveys
Aion määritellä kaistanleveyden tässä taajuutena, jolla DAC: n lähtö laskee 3dB: llä. Tämä on yleissopimus ja jossain määrin mielivaltainen. Esimerkiksi 6 dB: n pisteessä DAC lähettää edelleen signaalin, jonka amplitudi on vain ~ 50%.
Tämän mittaamiseksi yksinkertaisesti välitämme siniaaltoja yhä useammin DAC: sta ADC: hen ja mittaamme niiden keskihajonnan. Ei ole yllättävää, että 3dB-piste on taajuudella 30 Hz (1/(2*pi*5000*1e-6)).
ESP32 voi ottaa 1 meganäytteen sekunnissa. Tämä on käytännön voitto ESP32: lle. Sen amplitudi ei heikkene lainkaan 100 Hz: n kaistanleveyden testialueella.
Alla oleva koodi voi testata PWM DAC -kaistanleveyttä.
#sisältää
#Sisällytä Adafruit_ADS1115 -mainokset; / * Käytä tätä 16-bittisessä versiossa */ int16_t adc0; int16_t adc1; void setup (void) {float M; float Mp = 0; float S = 0; kellua Sp = 0; Sarja.alku (115200); ads.setGain (GAIN_ONE); // 1x vahvistus +/- 4.096V 1 bitti = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); viive (5000); Serial.println ("Taajuus, amplitudi"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); allekirjoittamaton pitkä T = millis (); Sp = 0; S = 0; M = 0; Sp = 0; int k = 1; kelluva normi; while ((T - aloitus) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, ulos); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Sp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } jos (i == 1) {norm = sqrt (S / k); } Sarjajälki (i); Serial.print (","); Sarja.println (neliömetriä (S / k) / normi, 3); k = 0; }} void loop (void) {}
Ja tämä koodi testaa ESP32 -kaistanleveyttä. Varmista, että irrotat kondensaattorin, tai tulokset ovat samat molemmilla menetelmillä.
#sisältää
#Sisällytä Adafruit_ADS1115 -mainokset; / * Käytä tätä 16-bittisessä versiossa */ int16_t adc0; int16_t adc1; void setup (void) {float M; float Mp = 0; float S = 0; kellua Sp = 0; Sarja.alku (115200); ads.setGain (GAIN_ONE); // 1x vahvistus +/- 4.096V 1 bitti = 2mV 0.125mV ads.begin (); viive (5000); Serial.println ("Taajuus, amplitudi"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); allekirjoittamaton pitkä T = millis (); Sp = 0; S = 0; M = 0; Sp = 0; int k = 1; kelluva normi; while ((T - aloitus) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, ulos); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Sp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } jos (i == 1) {norm = sqrt (S / k); } Sarjajälki (i); Serial.print (","); Serial.println (neliömetriä (S / k) / normi, 3); k = 0; }} void loop (void) {}
Vaihe 5: Ajatuksien sulkeminen
Uusi DAC -muotoilu voittaa lineaarisuuden ja kohinan, mutta menettää kaistanleveyden. Sovelluksestasi riippuen yksi näistä indekseistä voi olla tärkeämpi kuin toinen. Näiden testausmenetelmien avulla sinun pitäisi pystyä tekemään objektiivinen päätös!
Mielestäni on myös syytä huomauttaa tässä, että koska PWM-lähtö on hiljainen, poikkeuksellisen lineaarisuuden vuoksi pitäisi olla mahdollista rakentaa paljon korkeamman resoluution DAC PWM-ulostulolla (ehkä jopa 16-bittinen tarkkuus). Se vie jonkin verran työtä. Siihen asti, hyvästi!
Suositeltava:
DIY Kuinka näyttää aika M5StickC ESP32: ssa Visuinon avulla - Helppo tehdä: 9 vaihetta
DIY Kuinka näyttää aika M5StickC ESP32: ssa Visuinon avulla - Helppo tehdä: Tässä opetusohjelmassa opimme ohjelmoimaan ESP32 M5Stack StickC: n Arduino IDE: n ja Visuinon avulla näyttämään ajan nestekidenäytöllä
DIY Kuinka tehdä tyylikkään näköinen kello - StickC - Helppo tehdä: 8 vaihetta
DIY Kuinka tehdä tyylikkään näköinen kello - StickC - Helppo tehdä: Tässä opetusohjelmassa opimme ohjelmoimaan ESP32 M5Stack StickC: n Arduino IDE: n ja Visuinon avulla näyttämään ajan nestekidenäytöllä ja asettamaan ajan myös StickC -painikkeilla
Arduino -volttimittari (0-100 V DC) - Versio 2 (parempi): 3 vaihetta
Arduino-volttimittari (0-100 V DC)-Versio 2 (parempi): Tässä ohjeessa olen rakentanut voltimittarin mittaamaan suurjännitteitä DC (0-100v) suhteellisen tarkasti ja tarkasti käyttämällä Arduino Nano ja ADS 1115 ADC .Tämä on toinen versio voltimittarista, jota käytin edellisellä ohjeellani täällä: https: // ww
Cree Led H4 -ajovalojen parempi jäähdytys - HYVÄKSYTY: 4 vaihetta
Cree Led H4 -ajovalojen parempi jäähdytys - HYVÄKSYTY: Varajäähdytystuulettimien korvaaminen ulkoisella puhallimella parantaa jäähdytystä ja pidentää käyttöikää. Käyttämäni ledit ovat Newsun h4 -ajovalojen vaihto Amazonista http://www.amazon.com/dp/B00HFK2RAE/ref=sr_ph?ie=UTF8&qid=1415547
Parempi tapa tarkastella/dokumentoida opetusohjelmien tiedostoja: 4 vaihetta
Parempi tapa tarkastella/dokumentoida Instructables -tiedostoja: Ihmiset sisällyttävät usein tiedostoja projektiin Instructables -latausten kautta. Usein tämä on ohjelmistolähdetiedostoja, jotka voivat olla jopa ohjattavan sydän. Instructables ei kuitenkaan anna lukijalle helppoa tapaa lukea ja tarkistaa koodia. (