Arduino – Entradas e saídas analógicas
Com um pouco de atenção, podemos perceber que a todo momento estamos rodeados de situações nas quais existem elementos que podem ser definidos como grandezas analógicas, como por exemplo, posição e temperatura. Sabendo a importância deste tipo de grandeza, torna-se necessário que nós aprendamos a lidar com este tipo de informação dentro do cenário que estamos adentrando, sendo assim, neste tutorial abordaremos com maior enfoque, o modo utilizado por uma placa Arduino para lidar com o tipo de grandeza citada.
Para acompanhar este tutorial com maior compreensão, recomendamos que o leitor acompanhe nosso tutorial sobre grandezas digitais, analógicas e PWM.
[toc]
Pinos de entrada e “saída” analógica
Como dissemos no tutorial citado anteriormente, as grandezas analógicas são aquelas que, ao contrário das grandezas digitais, podem assumir infinitos valores de amplitude dentro de uma faixa de valores. Além disso, demos também como exemplo, o velocímetro de um carro, que por sua vez, pode ser considerado analógico, pois o ponteiro gira continuamente conforme o automóvel acelera ou freia. Se o ponteiro girasse em saltos, o velocímetro seria considerado digital.
Uma placa Arduino possui um conjunto de pinos destinados a lidar com este tipo de grandeza, onde, alguns são utilizados como entradas analógicas, isto é, possuem a função de receber dados provenientes de grandezas analógicas, enquanto outros, possuem a função de produzir informações que simulam o comportamento de grandezas analógicas, aqui estamos falando da utilização de uma técnica chamada PWM.
Em um Arduino UNO, as entradas analógicas estão localizadas do pino A0 até o pino A5. Por outro lado, os elementos que podem atuar fornecendo sinais que simulam o comportamento de uma grandeza analógica, são alguns dos pinos caracterizados como pinos de entrada/saída digital (de maneira específica, os pinos 3,5,6,9,10 e 11).
Mãos à obra – Variando a luminosidade de um led com um potenciômetro utilizando PWM
Neste tutorial iremos elaborar um projeto onde você poderá compreender tanto o processo de aquisição de dados a partir das portas de entrada analógicas quanto os procedimentos de utilização do PWM. O hardware consistirá em uma estrutura onde será possível variar a luminosidade de um led através de um potenciômetro..
Componentes utilizados
- 1 x Arduino UNO Rev 3
- 1 x Protoboard
- 1 x Resistor 330 Ω
- 1 x Potenciômetro linear 10kΩ
- 1 x Led verde difuso
Montagem do projeto
Veja como ficou o nosso:
Programando
Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.
Conectando o Arduino ao computador
Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino UNO).
Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).
– Código do projeto
Segue o código a ser utilizado no Arduino UNO para alterar a luminosidade do led através do potenciômetro.
unsigned int potenciometro unsigned int pwm void setup() { pinMode(10,OUTPUT); } void loop() { potenciometro = analogRead(A0); pwm = map(potenciometro,0,1023,0,255); analogWrite(10,pwm); }
Entendendo a fundo
Hardware
– Potenciômetro e trimpot
Potenciômetros e trimpots são resistores variáveis e ajustáveis, portanto, são bastante utilizados para realizar o controle analógico de algumas funcionalidades de aparelhos eletrônicos, como por exemplo, o volume de um aparelho de som.
Geralmente, estes dispositivos possuem três pernas, de modo que, duas destas são ligadas às extremidades de um material resistivo resistência (A e B), que por sua vez, são ligadas em dois potenciais distintos, enquanto a terceira, é conectada a um cursor que se movimenta ao longo do material citado. Este deslocamento faz com que seja possível obtermos diferentes níveis de tensão, obviamente, entre os valores de potenciais citados anteriormente.
– Divisor de tensão
O princípio de funcionamento descrito na seção anterior corresponde ao conceito de divisor de tensão. Imagine a seguinte configuração:
Sabemos que, quando temos duas resistências são associadas em série e o conjunto é sujeito a uma diferença de potencial, ambas serão percorridas pela mesma corrente. A equação que rege o comportamento do conjunto citado é dada por:
Se aplicarmos uma tensão de 5V nos terminais do conjunto, teremos:
Onde a corrente é o resultado da razão entre a tensão pela soma dos valores das resistências. Observe que, apesar de termos a mesma corrente passando pelos resistores, os mesmos estão sujeitos a tensões diferentes em seus respectivos terminais.
e
Pelos cálculos realizados acima, podemos perceber que a queda de tensão será maior no resistor de maior resistência.
Um circuito divisor de tensão é justamente aquele em que podemos extrair apenas uma fração da tensão aplicada nos terminais do mesmo. Observe como podemos calcular a tensão em um dos resistores de forma direta:
O exemplo a seguir mostra como funciona o cálculo o para dois resistores.
– Em resumo
Quando estamos utilizando um potenciômetro, estamos recorrendo ao conceito de divisor de tensão para obter diferentes valores de tensão em virtude da rotação do mesmo, de modo que, com a tensão total e a resistência total fixas, o divisor de tensão vai variar com a resistência entre A0 e GND (Considere no GIF que 0 a 100% é a posição inicial e final de rotação do potenciômetro. Teremos a tensão sobre o pino central variando conforme a posição angular do potenciômetro.)
Software
– Declarando as variáveis
O primeiro passo realizado neste código foi a declaração das variáveis que serão utilizadas ao longo do código do projeto. Observe que a declaração de uma variável é feita colocando-se o tipo da mesma (neste caso, as duas variáveis declaradas são do tipo unsigned int, pois, consistem apenas em números positivos) e em seguida, o seu nome (potenciometro e pwm).
A diferença entre os tipos int e unsigned int consiste no fato de que, no arduino UNO, uma variável do tipo int pode armazenar números que vão de -32.768 a 32.767, portanto, perceba que neste tipo de variável é possível que haja a ocorrência de números negativos em seu conteúdo. Em contrapartida, quando uma variável é do tipo unsigned int, ela pode armazenar números de 0 a 65.535, portanto, positivos.
unsigned int potenciometro unsigned int pwm
– Definindo as configurações iniciais
Em seguida, devemos determinar o modo de operação do pino utilizado para acionar o led, fazendo com que o mesmo se comporte como uma saída digital. Para isso, dentro da função setup() (lembre-se que esta função é executada apenas quando o Arduino UNO é ligado) utiliza-se a função pinMode(), onde os parâmetros passados para a mesma são: o número do pino a ser utilizado e o modo de operação do mesmo (neste caso, definimos o pino 10 como uma saída digital através da palavra OUTPUT).
void setup() { pinMode(10,OUTPUT); }
– Realizando a leitura de uma entrada analógica
Em primeiro lugar, como vimos no tutorial sobre grandezas digitais, analógicas e pwm, o Arduino UNO possui conversores A/D com resolução de 10 bits e que trabalham com intervalos de tensão de referência de 0 a 5V. Estes conversores são responsáveis por transformar o sinal de tensão aplicado nas suas entradas analógicas em informações digitais que possam ser interpretadas pelo Arduino UNO.
Basicamente, o que os conversores citados fazem é dividir o intervalo citado (0 a 5V) em 1024 (210, onde 10 é a resolução do conversor) pedaços, que por sua vez, estão distantes uns dos outros por 0,0048828 V (5/1024 V) e além disso, relacionar o sinal de tensão presente em uma determinada porta de entrada analógica com um destes pedaços.
Por exemplo: imagine que um potencial de 3,25V esteja presente em um pino de entrada analógica, neste caso, o valor retornado pela conversão será:
Como o resultado deve ser um número inteiro para que o conversor consiga representá-lo, o Arduino UNO escolhe o valor 666 (por ser o inteiro mais próximo) para representar o nível de tensão aplicado.
Sabendo disso, utilizamos a função analogRead() para que o Arduino UNO realize a leitura do valor entregue pelo potenciômetro à porta de entrada analógica A0, realize a conversão do mesmo e por fim, armazene ele na variável potenciometro . Esta função recebe apenas um parâmetro que consiste na porta de entrada analógica que está sendo utilizada na aquisição dos dados.
potenciometro = analogRead(A0);
– Convertendo intervalos de entrada em intervalos de saída
Para realizarmos a alteração na luminosidade do led, devemos relembrar o conceito de PWM. No nosso artigo sobre entradas digitais, analógicas e pwm explicamos que este recurso consiste na geração de uma onda quadrada, na qual, definimos a porcentagem do tempo em que a onda permanece em nível lógico alto (Duty cycle), provocando a mudança no valor médio da onda, que por sua vez, está relacionada com a potência entregue ao led e consequentemente com o brilho emitido pelo mesmo.
Além disso, mostramos também que, no código, o Duty Cycle corresponde a um número inteiro de 8 bits, variando, portanto, de 0 (0% de Duty cycle) a 255 (100% de Duty cycle).
De posse destas informações, observe que, de um lado, temos uma sinal analógico de 0 a 5 V que é entendido pelo Arduino UNO como um número inteiro que vai de 0 a 1023 e de outro temos um sinal PWM que deve ser aplicado a um dispositivo cujo valor do Duty cycle corresponde, no código, a um valor que varia de 0 e 255.
Neste momento, você deve ter percebido temos a necessidade de elaborar algo para que seja possível estabelecer uma correspondência entre os valores de entrada e os valores de saída citados, conforme a figura abaixo.
Este procedimento pode ser realizado através da função map(), confira:
A função map() permite o mapeamento de um intervalo numérico em outro intervalo numérico. Basicamente, o que a função map() faz é pegar um intervalo possua os extremos X1 e X2 e transformar-lo em um outro intervalo cujos valores extremos são Y1 e Y2.
A utilização da função map() requer o uso de 5 parâmetros, onde, o primeiro diz respeito à variável cujo intervalo queremos converter, o segundo e a terceiro correspondem aos extremos mínimo e máximo do intervalo original e os dois últimos estão relacionados com os extremos mínimo e máximo do intervalo novo. Na linha de código abaixo, a variável pwm (criada anteriormente) recebe o valor resultante da conversão da posição do potenciômetro no valor adequado para utilização do PWM, isto é, um valor entre 0 e 255.
pwm = map(potenciometro,0,1023,0,255);
– Acionando o led através de um sinal PWM
Em seguida recorremos à função analogWrite() para aplicar o sinal PWM na saída em que o led está conectado. Esta função possui dois parâmetros, onde, o primeiro corresponde ao pino utilizado e o segundo diz respeito ao número inteiro que representa o Duty cycle (lembre-se que este número está armazenado na variável pwm) do sinal PWM que será entregue pelo Arduino UNO.
analogWrite(10,pwm);
Por fim, devemos lembrar que todo conteúdo apresentado anteriormente faz parta da função loop(), pois, desta maneira, é possível realizar de maneira contínua e constante tanto a leitura do potenciômetro quanto o acionamento do led através da utilização do sinal PWM.
void loop() { potenciometro = analogRead(A0); pwm = map(potenciometro,0,1023,0,255); analogWrite(10,pwm); }
Considerações finais
Este conteúdo foi elaborado para que você possa compreender o básico para poder manipular as entradas analógicas bem como fazer a utilização do PWM para acionar uma infinidade de dispositivos. Esperamos que você tenha gostado deste tutorial e sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.
Lucas Kieling Jung
19 de junho de 2018
Amigo estou com um sério problema no Arduíno UNO , Fiz um código para ele acionar individualmente dois reles , e dois sensores de gás ….
aciona sensor A0 – liga rele D3
aciona sensor A2 liga rele D4
No entanto os reles estão sendo acionado os dois juntos independente do sensor que for acionado ,
aciona A0 liga rele D3 e D4
aciona A2 liga rele D3 e D4
na verdade qualquer porta logica que for acionada aciona os relês !!
Segue código:
int var = 0;
int ValDesarm = 30; //Variável para selecionar a quantidade de Gás/Fumaça detectada
int valor = 0;
int valor1 = 0;
void setup()
{
Serial.begin(9600); //Inicia porta Serial em 9600 baud
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
void loop()
{
//Sensor 1
valor = analogRead(A0); //Faz a leitura da entrada do sensor
valor = map(valor, 0, 1023, 0, 100); //Faz a conversão da variável para porcentagem
Serial.println(valor); //Escreve o valor na porta Serial
if (valor>=ValDesarm){ //Condição, se valor continuar maior que ValDesarm faça:
digitalWrite(3, HIGH); //Liga relé para solenóide
delay(200);
}
if(valor=ValDesarm){ //Condição, se valor continuar maior que ValDesarm faça:
digitalWrite(4, HIGH); //Liga relé para solenóide
delay(200);
}
if(valor=desarm – se tiver maior ou IGUAL pino 3 High
Valor=desarm – se tiver IGUAL pino 4 High… bate com a mesma condição do primeiro if.
NA última vc botou valorValDesarm){
Digitalwrite(3, HIGH);
DELAY(200);
}
if(valor=ValDesarm){
digitalWrite(4, HIGH);
delay(200);
}
if(valor<ValDesarm){
digitalWrite(4, LOW); //desliga o rele
}
delay(200);
Aí tem q ver se esse valor vai dar igual ao desarm em algum momento, como o sinal é analógico… talvez tenha q colocar uma faixa de operação tensão aproximada q vc quer<=desarm <=outra aproximada…
Não sei qual é a fonte
muito bem explicado, me ajudou muito
Muito bom a explicação. Obrigado
Parabéns! Assunto muito bem explicado!
Boa noite. Estou com um problema aqui com meu projeto (na verdade alguns, mas vamos solucionar o mais urgente).. hehehe.
Meu projeto é uma controladora para aquário, vou controlar diversas funções dentre elas a iluminação.
Em resumo, para dimerizar a luz (leds de 3w) usei aquelas shield com o IRF520. São 3 leds de 3w em série ligados com um resistor para limitar a tensão.
O problema é o seguinte: Com os leds em 100% (arduino mandando sinal de 255 no pino) os leds estão ok mas, conforme vou baixando eles ficam oscilando. Quanto menor o valor mais eles oscilam. Alguém já enfrentou algo parecido? Estou fazendo algo errado?
Obrigado.
Quando você diz que está oscilando quer dizer que a luminosidade oscila?
Uma dica, você disse que colocou os leds em série, penso que o mais adequado seria coloca-los em paralelo para que você tenha a mesma tensão sobre todos eles.
Parabens Daniel Madeira pela sua contibuiçao pelo avanço da ciencia
Fiz o circuito no Arduino UNO e ao final nao quis funcionar e o Igor Paulo resolveu o problema usando ” ; ” no final do comando de criação da variável.
Parabens a todos pela dedicaçao em ensinar pessoas com eu que preciso aprender
Obrigado
Daniel, primeiro quero agradecer por compartilhar conhecimento, mas tenho uma dúvida se é possível aferir a leitura de manometro analoigico
Daniel, preciso variar a tensão sobre o LED continuamente, de 0 até 2V, aproximadamente. Existe alguma função que faça isso? Agradeço!
Qual a frequência da saída PWM?
Amigo estou com um sério problema no Arduíno UNO , Fiz um código para ele acionar individualmente dois reles , e dois sensores de gás ….
aciona sensor A0 – liga rele D3
aciona sensor A2 liga rele D4
No entanto os reles estão sendo acionado os dois juntos independente do sensor que for acionado ,
aciona A0 liga rele D3 e D4
aciona A2 liga rele D3 e D4
na verdade qualquer porta logica que for acionada aciona os relês !!
Segue código:
int var = 0;
int ValDesarm = 30; //Variável para selecionar a quantidade de Gás/Fumaça detectada
int valor = 0;
int valor1 = 0;
void setup()
{
Serial.begin(9600); //Inicia porta Serial em 9600 baud
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
void loop()
{
//Sensor 1
valor = analogRead(A0); //Faz a leitura da entrada do sensor
valor = map(valor, 0, 1023, 0, 100); //Faz a conversão da variável para porcentagem
Serial.println(valor); //Escreve o valor na porta Serial
if (valor>=ValDesarm){ //Condição, se valor continuar maior que ValDesarm faça:
digitalWrite(3, HIGH); //Liga relé para solenóide
delay(200);
}
if(valor=ValDesarm){ //Condição, se valor continuar maior que ValDesarm faça:
digitalWrite(4, HIGH); //Liga relé para solenóide
delay(200);
}
if(valor<=ValDesarm){
digitalWrite(4, LOW); //desliga o rele
}
delay(200);
Tenta isso aqui:
int var = 0;
int ValDesarm = 30; //Variável para selecionar a quantidade de Gás/Fumaça detectada
int valor = 0;
int valor1 = 0;
int rele1 = 3;
int rele2 = 4;
void setup()
{
Serial.begin(9600); //Inicia porta Serial em 9600 baud
}
void loop()
{
//Sensor 1
valor = analogRead(A0); //Faz a leitura da entrada do sensor
valor = map(valor, 0, 1023, 0, 100); //Faz a conversão da variável para porcentagem
Serial.println(valor); //Escreve o valor na porta Serial
if (valor>=ValDesarm){ //Condição, se valor continuar maior que ValDesarm faça:
digitalWrite(rele1, HIGH); //Liga relé para solenóide
delay(200);
}
if(valor=ValDesarm){ //Condição, se valor continuar maior que ValDesarm faça:
digitalWrite(rele2, HIGH); //Liga relé para solenóide
delay(200);
}
if(valor<=ValDesarm){
digitalWrite(rele2, LOW); //desliga o rele
}
delay(200);
No caso a saida de tensao é variavel para o led é de 0 a 5v tambem?
A saída pode ter os dois valores, 0 e 5 e não um valor intermediário, entende?
Muito legal o método usado para ensinar, muito bem explicado.
No meu Arduino(MEGA) o código só foi aceito com ponto e virgula após as definições da primeira e segunda linha.
//————————————————-//
1 unsigned int potenciometro ; //
2 unsigned int pwm ; //
//———————————————-//
3
4 void setup()
5 {
6 pinMode(10,OUTPUT);
7 }
8
9 void loop()
10 …
Muito obrigado pela sua contribuição Igor!
Parabens pela sua contibuiçao pelo avanço da ciencia
Fiz o circuito no Arduino UNO e ao final nao quis funcionar e o Igor Paulo resolveu o problema usando ” ; ” no final do comando de criação da variável.
Parabens a todos pela dedicaçao em ensinar pessoas com eu que preciso aprender
Obrigado
Site maravilhoso! Único local na qual pude entender as funcionalidades do PWM. Parabéns!
Fábio, muito obrigado pelo seu retorno. Este tipo de incentivo nos ajuda a produzir um conteúdo cada vez melhor!