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
- 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.
- Ligue o pino do meio em A0. Este é o único que vai para a entrada analógica.
- Use o mesmo GND do Arduino para tudo que estiver no circuito. Terra separado faz o número dançar sem ninguém tocar.
- Grave um teste de leitura bruta e anote o valor no início, no meio e no fim do curso.
- Aplique média, histerese e zona morta, como no código abaixo.
- Converta para a unidade do projeto com
mapeconstrain.
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
constrainemap. - 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?
Referência: http://www.ajudino.com/2013/04/3-utilizando-potenciometro-no-arduino.html