Cuprins:

Arduino și PCF8591 ADC DAC IC: 7 pași
Arduino și PCF8591 ADC DAC IC: 7 pași

Video: Arduino și PCF8591 ADC DAC IC: 7 pași

Video: Arduino și PCF8591 ADC DAC IC: 7 pași
Video: Electronic Basics #10: Digital to Analog Converter (DAC) 2024, Iulie
Anonim
IC Arduino și PCF8591 ADC DAC
IC Arduino și PCF8591 ADC DAC

V-ați dorit vreodată mai mulți pini de intrare analogici în proiectul dvs. Arduino, dar nu ați dorit să obțineți un Mega? Sau ați dori să generați semnale analogice? Apoi verificați subiectul tutorialului nostru - IC NXP PCF8591.

Rezolvă atât aceste probleme, deoarece are un singur convertor DAC (digital la analog), cât și patru ADC (convertoare analogice la digitale) - toate accesibile prin intermediul magistralei I2C. PCF8591 este disponibil sub formă de DIP, montare pe suprafață și modul, ceea ce îl face ușor de experimentat.

Înainte de a trece mai departe, descărcați fișa tehnică. PCF8591 poate funcționa atât pe 5V, cât și pe 3.3V, deci dacă utilizați un Arduino Due, Raspberry Pi sau altă placă de dezvoltare de 3,3 V, sunteți bine. Acum vom explica mai întâi DAC, apoi ADC-urile.

Pasul 1: Utilizarea DAC (convertor digital-analog)

Utilizarea DAC (convertor digital-analog)
Utilizarea DAC (convertor digital-analog)

DAC-ul de pe PCF8591 are o rezoluție de 8 biți - deci poate genera un semnal teoretic între zero volți și tensiunea de referință (Vref) în 255 de pași. În scopuri demonstrative, vom folosi un Vref de 5V și puteți utiliza un Vref inferior, cum ar fi 3,3V sau orice doriți să fie valoarea maximă … totuși trebuie să fie mai mică decât tensiunea de alimentare.

Rețineți că atunci când există o sarcină pe ieșirea analogică (o situație din lumea reală), tensiunea maximă de ieșire va scădea - foaia de date (pe care ați descărcat-o) arată o scădere de 10% pentru o sarcină de 10kΩ. Acum, pentru circuitul nostru demonstrativ.

Rețineți utilizarea rezistențelor de tracțiune de 10kΩ pe magistrala I2C și a condensatorului de 10μF între 5V și GND. Adresa autobuzului I2C este setată de o combinație de pini A0 ~ A2, iar cu toate acestea la GND adresa este 0x90. Ieșirea analogică poate fi preluată de la pinul 15 (și există un GND analogic separat pe pinul 13. De asemenea, conectați pinul 13 la GND și conectați GND la Arduino GND.

Pentru a controla DAC, trebuie să trimitem doi octeți de date. Primul este octetul de control, care activează pur și simplu DAC și este 1000000 (sau 0x40), iar următorul octet este valoarea între 0 și 255 (nivelul de ieșire). Acest lucru este demonstrat în următoarea schiță:

// Exemplul 52.1 Demo PCF8591 DAC

#includeți „Wire.h” #define PCF8591 (0x90 >> 1) // I2C bus address void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // trezește PCF8591 Wire.write (0x40); // octet de control - activați DAC (binar 1000000) Wire.write (i); // valoare de trimis către DAC Wire.endTransmission (); // sfârșitul transmisiei}

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

{Wire.beginTransmission (PCF8591); // treziți PCF8591 Wire.write (0x40); // octet de control - activați DAC (binar 1000000) Wire.write (i); // valoare de trimis către DAC Wire.endTransmission (); // sfârșitul transmisiei}}

Ați observat schimbarea de biți a adresei autobuzului în declarația #define? Arduino trimite adrese pe 7 biți, dar PCF8591 dorește 8 biți, așa că schimbăm octetul cu un bit.

Pasul 2:

Imagine
Imagine

Rezultatele schiței sunt afișate în imagine, am conectat Vref la 5V și sonda osciloscopului și GND la ieșirea analogică și respectiv GND.

Pasul 3:

Imagine
Imagine

Dacă vă plac curbele, puteți genera unde sinusoidale cu schița de mai jos. Folosește un tabel de căutare într-o matrice care conține punctele de date precalculate necesare:

// Exemplul 52.2 Demo PCF8591 DAC - undă sinusoidală

#include "Wire.h" #define PCF8591 (0x90 >> 1) // Adresa autobuzului 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, 0xD, 0xD, 0xD, 0xD, 0xD 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xF, 0xFC, 0xF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xFx, 0xFx, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xB, 0xB, 0xB 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x77, 0x7 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 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0x0, 0x0x0 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1x, 0x, 22, 0 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x61, 0x61, 0x61 0x70, 0x74, 0x77, 0x7A, 0x7D}; void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // treziți PCF8591 Wire.write (0x40); // octet de control - activați DAC (binar 1000000) Wire.write (sine_wave ); // valoare de trimis către DAC Wire.endTransmission (); // sfârșitul transmisiei}}

Pasul 4:

Imagine
Imagine

Pentru următoarea descărcare a imaginii DSO, am schimbat Vref la 3,3V - observați modificarea valorilor maxime pe unde sinusoidale.

Acum puteți experimenta cu DAC pentru a produce efecte sonore, semnale sau controla alte circuite analogice.

Pasul 5: Utilizarea ADC-urilor (convertoare analog-digital)

Dacă ați folosit funcția analogRead () pe Arduino (înapoi în capitolul unu), atunci sunteți deja familiarizat cu un ADC. Cu PCF8591 putem citi o tensiune între zero și Vref și va returna o valoare între zero și 255, care este direct proporțională cu zero și Vref.

De exemplu, măsurarea 3,3V ar trebui să returneze 168. Rezoluția (8 biți) a ADC este mai mică decât Arduino la bord (10 biți), totuși PCF8591 poate face ceva ADC-ul Arduino nu. Dar vom ajunge la asta într-o clipă. În primul rând, pentru a citi pur și simplu valorile fiecărui pin ADC, trimitem un octet de control pentru a spune PCF8591 ce ADC dorim să citim. Pentru ADC-uri de la zero la trei octetul de control este 0x00, 0x01, ox02 și respectiv 0x03.

Apoi solicităm doi octeți de date înapoi de la ADC și stocăm al doilea octet pentru utilizare. De ce doi octeți? PCF8591 returnează mai întâi valoarea măsurată anterior - apoi octetul curent. (Vezi Figura 8 din foaia de date). În cele din urmă, dacă nu utilizați toți pinii ADC, conectați-i pe cei neutilizați la GND. Următorul schiță de exemplu preia pur și simplu valorile din fiecare pin ADC unul câte unul, apoi le afișează în monitorul serial:

#include „Wire.h”

#define PCF8591 (0x90 >> 1) // Adresa autobuzului I2C #define ADC0 0x00 // octeți de control pentru citirea ADC-urilor individuale #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 octet value0, value1, value2, value3; void setup () {Wire.begin (); Serial.begin (9600); } bucla void () {Wire.beginTransmission (PCF8591); // treziți PCF8591 Wire.write (ADC0); // octet de control - citiți ADC0 Wire.endTransmission (); // încheie tranmission Wire.requestFrom (PCF8591, 2); valoare0 = Wire.read (); valoare0 = Wire.read (); Wire.beginTransmission (PCF8591); // treziți PCF8591 Wire.write (ADC1); // octet de control - citiți ADC1 Wire.endTransmission (); // încheie tranmission Wire.requestFrom (PCF8591, 2); valoare1 = Wire.read (); valoare1 = Wire.read (); Wire.beginTransmission (PCF8591); // treziți PCF8591 Wire.write (ADC2); // octet de control - citiți ADC2 Wire.endTransmission (); // încheie tranmission Wire.requestFrom (PCF8591, 2); valoare2 = Wire.read (); valoare2 = Wire.read (); Wire.beginTransmission (PCF8591); // treziți PCF8591 Wire.write (ADC3); // octet de control - citiți ADC3 Wire.endTransmission (); // încheie tranmission Wire.requestFrom (PCF8591, 2); valoare3 = Wire.read (); valoare3 = Wire.read (); Serial.print (valoare0); Serial.print (""); Serial.print (valoare1); Serial.print (""); Serial.print (valoare2); Serial.print (""); Serial.print (valoare3); Serial.print (""); Serial.println (); }

La rularea schiței vi se vor prezenta valorile fiecărui ADC pe monitorul serial. Deși a fost o demonstrație simplă pentru a vă arăta cum să citiți fiecare ADC, este o metodă greoaie de a obține mai mult de un octet la un moment dat dintr-un anumit ADC.

Pasul 6:

Pentru a face acest lucru, modificați octetul de control pentru a solicita creșterea automată, ceea ce se face prin setarea bitului 2 al octetului de control la 1. Deci, pentru a începe de la ADC0, utilizăm un nou octet de control al binarului 00000100 sau hexazecimal 0x04. Apoi solicitați cinci octeți de date (încă o dată ignorăm primul octet) ceea ce va determina PCF8591 să returneze toate valorile într-un lanț de octeți. Acest proces este demonstrat în următoarea schiță:

#include „Wire.h”

#define PCF8591 (0x90 >> 1) // I2C bus address address byte value0, value1, value2, value3; void setup () {Wire.begin (); Serial.begin (9600); } bucla void () {Wire.beginTransmission (PCF8591); // trezește PCF8591 Wire.write (0x04); // octet de control - citiți ADC0 apoi auto-incrementați Wire.endTransmission (); // încheie tranmission Wire.requestFrom (PCF8591, 5); valoare0 = Wire.read (); valoare0 = Wire.read (); valoare1 = Wire.read (); valoare2 = Wire.read (); valoare3 = Wire.read (); Serial.print (valoare0); Serial.print (""); Serial.print (valoare1); Serial.print (""); Serial.print (valoare2); Serial.print (""); Serial.print (valoare3); Serial.print (""); Serial.println (); }

Anterior am menționat că PCF8591 poate face ceva ce ADC-ul Arduino nu poate, iar acesta oferă un ADC diferențial. Spre deosebire de Arduino cu un singur capăt (adică returnează diferența dintre tensiunea pozitivă a semnalului și GND, diferențialul ADC acceptă două semnale (care nu trebuie neapărat să fie referite la masă) și returnează diferența dintre cele două semnale Acest lucru poate fi convenabil pentru măsurarea micilor modificări de tensiune pentru celulele de sarcină și așa mai departe.

Pasul 7:

Imagine
Imagine

Configurarea PCF8591 pentru ADC diferențial este o chestiune simplă de schimbare a octetului de control. Dacă treceți la pagina șapte din foaia de date, atunci luați în considerare diferitele tipuri de programare de intrare analogică. Anterior am folosit modul '00' pentru patru intrări, totuși puteți selecta celelalte care sunt clar ilustrate, de exemplu imaginea.

Deci, pentru a seta octetul de control pentru două intrări diferențiale, utilizați binarul 00110000 sau 0x30. Apoi, este o chestiune simplă de a solicita octeții de date și de a lucra cu ei. După cum puteți vedea, există, de asemenea, o combinație single / diferențială și o intrare complexă cu trei diferențiale. Cu toate acestea, le vom lăsa pentru moment.

Sperăm că ați găsit acest lucru interesant, fie că adăugați un DAC la experimentele dvs., fie că aflați mai multe despre ADC-uri. Vă rugăm să luați în considerare comanda PCF8591 de la PMD Way.

Această postare ți-a fost adusă de pmdway.com - totul pentru producătorii și pasionații de electronice, cu livrare gratuită în toată lumea.

Recomandat: