Sisukord:

Kuidas teha ja testida paremat DAC -i ESP32 abil: 5 sammu
Kuidas teha ja testida paremat DAC -i ESP32 abil: 5 sammu

Video: Kuidas teha ja testida paremat DAC -i ESP32 abil: 5 sammu

Video: Kuidas teha ja testida paremat DAC -i ESP32 abil: 5 sammu
Video: Как и по каким признакам можно определить когда копать картошку 2024, November
Anonim
Kuidas teha ja testida paremat DAC -i ESP32 abil
Kuidas teha ja testida paremat DAC -i ESP32 abil
Kuidas teha ja testida paremat DAC -i ESP32 abil
Kuidas teha ja testida paremat DAC -i ESP32 abil

ESP32-l on 2 8-bitist digitaalset analoogmuundurit (DAC). Need DAC-id võimaldavad meil toota suvalisi pingeid teatud vahemikus (0–3,3 V) 8 eraldusvõimega. Selles juhendis näitan teile, kuidas DAC -i luua ja selle toimivust iseloomustada, ning võrrelda seda ESP32 DAC -iga. Tulemusindeksid, mida ma vaatan, hõlmavad

  • Müratase
  • Ribalaius
  • Integraalne mittelineaarsus
  • Diferentsiaalne mittelineaarsus

Nende indeksite testimiseks kasutan ADS1115.

Oluline on märkida, et teie hinnang kõikidele nendele indeksitele on ainult sama täpne kui teie võrdlusseade (antud juhul ADS115). Näiteks pole ADS115 16-bitise täpsusega pinge nihke ja võimenduse osas. Need vead võivad ulatuda 0,1%-ni. Paljude süsteemide puhul võib neid vigu ignoreerida, kui absoluutne täpsus on piiratud.

Tarvikud

  • ADS1115
  • ESP32 juhatus
  • leivalaud
  • hüppaja juhtmed
  • 5 kOhm takisti
  • 1 keraamiline mikro-Farad kondensaator

1. samm: leivalaua paigutamine

Leivalaua paigutamine
Leivalaua paigutamine

Ühendage juhtmed järgmiste tihvtidega

ESP32 ja ADS1115 vahel

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Aadressil ADS1115

ADDR GND (ADS115)

DAC -i tegemine

DAC -i tegemiseks on palju võimalusi. Lihtsaim on PWM-signaali madalpääsfiltrimine takisti ja kondensaatoriga. Ma oleks võinud siia lisada puhverina op-võimendi, kuid tahtsin asju lihtsana hoida. See disain on lihtne ja odav rakendada mis tahes PWM -i toetava mikrokontrolleriga. Ma ei hakka siin läbi vaatama disainiteooriat (google PWM DAC).

Lihtsalt ühendage GPIO255 KOhm takisti 1 microFarad kondensaator gnd

Nüüd ühendage hüppaja traat punktist, kus takisti vastab kondensaatorile, ADS115 A0 -ga.

Samm: hinnake signaali müratasemele

Hinnake signaali müratasemele
Hinnake signaali müratasemele

Mürataseme hindamiseks käivitage lihtsalt allolev skript. Selle hindamiseks jätame DAC -i kindlale väärtusele ja mõõdame, kuidas pinge aja jooksul võnkub.

DAC -i konstruktsiooni tõttu on müra suurim, kui PWM -signaal on 50% töötsüklis. Seetõttu hindame seda siin. Samuti hindame ESP32 samal signaalitasemel. Samuti filtreerime ESP32 DAC sama madalpääsfiltriga, et mõõtmine oleks võrreldav.

Minu jaoks oli väljund selge. PWM -i disainil oli> 6 dB parem SNR (see on 2 korda parem). Selge võit uuele DAC -ile. Üks väike segadus on see, et ADC -sse on sisse ehitatud filtrid, mis kindlasti parandavad SNR -i. Seega võib absoluutväärtusi olla raske tõlgendada. Kui ma oleksin kasutanud teise järgu filtrit, poleks see nii.

Igatahes kood on allpool

#kaasake

#kaasake Adafruit_ADS1115 reklaame; // adafruit raamatukogu jaoks adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Seeriareklaamide käivitamine.setGain (GAIN_TWO); // 2x võimendus +/- 2.048V 1 bit = 0.0625mV ads.begin (); // algus adc float M = 0; // algne keskmine ujuk Mp = 0; // eelnev keskmine ujuk S = 0; // esialgne dispersiooni ujuk Sp = 0; // eelmine dispersioon const int reps = 500; // korduste arv int n = 256; // proovide arv ledcSetup (0, 25000, 8); // määrake pwm frequecny = 25000 Hz 8 -bitise eraldusvõimega ledcAttachPin (25, 0); // määrake pwm tihvtile 25 ledcWrite (0, 128); // seada poole töötsükli (suurim müra) viivitus (3000); // oota settimisaega float snrPWM [reps]; // PWM ujukite massiiv snrDAC [reps]; // DAC -i snr -massiiv (int i = 0; i <reps; i ++) {// silmus üle korduste (int k = 1; k <(n+1); k ++) {// silmus proovide kohal adc0 = ads.readADC_SingleEnded (0); // lugemise saamine M = Mp + (adc0 - Mp) / k; // jooksva keskmise arvutamine Mp = M; // määra eelmine keskmine S = Sp + (adc0 - Mp) * (adc0 - M); // veerev dispersiooni arvutamine Sp = S; // määrake eelmine dispersioon} // snr dB -des snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // väärtuste lähtestamine M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // lahutage PWM tihvtilt 25 dacWrite (25, 128); // kirjutada DAC viivitusse (3000); // oota, et leppida (int i = 0; i <reps; i ++) {// sama mis PWM -tsükkel (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 / (ruut (S / n) *.0625 *.001)); M = 0; Mp = 0; S = 0; Sp = 0; } // joonistage SNR -id ühele graafikule (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Seeria.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Seeria.println (snrDAC ); }} tühine silmus (tühine) {}

3. samm: integraalne mittelineaarsus ja diferentsiaalne mittelineaarsus

Integraalne mittelineaarsus ja diferentsiaalne mittelineaarsus
Integraalne mittelineaarsus ja diferentsiaalne mittelineaarsus

Integreeritud mittelineaarsus mõõdab ligikaudu seda, kui palju kõrvalekaldeid on teie DAC väljundpinge ja sirgjoone vahel. Mida suurem see on, seda hullem see on…

Diferentsiaalne mittelineaarsus on ligikaudne näitaja, kui palju erineb täheldatud pinge muutus (ühelt koodilt teisele) sirgjoonelt oodatavast.

Siinsed tulemused olid tõesti huvitavad. Esiteks on mõlemal viga alla 0,5 lbs (8-bitise eraldusvõimega), mis on hea, kuid PWM-il on palju parem integraalne lineaarsus. Mõlemal on võrreldav erinev mittelineaarsus, kuid ESP32 DAC -l on väga imelikke naelu. Veelgi enam, PWM -meetodil on vigadele teatud struktuur. Põhimõtteliselt ületab ja lööb see vaheldumisi õiget pinget.

Ma kahtlustan, et see on imelik ümardamisviga selles, kuidas ESP32-l 8-bitine PWM-signaal toodetakse.

Üks viis selle parandamiseks on PWM -iga kiiresti kahe külgneva koodi (nt 128, 129) vahel liikumine. Analoog -madalpääsfiltri korral on saadud vead keskmiselt nullini. Simuleerisin seda tarkvaras ja tõepoolest kadusid kõik vead. Nüüd on PWM-meetodil lineaarsus, mis on täpne 16-bitisele!

Allpool on andmete genereerimiseks vajalik kood. Väljund kuvatakse jadamonitoril.csv -vormingus. Lihtsalt kopeerige see tekstifaili edasiseks töötlemiseks.

#kaasake

#kaasake Adafruit_ADS1115 reklaame; / * Kasutage seda 16-bitise versiooni puhul */ int16_t adc0; tühine seadistus (tühine) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x võimendus +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Oodatud, täheldatud"); ledcWrite (0, 2); viivitus (3000); jaoks (int i = 2; i <255; i ++) {ledcWrite (0, i); viivitus (100); adc0 = ads.readADC_SingleEnded (0); oodatav ujuk = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print (eeldatav); Serial.print (","); Serial.println (adc0); }} tühine silmus (tühine) {}

4. samm: ribalaius

Ribalaius
Ribalaius

Ma määratlen ribalaiuse siin sagedusena, millega DAC väljund langeb 3dB võrra. See on kokkulepe ja teatud määral meelevaldne. Näiteks 6dB punktis väljastab DAC endiselt signaali, mille amplituud on ainult ~ 50%.

Selle mõõtmiseks edastame DAC -ist ADC -sse üha sagedamini siinuslaineid ja mõõdame nende standardhälvet. Pole üllatav, et 3dB punkt on sagedusel 30 Hz (1/(2*pi*5000*1e-6)).

ESP32 suudab teha 1 megaproovi sekundis. See on ESP32 praktiline võit. Selle amplituud ei vähene 100 Hz ribalaiuse testpiirkonnas üldse.

Allolev kood võimaldab testida PWM DAC ribalaiust.

#kaasake

#kaasake Adafruit_ADS1115 reklaame; / * Kasutage seda 16-bitise versiooni puhul */ int16_t adc0; int16_t adc1; void setup (void) {float M; ujuk Mp = 0; ujuk S = 0; ujuk Sp = 0; Seriaalne algus (115200); ads.setGain (GAIN_ONE); // 1x võimendus +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); viivitus (5000); Serial.println ("Sagedus, amplituud"); jaoks (int i = 1; i <100; i ++) {allkirjata pikk algus = millis (); allkirjata pikk T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; ujuki norm; samas ((T - algus) <1000) {int out = 24 * sin (2 * PI * i * (T - algus) / 1000,0) + 128; ledcWrite (0, välja); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } kui (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Seeria.println (sqrt (S / k) / norm, 3); k = 0; }} tühine silmus (tühine) {}

Ja see kood testib ESP32 ribalaiust. Eemaldage kindlasti kondensaator, vastasel juhul on tulemused mõlema meetodi puhul samad.

#kaasake

#kaasake Adafruit_ADS1115 reklaame; / * Kasutage seda 16-bitise versiooni puhul */ int16_t adc0; int16_t adc1; void setup (void) {float M; ujuk Mp = 0; ujuk S = 0; ujuk Sp = 0; Seriaalne algus (115200); ads.setGain (GAIN_ONE); // 1x võimendus +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); viivitus (5000); Serial.println ("Sagedus, amplituud"); jaoks (int i = 1; i <100; i ++) {allkirjata pikk algus = millis (); allkirjata pikk T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; ujuki norm; samas ((T - algus) <1000) {int out = 24 * sin (2 * PI * i * (T - algus) / 1000,0) + 128; dacWrite (25, välja); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } kui (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Seeria.println (sqrt (S / k) / norm, 3); k = 0; }} tühine silmus (tühine) {}

5. samm: mõtete sulgemine

Uus DAC -disain võidab lineaarsuse ja müra osas, kuid kaotab ribalaiuse. Sõltuvalt teie rakendusest võib üks neist indeksitest olla olulisem kui teine. Nende testimisprotseduuridega peaksite saama selle otsuse objektiivselt teha!

Samuti arvan, et tasub siinkohal märkida, et kuna PWM-väljund on madala müratasemega, peaks erakordse lineaarsusega olema võimalik PWM-väljundiga konstrueerida palju suurema eraldusvõimega DAC (võib-olla isegi 16-bitine täpsus). See võtab natuke tööd. Seniks jätan hüvasti!

Soovitan: