Turinys:
- Prekės
- 1 žingsnis: Duonos lentos išdėstymas
- 2 žingsnis: įvertinkite signalą iki triukšmo lygio
- 3 žingsnis: integralus netiesiškumas ir diferencialinis netiesiškumas
- 4 žingsnis: pralaidumas
- 5 žingsnis: uždarykite mintis
Video: Kaip sukurti ir išbandyti geresnį DAC naudojant ESP32: 5 žingsniai
2024 Autorius: John Day | [email protected]. Paskutinį kartą keistas: 2024-01-30 10:44
ESP32 turi 2 8 bitų skaitmeninius analoginius keitiklius (DAC). Šie DAC leidžia mums sukurti savavališką įtampą tam tikrame diapazone (0–3,3 V) su 8 bitų skiriamąja geba. Šioje instrukcijoje aš jums parodysiu, kaip sukurti DAC ir apibūdinti jo veikimą, taip pat palyginti jį su ESP32 DAC. Į našumo indeksus, kuriuos apžvelgsiu, yra
- Triukšmo lygis
- Pralaidumas
- Integralus netiesiškumas
- Diferencialinis netiesiškumas
Šiems indeksams išbandyti naudosiu ADS1115.
Svarbu pažymėti, kad visų šių rodiklių įvertinimas bus toks pat tikslus, kaip ir jūsų atskaitos prietaisas (šiuo atveju ADS115). Pavyzdžiui, ADS115 neturi 16 bitų tikslumo, kai kalbama apie įtampos poslinkį ir padidėjimą. Šios klaidos gali siekti 0,1%. Daugelio sistemų atveju šios klaidos gali būti ignoruojamos, kai absoliutus tikslumas kelia nerimą.
Prekės
- ADS1115
- ESP32 lenta
- Bandomoji Lenta
- jungiamieji laidai
- 5 kOhm rezistorius
- 1 mikro Farad keraminis kondensatorius
1 žingsnis: Duonos lentos išdėstymas
Sujunkite šiuos kaiščius
Tarp ESP32 ir ADS1115
3v3 VDD
GND GND
GPIO22 SCL
GPIO21 SDA
ADS1115
ADDR GND (ADS115)
DAC kūrimas
Yra daug būdų, kaip sukurti DAC. Paprasčiausias yra žemo dažnio filtras PWM signalui su rezistoriumi ir kondensatoriumi. Aš galėjau čia pridėti op-amp kaip buferį, bet norėjau, kad viskas būtų paprasta. Šią konstrukciją paprasta ir pigu įgyvendinti su bet kokiu PWM palaikančiu mikrovaldikliu. Čia nesiruošiu nagrinėti dizaino teorijos (google PWM DAC).
Tiesiog prijunkite GPIO255 KOhm rezistorių 1 „microFarad“kondensatorių
Dabar prijunkite trumpąjį laidą nuo taško, kuriame rezistorius susitinka su kondensatoriumi, prie A0 ADS115.
2 žingsnis: įvertinkite signalą iki triukšmo lygio
Norėdami įvertinti triukšmo lygį, tiesiog paleiskite žemiau esantį scenarijų. Norėdami tai įvertinti, mes tiesiog paliekame DAC fiksuotą vertę ir matuojame, kaip laikui bėgant svyruoja įtampa.
Dėl DAC konstrukcijos triukšmas bus didžiausias, kai PWM signalas bus 50% darbinio ciklo. Todėl čia mes jį įvertinsime. Mes taip pat įvertinsime ESP32 tuo pačiu signalo lygiu. Mes taip pat filtruosime ESP32 DAC tuo pačiu žemo dažnio filtru, kad matavimai būtų palyginami.
Man rezultatas buvo aiškus. PWM dizainas turėjo> 6 dB geresnį SNR (tai yra 2 kartus geriau). Aiškus naujo DAC laimėjimas. Viena nedidelė painiava yra ta, kad ADC yra įmontuoti filtrai, kurie neabejotinai pagerina SNR. Taigi absoliučias vertes gali būti sunku interpretuoti. Jei būčiau naudojęs antros eilės filtrą, taip nebūtų.
Bet kokiu atveju kodas yra žemiau
#įtraukti
#įtraukti „Adafruit_ADS1115“skelbimus; // adafruit biblioteka, skirta adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Pradėti serijinius skelbimus.setGain (GAIN_TWO); // 2x stiprinimas +/- 2.048V 1 bitas = 0.0625mV ads.begin (); // start adc float M = 0; // pradinis vidutinis plūdė Mp = 0; // ankstesnis vidutinis plūdė S = 0; // pradinis dispersijos plūdė Sp = 0; // ankstesnė dispersija const int pakartojimai = 500; // pakartojimų skaičius int n = 256; // mėginių skaičius ledcSetup (0, 25000, 8); // nustatyti pwm frequecny = 25000 Hz esant 8 bitų raiškai ledcAttachPin (25, 0); // nustatyti pwm ant 25 kaiščio ledcWrite (0, 128); // nustatyti pusę darbo ciklo (didžiausias triukšmas) uždelsimas (3000); // laukti nusistovėjimo laiko float snrPWM [pakartojimai]; // PWM plūdės snr masyvas snrDAC [pakartojimai]; // DAC „snrs“masyvas, skirtas (int i = 0; i <pakartojimai; i ++) {// ciklas per pakartojimus (int k = 1; k <(n+1); k ++) {// kilpas virš mėginių adc0 = ads.readADC_SingleEnded (0); // gauti skaitymą M = Mp + (adc0 - Mp) / k; // apskaičiuoti riedėjimo vidurkį Mp = M; // nustatyti ankstesnį vidurkį S = Sp + (adc0 - Mp) * (adc0 - M); // skaičiuoti riedėjimo dispersiją Sp = S; // nustatyti ankstesnę dispersiją} // snr dB dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // atstatyti reikšmes M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // atjungti PWM nuo 25 kaiščio dacWrite (25, 128); // rašyti į DAC uždelsimą (3000); // laukti, kol atsiskaitys (int i = 0; i <pakartojimai; i ++) {// tas pats kaip PWM kilpa (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 / (kv. (S / n) *.0625 *.001)); M = 0; Mp = 0; S = 0; Sp = 0; } // brėžti SNR viename grafike, skirtas (int i = 1; i <pakartojimai; i ++) {Serial.print ("PWM_SNR (dB):"); Serijinis atspaudas (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serijinis.println (snrDAC ); }} void loop (void) {}
3 žingsnis: integralus netiesiškumas ir diferencialinis netiesiškumas
Integruotas netiesiškumas yra maždaug matas, kiek yra nukrypimų tarp jūsų DAC išėjimo įtampos ir tiesios linijos. Kuo šis didesnis, tuo blogiau…
Diferencialinis netiesiškumas yra maždaug matas, kiek pastebėtas įtampos pokytis (iš vieno kodo į kitą) nukrypsta nuo to, ko būtų galima tikėtis iš tiesios linijos.
Rezultatai čia buvo tikrai įdomūs. Visų pirma, abu turi mažiau nei 0,5 lsb klaidą (esant 8 bitų skiriamai gebai), o tai yra gerai, tačiau PWM turi daug geresnį vientisumą. Abi turi skirtingą netiesiškumą, tačiau ESP32 DAC turi labai keistų šuolių. Be to, PWM metodas turi tam tikrą klaidų struktūrą. Iš esmės jis kintamai viršija ir sumažina teisingą įtampą.
Įtariu, kad tai keista apvalinimo klaida, kaip ESP32 sukuriamas 8 bitų PWM signalas.
Vienas iš būdų tai ištaisyti yra greitai pereiti tarp dviejų gretimų kodų (pvz., 128, 129) naudojant PWM. Naudojant analoginį žemo dažnio filtrą, klaidų vidurkis bus lygus nuliui. Aš tai imitavau programinėje įrangoje ir visos klaidos išnyko. Dabar PWM metodas turi tiesiškumą, kuris yra tikslus 16 bitų!
Toliau pateikiamas bet koks duomenų generavimo kodas. Išvestis serijiniame monitoriuje bus.csv formatu. Tiesiog nukopijuokite jį į teksto failą tolesniam apdorojimui.
#įtraukti
#įtraukti „Adafruit_ADS1115“skelbimus; / * Naudokite tai 16 bitų versijai */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x stiprinimas +/- 2.048V 1 bitas = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Tikimasi, pastebėtas"); ledcWrite (0, 2); vėlavimas (3000); už (int i = 2; i <255; i ++) {ledcWrite (0, i); vėlavimas (100); adc0 = ads.readADC_SingleEnded (0); tikimasi plūdės = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print (tikimasi); Serial.print (","); Serial.println (adc0); }} void loop (void) {}
4 žingsnis: pralaidumas
Aš čia apibrėžsiu pralaidumą kaip dažnį, kuriuo DAC išvestis sumažėja 3dB. Tai yra susitarimas ir tam tikru mastu savavališkas. Pavyzdžiui, 6 dB taške DAC vis tiek perduos signalą, kurio amplitudė bus tik ~ 50%.
Norėdami tai išmatuoti, mes vis dažniau perduodame sinusines bangas iš DAC į ADC ir matuojame jų standartinį nuokrypį. Nenuostabu, kad 3dB taškas yra 30 Hz dažniu (1/(2*pi*5000*1e-6)).
ESP32 gali atlikti 1 mega mėginį per sekundę. Tai „ESP32“laimėjimas iš rankų. Jo amplitudė visiškai nesumažėja 100 Hz dažnių juostos pločio bandymo srityje.
Žemiau pateiktas kodas gali patikrinti PWM DAC pralaidumą.
#įtraukti
#įtraukti „Adafruit_ADS1115“skelbimus; / * Naudokite tai 16 bitų versijai */ int16_t adc0; int16_t adc1; void setup (void) {float M; plūdė Mp = 0; plūdė S = 0; plūdė Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x padidinimas +/- 4,096V 1 bitas = 2mV 0,125 m skelbimai.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); vėlavimas (5000); Serial.println („Dažnis, amplitudė“); for (int i = 1; i <100; i ++) {unsigned long start = milis (); nepasirašytas ilgas T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plūdės norma; tuo tarpu ((T - pradžia) <1000) {int out = 24 * sin (2 * PI * i * (T - pradžia) / 1000,0) + 128; ledcWrite (0, išėjimas); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } jei (i == 1) {norma = kv. (S / k); } Serijinis atspaudas (i); Serial.print (","); Serijinis.println (kv. (S / k) / norma, 3); k = 0; }} void loop (void) {}
Ir šis kodas patikrins ESP32 pralaidumą. Būtinai nuimkite kondensatorių, nes abiejų metodų rezultatai bus vienodi.
#įtraukti
#įtraukti „Adafruit_ADS1115“skelbimus; / * Naudokite tai 16 bitų versijai */ int16_t adc0; int16_t adc1; void setup (void) {float M; plūdė Mp = 0; plūdė S = 0; plūdė Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x padidinimas +/- 4,096V 1 bitas = 2mV 0,125 m skelbimai.begin (); vėlavimas (5000); Serial.println („Dažnis, amplitudė“); for (int i = 1; i <100; i ++) {unsigned long start = milis (); nepasirašytas ilgas T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; plūdės norma; tuo tarpu ((T - pradžia) <1000) {int out = 24 * sin (2 * PI * i * (T - pradžia) / 1000,0) + 128; dacWrite (25, išėjimas); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } jei (i == 1) {norma = kv. (S / k); } Serijinis atspaudas (i); Serial.print (","); Serijinis.println (kv. (S / k) / norma, 3); k = 0; }} void loop (void) {}
5 žingsnis: uždarykite mintis
Naujasis DAC dizainas laimi tiesiškumu ir triukšmu, bet praranda pralaidumą. Priklausomai nuo jūsų taikymo, vienas iš šių rodiklių gali būti svarbesnis už kitą. Taikydami šias testavimo procedūras, turėtumėte sugebėti objektyviai priimti tokį sprendimą!
Taip pat manau, kad čia verta pažymėti, kad kadangi PWM išvestis yra mažo triukšmo, turint išskirtinį tiesiškumą, turėtų būti įmanoma sukurti daug didesnės skiriamosios gebos DAC su PWM išvestimi (galbūt net 16 bitų tikslumu). Tai užtruks šiek tiek darbo. Iki tol linkiu jums atsisveikinti!
Rekomenduojamas:
Kaip sukurti MP3 grotuvą naudojant LCD naudojant „Arduino“ir „DFPlayer Mini“MP3 grotuvo modulį: 6 žingsniai
Kaip sukurti MP3 grotuvą naudojant skystųjų kristalų ekraną naudojant „Arduino“ir „DFPlayer Mini“MP3 grotuvo modulį: Šiandien mes pagaminsime MP3 grotuvą su LCD, naudodami „Arduino“ir „DFPlayer“mini MP3 grotuvo modulį. Projektas gali nuskaityti MP3 failus SD kortelėje ir gali pristabdyti ir žaisti taip pat, kaip ir prieš 10 metų. Taip pat jame yra linksma ankstesnė ir kita daina
Geresni projektai naudojant PCB: 6 žingsniai
Geresni projektai naudojant PCB: jei praleidote laiko dirbdami su elektronikos projektais, žinote, kaip tai gali būti smagu ir įdomu. Nieko nėra jaudinančio, kaip pamatyti, kaip jūsų grandinė atgyja prieš jūsų akis. Tai tampa dar įdomiau, kai jūsų projektas virsta
Kaip naudoti „Tinkercad“aparatinei įrangai išbandyti ir įdiegti: 5 žingsniai (su paveikslėliais)
Kaip naudoti „Tinkercad“aparatinei įrangai išbandyti ir įdiegti: Grandinės modeliavimas yra metodas, kai kompiuterinė programinė įranga imituoja elektroninės grandinės ar sistemos elgesį. Naujus dizainus galima išbandyti, įvertinti ir diagnozuoti faktiškai nesukūrus grandinės ar sistemos. Grandinės modeliavimas gali būti
Kaip išbandyti ir gauti nemokamus komponentus: 5 žingsniai
Kaip išbandyti ir gauti nemokamų komponentų: kartais jūs neturite pinigų, bet norite sukurti kažką puikaus. čia yra vadovas, kuris jums padės
Kaip sukurti autonominį krepšinio žaidimo robotą, naudojant „IRobot“, sukurti kaip pagrindą: 7 žingsniai (su paveikslėliais)
Kaip sukurti autonominį krepšinio žaidimo robotą naudojant „IRobot“sukurti kaip pagrindą: tai mano įrašas, skirtas iššūkiui „iRobot Create“. Sunkiausia viso šio proceso dalis buvo nuspręsti, ką robotas ketina daryti. Norėjau pademonstruoti puikias „Create“savybes, kartu pridėdamas šiek tiek robo nuojautos. Visas mano