INHOUDSOPGAWE:

Hoe om 'n beter DAC te maak en te toets met ESP32: 5 stappe
Hoe om 'n beter DAC te maak en te toets met ESP32: 5 stappe

Video: Hoe om 'n beter DAC te maak en te toets met ESP32: 5 stappe

Video: Hoe om 'n beter DAC te maak en te toets met ESP32: 5 stappe
Video: Output DC or AC Voltage using MCP4725 DAC with LCD and PWM to Voltage Converter with Arduino 2024, November
Anonim
Hoe om 'n beter DAC te maak en te toets met ESP32
Hoe om 'n beter DAC te maak en te toets met ESP32
Hoe om 'n beter DAC te maak en te toets met ESP32
Hoe om 'n beter DAC te maak en te toets met ESP32

Die ESP32 het 2 8-bis digitale na analoog omskakelaars (DAC's). Met hierdie DAC's kan ons arbitrêre spannings binne 'n sekere reeks (0-3.3V) produseer met 8 bisse resolusie. In hierdie instruksies sal ek jou wys hoe om 'n DAC te bou en die prestasie daarvan te kenmerk, sowel as om dit te vergelyk met die ESP32 DAC. Die prestasie -indekse waarna ek sal kyk, sluit in

  • Klankvlak
  • Bandwydte
  • Integrale nie -lineariteit
  • Differensiële nie -lineariteit

Om hierdie indekse te toets, sal ek die ADS1115 gebruik.

Dit is belangrik om daarop te let dat u beoordeling van al hierdie indekse net so akkuraat is as u verwysingsapparaat (in hierdie geval die ADS115). Die ADS115 het byvoorbeeld nie 'n 16-bis-presisie as dit kom by die spanningsverset en -versterking nie. Hierdie foute kan tot 0,1%wees. Vir baie stelsels kan hierdie foute geïgnoreer word as absolute akkuraatheid beperkte kommer het.

Voorrade

  • ADS1115
  • ESP32 -bord
  • broodbord
  • springdrade
  • Weerstand van 5 kOhm
  • 1 mikro-Farad keramiek kondensator

Stap 1: Plaas die broodbord

Lê die broodbord uit
Lê die broodbord uit

Draai die volgende penne

Tussen die ESP32 en die ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

By die ADS1115

ADDR GND (ADS115)

Die maak van die DAC

Daar is baie maniere om 'n DAC te maak. Die eenvoudigste is om 'n PWM-sein met 'n weerstand en 'n kapasitor te laatfilter. Ek kon 'n op-amp hier as buffer bygevoeg het, maar wou dinge eenvoudig hou. Hierdie ontwerp is eenvoudig en goedkoop om te implementeer met enige mikrobeheerder wat PWM ondersteun. Ek gaan nie hier deur die teorie van die ontwerp nie (google PWM DAC).

Koppel net GPIO255 KOhm -weerstand 1 microFarad -kondensator gnd

Koppel nou 'n jumperdraad vanaf die punt waar die weerstand die kondensator op A0 op die ADS115 ontmoet.

Stap 2: Beoordeel die sein op die geraasvlak

Beoordeel die sein tot die geraasvlak
Beoordeel die sein tot die geraasvlak

Om die geraasvlak te bepaal, voer eenvoudig die onderstaande script uit. Om dit te bepaal, laat ons die DAC eenvoudig op 'n vaste waarde en meet hoe die spanning mettertyd ossilleer.

As gevolg van die ontwerp van die DAC, sal die geraas die grootste wees as die PWM -sein op 'n 50% -siklus is. Daarom sal ons dit beoordeel. Ons sal ook die ESP32 op dieselfde seinvlak beoordeel. Ons sal ook die ESP32 DAC met dieselfde laagdeurlaatfilter filter om die meting vergelykbaar te maak.

Vir my was die uitset duidelik. Die PWM -ontwerp het> 6dB beter SNR (dit is 2 keer beter). 'N Duidelike oorwinning vir die nuwe DAC. Een klein verwarring is dat daar filters in die ADC ingebou is wat die SNR beslis verbeter. Die absolute waardes is dus moeilik om te interpreteer. As ek 'n tweede-orde filter gebruik het, was dit nie die geval nie.

Die kode is in elk geval hieronder

#insluit

#sluit Adafruit_ADS1115 advertensies in; // adafruit biblioteek vir adc int16_t adc0; // leemte -opstelling (leegte) {Serial.begin (115200); // Begin reeksadvertensies.setGain (GAIN_TWO); // 2x gain +/- 2.048V 1 bit = 0.0625mV ads.begin (); // begin adc float M = 0; // aanvanklike gemiddelde vlot Mp = 0; // previouos beteken vlot S = 0; // aanvanklike afwyking float Sp = 0; // vorige variansie const int reps = 500; // aantal herhalings int n = 256; // aantal monsters ledcSetup (0, 25000, 8); // stel pwm frequecny = 25000 Hz op met 8 bits resolusie ledcAttachPin (25, 0); // stel pwm op pen 25 ledcWrite (0, 128); // stel dit in op 'n halfvertragingssiklus (grootste geraas) vertraging (3000); // wag vir die vestigingstyd float snrPWM [herhalings]; // verskeidenheid snrs vir PWM float snrDAC [herhalings]; // verskeidenheid snrs vir DAC vir (int i = 0; i <reps; i ++) {// loop oor herhalings vir (int k = 1; k <(n+1); k ++) {// loope over monsters adc0 = ads.readADC_SingleEnded (0); // lees M = Mp + (adc0 - Mp) / k; // bereken rollende gemiddelde Mp = M; // stel vorige gemiddelde S = Sp + (adc0 - Mp) * (adc0 - M); // bereken rolafwyking Sp = S; // stel vorige afwyking} // snr in dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // stel waardes M = 0 terug; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // maak PWM los van pen 25 dacWrite (25, 128); // skryf na DAC vertraging (3000); // wag om tevrede te wees met (int i = 0; i <reps; i ++) {// dieselfde as PWM -lus vir (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; } // plot SNR's op een grafiek vir (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} leegte -lus (leegte) {}

Stap 3: Integrale nie -lineariteit en differensiële nie -lineariteit

Integrale nie -lineariteit en differensiële nie -lineariteit
Integrale nie -lineariteit en differensiële nie -lineariteit

Die integrale nie -lineariteit is 'n maatstaf van hoeveel afwyking daar is tussen u DAC -uitgangsspanning en 'n reguitlyn. Hoe groter dit is, hoe erger is dit …

Die differensiële nie -lineariteit is 'n maatstaf van hoeveel die waargenome verandering in die spanning (van een kode na die volgende) afwyk van wat van 'n reguitlyn verwag sou word.

Die resultate hier was regtig interessant. Eerstens het albei minder as 0.5lsb fout (met 'n resolusie van 8 bis), wat goed is, maar die PWM het 'n baie beter integrale lineariteit. Albei het 'n vergelykbare differensiële nie -lineariteit, maar die ESP32 DAC het 'n paar baie vreemde spykers. Boonop het die PWM -metode 'n paar strukture vir die foute. Dit oorskry in wese afwisselend die korrekte spanning.

My vermoede is dat dit 'n vreemde afrondingsfout is in die manier waarop 'n 8-bis PWM-sein op die ESP32 geproduseer word.

Een manier om dit reg te stel, is om vinnig tussen twee aangrensende kodes (bv. 128, 129) met die PWM te skakel. Met 'n analoog laagdeurlaatfilter is die gevolglike foute gemiddeld tot nul. Ek het dit in sagteware gesimuleer en al die foute het verdwyn. Nou het die PWM-metode 'n lineariteit wat akkuraat is tot 16-bis!

Hieronder is die kode om die data te genereer. Die uitset sal op die seriële monitor in.csv -formaat verskyn. Kopieer dit net na 'n tekslêer vir verdere verwerking.

#insluit

#sluit Adafruit_ADS1115 advertensies in; / * Gebruik dit vir die 16-bis weergawe */ int16_t adc0; leemte opstel (leeg) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Verwag, waargeneem"); ledcWrite (0, 2); vertraging (3000); vir (int i = 2; i <255; i ++) {ledcWrite (0, i); vertraging (100); adc0 = ads.readADC_SingleEnded (0); vlot verwag = (i / 256.0 * 3.3) / 4.096 * 32767; Serial.print (verwag); Serial.print (","); Serial.println (adc0); }} leemte lus (leeg) {}

Stap 4: Bandwydte

Bandwydte
Bandwydte

Ek gaan die bandwydte hier definieer as die frekwensie waarop die uitset van die DAC met 3dB daal. Dit is 'n konvensie en tot 'n mate arbitrêr. Byvoorbeeld, op die 6dB punt, sal die DAC steeds 'n sein lewer, dit sal net ~ 50% amplitude wees.

Om dit te meet, gaan ons eenvoudig sinusgolwe by 'n toenemende frekwensie van die DAC na die ADC deur en meet hul standaardafwyking. Dit is nie verbasend dat die 3dB-punt by 30Hz (1/(2*pi*5000*1e-6) is nie.

Die ESP32 kan 1 megamonster per sekonde doen. Dit is 'n praktiese oorwinning vir die ESP32. Die amplitude daarvan verval glad nie in die 100Hz -bandwydte -toetsgebied nie.

Die onderstaande kode kan die PWM DAC -bandwydte toets.

#insluit

#sluit Adafruit_ADS1115 advertensies in; / * Gebruik dit vir die 16-bis weergawe */ int16_t adc0; int16_t adc1; leemte opstel (leeg) {float M; vlot Mp = 0; vlot S = 0; vlot Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); vertraging (5000); Serial.println ("Frekwensie, amplitude"); vir (int i = 1; i <100; i ++) {ongetekende lang begin = millis (); ongetekende lang T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; vlotnorm; terwyl ((T - begin) <1000) {int out = 24 * sin (2 * PI * i * (T - begin) / 1000.0) + 128; ledcWrite (0, uit); adc0 = ads.readADC_SingleEnded (0); M = MP + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } as (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norm, 3); k = 0; }} leegte -lus (leegte) {}

En hierdie kode toets die ESP32 -bandwydte. Maak seker dat u die kapasitor verwyder, anders is die resultate dieselfde vir beide metodes.

#insluit

#sluit Adafruit_ADS1115 advertensies in; / * Gebruik dit vir die 16-bis weergawe */ int16_t adc0; int16_t adc1; leemte opstel (leeg) {float M; vlot Mp = 0; vlot S = 0; vlot Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); vertraging (5000); Serial.println ("Frekwensie, amplitude"); vir (int i = 1; i <100; i ++) {ongetekende lang begin = millis (); ongetekende lang T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; vlotnorm; terwyl ((T - begin) <1000) {int out = 24 * sin (2 * PI * i * (T - begin) / 1000.0) + 128; dacWrite (25, uit); adc0 = ads.readADC_SingleEnded (0); M = MP + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } as (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norm, 3); k = 0; }} leemte lus (leeg) {}

Stap 5: Sluit gedagtes

Die nuwe DAC -ontwerp wen op lineariteit en geraas, maar verloor op bandwydte. Afhangende van u toepassing, kan een van hierdie indekse belangriker wees as die ander. Met hierdie toetsprosedures behoort u die besluit objektief te kan neem!

Ek dink ook dat dit die moeite werd is om hier op te wys dat omdat PWM-uitset lae geraas het, met buitengewone lineariteit dit moontlik sou wees om 'n DAC met 'n veel hoër resolusie met die PWM-uitset te konstrueer (miskien selfs 16-bis presisie). Dit gaan 'n bietjie werk verg. Tot dan groet ek julle!

Aanbeveel: