Cuprins:
- Provizii
- Pasul 1: așezarea panoului de calcul
- Pasul 2: evaluați nivelul semnalului la zgomot
- Pasul 3: neliniaritatea integrală și neliniaritatea diferențială
- Pasul 4: Lățime de bandă
- Pasul 5: închiderea gândurilor
Video: Cum să faci și să testezi un DAC mai bun cu ESP32: 5 pași
2024 Autor: John Day | [email protected]. Modificat ultima dată: 2024-01-30 11:41
ESP32 are 2 convertoare digitale-analogice pe 8 biți (DAC). Aceste DAC-uri ne permit să producem tensiuni arbitrare într-un anumit interval (0-3,3V) cu 8 biți de rezoluție. În acest Instructable, vă voi arăta cum să construiți un DAC și să-i caracterizez performanța, precum și să-l compar cu ESP32 DAC. Indicii de performanță pe care îi voi analiza includ
- Nivel de zgomot
- Lățime de bandă
- Neliniaritatea integrală
- Neliniaritatea diferențială
Pentru a testa acești indici, voi folosi ADS1115.
Este important să rețineți că evaluarea tuturor acestor indici va fi la fel de exactă ca dispozitivul dvs. de referință (în acest caz ADS115). De exemplu, ADS115 nu are precizie pe 16 biți când vine vorba de decalajul și câștigul său de tensiune. Aceste erori pot ajunge la 0,1%. Pentru multe sisteme, aceste erori pot fi ignorate atunci când precizia absolută este de îngrijorare limitată.
Provizii
- ADS1115
- Placa ESP32
- panou de masă
- fire jumper
- Rezistor de 5 kOhm
- 1 condensator ceramic micro-Farad
Pasul 1: așezarea panoului de calcul
Sârmați următorii pini
Între ESP32 și ADS1115
3v3 VDD
GND GND
GPIO22 SCL
GPIO21 SDA
La ADS1115
ADDR GND (ADS115)
Realizarea DAC
Există multe modalități de a crea un DAC. Cea mai simplă este să filtrați low-pass un semnal PWM cu un rezistor și un condensator. Aș fi putut adăuga un op-amp aici ca tampon, dar am vrut să păstrez lucrurile simple. Acest design este simplu și ieftin de implementat cu orice microcontroler care acceptă PWM. Nu voi trece prin teoria proiectării aici (google PWM DAC).
Doar conectați rezistorul GPIO255 KOhm 1 condensator microFarad gnd
Acum conectați un cablu jumper din punctul în care rezistența întâlnește condensatorul la A0 pe ADS115.
Pasul 2: evaluați nivelul semnalului la zgomot
Pentru a evalua nivelul de zgomot pur și simplu rulați scriptul de mai jos. Pentru a evalua acest lucru, lăsăm pur și simplu DAC la o valoare fixă și măsurăm modul în care tensiunea oscilează în timp.
Datorită designului DAC, zgomotul va fi cel mai mare atunci când semnalul PWM este la 50% ciclu de funcționare. Prin urmare, aici o vom evalua. De asemenea, vom evalua ESP32 la același nivel de semnal. De asemenea, vom filtra ESP32 DAC cu același filtru trece jos, astfel încât să facem măsurarea comparabilă.
Pentru mine rezultatul a fost clar. Designul PWM avea un SNR> 6dB mai bun (de 2 ori mai bun). O victorie clară pentru noul DAC. O ușoară confuzie este că există filtre încorporate în ADC care îmbunătățesc cu siguranță SNR. Deci, valorile absolute pot fi dificil de interpretat. Dacă aș fi folosit un filtru de ordinul doi, nu ar fi cazul.
Oricum codul este mai jos
#include
#include anunțuri Adafruit_ADS1115; // biblioteca adafruit pentru adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Porniți serial ads.setGain (GAIN_TWO); // 2x câștig +/- 2.048V 1 bit = 0.0625mV ads.begin (); // începe adc float M = 0; // float mediu inițial Mp = 0; // previouos înseamnă plutitor S = 0; // floare de variație inițială Sp = 0; // const anterioară varianță rep rep = 500; // numărul de repetiții int n = 256; // numărul de mostre ledcSetup (0, 25000, 8); // setează frecvența pwm = 25000 Hz la 8 biți rezoluție ledcAttachPin (25, 0); // setează pwm pe pinul 25 ledcWrite (0, 128); // setați-l la jumătate din ciclul de funcționare (cel mai mare zgomot) întârziere (3000); // așteptați timpul de decontare float snrPWM [reps]; // matrice de snrs pentru PWM float snrDAC [repetări]; // matrice de snrs pentru DAC pentru (int i = 0; i <reps; i ++) {// bucla peste repetiții pentru (int k = 1; k <(n + 1); k ++) {// bucla peste mostre adc0 = ads.readADC_SingleEnded (0); // obțineți citirea M = Mp + (adc0 - Mp) / k; // calculează media rulantă Mp = M; // setați media anterioară S = Sp + (adc0 - Mp) * (adc0 - M); // calculați varianța de rulare Sp = S; // setați varianța anterioară} // snr în dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // resetează valorile M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // detașează PWM de pinul 25 dacWrite (25, 128); // scrie la întârziere DAC (3000); // așteptați să vă mulțumiți cu (int i = 0; i <reps; i ++) {// la fel ca bucla PWM pentru (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; } // trasați SNR-uri pe un grafic pentru (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} bucla void (nul) {}
Pasul 3: neliniaritatea integrală și neliniaritatea diferențială
Neliniaritatea integrală este o măsură a cât de multă deviație există între tensiunea de ieșire DAC și o linie dreaptă. Cu cât este mai mare, cu atât este mai rău …
Neliniaritatea diferențială este o măsură a cât de mult deviază modificarea observată a tensiunii (de la un cod la altul) de la ceea ce s-ar aștepta de la o linie dreaptă.
Rezultatele aici au fost cu adevărat interesante. În primul rând, ambele au o eroare mai mică de 0,5 lb (la o rezoluție de 8 biți), ceea ce este bun, dar PWM are o linearitate integrală mult mai bună. Ambele au neliniaritate diferențială comparabilă, dar ESP32 DAC are niște vârfuri foarte ciudate. Mai mult, metoda PWM are o anumită structură a erorilor. În esență, depășește și depășește tensiunea corectă într-un mod alternativ.
Suspectul meu este că aceasta este o eroare de rotunjire ciudată în modul în care un semnal PWM pe 8 biți este produs pe ESP32.
O modalitate de a corecta acest lucru este de a parcurge rapid între două coduri adiacente (de exemplu 128, 129) cu PWM. Cu un filtru analog low-pass, erorile rezultate vor fi la zero. Am simulat acest lucru în software și într-adevăr toate erorile au dispărut. Acum metoda PWM are o linearitate care este precisă la 16 biți!
Oricine codul care generează datele este mai jos. Ieșirea va fi pe monitorul serial în format.csv. Doar copiați-l într-un fișier text pentru procesare ulterioară.
#include
#include anunțuri Adafruit_ADS1115; / * Utilizați acest lucru pentru versiunea pe 16 biți * / int16_t adc0; configurare nulă (nulă) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x câștig +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println („Așteptat, observat”); ledcWrite (0, 2); întârziere (3000); for (int i = 2; i <255; i ++) {ledcWrite (0, i); întârziere (100); adc0 = ads.readADC_SingleEnded (0); float expected = (i / 256.0 * 3.3) / 4.096 * 32767; Serial.print (așteptat); Serial.print (","); Serial.println (adc0); }} bucla void (nul) {}
Pasul 4: Lățime de bandă
Voi defini lățimea de bandă aici ca frecvența la care ieșirea DAC scade cu 3dB. Aceasta este o convenție și, într-o anumită măsură, arbitrară. De exemplu, la punctul 6dB, DAC va emite în continuare un semnal, acesta va fi doar ~ 50% amplitudine.
Pentru a măsura acest lucru, trecem pur și simplu unde sinusoidale la o frecvență crescândă de la DAC la ADC și măsurăm abaterea lor standard. În mod surprinzător, punctul 3dB este la 30Hz (1 / (2 * pi * 5000 * 1e-6)).
ESP32 poate face 1 Mega probă pe secundă. Aceasta este o victorie simplă pentru ESP32. Amplitudinea sa nu se descompune deloc în regiunea de testare a lățimii de bandă de 100Hz.
Codul de mai jos poate testa lățimea de bandă PWM DAC.
#include
#include anunțuri Adafruit_ADS1115; / * Utilizați acest lucru pentru versiunea pe 16 biți * / int16_t adc0; int16_t adc1; void setup (void) {float M; plutitor Mp = 0; plutitor S = 0; plutitor Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x câștig +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); întârziere (5000); Serial.println ("Frecvență, amplitudine"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); nesemnat lung T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma float; 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; }} bucla void (nul) {}
Și acest cod va testa lățimea de bandă ESP32. Asigurați-vă că îndepărtați condensatorul sau rezultatele vor fi aceleași pentru ambele metode.
#include
#include anunțuri Adafruit_ADS1115; / * Utilizați acest lucru pentru versiunea pe 16 biți * / int16_t adc0; int16_t adc1; void setup (void) {float M; plutitor Mp = 0; plutitor S = 0; plutitor Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x câștig +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); întârziere (5000); Serial.println ("Frecvență, amplitudine"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); nesemnat lung T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma float; 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; }} bucla void (nul) {}
Pasul 5: închiderea gândurilor
Noul design DAC câștigă pe liniaritate și zgomot, dar pierde pe lățimea de bandă. În funcție de aplicația dvs., unul dintre acești indici poate fi mai important decât celălalt. Cu aceste proceduri de testare, ar trebui să puteți lua în mod obiectiv această decizie!
De asemenea, cred că merită să subliniez aici că, deoarece ieșirea PWM are un zgomot redus, cu o liniaritate excepțională, ar trebui să fie posibil să se construiască un DAC cu rezoluție mult mai mare cu ieșirea PWM (poate chiar o precizie pe 16 biți). Asta o să meargă puțin. Până atunci, ți-l adjud!
Recomandat:
IoT cu bandă îngustă: iluminarea și măsurarea inteligentă deschid calea către un ecosistem mai bun și mai sănătos: 3 pași
IoT cu bandă îngustă: iluminatul inteligent și măsurarea deschid calea către un ecosistem mai bun și mai sănătos: automatizarea și-a găsit drumul în aproape fiecare sector. Începând de la producție până la asistență medicală, transport și lanțul de aprovizionare, automatizarea a văzut lumina zilei. Ei bine, toate acestea sunt, fără îndoială, atrăgătoare, dar există una care pare
Cultivarea mai multor salată în spațiu mai mic sau Cultivarea salatei în spațiu, (mai mult sau mai puțin) .: 10 pași
Cultivarea mai multor salată în spațiu mai mic sau … Cultivarea salată în spațiu, (mai mult sau mai puțin). Nu aș putea fi mai încântat să proiectez pentru producția de culturi spațiale și să postez primul meu Instructable. Pentru a începe, concursul ne-a cerut
Steadicam solid / Steadycam sub 20 $ GoPro, Dslr, Vdslr cel mai ieftin și mai bun Steadicam pe instrumente: 8 pași (cu imagini)
Solid Steadicam / Steadycam Sub 20 $ GoPro, Dslr, Vdslr cel mai ieftin și mai bun Steadicam pe instrumente: Pentru a construi o nevoie de steadicam1. Bucată plană de tablă cu o lungime de 1 m și o lățime de 30 mm. Mânerul burghiului3. Cheie cu soclu 3/8 inch4. Șurub șaibă 28mm - 13 buc Rulment cu bile, lățime interioară de 12 mm Cork mat7. Buton cu șurub M6 Articulație cardanică
Un ghid pentru cel mai bun și cel mai sigur freeware existent (colaborare): 9 pași
Un ghid pentru cel mai bun și cel mai sigur freeware existent (colaborare):
ACTUALIZAT !!!! Rapid și ușor WIFI Antena Signal Booster, care este mai bun și mai rapid decât hârtia !!!: 9 pași
ACTUALIZAT !!!! Rapid și ușor WIFI Antenna Signal Booster, care este mai bun și mai rapid decât hârtia !!!: Un nou swing pe o idee veche pentru îmbunătățirea semnalului WIFI