Sadržaj:

Kako napraviti i testirati bolji DAC pomoću ESP32: 5 koraka
Kako napraviti i testirati bolji DAC pomoću ESP32: 5 koraka

Video: Kako napraviti i testirati bolji DAC pomoću ESP32: 5 koraka

Video: Kako napraviti i testirati bolji DAC pomoću ESP32: 5 koraka
Video: Anja Bla - Nekad i sad 2024, Juli
Anonim
Kako napraviti i testirati bolji DAC pomoću ESP32
Kako napraviti i testirati bolji DAC pomoću ESP32
Kako napraviti i testirati bolji DAC pomoću ESP32
Kako napraviti i testirati bolji DAC pomoću ESP32

ESP32 ima 2 8-bitna digitalno-analogna pretvarača (DAC). Ovi DAC-ovi nam omogućuju da proizvedemo proizvoljne napone unutar određenog raspona (0-3.3V) sa 8 bita rezolucije. U ovom Instructable -u ću vam pokazati kako izgraditi DAC i okarakterizirati njegove performanse, kao i uporediti ga sa ESP32 DAC -om. Indeksi performansi koje ću pogledati uključuju

  • Nivo buke
  • Bandwidth
  • Integralna nelinearnost
  • Diferencijalna nelinearnost

Za testiranje ovih indeksa upotrijebit ću ADS1115.

Važno je napomenuti da će vaša procjena svih ovih indeksa biti točna samo koliko i vaš referentni uređaj (u ovom slučaju ADS115). Na primjer, ADS115 nema 16-bitnu preciznost kada je u pitanju njegov pomak napona i pojačanje. Ove greške mogu iznositi i do 0,1%. Za mnoge sisteme ove greške se mogu zanemariti kada je apsolutna tačnost ograničena briga.

Supplies

  • ADS1115
  • ESP32 ploča
  • matična ploča
  • kratkospojne žice
  • Otpornik od 5 kOhm
  • 1 mikro-Farad keramički kondenzator

Korak 1: Postavljanje tlocrta

Postavljanje Breadboard -a
Postavljanje Breadboard -a

Ožičite sljedeće pinove

Između ESP32 i ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Na ADS1115

ADDR GND (ADS115)

Izrada DAC -a

Postoji mnogo načina za izradu DAC -a. Najjednostavnije je niskopropusni filter PWM signala s otpornikom i kondenzatorom. Mogao sam ovdje dodati op-amp kao međuspremnik, ali želio bih da stvari budu jednostavne. Ovaj dizajn je jednostavan i jeftin za implementaciju sa bilo kojim mikrokontrolerom koji podržava PWM. Neću ovdje prolaziti kroz teoriju dizajna (google PWM DAC).

Samo spojite GPIO255 KOhm otpornik 1 microFarad kondenzator gnd

Sada spojite kratkospojnik sa mjesta gdje se otpornik susreće s kondenzatorom na A0 na ADS115.

Korak 2: Procijenite nivo signala do nivoa buke

Procijenite signal do nivoa buke
Procijenite signal do nivoa buke

Za procjenu nivoa buke jednostavno pokrenite donju skriptu. Da bismo to ocijenili, jednostavno ostavljamo DAC na fiksnoj vrijednosti i mjerimo kako napon oscilira s vremenom.

Zbog dizajna DAC -a, šum će biti najveći kada je PWM signal na radnom ciklusu od 50%. Stoga ćemo je ovdje ocijeniti. Također ćemo procijeniti ESP32 na istom nivou signala. Također ćemo filtrirati ESP32 DAC sa istim niskopropusnim filterom kako bismo mjerenje učinili uporedivim.

Za mene je izlaz bio jasan. Dizajn PWM -a imao je> 6dB bolji SNR (to je 2 puta bolji). Očigledna pobjeda za novi DAC. Jedna mala zabuna je u tome što postoje filteri ugrađeni u ADC koji definitivno poboljšavaju SNR. Dakle, apsolutne vrijednosti može biti teško protumačiti. Da sam koristio filter drugog reda to ne bi bio slučaj.

U svakom slučaju kôd je ispod

#include

#include Adafruit_ADS1115 oglasi; // adafruit biblioteka za adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Pokretanje serijskog ads.setGain (GAIN_TWO); // 2x pojačanje +/- 2.048V 1 bit = 0.0625mV ads.begin (); // započinje adc float M = 0; // početna srednja vrijednost float Mp = 0; // prethodni srednji plovak S = 0; // početni plivajući hod varijacije Sp = 0; // prethodna varijansa const int reps = 500; // broj ponavljanja int n = 256; // broj uzoraka ledcSetup (0, 25000, 8); // postavlja pwm frequecny = 25000 Hz pri rezoluciji 8 bita ledcAttachPin (25, 0); // postavlja pwm na pin 25 ledcWrite (0, 128); // postavimo ga na pola radnog ciklusa (najveća buka) kašnjenje (3000); // čekati na smirivanje vremena float snrPWM [ponavljanja]; // niz snrs za PWM float snrDAC [ponavljanja]; // niz snrs -a za DAC za (int i = 0; i <reps; i ++) {// petlja preko ponavljanja za (int k = 1; k <(n+1); k ++) {// petlja preko uzoraka adc0 = ads.readADC_SingleEnded (0); // očitavanje M = Mp + (adc0 - Mp) / k; // izračunati srednju kotrljajuću vrijednost Mp = M; // postavljamo prethodnu srednju vrijednost S = Sp + (adc0 - Mp) * (adc0 - M); // izračunati varijaciju kotrljanja Sp = S; // postavlja prethodnu varijansu} // snr u dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // resetiranje vrijednosti M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // odvojimo PWM od pina 25 dacWrite (25, 128); // zapisivanje u DAC kašnjenje (3000); // čekamo da se zadovoljimo (int i = 0; i <reps; i ++) {// isto što i PWM petlja za (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; } // iscrtati SNR -ove na jednom grafikonu za (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} void petlja (void) {}

Korak 3: Integralna nelinearnost i diferencijalna nelinearnost

Integralna i linearna nelinearnost
Integralna i linearna nelinearnost

Integralna nelinearnost je mjera otprilike koliko postoji odstupanje između vašeg izlaznog napona DAC -a i ravne linije. Što je ovo veće, to je gore…

Diferencijalna nelinearnost je mjera otprilike koliko opažena promjena napona (od jednog koda do drugog) odstupa od onoga što bi se očekivalo od ravne linije.

Ovdje su rezultati bili zaista zanimljivi. Prije svega, oba imaju grešku manju od 0,5 lbs (pri 8-bitnoj rezoluciji) što je dobro, ali PWM ima mnogo bolju integralnu linearnost. Oba imaju uporedivu diferencijalnu nelinearnost, ali ESP32 DAC ima neke vrlo čudne skokove. Štaviše, PWM metoda ima određenu strukturu grešaka. U suštini naizmjenično nadilazi i podcjenjuje ispravan napon.

Sumnjam da je ovo neka čudna greška zaokruživanja u načinu na koji se 8-bitni PWM signal proizvodi na ESP32.

Jedan od načina da to ispravite je brzo kretanje između dva susjedna koda (npr. 128, 129) pomoću PWM -a. Sa analognim niskopropusnim filterom, rezultirajuće greške će biti prosječne na nulu. Simulirao sam ovo u softveru i zaista su sve greške nestale. Sada PWM metoda ima linearnost koja je tačna do 16 bita!

U nastavku se nalazi bilo koji kôd za generiranje podataka. Izlaz će biti na serijskom monitoru u.csv formatu. Samo ga kopirajte u tekstualnu datoteku za daljnju obradu.

#include

#include Adafruit_ADS1115 oglasi; / * Koristite ovo za 16-bitnu verziju */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x pojačanje +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Očekivano, uočeno"); ledcWrite (0, 2); kašnjenje (3000); for (int i = 2; i <255; i ++) {ledcWrite (0, i); kašnjenje (100); adc0 = ads.readADC_SingleEnded (0); očekivano plutanje = (i / 256.0 * 3.3) / 4.096 * 32767; Serial.print (očekivano); Serial.print (","); Serial.println (adc0); }} void petlja (void) {}

Korak 4: Propusnost

Bandwidth
Bandwidth

Ovdje ću definirati propusnost kao frekvenciju na kojoj izlaz DAC -a opada za 3 dB. Ovo je konvencija i donekle proizvoljna. Na primjer, na točki od 6 dB, DAC će i dalje emitirati signal čija će amplituda biti samo ~ 50%.

Da bismo to izmjerili, jednostavno prosljeđujemo sinusne valove povećanom frekvencijom od DAC -a do ADC -a i mjerimo njihovu standardnu devijaciju. Ne iznenađuje da je 3dB točka na 30Hz (1/(2*pi*5000*1e-6)).

ESP32 može napraviti 1 mega uzorak u sekundi. Ovo je ručna pobjeda za ESP32. Njegova amplituda uopće ne opada u području testiranja propusnosti od 100Hz.

Donji kod može testirati PWM DAC propusnost.

#include

#uključuje oglase Adafruit_ADS1115; / * Koristite ovo za 16-bitnu verziju */ int16_t adc0; int16_t adc1; void setup (void) {float M; plovak Mp = 0; plovak S = 0; plovak Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x pojačanje +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); kašnjenje (5000); Serial.println ("Frekvencija, amplituda"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); bez potpisa dugo T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; float norma; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, izlaz); 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) {norma = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norma, 3); k = 0; }} void petlja (void) {}

Ovaj kod će testirati ESP32 propusnost. Uklonite kondenzator ili će rezultati biti isti za obje metode.

#include

#uključuje oglase Adafruit_ADS1115; / * Koristite ovo za 16-bitnu verziju */ int16_t adc0; int16_t adc1; void setup (void) {float M; plovak Mp = 0; plovak S = 0; plovak Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x pojačanje +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); kašnjenje (5000); Serial.println ("Frekvencija, amplituda"); for (int i = 1; i <100; i ++) {dug potpis bez potpisa = millis (); bez potpisa dugo T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; float norma; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, izlaz); 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) {norma = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norma, 3); k = 0; }} void petlja (void) {}

Korak 5: Zatvaranje misli

Novi DAC dizajn pobjeđuje na linearnosti i šumu, ali gubi na propusnosti. Ovisno o vašoj primjeni, jedan od ovih indeksa može biti važniji od drugog. S ovim postupcima testiranja trebali biste biti u mogućnosti objektivno donijeti tu odluku!

Također, mislim da je vrijedno ovdje naglasiti da bi, s obzirom na to da je izlaz PWM nizak šum, uz izuzetnu linearnost, trebalo biti moguće konstruirati DAC mnogo veće rezolucije sa PWM izlazom (možda čak i 16-bitnu preciznost). To će potrajati. Do tada, zbogom!

Preporučuje se: