Daftar Isi:

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

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

Video: Cara Membuat dan Menguji DAC yang Lebih Baik Dengan ESP32: 5 Langkah
Video: Tutorial Komunikasi Data Dengan MQTT Pada Esp32 2024, Juli
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 memiliki 2 8-bit Digital to Analogue Converters (DACs). DAC ini memungkinkan kita untuk menghasilkan tegangan sewenang-wenang dalam kisaran tertentu (0-3.3V) dengan resolusi 8 bit. Dalam Instruksi ini, saya akan menunjukkan kepada Anda bagaimana membangun DAC dan mengkarakterisasi kinerjanya serta membandingkannya dengan DAC ESP32. Indeks kinerja yang akan saya lihat meliputi

  • Tingkat kebisingan
  • Bandwidth
  • Nonlinier integral
  • Nonlinier diferensial

Untuk menguji indeks ini saya akan menggunakan ADS1115.

Penting untuk dicatat bahwa penilaian Anda terhadap semua indeks ini hanya akan seakurat perangkat referensi Anda (dalam hal ini ADS115). Misalnya, ADS115 tidak memiliki presisi 16-bit dalam hal offset dan penguatan tegangan. Kesalahan ini mungkin sebesar 0,1%. Untuk banyak sistem, kesalahan ini dapat diabaikan ketika akurasi mutlak menjadi perhatian terbatas.

Perlengkapan

  • ADS1115
  • Papan ESP32
  • papan tempat memotong roti
  • kabel jumper
  • Resistor 5 kOhm
  • 1 kapasitor keramik mikro-Farad

Langkah 1: Meletakkan Papan Tempat memotong roti

Meletakkan Papan Tempat memotong roti
Meletakkan Papan Tempat memotong roti

Kawat pin berikut:

Antara ESP32 dan ADS1115

3v3 VDD

GND GND

GPIO22 SCL

GPIO21 SDA

Di ADS1115

TAMBAHKAN GND (ADS115)

Membuat DAC

Ada banyak cara untuk membuat DAC. Yang paling sederhana adalah menyaring sinyal PWM dengan resistor dan kapasitor. Saya bisa saja menambahkan sebuah op-amp di sini sebagai penyangga tetapi ingin menjaga semuanya tetap sederhana. Desain ini sederhana dan murah untuk diimplementasikan dengan mikrokontroler apa pun yang mendukung PWM. Saya tidak akan membahas teori desain di sini (google PWM DAC).

Cukup sambungkan GPIO255 KOhm resistor 1 microFarad Capacitor gnd

Sekarang sambungkan kabel jumper dari titik pertemuan resistor dengan kapasitor ke A0 pada ADS115.

Langkah 2: Nilai Sinyal ke Tingkat Kebisingan

Nilai Sinyal ke Tingkat Kebisingan
Nilai Sinyal ke Tingkat Kebisingan

Untuk menilai tingkat kebisingan cukup jalankan skrip di bawah ini. Untuk menilai ini, kita cukup membiarkan DAC pada nilai tetap dan mengukur bagaimana tegangan berosilasi dari waktu ke waktu.

Karena desain DAC, noise akan paling besar ketika sinyal PWM berada pada duty cycle 50%. Oleh karena itu di sinilah kita akan menilainya. Kami juga akan menilai ESP32 pada level sinyal yang sama ini. Kami juga akan memfilter ESP32 DAC dengan filter low pass yang sama agar pengukurannya sebanding.

Bagi saya hasilnya jelas. Desain PWM memiliki SNR >6dB yang lebih baik (itu 2 kali lebih baik). Kemenangan yang jelas untuk DAC baru. Satu hal yang membingungkan adalah bahwa ada filter yang dibangun ke dalam ADC yang paling pasti meningkatkan SNR. Jadi nilai absolut mungkin sulit untuk ditafsirkan. Jika saya menggunakan filter orde kedua, ini tidak akan terjadi.

Pokoknya kode di bawah ini

#termasuk

#sertakan iklan Adafruit_ADS1115; // adafruit library untuk adc int16_t adc0; // void setup(void) { Serial.begin(115200); // Mulai iklan serial.setGain(GAIN_TWO); // 2x gain +/- 2.048V 1 bit =0.0625mV ads.begin(); // mulai adc float M = 0; // awal mean float Mp = 0; // sebelumnya berarti float S = 0; // Varian awal float Sp = 0; // varians sebelumnya int repetisi = 500; // jumlah pengulangan int n = 256; // jumlah sampel ledcSetup(0, 25000, 8); // setel frekuensi pwm =25000 Hz pada resolusi 8 bit ledcAttachPin(25, 0); // set pwm pada pin 25 ledcWrite(0, 128); // setel ke half duty cycle(bising terbesar) delay(3000); // tunggu waktu penyelesaian float snrPWM[reps]; // array snrs untuk PWM float snrDAC[reps]; // larik snrs untuk DAC for (int i = 0; i < repetisi; i++) { // mengulang pengulangan untuk (int k = 1; k < (n + 1); k++) { // mengulang sampel adc0 = ads.readADC_SingleEnded(0); // dapatkan pembacaan M = Mp + (adc0 - Mp) / k; // menghitung rata-rata bergulir Mp = M; // atur mean sebelumnya S = Sp + (adc0 - Mp) * (adc0 - M); // menghitung varians bergulir Sp = S; // setel varian sebelumnya } // snr dalam dB snrPWM = 20 * log10(3.3 / (sqrt(S / n) *.0625 *.001)); //reset nilai M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin(25); // lepaskan PWM dari pin 25 dacWrite(25, 128); // menulis ke DAC delay(3000); // tunggu sampai selesai (int i = 0; i < repetisi; i++) { // sama dengan PWM loop for (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; } // plot SNR pada satu grafik untuk (int i = 1; i < repetisi; i++) { Serial.print("PWM_SNR(dB):"); Serial.print(snrPWM); Serial.print(", "); Serial.print("ESP32_SNR(dB):"); Serial.println(snrDAC); } } lingkaran batal (batal) {}

Langkah 3: Nonlinier Integral dan Nonlinier Diferensial

Nonlinier Integral dan Nonlinier Diferensial
Nonlinier Integral dan Nonlinier Diferensial

Nonlinier integral adalah ukuran kira-kira berapa banyak penyimpangan yang ada antara tegangan output DAC Anda dan garis lurus. Semakin besar ini semakin buruk…

Nonlinier diferensial adalah ukuran kira-kira seberapa besar perubahan tegangan yang diamati (dari satu kode ke kode berikutnya) menyimpang dari apa yang diharapkan dari garis lurus.

Hasil di sini sangat menarik. Pertama-tama, keduanya memiliki kesalahan kurang dari 0,5 lsb (pada resolusi 8-bit) yang bagus tetapi PWM memiliki linearitas integral yang jauh lebih baik. Keduanya memiliki nonlinier diferensial yang sebanding tetapi DAC ESP32 memiliki beberapa lonjakan yang sangat aneh. Terlebih lagi, metode PWM memiliki beberapa struktur kesalahan. Pada dasarnya overshoot dan undershoot tegangan yang benar secara bergantian.

Kecurigaan saya adalah ini adalah kesalahan pembulatan yang aneh tentang bagaimana sinyal PWM 8-bit dihasilkan pada ESP32.

Salah satu cara untuk memperbaikinya adalah dengan cepat menggilir antara dua kode yang berdekatan (misalnya 128, 129) dengan PWM. Dengan filter lowpass analog, kesalahan yang dihasilkan akan rata-rata menjadi nol. Saya mensimulasikan ini dalam perangkat lunak dan memang semua kesalahan hilang. Sekarang metode PWM memiliki linearitas yang akurat hingga 16-bit!

Siapa saja kode untuk menghasilkan data di bawah ini. Output akan berada di monitor serial dalam format.csv. Cukup salin ke file teks untuk diproses lebih lanjut.

#termasuk

#sertakan iklan Adafruit_ADS1115; /* Gunakan ini untuk versi 16-bit */ int16_t adc0; void setup(void) { 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("Diharapkan, Diamati "); ledcTulis(0, 2); penundaan(3000); for (int i = 2; i < 255; i++) { ledcWrite(0, i); penundaan(100); adc0 = ads.readADC_SingleEnded(0); float diharapkan = (i / 256,0 * 3,3) / 4,096 * 32767; Serial.print(diharapkan); Serial.print(", "); Serial.println(adc0); } } lingkaran batal (batal) {}

Langkah 4: Bandwidth

Bandwidth
Bandwidth

Saya akan mendefinisikan bandwidth seperti di sini sebagai frekuensi di mana output dari DAC turun sebesar 3dB. Ini adalah konvensi dan, sampai taraf tertentu, sewenang-wenang. Misalnya, pada titik 6dB, DAC akan tetap mengeluarkan sinyal dengan amplitudo ~50%.

Untuk mengukur ini, kita cukup melewatkan gelombang sinus pada frekuensi yang meningkat dari DAC ke ADC dan mengukur standar deviasinya. Tidak mengherankan, titik 3dB berada pada 30Hz (1/(2*pi*5000*1e-6)).

ESP32 dapat melakukan 1 Mega sampel per detik. Ini adalah kemenangan langsung untuk ESP32. Amplitudonya tidak membusuk sama sekali di wilayah uji bandwidth 100Hz.

Kode di bawah ini dapat menguji bandwidth DAC PWM.

#termasuk

#sertakan iklan Adafruit_ADS1115; /* Gunakan ini untuk versi 16-bit */ int16_t adc0; int16_t adc1; void setup(void) { float M; mengapung Mp = 0; mengapung S = 0; mengapung Sp = 0; Serial.begin(115200); ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV ads.begin(); ledcSetup(0, 25000, 8); ledcAttachPin(25, 0); penundaan(5000); Serial.println("Frekuensi, Amplitudo"); for (int i = 1; i < 100; i++) { unsigned long start = millis(); unsigned panjang T = milis(); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma mengambang; while ((T - mulai) < 1000) { int keluar = 24 * sin(2 * PI * i * (T - mulai) / 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 = mili(); k++; } if (i == 1) { norma = kuadrat(S / k); } Serial.print(i); Serial.print(", "); Serial.println(sqrt(S / k) / norma, 3); k = 0; } } lingkaran batal (batal) {}

Dan kode ini akan menguji bandwidth ESP32. Pastikan untuk melepas kapasitor atau hasilnya akan sama untuk kedua metode.

#termasuk

#sertakan iklan Adafruit_ADS1115; /* Gunakan ini untuk versi 16-bit */ int16_t adc0; int16_t adc1; void setup(void) { float M; mengapung Mp = 0; mengapung S = 0; mengapung Sp = 0; Serial.begin(115200); ads.setGain(GAIN_ONE); // 1x gain +/- 4.096V 1 bit = 2mV 0.125mV ads.begin(); penundaan(5000); Serial.println("Frekuensi, Amplitudo"); for (int i = 1; i < 100; i++) { unsigned long start = millis(); unsigned panjang T = milis(); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; norma mengambang; while ((T - mulai) < 1000) { int keluar = 24 * sin(2 * PI * i * (T - mulai) / 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 = mili(); k++; } if (i == 1) { norma = kuadrat(S / k); } Serial.print(i); Serial.print(", "); Serial.println(sqrt(S / k) / norma, 3); k = 0; } } lingkaran batal (batal) {}

Langkah 5: Menutup Pikiran

Desain DAC baru menang pada linearitas dan kebisingan tetapi kalah pada bandwidth. Tergantung pada aplikasi Anda, salah satu indeks ini mungkin lebih penting daripada yang lain. Dengan prosedur pengujian ini, Anda harus dapat membuat keputusan itu secara objektif!

Juga, saya pikir itu layak menunjukkan di sini bahwa karena output PWM kebisingan rendah, dengan linearitas yang luar biasa itu harus mungkin untuk membangun DAC resolusi yang jauh lebih tinggi dengan output PWM (bahkan mungkin presisi 16-bit). Itu akan membutuhkan beberapa pekerjaan. Sampai saat itu, saya mengucapkan selamat tinggal!

Direkomendasikan: