Kazalo:

Kako narediti in preizkusiti boljši DAC z ESP32: 5 korakov
Kako narediti in preizkusiti boljši DAC z ESP32: 5 korakov

Video: Kako narediti in preizkusiti boljši DAC z ESP32: 5 korakov

Video: Kako narediti in preizkusiti boljši DAC z ESP32: 5 korakov
Video: Маленький лисенок вышел к людям за помощью 2024, November
Anonim
Kako narediti in preizkusiti boljši DAC z ESP32
Kako narediti in preizkusiti boljši DAC z ESP32
Kako narediti in preizkusiti boljši DAC z ESP32
Kako narediti in preizkusiti boljši DAC z ESP32

ESP32 ima 2 8-bitna digitalno-analogna pretvornika (DAC). Ti DAC-ji nam omogočajo izdelavo poljubnih napetosti v določenem območju (0-3,3 V) z ločljivostjo 8 bitov. V tem navodilu vam bom pokazal, kako sestaviti DAC in opisati njegovo delovanje ter ga primerjati z DSP ESP32. Indeksi uspešnosti, ki jih bom pregledal, vključujejo

  • Stopnja hrupa
  • Pasovna širina
  • Celostna nelinearnost
  • Diferencialna nelinearnost

Za testiranje teh indeksov bom uporabil ADS1115.

Pomembno je omeniti, da bo vaša ocena vseh teh indeksov natančna le kot vaša referenčna naprava (v tem primeru ADS115). Na primer, ADS115 nima 16-bitne natančnosti, ko gre za odmik in ojačanje napetosti. Te napake so lahko do 0,1%. Pri mnogih sistemih je mogoče te napake prezreti, če je absolutna natančnost omejena.

Zaloge

  • ADS1115
  • Plošča ESP32
  • deska
  • mostične žice
  • 5 kOhm upor
  • 1 mikro-Farad keramični kondenzator

1. korak: Polaganje ploščice

Polaganje ploščice
Polaganje ploščice

Ožičite naslednje zatiče

Med ESP32 in ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Na ADS1115

ADDR GND (ADS115)

Izdelava DAC -a

Obstaja veliko načinov za izdelavo DAC -a. Najenostavnejše je nizkoprepustni filter PWM signala z uporom in kondenzatorjem. Tu bi lahko dodal op-amp kot vmesnik, vendar bi želel, da so stvari preproste. Ta zasnova je preprosta in poceni za izvedbo s katerim koli mikrokrmilnikom, ki podpira PWM. Tu ne bom šel skozi teorijo oblikovanja (google PWM DAC).

Samo priključite GPIO255 KOhm upor 1 microFarad kondenzator gnd

Zdaj priključite mostično žico od točke, kjer se upor sreča s kondenzatorjem na A0 na ADS115.

2. korak: Ocenite signal do ravni hrupa

Ocenite signal do ravni hrupa
Ocenite signal do ravni hrupa

Če želite oceniti raven hrupa, preprosto zaženite spodnji skript. Za oceno tega preprosto pustimo DAC pri fiksni vrednosti in izmerimo, kako napetost s časom niha.

Zaradi zasnove DAC -a bo hrup največji, ko je signal PWM pri 50% obratovalnem ciklu. Zato ga bomo tukaj ocenili. Na tej isti ravni signala bomo ocenili tudi ESP32. ESP32 DAC bomo filtrirali tudi z istim nizkoprepustnim filtrom, da bo meritev primerljiva.

Zame je bil rezultat jasen. Zasnova PWM je imela> 6dB boljši SNR (to je 2 -krat boljši). Jasna zmaga za nov DAC. Nekoliko moteče je, da so v ADC vgrajeni filtri, ki zagotovo povečujejo SNR. Zato je absolutne vrednosti morda težko razlagati. Če bi uporabil filter drugega reda, to ne bi bilo tako.

Kakorkoli, koda je spodaj

#vključi

#vključi oglase Adafruit_ADS1115; // knjižnica adafruit za adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Zaženi serijski ads.setGain (GAIN_TWO); // 2x ojačanje +/- 2.048V 1 bit = 0,0625mV ads.begin (); // začnite adc float M = 0; // začetno povprečno plavajoče Mp = 0; // predhodno povprečno plavajoče S = 0; // začetni plovec variacije Sp = 0; // prejšnja varianca const int reps = 500; // število ponovitev int n = 256; // število vzorcev ledcSetup (0, 25000, 8); // nastavite pwm frequecny = 25000 Hz pri ločljivosti 8 bitov ledcAttachPin (25, 0); // nastavimo pwm na pin 25 ledcWrite (0, 128); // nastavimo na zamik pol delovnega cikla (največji hrup) (3000); // čakanje na poravnavo časa float snrPWM [ponovitve]; // niz snrs za PWM float snrDAC [ponovitve]; // matrika snrs za DAC za (int i = 0; i <reps; i ++) {// zanka nad ponovitvami za (int k = 1; k <(n+1); k ++) {// zanka nad vzorci adc0 = ads.readADC_SingleEnded (0); // dobimo branje M = Mp + (adc0 - Mp) / k; // izračunamo kotalno sredino Mp = M; // nastavimo prejšnjo sredino S = Sp + (adc0 - Mp) * (adc0 - M); // izračunamo varianco valjanja Sp = S; // nastavi prejšnjo varianco} // snr v dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // ponastavimo vrednosti M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // ločimo PWM od zatiča 25 dacWrite (25, 128); // pisanje v DAC zakasnitev (3000); // počakajte, da se zadovolji (int i = 0; i <ponovitve; i ++) {// enako kot zanka PWM 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; } // nanesemo SNR na en graf 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 zanka (void) {}

3. korak: Integralna nelinearnost in diferencialna nelinearnost

Integralna nelinearnost in diferencialna nelinearnost
Integralna nelinearnost in diferencialna nelinearnost

Integralna nelinearnost je merilo za približno odstopanje med vašo izhodno napetostjo DAC -a in ravno črto. Večje kot je, slabše je …

Diferencialna nelinearnost je merilo, koliko približno opažena sprememba napetosti (od ene kode do druge) odstopa od tistega, kar bi pričakovali od ravne črte.

Tu so bili rezultati res zanimivi. Prvič, oba imata napako manj kot 0,5 l / s (pri 8-bitni ločljivosti), kar je dobro, vendar ima PWM veliko boljšo integralno linearnost. Oba imata primerljivo diferencialno nelinearnost, vendar ima ESP32 DAC nekaj zelo čudnih trnov. Še več, metoda PWM ima določeno strukturo napak. V bistvu izmenično presega in podceni pravilno napetost.

Sumim, da je to neka čudna napaka pri zaokroževanju, kako se na ESP32 proizvaja 8-bitni signal PWM.

Eden od načinov, kako to popraviti, je hitro premikanje med dvema sosednjima kodama (npr. 128, 129) s PWM. Pri analognem nizkoprepustnem filtru bodo nastale napake povprečno na nič. To sem simuliral v programski opremi in vse napake so izginile. Zdaj ima metoda PWM linearnost, ki je natančna do 16 bitov!

Kdo za ustvarjanje podatkov je spodaj. Izhod bo na serijskem monitorju v formatu.csv. Preprosto ga kopirajte v besedilno datoteko za nadaljnjo obdelavo.

#vključi

#vključi oglase Adafruit_ADS1115; / * To uporabite za 16-bitno različico */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x ojačanje +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Pričakovano, opaženo"); ledcWrite (0, 2); zamuda (3000); for (int i = 2; i <255; i ++) {ledcWrite (0, i); zamuda (100); adc0 = ads.readADC_SingleEnded (0); pričakovani plovec = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print (pričakovano); Serial.print (","); Serial.println (adc0); }} void zanka (void) {}

4. korak: Pasovna širina

Pasovna širina
Pasovna širina

Tukaj bom opredelil pasovno širino kot frekvenco, pri kateri izhod DAC pade za 3dB. To je konvencija in do neke mere samovoljna. Na primer, na točki 6 dB bo DAC še vedno oddajal signal, le amplituda bo ~ 50%.

Za merjenje preprosto prehajamo sinusne valove z naraščajočo frekvenco od DAC do ADC in merimo njihovo standardno odstopanje. Ni presenetljivo, da je točka 3dB pri 30Hz (1/(2*pi*5000*1e-6)).

ESP32 lahko naredi 1 mega vzorca na sekundo. To je zmaga za ESP32. Njegova amplituda sploh ne propade v testnem območju pasovne širine 100Hz.

Spodnja koda lahko preizkusi pasovno širino PWM DAC.

#vključi

#vključi oglase Adafruit_ADS1115; / * To uporabite za 16-bitno različico */ int16_t adc0; int16_t adc1; void setup (void) {float M; plavajoče Mp = 0; plovec S = 0; plovec Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x ojačanje +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); zamuda (5000); Serial.println ("Frekvenca, amplituda"); za (int i = 1; i <100; i ++) {dolg začetek brez podpisa = millis (); brez podpisa dolg T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plavajoča norma; medtem ko ((T - začetek) <1000) {int out = 24 * sin (2 * PI * i * (T - začetek) / 1000.0) + 128; ledcWrite (0, ven); 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 zanka (void) {}

Ta koda bo preizkusila pasovno širino ESP32. Odstranite kondenzator, sicer bodo rezultati pri obeh metodah enaki.

#vključi

#vključi oglase Adafruit_ADS1115; / * To uporabite za 16-bitno različico */ int16_t adc0; int16_t adc1; void setup (void) {float M; plavajoče Mp = 0; plovec S = 0; plovec Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x ojačanje +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); zamuda (5000); Serial.println ("Frekvenca, amplituda"); za (int i = 1; i <100; i ++) {dolg začetek brez podpisa = millis (); brez podpisa dolg T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plavajoča norma; medtem ko ((T - začetek) <1000) {int out = 24 * sin (2 * PI * i * (T - začetek) / 1000.0) + 128; dacWrite (25, ven); 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 zanka (void) {}

5. korak: Zaključek misli

Nova zasnova DAC zmaga na linearnosti in hrupu, izgubi pa na pasovni širini. Glede na vašo uporabo je eden od teh indeksov lahko pomembnejši od drugega. S temi preskusnimi postopki bi se morali objektivno odločiti!

Prav tako mislim, da je tukaj vredno poudariti, da bi bilo treba zaradi izhoda PWM z nizkim šumom in izjemno linearnostjo z izhodom PWM zgraditi DAC veliko višje ločljivosti (morda celo 16-bitno natančnost). To bo trajalo nekaj dela. Do takrat pa vas želim pozdraviti!

Priporočena: