Índice:

Arduino e PCF8591 ADC DAC IC: 7 etapas
Arduino e PCF8591 ADC DAC IC: 7 etapas

Vídeo: Arduino e PCF8591 ADC DAC IC: 7 etapas

Vídeo: Arduino e PCF8591 ADC DAC IC: 7 etapas
Vídeo: ADC DAC Mirror 2024, Julho
Anonim
Arduino e PCF8591 ADC DAC IC
Arduino e PCF8591 ADC DAC IC

Você já quis mais pinos de entrada analógica em seu projeto Arduino, mas não quis pagar por um Mega? Ou você gostaria de gerar sinais analógicos? Então confira o assunto do nosso tutorial - o NXP PCF8591 IC.

Ele resolve esses dois problemas, pois tem um único conversor DAC (digital para analógico), bem como quatro ADCs (conversores analógico para digital) - todos acessíveis através do barramento I2C. O PCF8591 está disponível em DIP, montagem em superfície e forma de módulo, o que o torna fácil de experimentar.

Antes de prosseguir, baixe a folha de dados. O PCF8591 pode operar em 5 V e 3,3 V, portanto, se você estiver usando um Arduino Due, Raspberry Pi ou outra placa de desenvolvimento de 3,3 V, tudo bem. Agora vamos explicar primeiro o DAC, depois os ADCs.

Etapa 1: usando o DAC (conversor digital para analógico)

Usando o DAC (conversor digital para analógico)
Usando o DAC (conversor digital para analógico)

O DAC do PCF8591 tem resolução de 8 bits - portanto, ele pode gerar um sinal teórico entre zero volts e a tensão de referência (Vref) em 255 passos. Para fins de demonstração, usaremos um Vref de 5 V, e você pode usar um Vref mais baixo, como 3,3 V ou o que quiser que o valor máximo seja … no entanto, deve ser menor do que a tensão de alimentação.

Observe que quando há uma carga na saída analógica (uma situação do mundo real), a tensão máxima de saída cairá - a planilha de dados (que você baixou) mostra uma queda de 10% para uma carga de 10kΩ. Agora, para nosso circuito de demonstração.

Observe o uso de resistores pull-up de 10kΩ no barramento I2C e o capacitor de 10μF entre 5V e GND. O endereço do barramento I2C é definido por uma combinação dos pinos A0 ~ A2 e, com todos eles para GND, o endereço é 0x90. A saída analógica pode ser obtida do pino 15 (e há um GND analógico separado no pino 13. Além disso, conecte o pino 13 ao GND e o circuito GND ao Arduino GND.

Para controlar o DAC, precisamos enviar dois bytes de dados. O primeiro é o byte de controle, que simplesmente ativa o DAC e é 1000000 (ou 0x40) e o próximo byte é o valor entre 0 e 255 (o nível de saída). Isso é demonstrado no seguinte esboço:

// Exemplo 52.1 PCF8591 DAC demo

#include "Wire.h" #define PCF8591 (0x90 >> 1) // endereço de barramento I2C void setup () {Wire.begin (); } void loop () {para (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // desperta PCF8591 Wire.write (0x40); // byte de controle - liga o DAC (binário 1000000) Wire.write (i); // valor a ser enviado ao DAC Wire.endTransmission (); // fim da transmissão}

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

{Wire.beginTransmission (PCF8591); // desperta PCF8591 Wire.write (0x40); // byte de controle - liga o DAC (binário 1000000) Wire.write (i); // valor a ser enviado ao DAC Wire.endTransmission (); // fim da transmissão}}

Você notou a mudança de bit do endereço do barramento na instrução #define? O Arduino envia endereços de 7 bits, mas o PCF8591 quer um de 8 bits, então mudamos o byte um bit.

Passo 2:

Imagem
Imagem

Os resultados do esboço são mostrados na imagem, conectamos o Vref a 5V e a ponta de prova do osciloscópio e GND à saída analógica e GND respectivamente.

Etapa 3:

Imagem
Imagem

Se você gosta de curvas, pode gerar ondas senoidais com o esboço abaixo. Ele usa uma tabela de pesquisa em uma matriz que contém os pontos de dados pré-calculados necessários:

// Exemplo 52.2 PCF8591 DAC demo - onda senoidal

#include "Wire.h" #define PCF8591 (0x90 >> 1) // Endereço de barramento 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, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 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, 0xF1, 0xF0, 0xEF, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A, 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, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64, 0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D}; void setup () {Wire.begin (); } void loop () {para (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // desperta PCF8591 Wire.write (0x40); // byte de controle - liga o DAC (binário 1000000) Wire.write (sine_wave ); // valor a ser enviado ao DAC Wire.endTransmission (); // fim da transmissão}}

Passo 4:

Imagem
Imagem

Para o seguinte dump de imagem DSO, mudamos o Vref para 3,3V - observe a mudança no máximo na onda senoidal.

Agora você pode experimentar o DAC para criar efeitos sonoros, sinais ou controlar outros circuitos analógicos.

Etapa 5: usando os ADCs (conversores analógico para digital)

Se você usou a função analogRead () em seu Arduino (no Capítulo Um), então você já está familiarizado com um ADC. Sem o PCF8591 podemos ler uma tensão entre zero e o Vref e ela retornará um valor entre zero e 255 que é diretamente proporcional a zero e o Vref.

Por exemplo, medir 3,3 V deve retornar 168. A resolução (8 bits) do ADC é menor do que a do Arduino integrado (10 bits), no entanto, o PCF8591 pode fazer algo que o ADC do Arduino não pode. Mas vamos chegar a isso em um momento. Primeiro, para simplesmente ler os valores de cada pino ADC, enviamos um byte de controle para informar ao PCF8591 qual ADC queremos ler. Para ADCs de zero a três, o byte de controle é 0x00, 0x01, ox02 e 0x03, respectivamente.

Em seguida, solicitamos dois bytes de dados de volta do ADC e armazenamos o segundo byte para uso. Por que dois bytes? O PCF8591 retorna o valor medido anteriormente primeiro - depois o byte atual. (Veja a Figura 8 na folha de dados). Finalmente, se você não estiver usando todos os pinos ADC, conecte os não usados ao GND. O seguinte esboço de exemplo simplesmente recupera os valores de cada pino ADC, um de cada vez, e os exibe no monitor serial:

#include "Wire.h"

# define PCF8591 (0x90 >> 1) // endereço de barramento I2C # define ADC0 0x00 // bytes de controle para leitura de ADCs individuais # define ADC1 0x01 # define ADC2 0x02 # define ADC3 0x03 byte valor0, valor1, valor2, valor3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // ativa PCF8591 Wire.write (ADC0); // byte de controle - leia ADC0 Wire.endTransmission (); // fim da transmissão Wire.requestFrom (PCF8591, 2); valor0 = Wire.read (); valor0 = Wire.read (); Wire.beginTransmission (PCF8591); // ativa PCF8591 Wire.write (ADC1); // byte de controle - leia ADC1 Wire.endTransmission (); // fim da transmissão Wire.requestFrom (PCF8591, 2); valor1 = Wire.read (); valor1 = Wire.read (); Wire.beginTransmission (PCF8591); // ativa PCF8591 Wire.write (ADC2); // byte de controle - leia ADC2 Wire.endTransmission (); // fim da transmissão Wire.requestFrom (PCF8591, 2); valor2 = Wire.read (); valor2 = Wire.read (); Wire.beginTransmission (PCF8591); // ativa PCF8591 Wire.write (ADC3); // byte de controle - leia ADC3 Wire.endTransmission (); // fim da transmissão Wire.requestFrom (PCF8591, 2); valor3 = Wire.read (); valor3 = Wire.read (); Serial.print (valor0); Serial.print (""); Serial.print (valor1); Serial.print (""); Serial.print (valor2); Serial.print (""); Serial.print (valor3); Serial.print (""); Serial.println (); }

Ao executar o esboço, você verá os valores de cada ADC no monitor serial. Embora tenha sido uma demonstração simples para mostrar a você como ler individualmente cada ADC, é um método complicado de obter mais de um byte por vez de um ADC específico.

Etapa 6:

Para fazer isso, altere o byte de controle para solicitar o auto-incremento, o que é feito definindo o bit 2 do byte de controle como 1. Portanto, para começar a partir do ADC0, usamos um novo byte de controle do binário 00000100 ou hexadecimal 0x04. Em seguida, solicite cinco bytes de dados (mais uma vez, ignoramos o primeiro byte), o que fará com que o PCF8591 retorne todos os valores em uma cadeia de bytes. Este processo é demonstrado no seguinte esboço:

#include "Wire.h"

# define PCF8591 (0x90 >> 1) // byte de endereço de barramento I2C valor0, valor1, valor2, valor3; void setup () {Wire.begin (); Serial.begin (9600); } void loop () {Wire.beginTransmission (PCF8591); // desperta PCF8591 Wire.write (0x04); // byte de controle - leia ADC0 e então auto-incremente Wire.endTransmission (); // fim da transmissão Wire.requestFrom (PCF8591, 5); valor0 = Wire.read (); valor0 = Wire.read (); valor1 = Wire.read (); valor2 = Wire.read (); valor3 = Wire.read (); Serial.print (valor0); Serial.print (""); Serial.print (valor1); Serial.print (""); Serial.print (valor2); Serial.print (""); Serial.print (valor3); Serial.print (""); Serial.println (); }

Anteriormente, mencionamos que o PCF8591 pode fazer algo que o ADC do Arduino não pode, e isso é oferecer um ADC diferencial. Ao contrário do Arduino de terminação única (ou seja, ele retorna a diferença entre a tensão do sinal positivo e GND, o ADC diferencial aceita dois sinais (que não necessariamente precisam ser referenciados ao terra) e retorna a diferença entre os dois sinais Isso pode ser conveniente para medir pequenas mudanças nas tensões das células de carga e assim por diante.

Etapa 7:

Imagem
Imagem

Configurar o PCF8591 para ADC diferencial é uma simples questão de alterar o byte de controle. Se você abrir a página sete da folha de dados, considere os diferentes tipos de programação de entrada analógica. Anteriormente, usávamos o modo '00' para quatro entradas, no entanto, você pode selecionar os outros que estão claramente ilustrados, por exemplo, a imagem.

Portanto, para definir o byte de controle para duas entradas diferenciais, use o binário 00110000 ou 0x30. Então é uma simples questão de solicitar os bytes de dados e trabalhar com eles. Como você pode ver, há também uma combinação única / diferencial e uma entrada complexa de três diferenciais. No entanto, vamos deixá-los por enquanto.

Esperançosamente, você achou isso interessante, seja adicionando um DAC aos seus experimentos ou aprendendo um pouco mais sobre ADCs. Considere pedir seu PCF8591 da PMD Way.

Esta postagem foi trazida a você por pmdway.com - tudo para fabricantes e entusiastas de eletrônicos, com entrega gratuita em todo o mundo.

Recomendado: