İçindekiler:

Arduino ve PCF8591 ADC DAC IC: 7 Adım
Arduino ve PCF8591 ADC DAC IC: 7 Adım

Video: Arduino ve PCF8591 ADC DAC IC: 7 Adım

Video: Arduino ve PCF8591 ADC DAC IC: 7 Adım
Video: How to Interface PCF8591 ADC/DAC Module with Arduino 2024, Kasım
Anonim
Arduino ve PCF8591 ADC DAC IC
Arduino ve PCF8591 ADC DAC IC

Arduino projenizde hiç daha fazla analog giriş pini istediniz, ancak bir Mega için ayrılmak istemediniz mi? Yoksa analog sinyaller mi üretmek istiyorsunuz? Ardından eğitimimizin konusuna göz atın – NXP PCF8591 IC.

Tek bir DAC (dijitalden analoğa) dönüştürücünün yanı sıra dört ADC'ye (analogdan dijitale dönüştürücüler) sahip olduğu için bu sorunların her ikisini de çözer - hepsine I2C veriyolu üzerinden erişilebilir. PCF8591, denemeyi kolaylaştıran DIP, yüzeye montaj ve modül biçiminde mevcuttur.

Devam etmeden önce veri sayfasını indirin. PCF8591 hem 5V hem de 3.3V üzerinde çalışabilir, yani bir Arduino Due, Raspberry Pi veya diğer 3.3V geliştirme kartı kullanıyorsanız sorun yok. Şimdi önce DAC'yi, sonra ADC'leri açıklayacağız.

Adım 1: DAC'yi (dijitalden analoga Dönüştürücü) kullanma

DAC'yi (dijitalden analoga Dönüştürücü) kullanma
DAC'yi (dijitalden analoga Dönüştürücü) kullanma

PCF8591'deki DAC, 8 bit çözünürlüğe sahiptir - bu nedenle, 255 adımda sıfır volt ile referans voltajı (Vref) arasında teorik bir sinyal üretebilir. Gösteri amacıyla 5V'luk bir Vref kullanacağız ve 3.3V gibi daha düşük bir Vref veya maksimum değerin ne olmasını istiyorsanız onu kullanabilirsiniz… ancak bu, besleme voltajından daha az olmalıdır.

Analog çıkışta bir yük olduğunda (gerçek dünya durumu), maksimum çıkış voltajının düşeceğini unutmayın - veri sayfası (indirdiğiniz) 10kΩ yük için %10'luk bir düşüş gösterir. Şimdi gösteri devremiz için.

I2C veriyolunda 10kΩ çekme dirençlerinin ve 5V ile GND arasında 10μF kapasitör kullanımına dikkat edin. I2C veri yolu adresi, A0~A2 pinlerinin bir kombinasyonu ile ayarlanır ve hepsi GND'ye göre adres 0x90'dır. Analog çıkış pim 15'ten alınabilir (ve pim 13'te ayrı bir analog GND vardır. Ayrıca pim 13'ü GND'ye ve GND'yi Arduino GND'ye bağlayın.

DAC'yi kontrol etmek için iki bayt veri göndermemiz gerekiyor. İlki, DAC'yi basitçe etkinleştiren ve 1000000 (veya 0x40) olan kontrol baytıdır ve sonraki bayt, 0 ile 255 (çıkış seviyesi) arasındaki değerdir. Bu, aşağıdaki çizimde gösterilmiştir:

// Örnek 52.1 PCF8591 DAC demosu

#include "Wire.h" #define PCF8591 (0x90 >> 1) // I2C bus adresi void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(0x40) uyandır; // kontrol baytı - DAC'yi aç (ikili 1000000) Wire.write(i); // DAC Wire.endTransmission()'a gönderilecek değer; // iletimi sonlandır }

için (int i=255; i>=0; --i)

{ Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(0x40) uyandır; // kontrol baytı - DAC'yi aç (ikili 1000000) Wire.write(i); // DAC Wire.endTransmission()'a gönderilecek değer; // iletimi sonlandır } }

#define ifadesindeki veri yolu adresinin bit kaymasını fark ettiniz mi? Arduino 7 bit adresler gönderir ancak PCF8591 8 bit ister, bu nedenle baytı bir bit kaydırırız.

Adım 2:

resim
resim

Çizimin sonuçları resimde gösteriliyor, Vref'i 5V'a ve osiloskop probunu ve GND'yi sırasıyla analog çıkışa ve GND'ye bağladık.

Aşama 3:

resim
resim

Eğrileri seviyorsanız, aşağıdaki çizim ile sinüs dalgaları oluşturabilirsiniz. Gerekli önceden hesaplanmış veri noktalarını içeren bir dizide bir arama tablosu kullanır:

// Örnek 52.2 PCF8591 DAC demosu - sinüs dalgası

#include "Wire.h" #define PCF8591 (0x90 >> 1) // I2C veri yolu adresi 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, 0xD5xDA, 0xD8, 0xD5, 0xD8, 0x, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 01,F3, 0xF 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xC1, 0xBC, 0xBx, 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x6, 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,F 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, x 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0,x22, 0x20, 0,x22, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5D, 0x61, 0,x64 0x70, 0x74, 0x77, 0x7A, 0x7D }; geçersiz kurulum() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(0x40) uyandır; // kontrol baytı - DAC'yi aç (ikili 1000000) Wire.write(sine_wave); // DAC Wire.endTransmission()'a gönderilecek değer; // iletimi sonlandır } }

4. Adım:

resim
resim

Aşağıdaki DSO görüntü dökümü için Vref'i 3.3V olarak değiştirdik – sinüs dalgasındaki maksimumdaki değişikliğe dikkat edin.

Artık ses efektleri, sinyaller yapmak veya diğer analog devreleri kontrol etmek için DAC ile deneyler yapabilirsiniz.

Adım 5: ADC'lerin (analogdan dijitale Dönüştürücüler) kullanılması

Arduino'nuzda analogRead() işlevini kullandıysanız (Birinci Bölüme geri dönersek), o zaman zaten bir ADC'ye aşinasınızdır. PCF8591 ile sıfır ile Vref arasındaki bir voltajı okuyabilir ve sıfır ve Vref ile doğru orantılı olan sıfır ile 255 arasında bir değer döndürür.

Örneğin, 3.3V ölçmek 168 döndürmelidir. ADC'nin çözünürlüğü (8-bit) yerleşik Arduino'dan (10-bit) daha düşüktür, ancak PCF8591, Arduino'nun ADC'sinin yapamadığı bir şeyi yapabilir. Ama buna birazdan geleceğiz. İlk olarak, her ADC pininin değerlerini okumak için PCF8591'e hangi ADC'yi okumak istediğimizi söylemek için bir kontrol baytı göndeririz. Sıfırdan üçe kadar olan ADC'ler için kontrol baytı sırasıyla 0x00, 0x01, ox02 ve 0x03'tür.

Ardından ADC'den iki bayt veri istiyoruz ve ikinci baytı kullanım için saklıyoruz. Neden iki bayt? PCF8591 önce önceden ölçülen değeri, ardından geçerli baytı döndürür. (Veri sayfasındaki Şekil 8'e bakın). Son olarak, tüm ADC pinlerini kullanmıyorsanız, kullanılmayanları GND'ye bağlayın. Aşağıdaki örnek çizim, her bir ADC pininden değerleri birer birer alır ve ardından bunları seri monitörde görüntüler:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // I2C bus adresi #define ADC0 0x00 // bireysel ADC'leri okumak için kontrol baytları #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 bayt değer0, değer1, değer2, değer3; geçersiz kurulum() { Wire.begin(); Seri.başla(9600); } void loop() { Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(ADC0)'ı uyandır; // kontrol baytı - okuma ADC0 Wire.endTransmission(); // iletimi sonlandır Wire.requestFrom(PCF8591, 2); değer0=Tel.read(); değer0=Tel.read(); Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(ADC1) uyandır; // kontrol baytı - okuma ADC1 Wire.endTransmission(); // iletimi sonlandır Wire.requestFrom(PCF8591, 2); değer1=Tel.read(); değer1=Tel.read(); Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(ADC2)'yi uyandır; // kontrol baytı - okuma ADC2 Wire.endTransmission(); // iletimi sonlandır Wire.requestFrom(PCF8591, 2); değer2=Tel.read(); değer2=Tel.read(); Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(ADC3) uyandır; // kontrol baytı - okuma ADC3 Wire.endTransmission(); // iletimi sonlandır Wire.requestFrom(PCF8591, 2); değer3=Tel.read(); değer3=Tel.read(); Seri.baskı(değer0); Seri.print(" "); Seri.baskı(değer1); Seri.print(" "); Seri.baskı(değer2); Seri.print(" "); Seri.baskı(değer3); Seri.print(" "); Seri.println(); }

Çizimi çalıştırdıktan sonra, seri monitörde her ADC'nin değerleri size sunulacaktır. Her ADC'yi ayrı ayrı nasıl okuyacağınızı göstermek için basit bir gösteri olmasına rağmen, belirli bir ADC'den bir seferde birden fazla bayt almanın zahmetli bir yöntemidir.

6. Adım:

Bunu yapmak için, kontrol baytının bit 2'sini 1'e ayarlayarak yapılan otomatik artış talep etmek için kontrol baytını değiştirin. Dolayısıyla, ADC0'dan başlamak için yeni bir ikili 00000100 veya onaltılık 0x04 kontrol baytı kullanıyoruz. Ardından, PCF8591'in tüm değerleri bir bayt zincirinde döndürmesine neden olacak beş bayt veri isteyin (bir kez daha ilk baytı yok sayarız). Bu işlem aşağıdaki çizimde gösterilmiştir:

#include "Wire.h"

#define PCF8591 (0x90 >> 1) // I2C bus adresi bayt değeri0, değer1, değer2, değer3; geçersiz kurulum() { Wire.begin(); Seri.başla(9600); } void loop() { Wire.beginTransmission(PCF8591); // PCF8591 Wire.write(0x04) uyandır; // kontrol baytı - ADC0'ı okuyun ve ardından Wire.endTransmission()'ı otomatik artırın; // iletimi sonlandır Wire.requestFrom(PCF8591, 5); değer0=Tel.read(); değer0=Tel.read(); değer1=Tel.read(); değer2=Tel.read(); değer3=Tel.read(); Seri.baskı(değer0); Seri.print(" "); Seri.baskı(değer1); Seri.print(" "); Seri.baskı(değer2); Seri.print(" "); Seri.baskı(değer3); Seri.print(" "); Seri.println(); }

Daha önce PCF8591'in Arduino'nun ADC'sinin yapamadığı bir şeyi yapabileceğinden bahsetmiştik ve bu bir diferansiyel ADC sunuyor. Arduino'nun tek uçlu (yani pozitif sinyal voltajı ve GND arasındaki farkı döndürür) aksine, diferansiyel ADC iki sinyali kabul eder (bunun mutlaka toprağa referans olması gerekmez) ve iki sinyal arasındaki farkı döndürür Bu, yük hücreleri vb. için voltajlardaki küçük değişiklikleri ölçmek için uygun olabilir.

7. Adım:

resim
resim

PCF8591'i diferansiyel ADC için ayarlamak, kontrol baytını değiştirmek gibi basit bir meseledir. Veri sayfasının yedinci sayfasına dönerseniz, farklı analog giriş programlama türlerini göz önünde bulundurun. Daha önce dört giriş için '00' modunu kullandık, ancak örneğin resim gibi açıkça gösterilen diğerlerini seçebilirsiniz.

Bu nedenle, iki diferansiyel giriş için kontrol baytını ayarlamak için ikili 00110000 veya 0x30 kullanın. O zaman, veri baytlarını istemek ve onlarla çalışmak basit bir meseledir. Gördüğünüz gibi, tek/diferansiyel ve karmaşık üç diferansiyel giriş kombinasyonu da var. Ancak onları şimdilik bırakacağız.

Deneylerinize bir DAC eklemek veya ADC'ler hakkında biraz daha fazla bilgi edinmek olsun, umarım bunu ilginizi çekmiştir. Lütfen PCF8591'inizi PMD Way'den sipariş etmeyi düşünün.

Bu gönderi size pmdway.com tarafından getirildi - dünya çapında ücretsiz teslimat ile üreticiler ve elektronik meraklıları için her şey.

Önerilen: