Isi kandungan:

Cara Membuat dan Menguji DAC yang Lebih Baik Dengan Langkah ESP32: 5
Cara Membuat dan Menguji DAC yang Lebih Baik Dengan Langkah ESP32: 5

Video: Cara Membuat dan Menguji DAC yang Lebih Baik Dengan Langkah ESP32: 5

Video: Cara Membuat dan Menguji DAC yang Lebih Baik Dengan Langkah ESP32: 5
Video: Tutorial Komunikasi Data Dengan MQTT Pada Esp32 2024, November
Anonim
Cara Membuat dan Menguji DAC yang Lebih Baik Dengan ESP32
Cara Membuat dan Menguji DAC yang Lebih Baik Dengan ESP32
Cara Membuat dan Menguji DAC yang Lebih Baik Dengan ESP32
Cara Membuat dan Menguji DAC yang Lebih Baik Dengan ESP32

ESP32 mempunyai 2 Digital to Analogue Converter (DAC) 8-bit. DAC ini membolehkan kita menghasilkan voltan sewenang-wenang dalam julat tertentu (0-3.3V) dengan resolusi 8 bit. Dalam Instructable ini, saya akan menunjukkan kepada anda cara membina DAC dan mencirikan prestasinya serta membandingkannya dengan ESP32 DAC. Indeks prestasi yang akan saya lihat termasuk

  • Tahap Kebisingan
  • Lebar jalur
  • Ketidakjajaran integral
  • Nonlineariti perbezaan

Untuk menguji indeks ini saya akan menggunakan ADS1115.

Penting untuk diperhatikan bahawa penilaian anda terhadap semua indeks ini hanya setepat peranti rujukan anda (dalam hal ini ADS115). Sebagai contoh, ADS115 tidak mempunyai ketepatan 16-bit ketika datang ke voltan mengimbangi dan memperoleh. Kesalahan ini mungkin sebesar 0.1%. Bagi banyak sistem, kesalahan ini dapat diabaikan apabila ketepatan mutlak menjadi perhatian terhad.

Bekalan

  • ADS1115
  • Papan ESP32
  • papan roti
  • wayar pelompat
  • Perintang 5 kOhm
  • 1 kapasitor seramik mikro-Farad

Langkah 1: Menyusun Papan Roti

Menyusun Papan Roti
Menyusun Papan Roti

Kawat pin berikut

Antara ESP32 dan ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Pada ADS1115

ADDR GND (ADS115)

Membuat DAC

Terdapat banyak cara untuk membuat DAC. Yang paling mudah ialah menapis low-signal isyarat PWM dengan perintang dan kapasitor. Saya boleh menambahkan op-amp di sini sebagai penyangga tetapi ingin membuat perkara mudah. Reka bentuk ini mudah dan murah untuk dilaksanakan dengan pengawal mikro yang menyokong PWM. Saya tidak akan mengkaji teori reka bentuk di sini (google PWM DAC).

Sambungkan GPIO255 KOhm perintang 1 microFarad Capacitor gnd

Sekarang sambungkan wayar pelompat dari titik di mana perintang memenuhi kapasitor ke A0 pada ADS115.

Langkah 2: Menilai Isyarat ke Tahap Kebisingan

Menilai Isyarat ke Tahap Kebisingan
Menilai Isyarat ke Tahap Kebisingan

Untuk menilai tahap kebisingan, jalankan skrip di bawah. Untuk menilai ini, kita tinggalkan DAC pada nilai tetap dan mengukur bagaimana voltan bergegas dari masa ke masa.

Oleh kerana reka bentuk DAC, kebisingan akan menjadi paling besar apabila isyarat PWM berada pada 50% kitaran tugas. Oleh itu di sinilah kita akan menilai. Kami juga akan menilai ESP32 pada tahap isyarat yang sama. Kami juga akan menapis ESP32 DAC dengan penapis lulus rendah yang sama agar pengukuran dapat dibandingkan.

Bagi saya outputnya jelas. Reka bentuk PWM mempunyai> 6dB SNR lebih baik (itu 2 kali lebih baik). Kemenangan yang jelas untuk DAC baru. Satu kekeliruan sedikit ialah terdapat penapis yang dimasukkan ke dalam ADC yang pasti meningkatkan SNR. Jadi nilai mutlak mungkin sukar ditafsirkan. Sekiranya saya menggunakan penapis pesanan kedua ini tidak akan berlaku.

Bagaimanapun kod ada di bawah

#sertakan

#sertakan iklan Adafruit_ADS1115; // perpustakaan adafruit untuk adc int16_t adc0; // persediaan tidak sah (tidak sah) {Serial.begin (115200); // Mulakan siri iklan.setGain (GAIN_TWO); // Keuntungan 2x +/- 2.048V 1 bit = 0.0625mV ads.begin (); // mulakan adc float M = 0; // min awal pengapungan Mp = 0; // previouos bermaksud float S = 0; // Variance float awal Sp = 0; // varians sebelumnya const int reps = 500; // bilangan pengulangan int n = 256; // bilangan sampel ledcSetup (0, 25000, 8); // tetapkan frekuensi pwm = 25000 Hz pada resolusi 8 bit ledcAttachPin (25, 0); // tetapkan pwm pada pin 25 ledcWrite (0, 128); // tetapkan ke kelewatan kitaran separuh tugas (kebisingan terbesar) (3000); // tunggu penyelesaian masa flr snrPWM [wakil]; // array snrs untuk PWM float snrDAC [wakil]; // susunan snrs untuk DAC untuk (int i = 0; i <reps; i ++) {// gelung atas pengulangan untuk (int k = 1; k <(n + 1); k ++) {// gelung atas sampel adc0 = ads.readADC_SingleEnded (0); // dapatkan bacaan M = Mp + (adc0 - Mp) / k; // hitung rata bergolek Mp = M; // tetapkan min sebelumnya S = Sp + (adc0 - Mp) * (adc0 - M); // hitung varians rolling Sp = S; // tetapkan varians sebelumnya} // snr dalam dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // tetapkan semula nilai M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // lepaskan PWM dari pin 25 dacWrite (25, 128); // tulis kepada kelewatan DAC (3000); // tunggu untuk menyelesaikan (int i = 0; i <reps; i ++) {// sama dengan gelung PWM untuk (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; } // plotkan SNR pada satu graf untuk (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Cetakan bersiri (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} gelung kosong (kekosongan) {}

Langkah 3: Nonlineariti Integral dan Nonlineariti Berbeza

Nonlineariti Integral dan Nonlineariti Pembezaan
Nonlineariti Integral dan Nonlineariti Pembezaan

Nonlineariti terpadu adalah ukuran kira-kira berapa banyak penyimpangan antara voltan output DAC anda dan garis lurus. Semakin besar ini semakin teruk …

Nonlineariti pembezaan adalah ukuran kira-kira berapa perubahan voltan yang diperhatikan (dari satu kod ke kod berikutnya) menyimpang dari apa yang diharapkan dari garis lurus.

Hasilnya di sini sungguh menarik. Pertama sekali, kedua-duanya mempunyai ralat kurang dari 0.5lsb (pada resolusi 8-bit) yang baik tetapi PWM mempunyai linearitas integral yang jauh lebih baik. Kedua-duanya mempunyai perbezaan nonlineariti yang sebanding tetapi ESP32 DAC mempunyai beberapa lonjakan yang sangat pelik. Lebih-lebih lagi, kaedah PWM mempunyai beberapa struktur kesalahan. Pada dasarnya ia mengatasi dan menurunkan voltan yang betul secara bergantian.

Kecurigaan saya adalah ini adalah beberapa kesalahan pembundaran pelik bagaimana isyarat PWM 8-bit dihasilkan pada ESP32.

Salah satu cara untuk membetulkannya adalah dengan cepat berpusing antara dua kod bersebelahan (mis. 128, 129) dengan PWM. Dengan penapis lowpass analog, ralat yang dihasilkan akan rata-rata menjadi sifar. Saya mensimulasikan ini dalam perisian dan semua kesalahan hilang. Kini kaedah PWM mempunyai garis lurus yang tepat hingga 16-bit!

Bagaimanapun kod untuk menghasilkan data ada di bawah. Keluarannya akan berada di monitor bersiri dalam format.csv. Cukup salin ke fail teks untuk diproses lebih lanjut.

#sertakan

#sertakan iklan Adafruit_ADS1115; / * Gunakan ini untuk versi 16-bit * / int16_t adc0; persediaan kosong (tidak sah) {Serial.begin (115200); ads.setGain (GAIN_ONE); // 2x gain +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Dijangka, Diperhatikan"); ledcWrite (0, 2); kelewatan (3000); untuk (int i = 2; i <255; i ++) {ledcWrite (0, i); kelewatan (100); adc0 = ads.readADC_SingleEnded (0); apungan dijangka = (i / 256.0 * 3.3) / 4.096 * 32767; Cetakan bersiri (dijangka); Cetakan bersiri (","); Serial.println (adc0); }} gelung kosong (kekosongan) {}

Langkah 4: Lebar jalur

Lebar jalur
Lebar jalur

Saya akan menentukan lebar jalur seperti di sini sebagai frekuensi output DAC turun oleh 3dB. Ini adalah konvensyen dan, sampai tahap tertentu, sewenang-wenangnya. Sebagai contoh, pada titik 6dB, DAC akan tetap mengeluarkan isyarat yang hanya 50 ~ amplitud.

Untuk mengukur ini, kita hanya meneruskan gelombang sinus pada frekuensi yang meningkat dari DAC ke ADC dan mengukur sisihan piawai mereka. Tidak menghairankan, titik 3dB berada pada 30Hz (1 / (2 * pi * 5000 * 1e-6)).

ESP32 boleh melakukan 1 Mega sampel sesaat. Ini adalah kemenangan mudah bagi ESP32. Amplitudanya sama sekali tidak merosot di kawasan ujian lebar jalur 100Hz.

Kod di bawah ini dapat menguji lebar jalur DW PWM.

#sertakan

#sertakan iklan Adafruit_ADS1115; / * Gunakan ini untuk versi 16-bit * / int16_t adc0; int16_t adc1; persediaan kosong (kekosongan) {float M; apungan Mp = 0; terapung S = 0; apungan Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // Keuntungan 1x +/- 4.096V 1 bit = 2mV 0.125mV iklan. Mulakan (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); kelewatan (5000); Serial.println ("Kekerapan, Amplitud"); untuk (int i = 1; i <100; i ++) {permulaan panjang yang tidak ditandatangani = milis (); panjang tidak bertanda T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma apungan; manakala ((T - mula) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, keluar); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } jika (i == 1) {norm = sqrt (S / k); } Cetakan bersiri (i); Cetakan bersiri (","); Serial.println (sqrt (S / k) / norma, 3); k = 0; }} gelung kosong (kekosongan) {}

Dan kod ini akan menguji lebar jalur ESP32. Pastikan untuk mengeluarkan kapasitor atau hasilnya akan sama untuk kedua-dua kaedah tersebut.

#sertakan

#sertakan iklan Adafruit_ADS1115; / * Gunakan ini untuk versi 16-bit * / int16_t adc0; int16_t adc1; persediaan kosong (kekosongan) {float M; apungan Mp = 0; terapung S = 0; apungan Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // Keuntungan 1x +/- 4.096V 1 bit = 2mV 0.125mV iklan. Mulakan (); kelewatan (5000); Serial.println ("Kekerapan, Amplitud"); untuk (int i = 1; i <100; i ++) {permulaan panjang yang tidak ditandatangani = milis (); panjang tidak bertanda T = milis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma apungan; manakala ((T - mula) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, keluar); adc0 = ads.readADC_SingleEnded (0); M = Mp + (adc0 - Mp) / k; Mp = M; S = Sp + (adc0 - Mp) * (adc0 - M); Sp = S; T = milis (); k ++; } jika (i == 1) {norm = sqrt (S / k); } Cetakan bersiri (i); Cetakan bersiri (","); Serial.println (sqrt (S / k) / norma, 3); k = 0; }} gelung kosong (kekosongan) {}

Langkah 5: Menutup Pemikiran

Reka bentuk DAC baru menang berdasarkan lineariti dan kebisingan tetapi kehilangan lebar jalur. Bergantung pada aplikasi anda, salah satu indeks ini mungkin lebih penting daripada yang lain. Dengan prosedur ujian ini, anda seharusnya dapat membuat keputusan secara objektif!

Juga, saya rasa perlu dinyatakan di sini bahawa kerana output PWM adalah kebisingan yang rendah, dengan garis linier yang luar biasa, dapat membuat DAC resolusi yang jauh lebih tinggi dengan output PWM (mungkin juga ketepatan 16-bit). Itu akan mengambil kerja. Sehingga itu, saya menawar anda!

Disyorkan: