Tartalomjegyzék:

Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével: 5 lépés
Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével: 5 lépés

Videó: Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével: 5 lépés

Videó: Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével: 5 lépés
Videó: A TÖKÉLETES alvás titka 2024, Július
Anonim
Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével
Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével
Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével
Hogyan készítsünk és teszteljünk jobb DAC -t az ESP32 segítségével

Az ESP32 két 8 bites digitális-analóg átalakítóval (DAC) rendelkezik. Ezek a DAC-ok lehetővé teszik, hogy tetszőleges feszültségeket állítsunk elő egy adott tartományon belül (0-3,3 V) 8 bit felbontással. Ebben az utasításban megmutatom, hogyan kell felépíteni egy DAC -t, és jellemezni a teljesítményét, valamint összehasonlítani az ESP32 DAC -val. A teljesítménymutatók, amelyeket meg fogok vizsgálni, tartalmazzák

  • Zajszint
  • Sávszélesség
  • Integrális nemlinearitás
  • Differenciális nemlinearitás

Ezen indexek teszteléséhez az ADS1115 -öt fogom használni.

Fontos megjegyezni, hogy ezeknek az indexeknek az értékelése csak olyan pontos lesz, mint a referenciaeszköz (ebben az esetben az ADS115). Például az ADS115 nem rendelkezik 16 bites pontossággal a feszültségeltolódás és erősítés tekintetében. Ezek a hibák akár 0,1%is lehet. Sok rendszer esetében ezeket a hibákat figyelmen kívül lehet hagyni, ha az abszolút pontosság korlátozott.

Kellékek

  • ADS1115
  • ESP32 tábla
  • kenyeretábla
  • jumper vezetékek
  • 5 kOhm ellenállás
  • 1 db mikro-Farad kerámia kondenzátor

1. lépés: A kenyértábla elhelyezése

A kenyértábla elhelyezése
A kenyértábla elhelyezése

Csatlakoztassa a következő csapokat

Az ESP32 és az ADS1115 között

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Az ADS1115

ADDR GND (ADS115)

A DAC elkészítése

A DAC létrehozásának számos módja van. A legegyszerűbb az aluláteresztő PWM jel szűrése ellenállással és kondenzátorral. Hozzáadhattam volna egy op-erősítőt pufferként, de szeretném, ha a dolgok egyszerűek lennének. Ez a kialakítás egyszerű és olcsó bármilyen PWM -et támogató mikrovezérlővel. A tervezés elméletét itt nem fogom végigvenni (google PWM DAC).

Csak csatlakoztassa a GPIO255 KOhm ellenállást 1 microFarad kondenzátor gnd

Most csatlakoztassa az áthidaló vezetéket attól a ponttól, ahol az ellenállás találkozik a kondenzátorral, az ADS115 A0 -hoz.

2. lépés: Értékelje a jel zajszintjét

Értékelje a jel zajszintjét
Értékelje a jel zajszintjét

A zajszint felméréséhez egyszerűen futtassa az alábbi szkriptet. Ennek felméréséhez egyszerűen hagyjuk a DAC -t rögzített értéken, és mérjük meg, hogyan oszcillál a feszültség az idő múlásával.

A DAC kialakításának köszönhetően a zaj akkor lesz a legnagyobb, ha a PWM jel 50% -os üzemi ciklusban van. Ezért itt fogjuk értékelni. Ugyanezen jelszint mellett értékeljük az ESP32 -t is. Ugyanazzal az aluláteresztő szűrővel szűrjük az ESP32 DAC -t is, hogy a mérés összehasonlítható legyen.

Számomra a kimenet egyértelmű volt. A PWM kialakítás> 6 dB -rel jobb SNR értékkel rendelkezett (ez kétszer jobb). Egyértelmű győzelem az új DAC számára. Egy kis zavar az, hogy az ADC -be beépített szűrők vannak, amelyek határozottan javítják az SNR -t. Tehát az abszolút értékeket nehéz lehet értelmezni. Ha másodrendű szűrőt használtam volna, ez nem így lenne.

Egyébként a kód alább

#befoglalni

#tartalmazza az Adafruit_ADS1115 hirdetéseket; // adafruit könyvtár az adc int16_t adc0 számára; // void setup (void) {Serial.begin (115200); // Soros hirdetések indítása.setGain (GAIN_TWO); // 2x erősítés +/- 2.048V 1 bit = 0.0625mV ads.begin (); // start adc float M = 0; // kezdeti átlag úszó Mp = 0; // előzetes átlagos lebegés S = 0; // kezdeti variancia úszó Sp = 0; // előző variancia const int ismétlések = 500; // ismétlések száma int n = 256; // minták száma ledcSetup (0, 25000, 8); // pwm frequecny = 25000 Hz beállítása 8 bites felbontásban ledcAttachPin (25, 0); // a pwm beállítása a 25. tűre ledcWrite (0, 128); // fél üzemidő (legnagyobb zaj) késleltetés beállítása (3000); // várakozás a letelepedési időre float snrPWM [ismétlés]; // snrs tömb PWM float snrDAC [ismétlés]; // snrs tömb a DAC számára (int i = 0; i <ismétlések; i ++) {// ciklus az ismétlésekhez (int k = 1; k <(n+1); k ++) {// hurok minták fölött adc0 = ads.readADC_SingleEnded (0); // olvasás leolvasása M = Mp + (adc0 - Mp) / k; // gördülő átlag kiszámítása Mp = M; // előző középérték beállítása S = Sp + (adc0 - Mp) * (adc0 - M); // gördülő szórás kiszámítása Sp = S; // előző variancia beállítása} // snr dB -ben snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // értékek visszaállítása M = 0; Op.: 0; S = 0; Sp = 0; } ledcDetachPin (25); // leválasztani a PWM -et a 25. tűről dacWrite (25, 128); // írás DAC késleltetésre (3000); // várjon, amíg elégedett (int i = 0; i <ismétlések; i ++) {// ugyanaz, mint a PWM ciklus esetén (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; Op.: 0; S = 0; Sp = 0; } // ábrázolja az SNR -eket egy grafikonon a (int i = 1; i <ismétlések; i ++) {Serial.print ("PWM_SNR (dB):"); Soros.nyomat (snrPWM ); Serial.print (","); Soros.nyomtatás ("ESP32_SNR (dB):"); Soros.println (snrDAC ); }} void loop (void) {}

3. lépés: Integrális nemlinearitás és differenciális nemlinearitás

Integrális nemlinearitás és differenciális nemlinearitás
Integrális nemlinearitás és differenciális nemlinearitás

Az integrált nemlinearitás nagyjából azt méri, hogy mekkora eltérés van a DAC kimeneti feszültsége és egy egyenes között. Minél nagyobb ez annál rosszabb…

A differenciális nemlinearitás nagyjából azt méri, hogy a megfigyelt feszültségváltozás (egyik kódról a másikra) mennyiben tér el az egyenestől elvárttól.

Az eredmények itt valóban érdekesek voltak. Először is, mindkettőben kevesebb, mint 0,5 lsb hiba van (8 bites felbontásnál), ami jó, de a PWM sokkal jobb integrál linearitással rendelkezik. Mindkettő hasonló differenciális nemlinearitással rendelkezik, de az ESP32 DAC nagyon furcsa tüskékkel rendelkezik. Sőt, a PWM módszer bizonyos struktúrával rendelkezik a hibákhoz. Lényegében váltakozóan túllépi és alulmúlja a megfelelő feszültséget.

Az a gyanúm, hogy ez valami furcsa kerekítési hiba abban, hogyan állítanak elő 8 bites PWM jelet az ESP32 készüléken.

Ennek egyik módja az, ha gyorsan ciklusozunk két szomszédos kód (pl. 128, 129) között a PWM segítségével. Analóg aluláteresztő szűrő esetén a kapott hibák átlagosan nullára csökkennek. Szimuláltam ezt a szoftverben, és valóban minden hiba eltűnt. Most a PWM módszer lineáris, 16 bites pontosságú!

Az adatok létrehozására szolgáló kód az alábbiakban található. A kimenet a soros monitoron lesz.csv formátumban. Csak másolja át egy szöveges fájlba további feldolgozás céljából.

#befoglalni

#tartalmazza az Adafruit_ADS1115 hirdetéseket; / * Használja ezt a 16 bites verzióhoz */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x erősítés +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Várt, megfigyelt"); ledcWrite (0, 2); késleltetés (3000); for (int i = 2; i <255; i ++) {ledcWrite (0, i); késleltetés (100); adc0 = ads.readADC_SingleEnded (0); float várható = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print (várható); Serial.print (","); Serial.println (adc0); }} void loop (void) {}

4. lépés: Sávszélesség

Sávszélesség
Sávszélesség

A sávszélességet itt fogom definiálni, mint azt a frekvenciát, amelyen a DAC kimenete 3dB -val csökken. Ez egyezmény, és bizonyos mértékig önkényes. Például a 6dB ponton a DAC továbbra is jeleket ad ki, és csak ~ 50% amplitúdójú lesz.

Ennek mérésére egyszerűen szinuszhullámokat adunk egyre gyakrabban a DAC -ból az ADC -be, és mérjük azok szórását. Nem meglepő, hogy a 3dB pont 30 Hz-en van (1/(2*pi*5000*1e-6)).

Az ESP32 másodpercenként 1 megamintát tud készíteni. Ez kézenfekvő győzelem az ESP32 számára. Az amplitúdója egyáltalán nem csökken a 100 Hz -es sávszélesség -vizsgálati tartományban.

Az alábbi kód tesztelheti a PWM DAC sávszélességét.

#befoglalni

#tartalmazza az Adafruit_ADS1115 hirdetéseket; / * Használja ezt a 16 bites verzióhoz */ int16_t adc0; int16_t adc1; void setup (void) {float M; úszó Mp = 0; úszó S = 0; úszó Sp = 0; Sorozat.kezdet (115200); ads.setGain (GAIN_ONE); // 1x erősítés +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); késleltetés (5000); Serial.println ("Frekvencia, amplitúdó"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); előjel nélküli hosszú T = millis (); Sp = 0; S = 0; M = 0; Op.: 0; int k = 1; lebegési norma; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, ki); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Op.: M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } ha (i == 1) {norm = sqrt (S / k); } Sorozat.nyomtatás (i); Serial.print (","); Soros.println (sqrt (S / k) / norma, 3); k = 0; }} void loop (void) {}

És ez a kód teszteli az ESP32 sávszélességét. Győződjön meg róla, hogy eltávolítja a kondenzátort, különben az eredmények mindkét módszer esetében azonosak lesznek.

#befoglalni

#tartalmazza az Adafruit_ADS1115 hirdetéseket; / * Használja ezt a 16 bites verzióhoz */ int16_t adc0; int16_t adc1; void setup (void) {float M; úszó Mp = 0; úszó S = 0; úszó Sp = 0; Sorozat.kezdet (115200); ads.setGain (GAIN_ONE); // 1x erősítés +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); késleltetés (5000); Serial.println ("Frekvencia, amplitúdó"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); előjel nélküli hosszú T = millis (); Sp = 0; S = 0; M = 0; Op.: 0; int k = 1; lebegési norma; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, ki); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Op.: M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } ha (i == 1) {norm = sqrt (S / k); } Sorozat.nyomtatás (i); Serial.print (","); Soros.println (sqrt (S / k) / norma, 3); k = 0; }} void loop (void) {}

5. lépés: Gondolatok lezárása

Az új DAC kialakítás nyer a linearitás és a zaj tekintetében, de veszít a sávszélességben. Alkalmazásától függően az egyik mutató fontosabb lehet, mint a másik. Ezekkel a vizsgálati eljárásokkal képesnek kell lennie objektíven meghozni ezt a döntést!

Azt is érdemes itt kiemelni, hogy mivel a PWM kimenet alacsony zajszintű, kivételes linearitással lehetővé kell tenni egy sokkal nagyobb felbontású DAC létrehozását a PWM kimenettel (talán 16 bites pontossággal). Ez némi munkát igényel. Addig is búcsút veszek!

Ajánlott: