Estoy haciendo un medidor de nivel pequeño usando un microcontrolador ATtiny. Utiliza un potenciómetro lineal de 5K como un divisor de voltaje acoplado a un pin ADC. Hasta ahora está funcionando, excepto que los valores digitales no parecen estar bien correlacionados con el voltaje medido.
El esquema:
El código relevante:
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
int adc_value;
void ADC_init()
{
// Enable ADC
ADCSRA |= (1 << ADEN);
// Set ADC reference to AVCC
ADMUX |= (1 << REFS0);
// Prescaler /8, 125kHz ADC sample rate @ 1MHz
ADCSRA |= (0 << ADPS2) | ( 1 << ADPS1) | (1 << ADPS0);
// Auto trigger enable
ADCSRA |= (1 << ADATE);
// Use input channel ADC2 (PB4)
ADMUX |= (1 << MUX1) | (0 << MUX0);
// Left shift ADC result
ADMUX |= (1 << ADLAR);
// Start converting
ADCSRA |= (1 << ADSC);
}
int main(void)
{
DDRB = 0x07;
PORTB = 0x00;
ADC_init();
while(1)
{
adc_value = ADCH;
if (adc_value < 64)
// output A
else if (adc_value < 128)
// output B
else if (adc_value < 192)
// output C
else
// output D
}
}
Medí el voltaje en PB4 y noté los puntos en los que cambió la salida:
- Mínimo: 196 mV
- 64: ~ 235 mV
- 128: ~ 500 mV
- 192: ~ 770 mV
- Máximo: 2.849 V
Esperaba que aproximadamente 1.5 V estuvieran donde se obtiene un valor digital de 128, no 500 mV.
Si entiendo correctamente, el ATtiny13A tiene un ADC de 10 bits, cuyos valores se almacenan en dos registros, ADCH y ADCL. Con ADLAR (el ajuste a la izquierda) habilitado, el valor se cambia al registro ADCH y efectivamente se descartan dos bits.
La hoja de datos indica:
Si el resultado se deja ajustado y no se requiere una precisión de más de 8 bits, es suficiente para leer ADCH.
Estoy confundido acerca de por qué estoy obteniendo una conversión no lineal en el ADC. ¿Puedes explicar lo que puedo estar pasando por alto?