Voltímetro com Arduino: como montar, programar e calibrar

Como usar as portas analógicas para medir bem acima do seu limite de 5V, e como calibrá-las para maior precisão e acurácia.

Com poucos componentes – basicamente resistores e jumpers – e um circuito simples, é possível usar um Arduino como um voltímetro programável.

Neste artigo veremos o princípio de funcionamento para a medição simultânea de até 2 tensões DC positivas até 55V, bem como 3 maneiras simples de ampliar a precisão e acurácia dessas medições.

O divisor de tensão

As portas analógicas do Arduino Uno e similares são limitadas a identificar tensões entre 0 e 5V (aproximadamente), portanto, para identificar tensões em outras faixas, é necessário primeiro convertê-las para esse intervalo.

Uma das formas mais simples de converter, para tensões positivas, é usar a regra do divisor de tensão, um dos circuitos básicos mais usados em aplicações práticas.

Um divisor de tensão bem simples pode ser composto por 2 resistores (R1 e R2) conectados em série ao terra. A tensão de entrada Vin é conectada a R1, e o segundo terminal de R2 pode ser conectado ao terra. A tensão de saída Vout é obtida na conexão entre R1 e R2, e é sempre uma fração de V1 proporcional à relação entre esses 2 resistores, com base na fórmula a seguir:

Vout = Vin × R2 ÷ (R1 + R2)

Ou seja: a relação entre R2 e a soma de R1 e R2 governa a relação entre a tensão de entrada e a de saída.

Divisor de tensão para medir tensões no Arduino

Ao selecionar os resistores R1 e R2 para medições de tensões positivas nas portas analógicas do Arduino, é importante usar a fórmula acima tendo em vista 2 critérios adicionais:

  1. Quanto maior a soma R1 + R2, menos o circuito de medição irá interferir nas propriedades sendo medidas.
  2. O valor de Vout para a maior tensão Vin plausível no circuito sendo medido deve ser ≤5V, para evitar danos à porta analógica ou ao próprio Arduino.

Para garantir o 1º critério, escolha para R1 um dos maiores resistores que você tenha à disposição. Eu tenho alguns de 1MΩ reservados justamente para esse tipo de aplicação mas, dependendo do que se for medir, um resistor menor pode ser suficiente, ou um resistor maior pode ser necessário.

Tendo escolhido R1 entre os maiores resistores da sua coleção, é fácil calcular o valor necessário para R2.

Para atender ao segundo critério, já sabendo o valor de R1, basta resolver a fórmula para saber o valor de R2 correspondente ao máximo Vin plausível1, e a um Vout de 5V (que é o limite que pode ser lido numa porta analógica do Arduino Uno.

Por exemplo: eu desejava medir tensões que iriam variar entre 0 e 50V. Para maior segurança, estimei com 10% de folga, e assim considerei que minha maior tensão de entrada Vin plausível seria de 55V. Sabendo que R1 iria ser de 1MΩ (ou seja, 1.000.000 ohms), e que a tensão de saída Vout a considerar no cálculo é a do limite do Arduino, ou seja, 5V, o cálculo de R2 fica assim:

Vout = Vin × R2 ÷ (R1 + R2)
5 = 55 × R2 ÷ (1.000.000 + R2)
5 ÷ 55 = R2 ÷ (1.000.000 + R2)
55 × R2 = 5.000.000 + 5 × R2
50 × R2 = 5.000.000
R2 = 100.000
R2 = 100KΩ

Dica: Fiz a resolução passo a passo para ilustrar, mas é provável que muitos leitores consigam resolver de cabeça (essencialmente é uma regra de três), ou saibam que existem infindáveis calculadores de divisor de tensão disponíveis facilmente na web.

A partir da aplicação da fórmula, acima, já posso montar o circuito, que fica assim:

Pelos nossos cálculos, sabemos que qualquer Vin entre 0V e 55V vai corresponder a um Vout entre 0V e 5V, ou seja, dentro da faixa das portas analógicas do Arduino.

Identificando na fórmula o fator de conversão, nosso programa ficará bem mais simples, depois.

Antes de prosseguir, vamos calcular mais um valor derivado da fórmula acima, e que será útil na forma de resolução que escolhi para o programa: o fator inverso correspondente ao fator de conversão que usamos na fórmula (que foi R2 ÷ (R1 + R2)). Como a nossa fórmula calcula Vout a partir de Vin, e queremos fazer o oposto (ou seja, descobrir a tensão Vin em um ponto externo a partir da tensão Vout que chega a uma porta analógica do Arduino), precisamos isolar Vin na fórmula, que passa a ficar assim:

Vin = Vout × (R1 + R2) ÷ R2

Trocando em miúdos, no nosso circuito sabemos que Vin sempre vai equivaler a Vout multiplicado pelo resultado de (R1 + R2) ÷ R2. Como temos os valores de R1 e de R2, podemos calcular esse fator, que será (1.000.000 + 100.000) ÷ 100.000, que dá 11. Isso significa que, no nosso circuito, para saber o valor de Vin basta multiplicar o valor de Vout por 11.

Voltímetro com Arduino: como montar

Para medir tensões DC com o Arduino, basta montar um circuito como o que ilustramos acima (com R2 e R2 selecionados de acordo com a tensão máxima que você pode medir), conectando Vout a uma porta analógica do seu Arduino e conectando o terra do circuito ao pino GND do Arduino. Da mesma forma, conecte Vin ao positivo do circuito DC (com tensão dentro da faixa calculada nos passos acima) cuja tensão você deseja medir, e cujo terra também esteja conectado ao GND do Arduino.

Como quero poder medir simultaneamente 2 tensões, montei em uma protoboard 2 exemplares do circuito divisor de tensão descrito acima. Veja-os na foto: marquei um deles com uma moldura vermelha, e o outro com uma moldura amarela.

Não há problema em usar simultaneamente 2 divisores diferentes, basta saber o fator de cada um deles.

Eles são idênticos, porque as tensões que eu vou medir têm o mesmo grau de variação, mas eu poderia ter feito 2 circuitos diferentes, como por exemplo um circuito com resistores aptos a medir tensões até 12V (quanto menor a tensão máxima, maior a precisão teórica possível na medição) e o outro apto a medir tensões até 55V - não é necessário serem iguais, basta saber qual o fator de conversão de cada um deles.

Note que, em cada um deles, temos um resistor de 1MΩ (sempre o de cima) e um de 100KΩ (sempre o de baixo), e que do ponto em que ambos os resistores se conectam sai um jumper em cor laranja – o nosso Vout – que é ligado a uma porta analógica do Arduino. A extremidade de baixo do resistor de baixo é sempre ligada ao terra, e da extremidade de cima sai um jumper (branco, no circuito de cima, e verde, no de baixo) com a outra ponta solta, correspondendo ao Vin, para conectar ao positivo do circuito a ser medido. Para maior conveniência, 2 jumpers pretos conectados ao GND (e com a outra ponta solta) também estão montados para conectar ao terra dos circuitos a serem medidos.

Voltímetro com Arduino: como programar

O programa em si é muito simples: lê e exibe, continuamente, a aplicação das fórmulas que vimos acima, sempre considerando o valor lido nas portas analógicas às quais conectamos os jumpers branco e verde da imagem acima, correspondentes ao Vout de cada um dos divisores de tensão.

Vale lembrar que chegamos a calcular o divisor equivalente da fórmula – que é 11, para os nossos resistores escolhidos, de modo a poder calcular qualquer Vin do nosso circuito simplesmente multiplicando Vout por 11.

Para chegar ao valor de Vin, entretanto, não basta ler o valor da porta analógica. O Arduino lê as tensões de entrada e as converte a um valor de amplitude 1024 (entre 0 e 1023), sendo que 0 corresponde a 0V e 1023 corresponde a 5V. Para converter em tensão o valor lido da porta, portanto, é necessário calcular a regra de 3 correspondente, que na prática equivale a multiplicar o número lido por 5 (a maior tensão que pode ser lida) e dividir o resultado por 1024 (a amplitude da faixa correspondente).

Vamos, portanto, ao programa:

float tensaoA2;
float tensaoA0;

float aRef=5;
float relacaoA0=11;
float relacaoA2=11;
#define AMOSTRAS 12

void setup() {
    Serial.begin(9600);
}

float lePorta(uint8_t portaAnalogica) {
  float total=0;  
  for (int i=0; i<AMOSTRAS; i++) {
    total += 1.0 * analogRead(portaAnalogica);
    delay(5);
  }
  return total / (float)AMOSTRAS;
}  

void mostraTensoes() {
  Serial.print("Tensao em A2: ");
  Serial.print(tensaoA2 * relacaoA2);
  Serial.print ("V / ");
  Serial.print("Tensao em A0: ");
  Serial.print(tensaoA0 * relacaoA0);
  Serial.println ("V");
}  

void loop() {
  tensaoA2 = (lePorta(A2) * aRef) / 1024.0;
  tensaoA0 = (lePorta(A0) * aRef) / 1024.0;
  mostraTensoes();
  delay(500);
}

Comece a analisá-lo pelo trecho em verde. Note que ali estão indicados os parâmetros dos nossos circuitos, incluindo a tensão máxima que pode ser lida numa porta analógica (aRef, 5 volts) e os fatores de conversão dos nossos 2 divisores de tensão (relacaoA0 e relacaoA2, correspondentes ao divisor conectado a A0 e a A2, respectivamente), que são ambos 11 mas poderiam ser valores diferentes entre si, se você tivesse optado por pares diferentes de resistores em cada circuito divisor de tensão.

Veja a seguir o trecho em roxo, a função lePorta() que recebe como parâmetro a identificação de uma porta analógica, aí faz 12 (o valor definido em AMOSTRAS) leituras dela com intervalos de 5ms entre si e retorna a média delas. Um detalhe interessante sobre leituras imprecisas ou com ruído é que, como os ruídos podem variar para cima ou para baixo, fazer múltiplas leituras permite que o ruído de algumas anule o ruído de outras, razão pela qual a média de várias leituras analógicas é uma técnica simples para reduzir a imprecisão inerente.

Pule agora para o final, as 2 linhas em rosa destacadas no nosso loop(). Note que ambas chamam lePorta() e depois multilpicam o resultado por 5 (que é o valor de aRef) e dividem por 1024. Já vimos acima a razão: é assim que se converte em tensão o valor lido em uma porta analógica do Arduino.

Agora retroceda um pouquinho, até as 2 linhas em laranja na função mostraTensões(). Note que são elas que mostram a tensão mas, antes de fazer isso, multiplicam por relacaoA2 ou relacaoA0 (ambos correspondem a 11, no nosso exemplo), para converter o Vout lido no Arduino no Vin correspondente.

O resultado pode ser visto abrindo o Monitor Serial. Em um teste com uma pilha AA parcialmente usada conectada ao divisor em A0 (jumper branco) e uma bateria de 9V quase nova conectado ao divisor em A2 (jumper verde), obtive linhas como as que seguem:

Tensao em A2: 9.20V / Tensao em A0: 1.46V
Tensao em A2: 9.20V / Tensao em A0: 1.47V
Tensao em A2: 9.19V / Tensao em A0: 1.46V
Tensao em A2: 9.20V / Tensao em A0: 1.46V

Calibrando nosso voltímetro

A leitura acima pode ser suficiente se o que você quiser for apenas identificar variações proporcionais. Mas se a intenção for saber o valor exato2 das tensões, é necessário perceber algo importante: o circuito acima tem imprecisões identificáveis e parcialmente corrigíveis, que interferem no resultado das medições.

Considerar 5V como a tensão máxima das portas analógicas é uma boa regra geral, mas tem seus limites.

Um desses elementos de imprecisão é a tensão máxima que pode ser lida na porta analógica, que usualmente consideramos como sendo 5V. Medindo a tensão entre os pinos AREF e GND do Arduino, você saberá o valor real do seu caso – e essa medição pode ser feita com um voltímetro calibrado (pode ser o de um multímetro no qual você confie). No meu caso de hoje, quando conectado a uma porta USB, esse valor é 5.06 – mas em outros modelos de Arduino e outras portas USB, já tive valores diferentes. Substituindo o valor lido no lugar do humilde 5 que consta na variável aRef do nosso programa, você ganhará um pouquinho mais de precisão.

Mas o maior ganho de precisão pode ser obtido analisando o valor correto dos resistores que você usou. A maior parte dos projetos de hobby que eu conheço usa resistores cuja última faixa de identificação é dourada, indicando uma precisão de 5%. Isso não significa que cada leitura poderá variar numa faixa de 5%, e sim que aquele resistor tem um valor específico, constante, que está numa proximidade de até 5% em relação ao valor indicado.

Este é um dos casos em que a linha da direita do código de cores do seu resistor faz bastante diferença prática.

Naturalmente essa diferença entre o valor nominal e o valor real específico de cada resistor interfere no resultado da conversão entre Vin e Vout, e você pode ajustá-la se medir (pode ser com um multímetro que você confia) os valores reais.

Existem várias de fazer essa medição e ajuste. Eu preferi usar o método que identifica o fator de conversão específico do par de resistores, mesmo sem precisar saber o valor de cada um deles em separado.

Para fazer essa medição em seu divisor de tensão, use a imagem acima como referência. Conecte o seu divisor de tensão aos 2 polos de uma fonte ou bateria razoavelmente constante (uma pilha de 9V ou par de pilhas AA podem ser suficientes) e use um voltímetro calibrado (pode ser um multímetro no qual você confie) para medir a tensão entre A e C (VAC) e a tensão entre B e C (VBC). Repita algumas vezes cada medição, e faça a média. Faça a divisão da média de (VAC) pela média de (VBC), e você terá o fator de conversão específico do seu divisor de tensão.

No meu caso, mesmo usando 2 pares de divisores que vieram das mesmas cartelas, os valores ficaram bem diferentes entre si, e do 11, que seria o valor nominal. Adaptando diretamente no programa, ficou assim:

float relacaoA0=11.32;
float relacaoA2=11.76;

A partir desse momento, as leituras do programa rodando no Arduino passaram a ficar bem próximas dos valores que obtive com um voltímetro externo.

Um alerta importante

Conectar seu Arduino, ou outros circuitos, a tensões externas exige uma série de cuidados. Leia com atenção a documentação correspondente aos limites dos seus componentes (até mesmo a protoboard e os jumpers) e tome todas as precauções necessárias para resguardar não apenas o resultado da experiência, mas também a sua integridade física e a do seu patrimônio, evitando causar danos ou incorrer em riscos.

 
  1.  Se você for estimar, prefira errar para cima...

  2.  Tanto quanto viável: para várias aplicações pode ser melhor recorrer a um instrumento especializado.

Comentar

Dos leds ao Arduino, ESP8266 e mais

Aprenda eletrônica com as experiências de um geek veterano dos bits e bytes que nunca tinha soldado um led na vida, e resolveu narrar para você o que descobre enquanto explora esse universo – a partir da eletrônica básica, até chegar aos circuitos modernos.

Por Augusto Campos, autor do BR-Linux e Efetividade.net.

Recomendados

Livro recomendado


Artigos já disponíveis

Comunidade Arduino

O BR-Arduino é integrante da comunidade internacional de entusiastas do Arduino, mas não tem relação com os criadores e distribuidores do produto, nem com os detentores das marcas registradas.

Livros recomendados