Sommario:
- Passaggio 1: utilizzo del DAC (convertitore digitale-analogico)
- Passo 2:
- Passaggio 3:
- Passaggio 4:
- Passaggio 5: utilizzo degli ADC (convertitori da analogico a digitale)
- Passaggio 6:
- Passaggio 7:
Video: Arduino e PCF8591 ADC DAC IC: 7 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:02
Hai mai desiderato più pin di ingresso analogico sul tuo progetto Arduino, ma non hai voluto sborsare per un Mega? Oppure desideri generare segnali analogici? Quindi dai un'occhiata all'argomento del nostro tutorial: NXP PCF8591 IC.
Risolve entrambi questi problemi in quanto dispone di un singolo convertitore DAC (da digitale ad analogico) e di quattro ADC (convertitori da analogico a digitale), tutti accessibili tramite il bus I2C. Il PCF8591 è disponibile in DIP, montaggio superficiale e modulo, che lo rende facile da sperimentare.
Prima di proseguire, scarica la scheda tecnica. Il PCF8591 può funzionare sia a 5 V che a 3,3 V, quindi se stai utilizzando un Arduino Due, un Raspberry Pi o un'altra scheda di sviluppo da 3,3 V sei a posto. Ora spiegheremo prima il DAC, poi gli ADC.
Passaggio 1: utilizzo del DAC (convertitore digitale-analogico)
Il DAC sul PCF8591 ha una risoluzione di 8 bit, quindi può generare un segnale teorico compreso tra zero volt e la tensione di riferimento (Vref) in 255 passi. A scopo dimostrativo useremo un Vref di 5V, e puoi usare un Vref più basso come 3,3V o qualunque cosa tu voglia che il valore massimo sia … tuttavia deve essere inferiore alla tensione di alimentazione.
Nota che quando c'è un carico sull'uscita analogica (una situazione del mondo reale), la tensione di uscita massima diminuirà: il foglio dati (che hai scaricato) mostra un calo del 10% per un carico di 10 kΩ. Ora per il nostro circuito dimostrativo.
Notare l'uso di resistori pull-up da 10kΩ sul bus I2C e il condensatore da 10μF tra 5V e GND. L'indirizzo del bus I2C è impostato da una combinazione di pin A0~A2, e con tutti loro a GND l'indirizzo è 0x90. L'uscita analogica può essere presa dal pin 15 (e c'è un GND analogico separato sul pin 13. Inoltre, collegare il pin 13 a GND e il circuito GND a Arduino GND.
Per controllare il DAC dobbiamo inviare due byte di dati. Il primo è il byte di controllo, che attiva semplicemente il DAC ed è 1000000 (o 0x40) e il byte successivo è il valore compreso tra 0 e 255 (il livello di uscita). Ciò è dimostrato nel seguente schizzo:
// Esempio 52.1 PCF8591 DAC demo
#include "Wire.h" #define PCF8591 (0x90 >> 1) // Indirizzo bus I2C void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(0x40); // byte di controllo - attiva DAC (binario 1000000) Wire.write(i); // valore da inviare al DAC Wire.endTransmission(); // fine trasmissione }
for (int i=255; i>=0; --i)
{ Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(0x40); // byte di controllo - attiva DAC (binario 1000000) Wire.write(i); // valore da inviare al DAC Wire.endTransmission(); // fine trasmissione } }
Hai notato lo spostamento di bit dell'indirizzo del bus nell'istruzione #define? Arduino invia indirizzi a 7 bit ma il PCF8591 vuole un 8 bit, quindi spostiamo il byte di un bit.
Passo 2:
I risultati dello sketch sono mostrati nell'immagine, abbiamo collegato il Vref a 5V e la sonda dell'oscilloscopio e GND rispettivamente all'uscita analogica e GND.
Passaggio 3:
Se ti piacciono le curve puoi generare onde sinusoidali con lo schizzo qui sotto. Utilizza una tabella di ricerca in un array che contiene i punti dati precalcolati necessari:
// Esempio 52.2 PCF8591 DAC demo - onda sinusoidale
#include "Wire.h" #define PCF8591 (0x90 >> 1) // Indirizzo 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, 0xD1, 0xD3, 0xD5, 0xD3, 0xD5, 0xD8, 0xD5, 0xD8, 0x 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xB6, 0xBC, 0xBF 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x7, 0x74, 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, 0x,0F 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x20, 0x22, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64 0x70, 0x74, 0x77, 0x7A, 0x7D }; void setup() { Wire.begin(); } void loop() { for (int i=0; i<256; i++) { Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(0x40); // byte di controllo - attiva DAC (binario 1000000) Wire.write(sine_wave); // valore da inviare al DAC Wire.endTransmission(); // fine trasmissione } }
Passaggio 4:
Per il seguente dump dell'immagine DSO, abbiamo cambiato il Vref a 3,3 V – nota il cambiamento nei massimi sull'onda sinusoidale.
Ora puoi sperimentare con il DAC per creare effetti sonori, segnali o controllare altri circuiti analogici.
Passaggio 5: utilizzo degli ADC (convertitori da analogico a digitale)
Se hai usato la funzione analogRead() sul tuo Arduino (molto indietro nel capitolo uno), allora hai già familiarità con un ADC. Senza PCF8591 possiamo leggere una tensione tra zero e Vref e restituirà un valore compreso tra zero e 255 che è direttamente proporzionale a zero e Vref.
Ad esempio, la misurazione di 3,3 V dovrebbe restituire 168. La risoluzione (8 bit) dell'ADC è inferiore a quella dell'Arduino integrato (10 bit), tuttavia il PCF8591 può fare qualcosa che l'ADC di Arduino non può. Ma ci arriveremo tra un momento. Innanzitutto, per leggere semplicemente i valori di ciascun pin ADC inviamo un byte di controllo per dire al PCF8591 quale ADC vogliamo leggere. Per gli ADC da zero a tre il byte di controllo è rispettivamente 0x00, 0x01, ox02 e 0x03.
Quindi chiediamo due byte di dati indietro dall'ADC e memorizziamo il secondo byte per l'uso. Perché due byte? Il PCF8591 restituisce prima il valore misurato in precedenza, quindi il byte corrente. (Vedi Figura 8 nella scheda tecnica). Infine, se non stai utilizzando tutti i pin ADC, collega quelli inutilizzati a GND. Il seguente schizzo di esempio recupera semplicemente i valori da ciascun pin ADC uno alla volta, quindi li visualizza nel monitor seriale:
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // Indirizzo bus I2C #define ADC0 0x00 // byte di controllo per la lettura dei singoli ADC #define ADC1 0x01 #define ADC2 0x02 #define ADC3 0x03 byte valore0, valore1, valore2, valore3; void setup() { Wire.begin(); Serial.begin(9600); } void loop() { Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(ADC0); // byte di controllo - legge ADC0 Wire.endTransmission(); // termina la trasmissione Wire.requestFrom(PCF8591, 2); valore0=Filo.read(); valore0=Filo.read(); Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(ADC1); // byte di controllo - legge ADC1 Wire.endTransmission(); // termina la trasmissione Wire.requestFrom(PCF8591, 2); valore1=Filo.leggi(); valore1=Filo.leggi(); Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(ADC2); // byte di controllo - legge ADC2 Wire.endTransmission(); // termina la trasmissione Wire.requestFrom(PCF8591, 2); valore2=Filo.leggi(); valore2=Filo.leggi(); Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(ADC3); // byte di controllo - legge ADC3 Wire.endTransmission(); // termina la trasmissione Wire.requestFrom(PCF8591, 2); valore3=Filo.leggi(); valore3=Filo.leggi(); Serial.print(value0); Serial.print(" "); Serial.print(value1); Serial.print(" "); Serial.print(value2); Serial.print(" "); Serial.print(value3); Serial.print(" "); Serial.println(); }
Dopo aver eseguito lo schizzo, ti verranno presentati i valori di ciascun ADC nel monitor seriale. Sebbene fosse una semplice dimostrazione per mostrare come leggere singolarmente ogni ADC, è un metodo scomodo per ottenere più di un byte alla volta da un particolare ADC.
Passaggio 6:
Per fare ciò, cambia il byte di controllo per richiedere l'auto-incremento, che viene fatto impostando il bit 2 del byte di controllo su 1. Quindi per iniziare da ADC0 usiamo un nuovo byte di controllo di 00000100 binario o esadecimale 0x04. Quindi richiedere cinque byte di dati (ancora una volta ignoriamo il primo byte) che farà sì che il PCF8591 restituisca tutti i valori in una catena di byte. Questo processo è dimostrato nel seguente schizzo:
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // Byte indirizzo bus I2C valore0, valore1, valore2, valore3; void setup() { Wire.begin(); Serial.begin(9600); } void loop() { Wire.beginTransmission(PCF8591); // riattiva PCF8591 Wire.write(0x04); // byte di controllo - legge ADC0 quindi incrementa automaticamente Wire.endTransmission(); // termina la trasmissione Wire.requestFrom(PCF8591, 5); valore0=Filo.read(); valore0=Filo.leggi(); valore1=Filo.leggi(); valore2=Filo.leggi(); valore3=Filo.read(); Serial.print(value0); Serial.print(" "); Serial.print(valore1); Serial.print(" "); Serial.print(value2); Serial.print(" "); Serial.print(value3); Serial.print(" "); Serial.println(); }
In precedenza abbiamo detto che il PCF8591 può fare qualcosa che l'ADC di Arduino non può, e questo è offrire un ADC differenziale. A differenza del single-ended di Arduino (cioè restituisce la differenza tra la tensione del segnale positivo e GND, l'ADC differenziale accetta due segnali (che non devono necessariamente essere riferiti a massa), e restituisce la differenza tra i due segnali Questo può essere utile per misurare piccole variazioni di tensione per celle di carico e così via.
Passaggio 7:
L'impostazione del PCF8591 per l'ADC differenziale è una semplice questione di modifica del byte di controllo. Se vai alla pagina sette della scheda tecnica, considera i diversi tipi di programmazione degli ingressi analogici. In precedenza abbiamo utilizzato la modalità '00' per quattro ingressi, tuttavia è possibile selezionare gli altri che sono chiaramente illustrati, ad esempio l'immagine.
Quindi per impostare il byte di controllo per due ingressi differenziali, utilizzare il binario 00110000 o 0x30. Quindi si tratta semplicemente di richiedere i byte di dati e lavorare con essi. Come puoi vedere c'è anche la combinazione singolo/differenziale e un complesso ingresso a tre differenziali. Comunque li lasceremo per il momento.
Spero che tu abbia trovato questo interessante, sia che tu aggiunga un DAC ai tuoi esperimenti o che impari qualcosa in più sugli ADC. Si prega di considerare di ordinare il PCF8591 da PMD Way.
Questo post ti è stato presentato da pmdway.com: tutto per produttori e appassionati di elettronica, con consegna gratuita in tutto il mondo.
Consigliato:
MicroPython PCF8591 DACtest: 3 passaggi (con immagini)
MicroPython PCF8591 DACtest: ho acquistato questo libro per migliorare le mie competenze Micropython: MicroPython per ESP8266 Development Workshop di Agus Kurniawan. Questo libro è un ottimo inizio, il progetto I2C utilizza un modulo PCF8591. Ma nessun esempio di programmazione DAC, quindi ho dovuto capire che ou
7 segmenti per visualizzare i valori ADC #Arduino, #Arduino: 4 passaggi
7 segmenti per visualizzare i valori ADC #Arduino, #Arduino: In questo articolo realizzerò un progetto che è ancora correlato all'articolo precedente. Vale a dire l'elaborazione dei dati ADC, quindi non è necessario un monitor seriale per vedere il valore dei dati adc. in questo articolo farò visualizzare un visualizzatore di valori ADC. quindi non
Arduino e ADC a 16 bit TI ADS1110: 6 passaggi
Arduino e ADC a 16 bit TI ADS1110: in questo tutorial esamineremo l'utilizzo di Arduino per lavorare con Texas Instruments ADS1110, un IC convertitore analogico-digitale a 16 bit incredibilmente piccolo ma utile. Può funzionare tra 2,7 e 5,5 V, quindi va bene anche per Arduino Due e altri
Riproduci brani con Arduino utilizzando ADC a PWM su trasformatore flyback o altoparlante: 4 passaggi
Riproduci brani con Arduino usando ADC su PWM su trasformatore o altoparlante Flyback: Ciao ragazzi, questa è la seconda parte del mio altro istruttivo (che è stato molto difficile), in sostanza, in questo progetto, ho usato l'ADC e i TIMER sul mio Arduino per converti il segnale audio in un segnale PWM. Questo è molto più semplice del mio precedente Instructa
PCF8591 (espansore I/O analogico i2c) Veloce e facile da usare: 9 passaggi
PCF8591 (i2c Analog I/O Expander) Veloce e facile da usare: libreria per utilizzare i2c pcf8591 IC con arduino ed esp8266. Questo IC può controllare (fino a 4) un ingresso analogico e/o 1 uscita analogica come misurare la tensione, leggere il valore del termistore o sfumare un led. Può leggere il valore analogico e scrivere il valore analogico con solo 2 fili (perfett