Mục lục:

Cách tạo và kiểm tra DAC tốt hơn với ESP32: 5 bước
Cách tạo và kiểm tra DAC tốt hơn với ESP32: 5 bước

Video: Cách tạo và kiểm tra DAC tốt hơn với ESP32: 5 bước

Video: Cách tạo và kiểm tra DAC tốt hơn với ESP32: 5 bước
Video: ESP32 | Lập Trình WebServer Trên ESP32 Giải Thích Từng Dòng Code 2024, Tháng mười một
Anonim
Cách tạo và kiểm tra DAC tốt hơn với ESP32
Cách tạo và kiểm tra DAC tốt hơn với ESP32
Cách tạo và kiểm tra DAC tốt hơn với ESP32
Cách tạo và kiểm tra DAC tốt hơn với ESP32

ESP32 có 2 Bộ chuyển đổi Digital sang Analogue (DAC) 8-bit. Các DAC này cho phép chúng ta tạo ra điện áp tùy ý trong một phạm vi nhất định (0-3.3V) với độ phân giải 8 bit. Trong phần Hướng dẫn này, tôi sẽ chỉ cho bạn cách xây dựng DAC và mô tả đặc điểm hiệu suất của nó cũng như so sánh nó với DAC ESP32. Các chỉ số hiệu suất mà tôi sẽ xem xét bao gồm

  • Mức độ ồn
  • Băng thông
  • Tích phân phi tuyến tính
  • Tính phi tuyến tính khác biệt

Để kiểm tra các chỉ số này, tôi sẽ sử dụng ADS1115.

Điều quan trọng cần lưu ý là đánh giá của bạn về tất cả các chỉ số này sẽ chỉ chính xác như thiết bị tham chiếu của bạn (trong trường hợp này là ADS115). Ví dụ, ADS115 không có độ chính xác 16-bit khi nói đến độ lợi và bù điện áp của nó. Những sai số này có thể lớn tới 0,1%. Đối với nhiều hệ thống, những sai số này có thể được bỏ qua khi độ chính xác tuyệt đối là mối quan tâm hạn chế.

Quân nhu

  • ADS1115
  • Bảng ESP32
  • breadboard
  • dây nhảy
  • Điện trở 5 kOhm
  • 1 tụ gốm micro-Farad

Bước 1: Đặt ra bảng mạch

Đặt ra bảng mạch
Đặt ra bảng mạch

Nối các chân sau

Giữa ESP32 và ADS1115

VDD 3v3

GND GND

GPIO22 SCL

GPIO21 SDA

Tại ADS1115

ĐỊA CHỈ GND (ADS115)

Làm DAC

Có nhiều cách để tạo ra một DAC. Đơn giản nhất là lọc thông thấp tín hiệu PWM với một điện trở và một tụ điện. Tôi có thể đã thêm một op-amp vào đây làm bộ đệm nhưng muốn giữ mọi thứ đơn giản. Thiết kế này đơn giản và rẻ để thực hiện với bất kỳ bộ vi điều khiển nào hỗ trợ PWM. Tôi sẽ không đi qua lý thuyết về thiết kế ở đây (google PWM DAC).

Chỉ cần kết nối GPIO255 KOhm điện trở 1 microFarad Capacitor gnd

Bây giờ kết nối một dây jumper từ điểm mà điện trở gặp tụ điện đến A0 trên ADS115.

Bước 2: Đánh giá tín hiệu đến mức độ tiếng ồn

Đánh giá tín hiệu đến mức độ tiếng ồn
Đánh giá tín hiệu đến mức độ tiếng ồn

Để đánh giá mức độ tiếng ồn, chỉ cần chạy tập lệnh bên dưới. Để đánh giá điều này, chúng tôi chỉ cần để DAC ở một giá trị cố định và đo điện áp dao động như thế nào theo thời gian.

Do thiết kế của DAC, tiếng ồn sẽ lớn nhất khi tín hiệu PWM ở 50% chu kỳ nhiệm vụ. Do đó, đây là nơi chúng tôi sẽ đánh giá nó. Chúng tôi cũng sẽ đánh giá ESP32 ở cùng mức tín hiệu này. Chúng tôi cũng sẽ lọc DAC ESP32 với cùng một bộ lọc thông thấp để làm cho phép đo có thể so sánh được.

Đối với tôi, đầu ra đã rõ ràng. Thiết kế PWM có SNR tốt hơn> 6dB (tốt hơn gấp 2 lần). Một chiến thắng rõ ràng cho DAC mới. Một điều khó hiểu là có những bộ lọc được tích hợp trong ADC chắc chắn sẽ nâng cao SNR. Vì vậy, các giá trị tuyệt đối có thể khó giải thích. Nếu tôi đã sử dụng bộ lọc bậc hai, điều này sẽ không xảy ra.

Dù sao mã ở bên dưới

#bao gồm

#include Adafruit_ADS1115 quảng cáo; // thư viện adafruit cho adc int16_t adc0; // void setup (void) {Serial.begin (115200); // Bắt đầu nối tiếp ads.setGain (GAIN_TWO); // Tăng 2x +/- 2.048V 1 bit = 0.0625mV ads.begin (); // begin adc float M = 0; // giá trị trung bình ban đầu float Mp = 0; // previouos có nghĩa là float S = 0; // biến phương ban đầu float Sp = 0; // phương sai trước đó const int reps = 500; // số lần lặp lại int n = 256; // số lượng mẫu ledcSetup (0, 25000, 8); // đặt pwm thường xuyênecny = 25000 Hz ở độ phân giải 8 bit ledcAttachPin (25, 0); // thiết lập pwm trên chân 25 ledcWrite (0, 128); // đặt nó thành một nửa chu kỳ nhiệm vụ (nhiễu lớn nhất) delay (3000); // đợi thời gian giải quyết float snrPWM [reps]; // mảng snrs cho PWM float snrDAC [reps]; // mảng snrs cho DAC for (int i = 0; i <reps; i ++) {// lặp lại lần lượt for (int k = 1; k <(n + 1); k ++) {// lặp lại trên các mẫu adc0 = ads.readADC_SingleEnded (0); // nhận đọc M = Mp + (adc0 - Mp) / k; // tính toán trung bình lăn Mp = M; // đặt giá trị trung bình trước đó S = Sp + (adc0 - Mp) * (adc0 - M); // tính phương sai lăn Sp = S; // đặt phương sai trước} // snr theo dB snrPWM = 20 * log10 (3.3 / (sqrt (S / n) *.0625 *.001)); // đặt lại các giá trị M = 0; Mp = 0; S = 0; Sp = 0; } ledcDetachPin (25); // tách PWM khỏi chân 25 dacWrite (25, 128); // ghi vào DAC delay (3000); // đợi để giải quyết cho (int i = 0; i <reps; i ++) {// giống như vòng lặp PWM 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; } // vẽ các SNR trên một đồ thị for (int i = 1; i <reps; i ++) {Serial.print ("PWM_SNR (dB):"); Serial.print (snrPWM ); Serial.print (","); Serial.print ("ESP32_SNR (dB):"); Serial.println (snrDAC ); }} vòng lặp void (void) {}

Bước 3: Tính phi tuyến tính tích phân và tính phi tuyến tính khác biệt

Tính phi tuyến tính tích phân và tính phi tuyến tính khác biệt
Tính phi tuyến tính tích phân và tính phi tuyến tính khác biệt

Tính phi tuyến tích phân là một phép đo khoảng độ lệch giữa điện áp đầu ra DAC của bạn và một đường thẳng. Càng lớn, điều này càng tệ hơn…

Độ phi tuyến tính vi phân là thước đo gần đúng mức độ thay đổi quan sát được trong điện áp (từ mã này sang mã tiếp theo) khác với những gì mong đợi từ một đường thẳng.

Kết quả ở đây thực sự thú vị. Trước hết, cả hai đều có sai số dưới 0,5lsb (ở độ phân giải 8-bit) là tốt nhưng PWM có độ tuyến tính tích phân tốt hơn nhiều. Cả hai đều có sự khác biệt phi tuyến tính tương đương nhưng DAC ESP32 có một số điểm rất kỳ lạ. Hơn nữa, phương pháp PWM có một số cấu trúc đối với các lỗi. Về cơ bản, nó vượt quá và làm giảm điện áp chính xác theo kiểu xoay chiều.

Sự nghi ngờ của tôi là đây là một số lỗi làm tròn kỳ lạ trong cách tín hiệu PWM 8 bit được tạo ra trên ESP32.

Một cách để sửa lỗi này là quay vòng nhanh giữa hai mã liền kề (ví dụ: 128, 129) với PWM. Với bộ lọc thông thấp tương tự, các lỗi kết quả sẽ trung bình bằng không. Tôi đã mô phỏng điều này trong phần mềm và thực sự tất cả các lỗi đã biến mất. Bây giờ phương pháp PWM có độ tuyến tính chính xác đến 16-bit!

Dưới đây là bất kỳ mã nào để tạo dữ liệu. Đầu ra sẽ nằm trên màn hình nối tiếp ở định dạng.csv. Chỉ cần sao chép nó vào một tệp văn bản để xử lý thêm.

#bao gồm

#include Adafruit_ADS1115 quảng cáo; / * Sử dụng điều này cho phiên bản 16-bit * / int16_t adc0; void setup (void) {Serial.begin (115200); ads.setGain (GAIN_ONE); // Tăng 2x +/- 2.048V 1 bit = 1mV 0.0625mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); Serial.println ("Dự kiến, Đã quan sát"); ledcWrite (0, 2); chậm trễ (3000); for (int i = 2; i <255; i ++) {ledcWrite (0, i); chậm trễ (100); adc0 = ads.readADC_SingleEnded (0); float dự kiến = (i / 256.0 * 3.3) / 4.096 * 32767; Serial.print (dự kiến); Serial.print (","); Serial.println (adc0); }} vòng lặp void (void) {}

Bước 4: Băng thông

Băng thông
Băng thông

Tôi sẽ xác định băng thông ở đây là tần số mà đầu ra của DAC giảm xuống 3dB. Đây là một quy ước và ở một mức độ nào đó, là tùy ý. Ví dụ, tại điểm 6dB, DAC vẫn sẽ xuất tín hiệu với biên độ ~ 50%.

Để đo điều này, chúng ta chỉ cần truyền các sóng sin với tần số tăng dần từ DAC đến ADC và đo độ lệch chuẩn của chúng. Không có gì ngạc nhiên khi điểm 3dB ở 30Hz (1 / (2 * pi * 5000 * 1e-6)).

ESP32 có thể thực hiện 1 Mega mẫu mỗi giây. Đây là một chiến thắng khó khăn cho ESP32. Biên độ của nó hoàn toàn không bị phân rã trong vùng kiểm tra băng thông 100Hz.

Đoạn mã dưới đây có thể kiểm tra băng thông PWM DAC.

#bao gồm

#include Adafruit_ADS1115 quảng cáo; / * Sử dụng điều này cho phiên bản 16-bit * / int16_t adc0; int16_t adc1; thiết lập void (void) {float M; float Mp = 0; float S = 0; float Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // Độ lợi 1x +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); ledcSetup (0, 25000, 8); ledcAttachPin (25, 0); chậm trễ (5000); Serial.println ("Tần số, Biên độ"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); không dấu dài T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; định mức phao; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; ledcWrite (0, hết); 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) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / quy chuẩn, 3); k = 0; }} vòng lặp void (void) {}

Và mã này sẽ kiểm tra băng thông ESP32. Đảm bảo loại bỏ tụ điện nếu không kết quả sẽ giống nhau cho cả hai phương pháp.

#bao gồm

#include Adafruit_ADS1115 quảng cáo; / * Sử dụng điều này cho phiên bản 16-bit * / int16_t adc0; int16_t adc1; thiết lập void (void) {float M; float Mp = 0; float S = 0; float Sp = 0; Serial.begin (115200); ads.setGain (GAIN_ONE); // Độ lợi 1x +/- 4.096V 1 bit = 2mV 0.125mV ads.begin (); chậm trễ (5000); Serial.println ("Tần số, Biên độ"); for (int i = 1; i <100; i ++) {unsigned long start = millis (); không dấu dài T = millis (); Sp = 0; S = 0; M = 0; Mp = 0; int k = 1; định mức phao; while ((T - start) <1000) {int out = 24 * sin (2 * PI * i * (T - start) / 1000.0) + 128; dacWrite (25, hết); 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) {norm = sqrt (S / k); } Serial.print (i); Serial.print (","); Serial.println (sqrt (S / k) / quy chuẩn, 3); k = 0; }} vòng lặp void (void) {}

Bước 5: Kết thúc suy nghĩ

Thiết kế DAC mới thắng về độ tuyến tính và độ nhiễu nhưng lại thua về băng thông. Tùy thuộc vào ứng dụng của bạn, một trong những chỉ số này có thể quan trọng hơn chỉ số kia. Với những quy trình kiểm tra này, bạn sẽ có thể đưa ra quyết định một cách khách quan!

Ngoài ra, tôi nghĩ điều đáng chỉ ra ở đây là bởi vì đầu ra PWM có độ nhiễu thấp, với độ tuyến tính đặc biệt, nên có thể tạo ra một DAC có độ phân giải cao hơn nhiều với đầu ra PWM (thậm chí có thể chính xác 16 bit). Nó sẽ mất một số công việc. Cho đến lúc đó, tôi trả giá bạn adieu!

Đề xuất: