Curso Arduino – #4 – Conversor Analógico-Digital

 

 

Nas lições anteriores do curso, abordamos a leitura de sinais digitais. Através desta, podíamos, por exemplo, verificar se um botão foi pressionado. No entanto, o mundo que nos rodeia não é digital, e, às vezes, 2 estados (high e low) não são suficientes para realizar o projeto pretendido.

Por isso é que, neste artigo, vamos falar do conversor analógico-digital, abreviado como ADC (analog-to-digital converter).

Introdução Teórica

A eletrónica divide-se em dois tipos de sinais: digital e analógico. Os sinais digitais estão limitados a dois estados: High (1) ou Low (0). Na prática, significa que o Arduino reconhecerá uma de duas tensões: 5V ou 0V, respetivamente.

Infelizmente, nem tudo em nosso redor pode ser descrito de uma forma tão simples. Por exemplo, ao usarmos um sensor de distância, provavelmente pretendemos saber a distância exata de um obstáculo, e não apenas informações básicas como: obstáculo detetado/sem obstáculo.

Tal sensor, na sua saída, pode fornecer uma tensão proporcional à distância do obstáculo. Então, a medição consiste em ler a tensão numa faixa de 0 a 5V. Esta é a abordagem analógica. Portanto, nos exemplos seguintes, vamos usar os periféricos apropriados do Arduino, que permitem medir a tensão fornecida às entradas especiais do sistema.

ATENÇÃO: Lembre-se que as entradas do Arduino só são compatíveis com tensões incluídas na seguinte faixa: 0-5V. Outras tensões poderão danificar a placa e até o computador ao qual ligar o circuito.

Para o processamento de sinais analógicos, é utilizado o chamado ADC: conversor analógico-digital. Este é um dos periféricos mais populares encontrados em microcontroladores. O seu trabalho é converter uma tensão aplicada numa entrada do sistema num formato digital. Por exemplo (transdutor linear):

Tensão => Valor lido no ADC
[V] (arredondado)
0 => 0
1 => 51
2 => 102
3 => 154
4 => 205
5 => 255

Neste caso, apresentamos um conversor de 8 bits, já que o valor lido poderia ter 256 combinações (começando em 0). Na verdade, podemos encontrar vários transdutores, por exemplo de 12 ou 16 bits. O conversor que possui mais bits é o mais preciso, porque seu o valor máximo é maior (funciona no mesmo intervalo, mas com uma resolução mais alta).

Como curiosidade, é interessante saber que os conversores analógico-digitais operam de forma relativamente lenta. Naturalmente, não vai verificar isso nos seus programas, pois, mesmo sendo “lentos” são inacreditavelmente rápidos (até 10.000 medições por segundo). No entanto, comparando o ADC a outros periféricos do microcontrolador, é a “ovelha negra”.

Os ADCs são, também, muito caros de produzir. Como se deve lembrar, na segunda lição do curso, verificamos que o Arduino UNO possui 6 entradas analógicas (A0-A5). De facto, na placa, existe apenas um conversor analógico-digital, que consegue medir a tensão das seis entradas.

Basta de teoria (para já!), vamos passar para os exercícios práticos!

Exercício Prático – ADC

Material necessário:

É hora de verificar como é que o ADC funciona na prática. Para isso, faça a montagem do circuito de acordo com a figura abaixo.

curso arduino - conversor analogico digital

O uso de software do ADC é trivial e limitado ao uso de apenas uma função analogRead (canal ADC), onde o canal ADC é o pino analógico utilizado (A0-A5).

Este é um código muito fácil! Para já, vamos somente enviar o valor lido para o computador, via UART, que conhecemos no artigo anterior.

int valorLido = 0;

void setup() {
Serial.begin(9600);//Configuração da velocidade de transmissão
}

void loop() {
valorLido = analogRead(A5);//Ler valor da tensão na entrada A5
Serial.println(valorLido);//Enviar sinal para o monitor série
delay(200);//Esperar 200ms
}

Ao girar o potenciómetro, obtemos valores de 0 a 1023 no monitor série. Isto significa que o conversor analógico-digital integrado no Arduino UNO, é de 10 bits.

Será que estes valores são úteis para nós? É difícil dizer. Mas seria melhor obter os resultados em unidades mais conhecidas. Por exemplo volts, certo?

Exercício Prático – Voltímetro

Esta tarefa é fácil, basta usar o circuito criado anteriormente. O exercício consiste apenas na conversão apropriada do valor lido. Sabemos que a tensão de entrada varia numa faixa de 0 a 5V, e o maior número que podemos obter do ADC é 1023. Portanto, eis o cálculo:

1023x \ rightarrow 5V

1 \ rightarrow xV

1 023x = 1 * 5V

x = \ frac {1 * 5V} {1 023} = ~ 0.0049V

Simplificando, qualquer aumento na tensão de entrada de ~0.005V aumentará a leitura do ADC em um. Assim, para obter um resultado em volts basta adicionar uma linha:

int valorLido = 0;//Ler valor do ADC
float tensão = 0;//Valor convertido em volts (V)

void setup() {
Serial.begin(9600);//Configuração da taxa de transmissão
}

void loop() {
valorLido = analogRead(A5);//Ler valor da tensão na entrada A5
tensão = valorLido * (5.0/1023.0); //Converter valores em volts
Serial.println(tensão);//Enviar tensão medida para monitor série
delay(200);//Esperar 200ms
}

Note que a declaração de tensão foi feita através de uma variável float, para que seja possível armazenar valores/números racionais.

Deverá conseguir ver no monitor série valores entre 0 e 5V. Acabamos de construir um voltímetro muito simples!

curso arduino - conversor adc

Já consegue encontrar outras aplicações para as medições do ADC (sem ser o voltímetro)? Se não, confira os exemplos abaixo.

Exercício Prático com ADC – Regulação do funcionamento do programa

O exemplo anterior pretendia apenas demonstrar o funcionamento do conversor. Agora vamos usar o potenciómetro para influenciar o funcionamento do programa.

Material necessário:

Faça a ligação do circuito de acordo com o esquema abaixo:

curso arduino conversor adc

O que é que será que acontece se o valor lido do ADC determinar o delay do programa? Este é o exemplo mais rápido para construir um dispositivo com um LED, que pisca a uma frequência controlada por um potenciómetro:

int valorLido = 0; //Variável para armazenar leituras do ADC

void setup() {
pinMode(2, OUTPUT); //Configuração do LED como saída
}

void loop() {
valorLido = analogRead(A5);//Ler valor do ADC
digitalWrite(2, HIGH);//Ligar o LED
delay(valorLido);//Tempo de espera igual ao valor lido pelo ADC
digitalWrite(2, LOW);//Desligar o LED
delay(valorLido);//Tempo de espera igual ao valor lido pelo ADC
}

Trabalho de Casa nº8

Verifique o que acontece numa das posições extremas do potenciómetro. Qual acredita ser a razão para isso?

Exercício Prático com ADC – Seleção de LEDs

Agora, está na hora de um projeto mais extenso. Neste exemplo, dependendo da posição em que o potenciómetro se encontre, um LED vai ser ligado.

Material necessário:

Primeiro, necessita de ligar todo o circuito. O nosso está disposto da seguinte forma:

curso arduino- conversor adc

A tarefa é simples, basta dividir o valor máximo que podemos ler do ADC (1023) por 5 e, com base nisso, criar condições para a ativação individual dos LEDs. Mas, para isso, podemos usar a função map (), que nos facilita muito o trabalho!

O seu uso, na prática, é assim:

valorEscala = map(valorLido, 0, 1023, 1, 5);

Esta função permite, rapidamente, dividir por escalas um determinado valor. O primeiro argumento, é o valor a ser dividido, que neste caso, são informações dadas pelo ADC. O segundo e terceiro parâmetros são o intervalo do valor de entrada, enquanto os dois últimos são o intervalo do valor de saída (após divisão).

Como resultado da linha de código acima, obtém-se sempre um valor no intervalo compreendido entre 1 e 5. Vejamos o código completo:

int valorLido = 0;

void setup() {
pinMode(8, OUTPUT); //Configuração dos LEDs como saídas
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
}

void loop() {
valorLido = analogRead(A5);//Ler valor do ADC
valorLido = map(valorLido, 0, 1023, 1, 5);//Valores para divisão

if (valorLido == 1) { //Primeiro intervalo
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
} else if (valorLido == 2) { //Segundo intervalo
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
} else if (valorLido == 3) { //Terceiro intervalo
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
} else if (valorLido == 4) { //Quarto intervalo
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
} else { //Quinto intervalo
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
}
delay(50); //Atraso para o ADC não ler demasiado rápido
}

Verifique o que acontece aos LEDs quando gira o potenciómetro. Se tudo estiver a funcionar corretamente, e se estiver tudo bem ligado, quando gira o potenciómetro deverá acender um LED diferente que que estava aceso anteriormente.

Trabalho de Casa nº9

Se tiver sorte (muita interferência no ambiente), será possível realizar uma experiência fantástica. Use o sistema de 5 LEDs anteriormente ligado, desconecte o cabo que liga o potenciómetro e deixe-o assim.

O que é que acontece quando se aproxima um dedo do cabo (sem tocar na ponta)? Faz ideia porque é que isso acontece?

Estamos à espera das vossas respostas nos comentários!

Exercício Prático com ADC – Ativar um LED quando está escuro

Vamos agora inserir um novo elemento e criar algo prático. Neste exercício, vamos usar um sensor de luz (LDR), um elemento cuja resistência muda sob a influência da luz incidente (quanto maior a quantidade de luz, menor a resistência).

Material necessário:

A resistência de 1KΩ deve estar ligada ao LDR. Faça as ligações do circuito da seguinte forma:

curso arduino - conversor adc

Quando uma grande quantidade de luz incide sobre o LDR, a sua resistência é mínima e se estiver ligado ao Arduino possui uma tensão relativamente alta. Quando escurece, a resistência do LDR aumenta e a tensão é baixa.

Com este programa, será capaz de criar uma lâmpada que liga quando está escuro. O código é muito simples (como sempre!):

int valorLido = 0; //Variável para armazenar leituras do ADC

void setup() {
pinMode(8, OUTPUT); //Configuração do LED como saída
}

void loop() {
valorLido = analogRead(A5);//Ler valor do ADC

if (valorLido < 100) {
digitalWrite(8, HIGH);//Ligar LED
} else {
digitalWrite(8, LOW);//Desligar LED
}

delay(50);
}

Como pode ver, existe uma condição que é responsável por ligar/desligar o LED. A questão é: como escolher o valor de mudança? O melhor é fazê-lo à mão, mas é pouco prático… Digamos que quer mudar o projeto de local, para uma sala com condições mínimas muito diferentes. Teremos de reconfigurar o código novamente? Sim, a menos que…

Exercício Prático com ADC – Ativar um LED quando está escuro v2

Desta vez o exercício é óbvio. Como antes, pretendemos que crie uma lâmpada que ligue após escurecer. No entanto, tem de ser muito mais fácil de regular. Faz ideia de como fazer isso?

Usamos o potenciómetro ligado à entrada analógica seguinte (A4):

Em vez de tornar o LED dependente de uma faixa muito específica, o objetivo é ajustar suavemente o limite de comutação com o potenciómetro. A alteração do código é muito fácil e consiste em editar 3 linhas de código:

int valorLido = 0; //Variável para armazenar leituras do ADC
int valorComutacao = 0; //Valor limite para ligar o LED - definido pelo potenciómetro

void setup() {
pinMode(8, OUTPUT); //Configuração do LED como saída
}

void loop() {
valorLido = analogRead(A5);//Ler valor do ADC
valorComutacao = analogRead(A4);//Ler valor do ADC

if (valorLido < valorComutacao) { //Se for mais escuro do que o limite encontrado
digitalWrite(8, HIGH);//Liga o LED
} else {
digitalWrite(8, LOW);//Desliga o LED
}

delay(50);
}

De agora em diante, pode ajustar o limite como preferir!

Usar o ADC é muito simples, portanto é tempo de trabalhar de forma independente com os trabalhos de casa. Lembre-se que, primeiro, deve dominar todas as lições.

 

Trabalho de Casa nº10

Escreva um programa para um jogo simples. Depois de iniciar o programa, gire o potenciómetro aleatoriamente e pressione um botão. Depois disto, o Arduino deverá exibir uma mensagem no monitor série:

Escolha um número:

Se o número enviado para o Arduino coincidir com a leitura do ADC em +/-50, o jogador ganha. Caso contrário, um LED amarelo acende e o jogador tem mais duas tentativas. Adicionalmente, sempre que é inserido um número errado, deve acender um LED vermelho na breadboard (máximo 3). No entanto, no caso do jogador ganhar, deve acender um LED verde.

Trabalho de Casa nº11

Use dois LDR e coloque-os em lados extremos da breadboard. O ideal será incliná-los um pouco para fora. Exiba os valores de ambos os sensores no monitor série. O que é que acontece quando acena com a mão por cima da breadboard (fazer sombra) ou ilumina com uma lanterna?

Analisando a equação entre as medições dos dois sensores, consegue escrever um programa que determine em que local da breadboard existe uma maior incidência de luz? Indique a direção com 1 de 5 LEDs dispostos na horizontal pela breadboard (mais à esquerda, centro, mais à direita, etc.)!

Sumário

Neste artigo do curso Arduino, abordamos, na nossa opinião, um dos periféricos mais interessantes, o ADC. Os conversores analógico-digitais são usados com muita frequência quando é suposto o sistema ler informações do meio envolvente. Esperamos que tenha ficado esclarecido quanto ao tem. Ficámos à espera das vossas respostas aos trabalhos de casa!

___________

O que achou deste artigo? Deixe o seu comentário abaixo, e partilhe nas Redes Sociais que certamente será útil e interessante para os seus amigos!

 

 

 

 Curso Arduino – #0 – Introdução

 Curso Arduino – #1 – O Básico do Arduino e o Software de Programação

 Curso Arduino – #2 – O Básico da Programação e as Portas I/O

 Curso Arduino – #3 – UART e Variáveis

 Curso Arduino – #4 – Conversor Analógico-Digital

 Curso Arduino – #5 – PWM, Servomecanismos e Bibliotecas

 Curso Arduino – #6 – UART (continuação) e Servos

 Curso Arduino – #7 – Displays

 Curso Arduino – #8 – Controlo de Motores DC

 Curso Arduino – #9 – Sensor de Distância Ultrassónico HC-SR04 e Novas Funções

 Curso Arduino – #10 – Gráficos, Números Aleatórios e Condições