Eletrônica Por Equipe DevBras

Capa do artigo: Potenciômetro no Arduino: leitura estável de 0 a 1023 sem número tremendo

Potenciômetro no Arduino: leitura estável de 0 a 1023 sem número tremendo

Ligue os três terminais certos, entenda o que o analogRead devolve e use média, histerese e zona morta para transformar o giro num comando estável.

Você liga um potenciômetro ao Arduino para controlar o brilho de um LED. Funciona, mas com a mão parada o monitor serial mostra 511, 513, 510, 514, e o LED pisca levemente. Girando até o fim, o valor para em 1019 e o brilho nunca chega ao máximo. A resposta curta: ligue o pino do meio na entrada analógica e os das pontas em 5 V e GND, leia com analogRead (0 a 1023 no Arduino Uno), tire a média de algumas leituras e só aceite mudanças maiores que alguns pontos. Nas pontas, use uma zona morta para garantir zero e máximo.

O tremor de dois ou três pontos não é defeito. É ruído normal de qualquer conversor analógico-digital, e o código precisa lidar com ele.

O que o Arduino está medindo

O potenciômetro é um resistor com um contato deslizante, o cursor. As duas pontas recebem 5 V e 0 V. O cursor, no pino do meio, pega uma fração dessa tensão conforme a posição: perto de 0 V num extremo, perto de 5 V no outro, 2,5 V no meio. É um divisor de tensão ajustável.

O Arduino Uno tem um conversor de 10 bits. Ele compara a tensão do pino com a referência (por padrão, a alimentação de 5 V da placa) e devolve um inteiro de 0 a 1023. Cada passo vale cerca de 4,9 mV. Por isso o número não é ângulo, nem porcentagem, nem brilho: é a escala do conversor. Você converte para a unidade que o projeto precisa.

Como cada passo é pequeno, qualquer variação mínima de tensão aparece. Ruído da fonte USB, fio longo, contato do cursor gasto: tudo isso move a leitura alguns pontos. Se o programa trata 512 e 514 como comandos diferentes, o atuador treme parado.

Que potenciômetro usar

Para leitura no Arduino, 10 kΩ é a escolha comum. Valores muito baixos gastam corrente à toa (um de 1 kΩ consome 5 mA o tempo todo). Valores muito altos deixam a leitura mais sensível a ruído, e o datasheet do microcontrolador do Uno recomenda fonte de sinal com impedância de até 10 kΩ para o conversor. Prefira curva linear; em muitos fabricantes, a letra B indica linear e A indica logarítmica, mas confira na ficha da peça.

Como ligar e ler, passo a passo

  1. Ligue uma ponta em 5 V e a outra em GND do Arduino. Se o giro sair invertido, troque essas duas; não precisa mudar código.
  2. Ligue o pino do meio em A0. Este é o único que vai para a entrada analógica.
  3. Use o mesmo GND do Arduino para tudo que estiver no circuito. Terra separado faz o número dançar sem ninguém tocar.
  4. Grave um teste de leitura bruta e anote o valor no início, no meio e no fim do curso.
  5. Aplique média, histerese e zona morta, como no código abaixo.
  6. Converta para a unidade do projeto com map e constrain.

Exemplo completo: dimmer de LED estável

O LED, com resistor em série, vai no pino 9, que tem PWM no Uno. O potenciômetro vai em A0.

const int PINO_POT = A0;
const int PINO_LED = 9;        // pino com PWM no Uno
const int AMOSTRAS = 8;
const int HISTERESE = 4;       // ignora variações menores que isto
const int ZONA_BAIXA = 10;     // abaixo disto, considera zero
const int ZONA_ALTA = 1013;    // acima disto, considera o máximo

int valorAceito = -1;

int lerMedia() {
  long soma = 0;
  for (int i = 0; i < AMOSTRAS; i++) {
    soma += analogRead(PINO_POT);
  }
  return soma / AMOSTRAS;
}

void setup() {
  pinMode(PINO_LED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int bruto = lerMedia();
  bool mudouBastante = valorAceito < 0 || abs(bruto - valorAceito) >= HISTERESE;
  bool chegouNaPonta = (bruto <= ZONA_BAIXA && valorAceito > ZONA_BAIXA) ||
                       (bruto >= ZONA_ALTA && valorAceito < ZONA_ALTA);

  if (mudouBastante || chegouNaPonta) {
    valorAceito = bruto;
    int limitado = constrain(bruto, ZONA_BAIXA, ZONA_ALTA);
    int brilho = map(limitado, ZONA_BAIXA, ZONA_ALTA, 0, 255);
    analogWrite(PINO_LED, brilho);
    Serial.print("bruto=");
    Serial.print(bruto);
    Serial.print(" brilho=");
    Serial.println(brilho);
  }
  delay(20);
}

O que cada parte resolve:

  • Média de 8 leituras: suaviza o ruído rápido sem atraso perceptível.
  • Histerese de 4 pontos: o valor só muda quando a mão realmente mexeu. Com a mão parada, o monitor fica em silêncio.
  • Zona morta nas pontas: se o curso termina em 1019, a leitura ainda passa de 1013 e o brilho chega a 255. O mesmo vale para o zero.
  • Teste de ponta: garante que, ao chegar ao extremo, o valor seja aceito mesmo que a diferença seja menor que a histerese.

Uma rodada de teste girando do início ao fim mostrou (valores de exemplo):

bruto=3 brilho=0
bruto=248 brilho=60
bruto=512 brilho=127
bruto=770 brilho=193
bruto=1019 brilho=255

Lembre que analogWrite não abaixa a tensão do pino; ele liga e desliga rápido, e o LED parece mais fraco pela média. O detalhe está em PWM não diminui a voltagem.

Ajustando para outros usos

A mesma estrutura serve para qualquer saída. Para comandar um servo, troque a escala final para ângulo ou largura de pulso, como em servo motor no Arduino. Para um sensor de luz resistivo, a lógica de leitura é a mesma, mas o divisor usa um resistor fixo, assunto de sensor de luz LDR. Se o projeto usa uma placa de 3,3 V, as pontas vão em 3,3 V, nunca em 5 V, para não exceder a tensão máxima do pino.

Erros comuns

  • Ligar o cursor numa ponta. O valor cola em 0 ou 1023 e não muda com o giro.
  • Usar terra diferente do Arduino. A leitura flutua e o atuador se mexe sozinho.
  • Tratar cada variação como comando. O motor ou servo vibra parado e gasta energia.
  • Mapear de 0 a 1023 cru. Se o curso real termina antes, o máximo nunca chega.
  • Escolher potenciômetro logarítmico para controle linear. Metade do giro quase não muda nada e o resto muda tudo.
  • Ligar 5 V numa placa de 3,3 V. Pode danificar a entrada analógica.

Checklist

  • Pino do meio em A0, pontas em 5 V e GND.
  • Todo o circuito compartilha o GND do Arduino.
  • Anotei os valores reais no início, meio e fim do curso.
  • O código usa média e histerese.
  • Zero e máximo são alcançados graças à zona morta.
  • A conversão para a unidade final usa constrain e map.
  • Com a mão parada, o monitor serial não imprime nada.

Abra o monitor serial e solte o knob no meio por dez segundos: quantas linhas aparecem, e o seu atuador se mexe a cada uma delas?

Avalie este artigo

Referência: http://www.ajudino.com/2013/04/3-utilizando-potenciometro-no-arduino.html