Indholdsfortegnelse:

Arduino og PCF8591 ADC DAC IC: 7 trin
Arduino og PCF8591 ADC DAC IC: 7 trin

Video: Arduino og PCF8591 ADC DAC IC: 7 trin

Video: Arduino og PCF8591 ADC DAC IC: 7 trin
Video: Модуль ADS1115, 16-Bit АЦП, Обзор 2024, November
Anonim
Arduino og PCF8591 ADC DAC IC
Arduino og PCF8591 ADC DAC IC

Har du nogensinde ønsket dig flere analoge input -pins på dit Arduino -projekt, men ikke ønsket at punge ud efter en Mega? Eller vil du gerne generere analoge signaler? Tjek derefter emnet for vores tutorial - NXP PCF8591 IC.

Det løser begge disse problemer, da det har en enkelt DAC (digital til analog) konverter samt fire ADC'er (analog til digital omformere) - alle tilgængelige via I2C -bussen. PCF8591 fås i DIP, overflademontering og modulform, hvilket gør det let at eksperimentere med.

Inden du går videre, skal du downloade databladet. PCF8591 kan fungere på både 5V og 3.3V, så hvis du bruger en Arduino Due, Raspberry Pi eller et andet 3.3 V udviklingsbord, har du det fint. Nu forklarer vi først DAC, derefter ADC'erne.

Trin 1: Brug af DAC (digital-til-analog konverter)

Brug af DAC (digital-til-analog konverter)
Brug af DAC (digital-til-analog konverter)

DAC'en på PCF8591 har en opløsning på 8-bit-så den kan generere et teoretisk signal på mellem nul volt og referencespændingen (Vref) i 255 trin. Af demonstrationsmæssige årsager bruger vi en Vref på 5V, og du kan bruge en lavere Vref som f.eks. 3.3V eller hvad du nu ønsker, at den maksimale værdi skal være … den skal dog være mindre end forsyningsspændingen.

Bemærk, at når der er en belastning på den analoge udgang (en virkelighedssituation), vil den maksimale udgangsspænding falde-databladet (som du downloadede) viser et fald på 10% for en 10kΩ belastning. Nu til vores demonstrationskredsløb.

Bemærk brugen af 10kΩ pull-up modstande på I2C bussen og 10μF kondensatoren mellem 5V og GND. I2C -busadressen indstilles med en kombination af ben A0 ~ A2, og med dem alle til GND er adressen 0x90. Den analoge udgang kan tages fra pin 15 (og der er en separat analog GND på pin 13. Tilslut også pin 13 til GND, og kredsløb GND til Arduino GND.

For at styre DAC skal vi sende to bytes data. Den første er kontrolbyten, som simpelthen aktiverer DAC og er 1000000 (eller 0x40), og den næste byte er værdien mellem 0 og 255 (outputniveauet). Dette fremgår af følgende skitse:

// Eksempel 52.1 PCF8591 DAC -demo

#include "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); // vågn op PCF8591 Wire.write (0x40); // kontrolbyte - tænd for DAC (binær 1000000) Wire.write (i); // værdi, der skal sendes til DAC Wire.endTransmission (); // slut transanmission}

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

{Wire.beginTransmission (PCF8591); // vågn op PCF8591 Wire.write (0x40); // kontrolbyte - tænd DAC (binær 1000000) Wire.write (i); // værdi, der skal sendes til DAC Wire.endTransmission (); // afslut transmission}}

Har du bemærket bitskiftet i busadressen i #define -sætningen? Arduino sender 7-bit adresser, men PCF8591 ønsker en 8-bit, så vi skifter byte med en bit.

Trin 2:

Billede
Billede

Resultaterne af skitsen er vist på billedet, vi har forbundet Vref til 5V og oscilloskopproben og GND til henholdsvis den analoge udgang og GND.

Trin 3:

Billede
Billede

Hvis du kan lide kurver, kan du generere sinusbølger med nedenstående skitse. Den bruger en opslagstabel i en matrix, der indeholder de nødvendige forudberegnede datapunkter:

// Eksempel 52.2 PCF8591 DAC demo - sinusbølge

#inkludere "Wire.h" #define PCF8591 (0x90 >> 1) // I2C busadresse 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 0, 0xD 0, 0xD, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF0, 0xF, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xB9, 0xB, 0xB, 0xB 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7, 0x6, 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, 0x0, 0x0, 0x0, 0x0 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0, 0x0, 0x0, 0x3 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x20, 0x20, 0x, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5, 0x6, 0x6, 0x6, 0x6, 0x6 0x70, 0x74, 0x77, 0x7A, 0x7D}; ugyldig opsætning () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // vågn op PCF8591 Wire.write (0x40); // kontrolbyte - tænd for DAC (binær 1000000) Wire.write (sinus_bølge ); // værdi, der skal sendes til DAC Wire.endTransmission (); // afslut transmission}}

Trin 4:

Billede
Billede

For følgende DSO -billeddump ændrede vi Vref til 3.3V - bemærk ændringen i maksima på sinusbølgen.

Nu kan du eksperimentere med DAC for at lave lydeffekter, signaler eller styre andre analoge kredsløb.

Trin 5: Brug af ADC'erne (analoge til digitale konvertere)

Hvis du har brugt analogRead () -funktionen på din Arduino (helt tilbage i kapitel 1), er du allerede bekendt med en ADC. Uden PCF8591 kan vi aflæse en spænding mellem nul og Vref, og den returnerer en værdi på mellem nul og 255, som er direkte proportional med nul og Vref.

For eksempel skal måling af 3.3V returnere 168. ADC-opløsningen (8-bit) er lavere end den indbyggede Arduino (10-bit), men PCF8591 kan gøre noget, Arduino's ADC ikke kan. Men det kommer vi til om et øjeblik. For det første, for blot at læse værdierne for hver ADC -pin, sender vi en kontrolbyte for at fortælle PCF8591, hvilken ADC vi vil læse. For ADC'er nul til tre er kontrolbyten henholdsvis 0x00, 0x01, ox02 og 0x03.

Derefter beder vi om to byte data tilbage fra ADC'en og gemmer den anden byte til brug. Hvorfor to bytes? PCF8591 returnerer den tidligere målte værdi først - derefter den aktuelle byte. (Se figur 8 i databladet). Endelig, hvis du ikke bruger alle ADC -benene, skal du slutte de ubrugte til GND. Følgende eksempelskitse henter simpelthen værdier fra hver ADC -pin en ad gangen og viser dem derefter i den serielle skærm:

#inkluder "Wire.h"

#define PCF8591 (0x90 >> 1) // I2C busadresse #define ADC0 0x00 // kontrolbytes til læsning af individuelle ADC'er #definer ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 byte værdi0, værdi1, værdi2, værdi3; ugyldig opsætning () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // vågn op PCF8591 Wire.write (ADC0); // kontrolbyte - læs ADC0 Wire.endTransmission (); // sluttransmission Wire.requestFrom (PCF8591, 2); value0 = Wire.read (); value0 = Wire.read (); Wire.beginTransmission (PCF8591); // vække PCF8591 Wire.write (ADC1); // kontrolbyte - læs ADC1 Wire.endTransmission (); // sluttransmission Wire.requestFrom (PCF8591, 2); værdi1 = Wire.read (); værdi1 = Wire.read (); Wire.beginTransmission (PCF8591); // vække PCF8591 Wire.write (ADC2); // kontrolbyte - læs ADC2 Wire.endTransmission (); // sluttransmission Wire.requestFrom (PCF8591, 2); value2 = Wire.read (); value2 = Wire.read (); Wire.beginTransmission (PCF8591); // vække PCF8591 Wire.write (ADC3); // kontrolbyte - læs ADC3 Wire.endTransmission (); // sluttransmission Wire.requestFrom (PCF8591, 2); value3 = Wire.read (); value3 = Wire.read (); Serial.print (værdi0); Serial.print (""); Serial.print (værdi1); Serial.print (""); Serial.print (værdi2); Serial.print (""); Serial.print (værdi3); Serial.print (""); Serial.println (); }

Når du kører skitsen, vil du blive præsenteret for værdierne for hver ADC i den serielle skærm. Selvom det var en simpel demonstration for at vise dig, hvordan du læser hver ADC individuelt, er det en besværlig metode til at få mere end en byte ad gangen fra en bestemt ADC.

Trin 6:

For at gøre dette skal du ændre kontrolbyten for at anmode om automatisk stigning, hvilket gøres ved at sætte bit 2 i kontrolbyten til 1. Så for at starte fra ADC0 bruger vi en ny kontrolbyte med binær 00000100 eller hexadecimal 0x04. Anmod derefter om fem bytes med data (endnu en gang ignorerer vi den første byte), hvilket får PCF8591 til at returnere alle værdier i en byte -kæde. Denne proces er demonstreret i følgende skitse:

#inkluder "Wire.h"

#define PCF8591 (0x90 >> 1) // I2C busadresse byte værdi0, værdi1, værdi2, værdi3; ugyldig opsætning () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // vågn op PCF8591 Wire.write (0x04); // kontrolbyte - læs ADC0, og stig automatisk Wire.endTransmission (); // sluttransmission Wire.requestFrom (PCF8591, 5); value0 = Wire.read (); value0 = Wire.read (); værdi1 = Wire.read (); value2 = Wire.read (); value3 = Wire.read (); Serial.print (værdi0); Serial.print (""); Serial.print (værdi1); Serial.print (""); Serial.print (værdi2); Serial.print (""); Serial.print (værdi3); Serial.print (""); Serial.println (); }

Tidligere nævnte vi, at PCF8591 kan gøre noget, som Arduino's ADC ikke kan, og dette er at tilbyde en differentiel ADC. I modsætning til Arduino's single-ended (dvs. den returnerer forskellen mellem den positive signalspænding og GND, accepterer differential ADC to signaler (der ikke nødvendigvis skal refereres til jorden) og returnerer forskellen mellem de to signaler Dette kan være praktisk til måling af små ændringer i spændinger for vejeceller og så videre.

Trin 7:

Billede
Billede

Opsætning af PCF8591 til differential ADC er et simpelt spørgsmål om at ændre kontrolbyte. Hvis du går til side syv i databladet, skal du overveje de forskellige typer analog indgangsprogrammering. Tidligere brugte vi tilstand '00' til fire indgange, men du kan vælge de andre, der er tydeligt illustreret, f.eks. Billedet.

Så for at indstille kontrolbyten for to differentialindgange, skal du bruge binær 00110000 eller 0x30. Så er det et simpelt spørgsmål om at anmode om bytes af data og arbejde med dem. Som du kan se, er der også kombinationen single/differential og en kompleks tre-differential input. Vi forlader dem dog foreløbig.

Forhåbentlig fandt du dette interessant, uanset om du tilføjede en DAC til dine eksperimenter eller lærte lidt mere om ADC'er. Overvej venligst at bestille din PCF8591 fra PMD Way.

Dette indlæg blev bragt til dig af pmdway.com - alt for producenter og elektronikentusiaster, med gratis levering over hele verden.

Anbefalede: