Isi kandungan:

Arduino dan PCF8591 ADC DAC IC: 7 Langkah
Arduino dan PCF8591 ADC DAC IC: 7 Langkah

Video: Arduino dan PCF8591 ADC DAC IC: 7 Langkah

Video: Arduino dan PCF8591 ADC DAC IC: 7 Langkah
Video: Step-by-Step ARDUINO Step#7 Analog to Digital Converter (ADC) | Arduino Uno & coding 2024, Julai
Anonim
Arduino dan PCF8591 ADC DAC IC
Arduino dan PCF8591 ADC DAC IC

Adakah anda pernah mahukan lebih banyak pin input analog untuk projek Arduino anda, tetapi tidak mahu membeli Mega? Atau adakah anda ingin menghasilkan isyarat analog? Kemudian lihat tajuk tutorial kami - NXP PCF8591 IC.

Ia menyelesaikan kedua-dua masalah ini kerana ia mempunyai penukar DAC tunggal (digital ke analog) serta empat ADC (penukar analog ke digital) - semuanya boleh diakses melalui bas I2C. PCF8591 tersedia dalam bentuk DIP, permukaan permukaan dan modul, yang memudahkan percubaan.

Sebelum meneruskan, muat turun lembaran data. PCF8591 dapat beroperasi pada kedua-dua 5V dan 3.3V jadi jika anda menggunakan Arduino Due, Raspberry Pi atau papan pengembangan 3.3 V yang lain, Anda baik-baik saja. Sekarang kita akan menerangkan DAC terlebih dahulu, kemudian ADC.

Langkah 1: Menggunakan DAC (digital-to-analog Converter)

Menggunakan DAC (penukar digital-ke-analog)
Menggunakan DAC (penukar digital-ke-analog)

DAC pada PCF8591 mempunyai resolusi 8-bit - sehingga dapat menghasilkan isyarat teoritis antara voltan sifar dan voltan rujukan (Vref) dalam 255 langkah. Untuk tujuan demonstrasi, kami akan menggunakan Vref 5V, dan anda boleh menggunakan Vref yang lebih rendah seperti 3.3V atau apa sahaja yang anda mahukan nilai maksimumnya … namun ia mestilah kurang daripada voltan bekalan.

Perhatikan bahawa apabila terdapat beban pada output analog (keadaan dunia nyata), voltan output maksimum akan turun - lembaran data (yang anda muat turun) menunjukkan penurunan 10% untuk beban 10kΩ. Sekarang untuk litar demonstrasi kami.

Perhatikan penggunaan resistor penarik 10kΩ pada bas I2C, dan kapasitor 10μF antara 5V dan GND. Alamat bas I2C ditetapkan oleh kombinasi pin A0 ~ A2, dan dengan semuanya GND alamatnya adalah 0x90. Output analog boleh diambil dari pin 15 (dan ada GND analog yang terpisah pada pin 13. Juga, sambungkan pin 13 ke GND, dan litar GND ke Arduino GND.

Untuk mengawal DAC, kami perlu menghantar dua bait data. Yang pertama adalah byte kawalan, yang hanya mengaktifkan DAC dan 1000000 (atau 0x40) dan bait seterusnya adalah nilai antara 0 dan 255 (tahap output). Ini ditunjukkan dalam lakaran berikut:

// Contoh demo DAC 52.1 PCF8591

#include "Wire.h" #define PCF8591 (0x90 >> 1) // Alamat bas I2C tidak disiapkan () {Wire.begin (); } gelung void () {untuk (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (0x40); // kawalan byte - hidupkan DAC (binary 1000000) Wire.write (i); // nilai untuk dihantar ke DAC Wire.endTransmission (); // penghantaran akhir}

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

{Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (0x40); // kawalan byte - hidupkan DAC (binary 1000000) Wire.write (i); // nilai untuk dihantar ke DAC Wire.endTransmission (); // penghantaran akhir}}

Adakah anda perhatikan sedikit perubahan alamat bas dalam pernyataan #define? Arduino menghantar alamat 7-bit tetapi PCF8591 menginginkan 8-bit, jadi kami menggeser bait itu sedikit demi sedikit.

Langkah 2:

Imej
Imej

Hasil lakaran ditunjukkan dalam gambar, kami telah menghubungkan Vref ke 5V dan probe osiloskop dan GND ke output analog dan GND masing-masing.

Langkah 3:

Imej
Imej

Sekiranya anda suka lekuk, anda boleh menghasilkan gelombang sinus dengan lakaran di bawah. Ia menggunakan jadual carian dalam array yang mengandungi titik data yang telah dikira sebelumnya:

// Contoh 52.2 Demo - gelombang sinus PCF8591 DAC

#include "Wire.h" #define PCF8591 (0x90 >> 1) // Alamat bas 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, 0xD1, 0xD3, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD 0, 0xD 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xF, 0xF, 0xF, 0xF, 0xF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0x4, 0x4, 0xF, 0xF, 0xF 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0x6, 0xC4, 0xB 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77 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, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x1, 0x1, 0x1, 0x1 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61 0x70, 0x74, 0x77, 0x7A, 0x7D}; batal persediaan () {Wire.begin (); } gelung void () {untuk (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (0x40); // control byte - hidupkan DAC (binary 1000000) Wire.write (sine_wave ); // nilai untuk dihantar ke DAC Wire.endTransmission (); // penghantaran akhir}}

Langkah 4:

Imej
Imej

Untuk pembuangan gambar DSO berikut, kami menukar Vref menjadi 3.3V - perhatikan perubahan maksima pada gelombang sinus.

Sekarang anda boleh bereksperimen dengan DAC untuk membuat kesan bunyi, isyarat atau mengawal litar analog yang lain.

Langkah 5: Menggunakan ADC (Penukar analog ke digital)

Sekiranya anda telah menggunakan fungsi analogRead () pada Arduino anda (kembali ke Bab Satu), maka anda sudah biasa dengan ADC. Tanpa PCF8591 kita dapat membaca voltan antara sifar dan Vref dan ia akan mengembalikan nilai antara sifar dan 255 yang berkadar langsung dengan sifar dan Vref.

Sebagai contoh, ukuran 3.3V harus kembali 168. Resolusi (8-bit) ADC lebih rendah daripada Arduino onboard (10-bit) namun PCF8591 dapat melakukan sesuatu yang tidak dapat dilakukan oleh ADC Arduino. Tetapi kita akan sampai ke sana sebentar. Pertama, untuk membaca nilai setiap pin ADC, kami menghantar bait kawalan untuk memberitahu PCF8591 mana ADC yang ingin kami baca. Untuk ADC sifar hingga tiga bait kawalan masing-masing adalah 0x00, 0x01, ox02 dan 0x03.

Kemudian kami meminta dua bait data kembali dari ADC, dan menyimpan bait kedua untuk digunakan. Mengapa dua bait? PCF8591 mengembalikan nilai yang diukur sebelumnya terlebih dahulu - kemudian bait semasa. (Lihat Rajah 8 dalam lembaran data). Akhirnya, jika anda tidak menggunakan semua pin ADC, sambungkan pin yang tidak digunakan ke GND. Sketsa contoh berikut hanya mengambil nilai dari setiap pin ADC satu demi satu, kemudian memaparkannya di monitor bersiri:

#sertakan "Wire.h"

#define PCF8591 (0x90 >> 1) // alamat bas I2C #define ADC0 0x00 // bait kawalan untuk membaca ADC individu #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 byte value0, value1, value2, value3; batal persediaan () {Wire.begin (); Serial.begin (9600); } gelung kosong () {Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (ADC0); // kawalan bait - baca ADC0 Wire.endTransmission (); // end tranmission Wire.requestFrom (PCF8591, 2); nilai0 = Wire.read (); nilai0 = Wire.read (); Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (ADC1); // kawalan bait - baca ADC1 Wire.endTransmission (); // end tranmission Wire.requestFrom (PCF8591, 2); nilai1 = Wire.read (); nilai1 = Wire.read (); Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (ADC2); // kawalan bait - baca ADC2 Wire.endTransmission (); // end tranmission Wire.requestFrom (PCF8591, 2); nilai2 = Wire.read (); nilai2 = Wire.read (); Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (ADC3); // kawalan bait - baca ADC3 Wire.endTransmission (); // end tranmission Wire.requestFrom (PCF8591, 2); nilai3 = Wire.read (); nilai3 = Wire.read (); Cetakan bersiri (nilai0); Cetakan bersiri (""); Cetakan bersiri (nilai1); Cetakan bersiri (""); Cetakan bersiri (nilai2); Cetakan bersiri (""); Cetakan bersiri (nilai3); Cetakan bersiri (""); Bersiri.println (); }

Setelah menjalankan lakaran, anda akan diberi nilai setiap ADC di monitor bersiri. Walaupun ini adalah demonstrasi sederhana untuk menunjukkan kepada anda bagaimana membaca setiap ADC secara berasingan, ini adalah kaedah yang sukar untuk mendapatkan lebih dari satu bait pada satu masa dari ADC tertentu.

Langkah 6:

Untuk melakukan ini, ubah bait kawalan untuk meminta kenaikan automatik, yang dilakukan dengan menetapkan bit 2 bait kawalan menjadi 1. Oleh itu untuk bermula dari ADC0 kita menggunakan bait kawalan baru binari 00000100 atau heksadesimal 0x04. Kemudian minta lima bait data (sekali lagi kita mengabaikan bait pertama) yang akan menyebabkan PCF8591 mengembalikan semua nilai dalam satu rantai bait. Proses ini ditunjukkan dalam lakaran berikut:

#sertakan "Wire.h"

#define PCF8591 (0x90 >> 1) // bait alamat bus I2C nilai0, nilai1, nilai2, nilai3; batal persediaan () {Wire.begin (); Serial.begin (9600); } gelung kosong () {Wire.beginTransmission (PCF8591); // bangunkan PCF8591 Wire.write (0x04); // kawalan bait - baca ADC0 kemudian kenaikan automatik Wire.endTransmission (); // end tranmission Wire.requestFrom (PCF8591, 5); nilai0 = Wire.read (); nilai0 = Wire.read (); nilai1 = Wire.read (); nilai2 = Wire.read (); nilai3 = Wire.read (); Serial.print (nilai0); Cetakan bersiri (""); Cetakan bersiri (nilai1); Cetakan bersiri (""); Cetakan bersiri (nilai2); Cetakan bersiri (""); Cetakan bersiri (nilai3); Cetakan bersiri (""); Bersiri.println (); }

Sebelumnya kami telah menyebutkan bahawa PCF8591 dapat melakukan sesuatu yang tidak dapat dilakukan oleh ADC Arduino, dan ini menawarkan ADC yang berbeza. Berbanding dengan ujung tunggal Arduino (iaitu mengembalikan perbezaan antara voltan isyarat positif dan GND, ADC pembezaan menerima dua isyarat (yang tidak semestinya harus dirujuk ke tanah), dan mengembalikan perbezaan antara dua isyarat Ini boleh digunakan untuk mengukur perubahan kecil voltan untuk sel beban dan sebagainya.

Langkah 7:

Imej
Imej

Menyiapkan PCF8591 untuk ADC pembezaan adalah perkara mudah untuk menukar bait kawalan. Sekiranya anda beralih ke halaman tujuh lembaran data, maka pertimbangkan pelbagai jenis pengaturcaraan input analog. Sebelumnya kami menggunakan mod '00' untuk empat input, namun anda boleh memilih yang lain yang digambarkan dengan jelas, misalnya gambar.

Oleh itu, untuk menetapkan bait kawalan untuk dua input pembezaan, gunakan binari 00110000 atau 0x30. Oleh itu, adalah mudah untuk meminta bait data dan bekerja dengannya. Seperti yang anda lihat terdapat juga gabungan tunggal / pembeza dan input tiga pembezaan yang kompleks. Walau bagaimanapun, kami akan meninggalkannya buat masa ini.

Semoga anda mendapat minat ini, sama ada menambahkan DAC pada percubaan anda atau mengetahui lebih lanjut mengenai ADC. Sila pertimbangkan untuk memesan PCF8591 anda dari PMD Way.

Catatan ini disampaikan kepada anda oleh pmdway.com - semuanya untuk pembuat dan peminat elektronik, dengan penghantaran percuma ke seluruh dunia.

Disyorkan: