Mục lục:

Arduino và PCF8591 ADC DAC IC: 7 bước
Arduino và PCF8591 ADC DAC IC: 7 bước

Video: Arduino và PCF8591 ADC DAC IC: 7 bước

Video: Arduino và PCF8591 ADC DAC IC: 7 bước
Video: ADC hoạt động như thế nào? | Bộ chuyển đổi tín hiệu Analog - Digital | Học Nghề Kỹ Sư Điện & Điện Tử 2024, Tháng bảy
Anonim
Arduino và PCF8591 ADC DAC IC
Arduino và PCF8591 ADC DAC IC

Bạn đã bao giờ muốn có nhiều chân đầu vào tương tự hơn trên dự án Arduino của mình, nhưng không muốn tách ra cho Mega? Hay bạn muốn tạo tín hiệu tương tự? Sau đó, hãy xem chủ đề của hướng dẫn của chúng tôi - IC NXP PCF8591.

Nó giải quyết được cả hai vấn đề này vì nó có một bộ chuyển đổi DAC (kỹ thuật số sang tương tự) duy nhất cũng như bốn bộ ADC (bộ chuyển đổi tương tự sang kỹ thuật số) - tất cả đều có thể truy cập thông qua bus I2C. PCF8591 có sẵn ở dạng DIP, giá đỡ bề mặt và dạng mô-đun, giúp bạn dễ dàng thử nghiệm.

Trước khi tiếp tục, hãy tải xuống bảng dữ liệu. PCF8591 có thể hoạt động trên cả 5V và 3.3V, vì vậy nếu bạn đang sử dụng Arduino Due, Raspberry Pi hoặc bảng phát triển 3.3 V khác thì bạn vẫn ổn. Bây giờ, trước tiên chúng ta sẽ giải thích về DAC, sau đó là ADC.

Bước 1: Sử dụng DAC (Bộ chuyển đổi kỹ thuật số sang tương tự)

Sử dụng DAC (Bộ chuyển đổi kỹ thuật số sang tương tự)
Sử dụng DAC (Bộ chuyển đổi kỹ thuật số sang tương tự)

DAC trên PCF8591 có độ phân giải 8-bit - vì vậy nó có thể tạo ra tín hiệu lý thuyết nằm trong khoảng từ 0 vôn đến điện áp tham chiếu (Vref) trong 255 bước. Đối với mục đích trình diễn, chúng tôi sẽ sử dụng Vref là 5V và bạn có thể sử dụng Vref thấp hơn chẳng hạn như 3.3V hoặc bất kỳ giá trị nào bạn muốn giá trị lớn nhất là… tuy nhiên nó phải nhỏ hơn điện áp cung cấp.

Lưu ý rằng khi có tải trên đầu ra tương tự (tình huống trong thế giới thực), điện áp đầu ra tối đa sẽ giảm - bảng dữ liệu (mà bạn đã tải xuống) cho thấy mức giảm 10% đối với tải 10kΩ. Bây giờ cho mạch trình diễn của chúng tôi.

Lưu ý việc sử dụng điện trở kéo lên 10kΩ trên bus I2C và tụ điện 10μF giữa 5V và GND. Địa chỉ bus I2C được thiết lập bởi sự kết hợp của các chân A0 ~ A2 và với tất cả chúng với GND, địa chỉ là 0x90. Đầu ra tương tự có thể được lấy từ chân 15 (và có một GND tương tự riêng biệt trên chân 13. Ngoài ra, kết nối chân 13 với GND và nối mạch GND với Arduino GND.

Để điều khiển DAC, chúng ta cần gửi hai byte dữ liệu. Đầu tiên là byte điều khiển, chỉ cần kích hoạt DAC và là 1000000 (hoặc 0x40) và byte tiếp theo là giá trị từ 0 đến 255 (mức đầu ra). Điều này được thể hiện trong bản phác thảo sau:

// Ví dụ 52.1 PCF8591 Bản demo DAC

#include "Wire.h" #define PCF8591 (0x90 >> 1) // Địa chỉ bus I2C void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (0x40); // byte điều khiển - bật DAC (binary 1000000) Wire.write (i); // giá trị cần gửi tới DAC Wire.endTransmission (); // kết thúc truyền}

for (int i = 255; i> = 0; --i)

{Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (0x40); // byte điều khiển - bật DAC (binary 1000000) Wire.write (i); // giá trị cần gửi tới DAC Wire.endTransmission (); // end tranmission}}

Bạn có nhận thấy sự thay đổi bit của địa chỉ xe buýt trong câu lệnh #define không? Arduino gửi địa chỉ 7-bit nhưng PCF8591 muốn có 8-bit, vì vậy chúng tôi chuyển byte qua một bit.

Bước 2:

Hình ảnh
Hình ảnh

Kết quả của bản phác thảo được hiển thị trong hình ảnh, chúng tôi đã kết nối Vref với 5V và đầu dò dao động ký và GND với đầu ra tương tự và GND tương ứng.

Bước 3:

Hình ảnh
Hình ảnh

Nếu bạn thích các đường cong, bạn có thể tạo ra các sóng hình sin với bản phác thảo bên dưới. Nó sử dụng một bảng tra cứu trong một mảng chứa các điểm dữ liệu cần thiết được tính toán trước:

// Ví dụ 52.2 PCF8591 Bản demo DAC - sóng sin

#include "Wire.h" #define PCF8591 (0x90 >> 1) // Địa chỉ bus I2C uint8_t sine_wave [256] = {0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96, 0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE, 0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4, 0xC7, 0xC9, 0xCC, 0xCE, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4, 0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD3, 0xD5, 0xD3, 0xD5 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFxF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF1, 0xF5, 0xF4, 0xF3 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0BCC9, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0BC, 0xC9, 0xC7, 0xC4, 0xB 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x70x6 0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52, 0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x 3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18, 0x16, 0x15, 0x13, 0x11, 0x0, 0x0F, 0x11, 0x0C0D0F, 0x11, 0x0C0D0F 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x03 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x24E, 0x26, 0x20, 0x24E, 0x26, 0x28 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x67, 0x6D, 0x61, 0x67, 0x64D, 0x61, 0x67 0x70, 0x74, 0x77, 0x7A, 0x7D}; void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (0x40); // byte điều khiển - bật DAC (binary 1000000) Wire.write (sine_wave ); // giá trị cần gửi tới DAC Wire.endTransmission (); // end tranmission}}

Bước 4:

Hình ảnh
Hình ảnh

Đối với kết xuất hình ảnh DSO sau đây, chúng tôi đã thay đổi Vref thành 3,3V - lưu ý sự thay đổi trong cực đại trên sóng hình sin.

Bây giờ bạn có thể thử nghiệm với DAC để tạo hiệu ứng âm thanh, tín hiệu hoặc điều khiển các mạch tương tự khác.

Bước 5: Sử dụng ADC (Bộ chuyển đổi tương tự sang kỹ thuật số)

Nếu bạn đã sử dụng hàm analogRead () trên Arduino của mình (quay lại Chương một) thì bạn đã quen với ADC. Với PCF8591, chúng ta có thể đọc điện áp từ 0 đến Vref và nó sẽ trả về giá trị từ 0 đến 255 tỷ lệ thuận với 0 và Vref.

Ví dụ: đo 3.3V sẽ trả về 168. Độ phân giải (8-bit) của ADC thấp hơn Arduino trên bo mạch (10-bit) tuy nhiên PCF8591 có thể làm điều gì đó mà Arduino’s ADC không thể. Nhưng chúng ta sẽ đạt được điều đó trong giây lát. Đầu tiên, để chỉ cần đọc các giá trị của mỗi chân ADC, chúng ta gửi một byte điều khiển để cho PCF8591 biết ADC nào chúng ta muốn đọc. Đối với ADC từ 0 đến 3 byte điều khiển lần lượt là 0x00, 0x01, ox02 và 0x03.

Sau đó, chúng tôi yêu cầu hai byte dữ liệu trở lại từ ADC và lưu trữ byte thứ hai để sử dụng. Tại sao lại là hai byte? PCF8591 trả về giá trị đã đo trước đó trước - sau đó là byte hiện tại. (Xem Hình 8 trong bảng dữ liệu). Cuối cùng, nếu bạn không sử dụng tất cả các chân ADC, hãy kết nối những chân không sử dụng với GND. Bản phác thảo ví dụ sau đây chỉ đơn giản là lấy các giá trị từ từng chân ADC một, sau đó hiển thị chúng trong màn hình nối tiếp:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // Địa chỉ bus I2C #define ADC0 0x00 // byte điều khiển để đọc các ADC riêng lẻ #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 byte value0, value1, value2, value3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (ADC0); // byte điều khiển - đọc ADC0 Wire.endTransmission (); // kết thúc tranmission Wire.requestFrom (PCF8591, 2); value0 = Wire.read (); value0 = Wire.read (); Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (ADC1); // byte điều khiển - đọc ADC1 Wire.endTransmission (); // kết thúc tranmission Wire.requestFrom (PCF8591, 2); value1 = Wire.read (); value1 = Wire.read (); Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (ADC2); // byte điều khiển - đọc ADC2 Wire.endTransmission (); // kết thúc tranmission Wire.requestFrom (PCF8591, 2); value2 = Wire.read (); value2 = Wire.read (); Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (ADC3); // byte điều khiển - đọc ADC3 Wire.endTransmission (); // kết thúc tranmission Wire.requestFrom (PCF8591, 2); value3 = Wire.read (); value3 = Wire.read (); Serial.print (value0); Serial.print (""); Serial.print (value1); Serial.print (""); Serial.print (value2); Serial.print (""); Serial.print (value3); Serial.print (""); Serial.println (); }

Khi chạy bản phác thảo, bạn sẽ được xem các giá trị của mỗi ADC trong màn hình nối tiếp. Mặc dù đây là một minh chứng đơn giản để chỉ cho bạn cách đọc riêng từng ADC, nhưng đây là một phương pháp rườm rà để lấy nhiều hơn một byte tại một thời điểm từ một ADC cụ thể.

Bước 6:

Để thực hiện việc này, hãy thay đổi byte điều khiển để yêu cầu tự động tăng, được thực hiện bằng cách đặt bit 2 của byte điều khiển thành 1. Vì vậy, để bắt đầu từ ADC0, chúng tôi sử dụng byte điều khiển mới của nhị phân 00000100 hoặc thập lục phân 0x04. Sau đó, yêu cầu năm byte dữ liệu (một lần nữa chúng tôi bỏ qua byte đầu tiên), điều này sẽ khiến PCF8591 trả về tất cả các giá trị trong một chuỗi byte. Quá trình này được thể hiện trong bản phác thảo sau:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // Địa chỉ bus I2C byte value0, value1, value2, value3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // đánh thức PCF8591 Wire.write (0x04); // byte điều khiển - đọc ADC0 rồi tự động gia tăng Wire.endTransmission (); // kết thúc tranmission Wire.requestFrom (PCF8591, 5); value0 = Wire.read (); value0 = Wire.read (); value1 = Wire.read (); value2 = Wire.read (); value3 = Wire.read (); Serial.print (value0); Serial.print (""); Serial.print (value1); Serial.print (""); Serial.print (value2); Serial.print (""); Serial.print (value3); Serial.print (""); Serial.println (); }

Trước đây, chúng tôi đã đề cập rằng PCF8591 có thể làm điều gì đó mà ADC của Arduino không thể và điều này cung cấp một ADC khác biệt. Trái ngược với kết thúc đơn của Arduino (tức là nó trả về sự khác biệt giữa điện áp tín hiệu dương và GND, bộ ADC vi sai chấp nhận hai tín hiệu (không nhất thiết phải được tham chiếu đến mặt đất) và trả về sự khác biệt giữa hai tín hiệu Điều này có thể thuận tiện cho việc đo những thay đổi nhỏ về điện áp của các cảm biến lực, v.v.

Bước 7:

Hình ảnh
Hình ảnh

Việc thiết lập PCF8591 cho ADC vi sai là một vấn đề đơn giản thay đổi byte điều khiển. Nếu bạn lật đến trang bảy của bảng dữ liệu, hãy xem xét các kiểu lập trình đầu vào tương tự khác nhau. Trước đây, chúng tôi sử dụng chế độ '00' cho bốn đầu vào, tuy nhiên bạn có thể chọn các đầu vào khác được minh họa rõ ràng, ví dụ như hình ảnh.

Vì vậy, để đặt byte điều khiển cho hai đầu vào vi phân, hãy sử dụng nhị phân 00110000 hoặc 0x30. Sau đó, vấn đề đơn giản là yêu cầu các byte dữ liệu và làm việc với chúng. Như bạn có thể thấy cũng có kết hợp đơn / vi sai và đầu vào ba vi sai phức tạp. Tuy nhiên, chúng tôi sẽ để lại chúng trong lúc này.

Hy vọng rằng bạn nhận thấy điều này quan tâm, cho dù thêm DAC vào các thử nghiệm của bạn hay tìm hiểu thêm một chút về ADC. Vui lòng xem xét đặt mua PCF8591 của bạn từ PMD Way.

Bài đăng này do pmdway.com mang đến cho bạn - mọi thứ dành cho các nhà sản xuất và những người đam mê điện tử, với giao hàng miễn phí trên toàn thế giới.

Đề xuất: