Përmbajtje:

Si të bëni dhe provoni një DAC më të mirë me ESP32: 5 hapa
Si të bëni dhe provoni një DAC më të mirë me ESP32: 5 hapa

Video: Si të bëni dhe provoni një DAC më të mirë me ESP32: 5 hapa

Video: Si të bëni dhe provoni një DAC më të mirë me ESP32: 5 hapa
Video: КАК НАСТРОИТЬ L4D2 2024, Nëntor
Anonim
Si të bëni dhe provoni një DAC më të mirë me ESP32
Si të bëni dhe provoni një DAC më të mirë me ESP32
Si të bëni dhe provoni një DAC më të mirë me ESP32
Si të bëni dhe provoni një DAC më të mirë me ESP32

ESP32 ka 2 konvertues dixhital në analoge 8-bitësh (DAC). Këto DAC na lejojnë të prodhojmë tensione arbitrare brenda një diapazoni të caktuar (0-3.3V) me 8 bit rezolucion. Në këtë Instructable, unë do t'ju tregoj se si të ndërtoni një DAC dhe të karakterizoni performancën e tij, si dhe ta krahasoni atë me ESP32 DAC. Indekset e performancës që do të shikoj përfshijnë

  • Niveli i zhurmes
  • Gjerësia e brezit
  • Jo lineariteti integral
  • Jolineariteti diferencial

Për të testuar këta tregues do të përdor ADS1115.

Importantshtë e rëndësishme të theksohet se vlerësimi juaj për të gjithë këta tregues do të jetë po aq i saktë sa pajisja juaj e referencës (në këtë rast ADS115). Për shembull, ADS115 nuk ka saktësi 16-bit kur është fjala për kompensimin dhe rritjen e tensionit të tij. Këto gabime mund të jenë deri në 0.1%. Për shumë sisteme, këto gabime mund të injorohen kur saktësia absolute është shqetësuese e kufizuar.

Furnizimet

  • ADS1115
  • Bordi ESP32
  • dërrasë buke
  • telat e kërcyesit
  • Rezistencë 5 kOhm
  • 1 kondensator qeramike mikro-Farad

Hapi 1: Shtrimi i tabelës së bukës

Shtrimi i tabelës së bukës
Shtrimi i tabelës së bukës

Lidhni kunjat e mëposhtëm

Midis ESP32 dhe ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Në ADS1115

ADDR GND (ADS115)

Duke bërë DAC

Ka shumë mënyra për të bërë një DAC. Më e thjeshta është të filtroni një sinjal PWM me një rezistencë dhe një kondensator. Mund të kisha shtuar një op-amp këtu si tampon, por doja t'i mbaja gjërat të thjeshta. Ky dizajn është i thjeshtë dhe i lirë për t’u zbatuar me çdo mikrokontrollues që mbështet PWM. Unë nuk do të kaloj nëpër teorinë e dizajnit këtu (google PWM DAC).

Thjesht lidhni rezistencën GPIO255 KOhm 1 microFarad Capacitor gnd

Tani lidhni një tel kërcyes nga pika ku rezistenca takon kondensatorin në A0 në ADS115.

Hapi 2: Vlerësoni sinjalin në nivelin e zhurmës

Vlerësoni sinjalin në nivelin e zhurmës
Vlerësoni sinjalin në nivelin e zhurmës

Për të vlerësuar nivelin e zhurmës, thjesht ekzekutoni skriptin më poshtë. Për ta vlerësuar këtë, ne thjesht e lëmë DAC -në në një vlerë fikse dhe matim sesi tensioni luhatet me kalimin e kohës.

Për shkak të modelit të DAC, zhurma do të jetë më e madhe kur sinjali PWM është në ciklin e punës 50%. Prandaj këtu do ta vlerësojmë. Ne gjithashtu do të vlerësojmë ESP32 në të njëjtin nivel sinjali. Ne gjithashtu do të filtrojmë ESP32 DAC me të njëjtin filtër me kalim të ulët në mënyrë që ta bëjmë matjen të krahasueshme.

Për mua rezultati ishte i qartë. Dizajni PWM kishte> 6dB SNR më të mirë (kjo është 2 herë më mirë). Një fitore e qartë për DAC -në e re. Një ngatërrim i vogël është se ka filtra të integruar në ADC të cilët definitivisht po rrisin SNR. Pra, vlerat absolute mund të jenë të vështira për t'u interpretuar. Nëse do të kisha përdorur një filtër të rendit të dytë, ky nuk do të ishte rasti.

Gjithsesi kodi është më poshtë

#përfshi

#përfshi reklamat e Adafruit_ADS1115; // biblioteka adafruit për adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Filloni reklamat seriale set. Gain (GAIN_TWO); // 2x fitim +/- 2.048V 1 bit = 0.0625mV reklama.fillo (); // fillo adc float M = 0; // nota mesatare fillestare Mp = 0; // previouos mesatarja noton S = 0; // Varianca fillestare noton Sp = 0; // varianca e mëparshme const int reps = 500; // numri i përsëritjeve int n = 256; // numri i mostrave ledcSetup (0, 25000, 8); // vendos pwm frequecny = 25000 Hz në rezolucion 8 bit të ledcAttachPin (25, 0); // vendos pwm në pin 25 ledcWrite (0, 128); // vendoseni në gjysmë cikli të funksionimit (zhurma më e madhe) vonesë (3000); // pres për kohën e zgjidhjes noton snrPWM [përsëritje]; // grup i snrs për PWM float snrDAC [përsëritje]; // grup i snrs për DAC për (int i = 0; i <përsërit; i ++) {// lak mbi repititions për (int k = 1; k <(n+1); k ++) {// lak mbi mostrat adc0 = ads.readADC_SingleEnded (0); // merrni lexim M = Mp + (adc0 - Mp) / k; // llogarit mesataren e rrotullimit Mp = M; // vendosni mesataren e mëparshme S = Sp + (adc0 - Mp) * (adc0 - M); // llogarit variancën e rrotullimit Sp = S; // vendos variancën e mëparshme} // snr në dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // rivendos vlerat M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // shkëput PWM nga kunja 25 dacWrite (25, 128); // shkruaj në DAC vonesë (3000); // prisni që të vendoseni për (int i = 0; i <përsërit; i ++) {// njësoj si laku PWM për (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; } // vizatoni SNR -të në një grafik për (int i = 1; i <përsërit; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} lak void (i pavlefshëm) {}

Hapi 3: Jolineariteti integral dhe jolineariteti diferencial

Jolineariteti integral dhe jolineariteti diferencial
Jolineariteti integral dhe jolineariteti diferencial

Jolineariteti integral është një masë e përafërsisht sa devijimi ekziston midis tensionit tuaj të daljes DAC dhe një linje të drejtë. Sa më e madhe të jetë aq më keq është…

Jolineariteti diferencial është një masë përafërsisht se sa ndryshimi i vërejtur në tension (nga një kod në tjetrin) devijon nga ajo që do të pritej nga një vijë e drejtë.

Rezultatet këtu ishin vërtet interesante. Para së gjithash, të dy kanë më pak se 0.5lsb gabim (me rezolucion 8-bit) që është i mirë, por PWM ka linearitet integral shumë më të mirë. Të dy kanë jolinearitet diferencial të krahasueshëm, por ESP32 DAC ka disa thumba shumë të çuditshme. Për më tepër, metoda PWM ka një strukturë të gabimeve. Në thelb ajo tejkalon dhe nënvlerëson tensionin e duhur në mënyrë alternative.

Dyshimi im është se ky është një gabim i çuditshëm i rrumbullakimit në mënyrën se si prodhohet një sinjal 8-bit PWM në ESP32.

Një mënyrë për të korrigjuar këtë është të lëvizni me shpejtësi midis dy kodeve ngjitur (p.sh. 128, 129) me PWM. Me një filtër analog të kalimit të ulët, gabimet që rezultojnë do të jenë mesatarisht në zero. Unë e simulova këtë në softuer dhe me të vërtetë të gjitha gabimet u zhdukën. Tani metoda PWM ka linearitet që është i saktë në 16-bit!

Kushdo që kodi për të gjeneruar të dhënat është më poshtë. Dalja do të jetë në monitorin serik në formatin.csv. Thjesht kopjoni atë në një skedar teksti për përpunim të mëtejshëm.

#përfshi

#përfshi reklamat Adafruit_ADS1115; / * Përdoreni këtë për versionin 16-bit */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x fitim +/- 2.048V 1 bit = 1mV 0.0625mV reklama.fillo (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("E pritshme, e vëzhguar"); ledcWrite (0, 2); vonesë (3000); për (int i = 2; i <255; i ++) {ledcWrite (0, i); vonesë (100); adc0 = ads.readADC_SingleEnded (0); noti i pritur = (i / 256.0 * 3.3) / 4.096 * 32767; Serial.print (pritet); Serial.print (","); Serial.println (adc0); }} lak void (i pavlefshëm) {}

Hapi 4: Gjerësia e brezit

Gjerësia e brezit
Gjerësia e brezit

Unë do të përcaktoj gjerësinë e brezit si këtu si frekuencën në të cilën prodhimi i DAC bie me 3dB. Kjo është një konventë dhe, deri diku, arbitrare. Për shembull, në pikën 6dB, DAC do të japë akoma një sinjal që do të jetë vetëm amplituda ~ 50%.

Për të matur këtë ne thjesht kalojmë valët sinusale me një frekuencë në rritje nga DAC në ADC dhe matim devijimin e tyre standard. Nuk është për t'u habitur, pika 3dB është në 30Hz (1/(2*pi*5000*1e-6)).

ESP32 mund të bëjë 1 Mega mostër për sekondë. Kjo është një fitore e ulët për ESP32. Amplituda e tij nuk kalbet fare në rajonin e testimit të gjerësisë së brezit 100Hz.

Kodi më poshtë mund të testojë gjerësinë e brezit PWM DAC.

#përfshi

#përfshi reklamat Adafruit_ADS1115; / * Përdoreni këtë për versionin 16-bit */ int16_t adc0; int16_t adc1; void setup (void) {float M; noton Mp = 0; noton S = 0; noton Sp = 0; Serial.filloj (115200); ads.setGain (GAIN_ONE); // 1x fitim +/- 4.096V 1 bit = 2mV 0.125mV reklama.fillo (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); vonesa (5000); Serial.println ("Frekuenca, Amplituda"); për (int i = 1; i <100; i ++) {nisje e gjatë e panënshkruar = millis (); pa shenjë e gjatë T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma notuese; ndërsa ((T - fillimi) <1000) {int out = 24 * sin (2 * PI * i * (T - fillimi) / 1000.0) + 128; ledcWrite (0, jashtë); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } nëse (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / normë, 3); k = 0; }} lak void (i pavlefshëm) {}

Dhe ky kod do të testojë gjerësinë e brezit ESP32. Sigurohuni që të hiqni kondensatorin ose rezultatet do të jenë të njëjta për të dyja metodat.

#përfshi

#përfshi reklamat Adafruit_ADS1115; / * Përdoreni këtë për versionin 16-bit */ int16_t adc0; int16_t adc1; void setup (void) {float M; noton Mp = 0; noton S = 0; noton Sp = 0; Serial.filloj (115200); ads.setGain (GAIN_ONE); // 1x fitim +/- 4.096V 1 bit = 2mV 0.125mV reklama.fillo (); vonesa (5000); Serial.println ("Frekuenca, Amplituda"); për (int i = 1; i <100; i ++) {nisje e gjatë e panënshkruar = millis (); pa shenjë e gjatë T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma notuese; ndërsa ((T - fillimi) <1000) {int out = 24 * sin (2 * PI * i * (T - fillimi) / 1000.0) + 128; dacWrite (25, jashtë); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } nëse (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / normë, 3); k = 0; }} lak void (i pavlefshëm) {}

Hapi 5: Mbyllja e Mendimeve

Dizajni i ri DAC fiton në linearitetin dhe zhurmën, por humbet në gjerësinë e brezit. Në varësi të aplikimit tuaj, njëri prej këtyre indekseve mund të jetë më i rëndësishëm se tjetri. Me këto procedura testimi, duhet të jeni në gjendje të merrni objektivisht atë vendim!

Gjithashtu, mendoj se ia vlen të theksohet këtu se për shkak se dalja PWM është me zhurmë të ulët, me linearitet të jashtëzakonshëm duhet të jetë e mundur të ndërtohet një DAC me rezolucion shumë më të lartë me daljen PWM (ndoshta edhe saktësi 16-bit). Kjo do të marrë pak punë. Deri atëherë, ju përgëzoj!

Recommended: