Mundarija:

ESP32: 5 bosqichda yaxshiroq DACni qanday qilish va sinovdan o'tkazish kerak
ESP32: 5 bosqichda yaxshiroq DACni qanday qilish va sinovdan o'tkazish kerak

Video: ESP32: 5 bosqichda yaxshiroq DACni qanday qilish va sinovdan o'tkazish kerak

Video: ESP32: 5 bosqichda yaxshiroq DACni qanday qilish va sinovdan o'tkazish kerak
Video: ESP32 Tutorial 5 - LED Fade, control brightness of an LED -ESP32 IoT Learnig kit 2024, Noyabr
Anonim
ESP32 yordamida yaxshiroq DACni qanday yaratish va sinab ko'rish
ESP32 yordamida yaxshiroq DACni qanday yaratish va sinab ko'rish
ESP32 yordamida yaxshiroq DACni qanday yaratish va sinab ko'rish
ESP32 yordamida yaxshiroq DACni qanday yaratish va sinab ko'rish

ESP32-da 2 ta 8 bitli raqamli-analogli konvertorlar (DAC) mavjud. Bu DAClar bizga 8 bitli aniqlikdagi ma'lum bir diapazonda (0-3.3V) o'zboshimchalikli kuchlanishlarni ishlab chiqarishga imkon beradi. Bu yo'riqnomada men sizga DACni qanday qurishni va uning ishlashini tavsiflashni, shuningdek uni ESP32 DAC bilan solishtirishni ko'rsataman. Men ko'rib chiqadigan ishlash ko'rsatkichlari o'z ichiga oladi

  • Shovqin darajasi
  • Tarmoqli kengligi
  • Integral chiziqsizlik
  • Differentsial chiziqli emaslik

Ushbu indekslarni sinab ko'rish uchun men ADS1115 dan foydalanaman.

Shuni ta'kidlash kerakki, sizning barcha indekslarni baholashingiz mos yozuvlar moslamasi kabi aniq bo'ladi (bu holda ADS115). Misol uchun, ADS115 kuchlanish o'lchami va ortishi haqida 16-bitli aniqlikka ega emas. Bu xatolar 0,1%gacha bo'lishi mumkin. Ko'p tizimlar uchun, agar aniqlik cheklanmagan bo'lsa, bu xatolarni e'tiborsiz qoldirish mumkin.

Ta'minotlar

  • ADS1115
  • ESP32 taxtasi
  • non taxtasi
  • o'tish simlari
  • 5 kOhm qarshilik
  • 1 ta mikro Farad sopol kondansatörü

1 -qadam: elektron jadvalni joylashtirish

Elektron jadvalni joylashtirish
Elektron jadvalni joylashtirish

Quyidagi pimlarni sim bilan ulang

ESP32 va ADS1115 o'rtasida

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

ADS1115 da

ADDR GND (ADS115)

DAC yaratish

DAC yaratishning ko'plab usullari mavjud. Eng oddiy-qarshilik va kondansatkichli PWM signalini past o'tkazgichli filtrlash. Men bu erga bufer sifatida op-amp qo'shgan bo'lardim, lekin hamma narsani oddiy saqlashni xohlardim. Ushbu dizayn PWM -ni qo'llab -quvvatlaydigan har qanday mikrokontroller bilan amalga oshirish uchun oddiy va arzon. Men bu erda dizayn nazariyasidan o'tmoqchi emasman (google PWM DAC).

Faqat GPIO255 KOhm qarshilik 1 microFarad Capacitor gnd ni ulang

Endi qarshilik simini ADS115 -dagi kondansatör A0 ga to'g'ri keladigan nuqtadan ulang.

2 -qadam: Signalni shovqin darajasiga baholang

Signalni shovqin darajasiga qarab baholang
Signalni shovqin darajasiga qarab baholang

Shovqin darajasini baholash uchun quyidagi skriptni ishlating. Buni baholash uchun biz DACni belgilangan qiymatda qoldiramiz va vaqt o'tishi bilan kuchlanish qanday tebranishini o'lchaymiz.

DAC dizayni tufayli, PWM signali 50% ish tsiklida bo'lganda, shovqin eng katta bo'ladi. Shuning uchun biz bu erda baho beramiz. Biz ESP32 -ni xuddi shu signal darajasida baholaymiz. O'lchovni solishtirish uchun biz ESP32 DAC -ni past o'tkazgichli filtr bilan filtrlaymiz.

Men uchun chiqish aniq edi. PWM dizayni> 6dB yaxshiroq SNRga ega edi (bu 2 barobar yaxshiroq). Yangi DAC uchun aniq g'alaba. Bir oz chalkashlik shundaki, ADC -ga o'rnatilgan SNRni yaxshilaydigan filtrlar mavjud. Shunday qilib, mutlaq qiymatlarni talqin qilish qiyin bo'lishi mumkin. Agar men ikkinchi darajali filtrdan foydalansam, bunday bo'lmaydi.

Qanday bo'lmasin, kod quyida

#qo'shing

#Adafruit_ADS1115 reklamalarini qo'shing; // adc int16_t adc0 uchun adafruit kutubxonasi; // void setup (void) {Serial.begin (115200); // Serial ads.setGain (GAIN_TWO) ni ishga tushiring; // 2x daromad +/- 2.048V 1 bit = 0.0625mV ads.begin (); // boshlang adc float M = 0; // boshlang'ich o'rtacha float Mp = 0; // previouos float o'rtacha S = 0; // boshlang'ich Variance float Sp = 0; // oldingi variatsiya const int reps = 500; // takrorlar soni int n = 256; // namunalar soni ledcSetup (0, 25000, 8); // pwm chastotasi = 25000 Gts ni 8 bitli piksellar soniga sozlash ledcAttachPin (25, 0); // pwm -ni 25 -pinga qo'ying ledcWrite (0, 128); // uni yarim ish tsikliga (eng katta shovqin) kechiktirishga qo'ying (3000); // vaqtni belgilashni kuting float snrPWM [reps]; // PWM float snrDAC [reps] uchun snrlar qatori; // (int i = 0; i <reps; i ++) {// DAC uchun snrlar majmui (int k = 1; k <(n+1); k ++) {// looplar uchun namunalar adc0 = ads.readADC_SingleEnded (0); // o'qishni oling M = Mp + (adc0 - Mp) / k; // hisoblash dumalovchi o'rtacha Mp = M; // oldingi o'rtacha qiymatni o'rnating S = Sp + (adc0 - Mp) * (adc0 - M); // hisoblash dumalab dispersiyasi Sp = S; // oldingi dispersiyani o'rnatish} // snr dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // qiymatlarni tiklash M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // 25 dacWrite (25, 128) pinidan PWMni ajratish; // DAC kechiktirishiga yozish (3000); // hal qilishni kuting (int i = 0; i <reps; i ++) {// PWM loopi bilan bir xil (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; } // SNR -larni bitta grafikda chizish (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} bo'sh bo'shliq (bo'sh) {}

3 -qadam: Integral chiziqli bo'lmaganlik va differentsial nochiziqlik

Integral chiziqsizlik va differentsial nochiziqlik
Integral chiziqsizlik va differentsial nochiziqlik

Integral chiziqli bo'lmaganlik - bu sizning DAC chiqish voltaji va to'g'ri chiziq o'rtasida qancha og'ish borligini o'lchash. Bu qanchalik katta bo'lsa, shuncha yomon bo'ladi …

Differentsial noaniqlik - bu kuchlanishning (bir koddan ikkinchisiga) kuzatilgan o'zgarishi to'g'ri chiziqdan kutilganidan qanchalik farq qilishining o'lchovidir.

Bu erda natijalar haqiqatan ham qiziq edi. Birinchidan, ikkalasida ham 0,5 lb dan kam xato bor (8 bitli aniqlikda), lekin PWM ancha yaxshi integral chiziqli. Har ikkalasida ham taqqoslanadigan differentsial chiziqli emas, lekin ESP32 DAC juda g'alati choklarga ega. Bundan tashqari, PWM usuli xatolar tuzilishiga ega. Asosan, u o'zgaruvchan tarzda to'g'ri kuchlanishni oshib ketadi va tushiradi.

Mening shubham, bu ESP32-da 8-bitli PWM signalini ishlab chiqarishda g'alati yaxlitlash xatosi.

Buni tuzatishning bir usuli - PWM yordamida ikkita qo'shni kodni (masalan, 128, 129) tez aylantirish. Analog past o'tkazgichli filtr yordamida, yuzaga keladigan xatolar o'rtacha nolga teng bo'ladi. Men buni dasturiy ta'minotda taqlid qildim va haqiqatan ham barcha xatolar yo'qoldi. Endi PWM usuli chiziqli bo'lib, 16 bitga to'g'ri keladi!

Ma'lumotni yaratish kodi kim bo'lsa, quyida. Chiqish ketma -ket monitorda.csv formatida bo'ladi. Keyingi ishlov berish uchun uni matnli faylga nusxalash kifoya.

#qo'shing

#Adafruit_ADS1115 e'lonlarini qo'shing; / * Buni 16-bitli versiya uchun ishlating */ int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x daromad +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Kutilgan, kuzatilgan"); ledcWrite (0, 2); kechikish (3000); uchun (int i = 2; i <255; i ++) {ledcWrite (0, i); kechikish (100); adc0 = ads.readADC_SingleEnded (0); kutilgan float = (i / 256.0 * 3.3) / 4.096 * 32767; Serial.print (kutilgan); Serial.print (","); Serial.println (adc0); }} bo'sh bo'shliq (bo'sh) {}

4 -qadam: tarmoqli kengligi

Tarmoqli kengligi
Tarmoqli kengligi

Men tarmoqli kengligini bu erda DAC chiqishi 3dB ga tushadigan chastota sifatida aniqlayman. Bu konventsiya va ma'lum darajada o'zboshimchalik. Masalan, 6dB nuqtada DAC hali ham ~ 50% amplitudali signal chiqaradi.

Buni o'lchash uchun biz sinus to'lqinlarni DACdan ADCga ko'payib borayotgan chastotada o'tkazamiz va ularning standart og'ishlarini o'lchaymiz. Ajablanarlisi shundaki, 3dB nuqtasi 30 Gts (1/(2*pi*5000*1e-6)).

ESP32 sekundiga 1 mega namuna olishi mumkin. Bu ESP32 uchun yutuq. Uning 100 gigagertsli sinov zonasida uning amplitudasi umuman buzilmaydi.

Quyidagi kod PWM DAC tarmoqli kengligini tekshirishi mumkin.

#qo'shing

#Adafruit_ADS1115 reklamalarini qo'shing; / * Buni 16-bitli versiya uchun ishlating */ int16_t adc0; int16_t adc1; void setup (void) {float M; float Mp = 0; float S = 0; float Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x daromad +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); kechikish (5000); Serial.println ("Chastotasi, amplitudasi"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); belgisiz uzun T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; suzish normasi; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, tashqarida); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } if (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norm, 3); k = 0; }} bo'sh bo'shliq (bo'sh) {}

Va bu kod ESP32 tarmoqli kengligini sinovdan o'tkazadi. Kondensatorni olib tashlashga ishonch hosil qiling, aks holda natijalar ikkala usul uchun ham bir xil bo'ladi.

#qo'shing

#Adafruit_ADS1115 reklamalarini qo'shing; / * Buni 16-bitli versiya uchun ishlating */ int16_t adc0; int16_t adc1; void setup (void) {float M; float Mp = 0; float S = 0; float Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // 1x daromad +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); kechikish (5000); Serial.println ("Chastotasi, amplitudasi"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); belgisiz uzun T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; suzish normasi; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, tashqarida); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = millis (); k ++; } if (i == 1) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / norm, 3); k = 0; }} void loop (void) {}

5 -qadam: Yakuniy fikrlar

Yangi DAC dizayni chiziqli va shovqinli bo'ladi, lekin tarmoqli kengligida yo'qotadi. Sizning arizangizga qarab, bu indekslardan biri boshqasidan ko'ra muhimroq bo'lishi mumkin. Ushbu test protseduralari yordamida siz ob'ektiv qaror qabul qilishingiz kerak!

Bundan tashqari, bu erda shuni ta'kidlash kerakki, PWM chiqishi past shovqinli, chunki chiziqli bo'lmagan holda, PWM chiqishi bilan ancha yuqori aniqlikdagi DAC (hatto 16-bitli aniqlik) qurilishi mumkin. Buning uchun biroz ish kerak bo'ladi. Ungacha, men sizga taklif qilaman!

Tavsiya: