← Índice del curso

Microcontroladores · Tema 30

Taller: potenciómetro, LM35 y termistor

El ADC entrega un entero entre 0 y 1023. Lo que interesa es un porcentaje, unos grados o una posición. Este taller conecta tres sensores clásicos a un ATmega328P y recorre el camino completo desde el código binario hasta la unidad física, con la aritmética que cabe en un microcontrolador de 8 bits.

01 · Punto de partida

Qué vamos a construir

Los tres sensores son los más comunes del primer proyecto analógico, y cada uno enseña una lección distinta:

  • El potenciómetro es el sensor más simple: un divisor de tensión variable. Enseña a mapear un rango a otro y a domar el ruido de la última cuenta.
  • El LM35 es un sensor de temperatura con salida lineal de 10 mV por grado. Enseña a elegir la referencia para ganar resolución y a calcular con enteros.
  • El termistor NTC cambia de resistencia con la temperatura, de forma no lineal. Enseña el divisor de resistencias, el modelo matemático y la verificación de un sensor desconectado.

Los valores se envían a la computadora por el puerto serie para verlos en el monitor serie. El UART se estudia en el tema 32; acá usamos solamente su parte más simple, la transmisión, y la explicación llega después.

02 · Tres montajes, una receta

El diseño: tres sensores, un ADC

Resumen del taller.
SensorPinReferenciaDel código a la unidadResolución
Potenciómetro 10 kΩA0AVcc (ratiométrica)% = código · 100 / 10230,1 % por cuenta
LM35A11,1 V internadécimas de °C = código · 1100 / 10240,107 °C por cuenta
NTC 10 kΩ + R fija 10 kΩA2AVcc (ratiométrica)Rt = R · código / (1024 − código); modelo Beta0,09 °C en el centro; peor en los extremos

Dos decisiones de diseño merecen explicación. Primera: la referencia cambia según el canal. El potenciómetro y el termistor son ratiométricos: ambos se alimentan de la misma tensión que sirve de referencia, de modo que la variación de Vcc afecta a la señal y a la escala por igual y se cancela. El LM35, en cambio, entrega una tensión absoluta (10 mV/°C) y solo llega a unos 0,25 V a temperatura ambiente: con la referencia de 5 V quedaría en 51 cuentas y 0,49 °C por escalón, mientras que con 1,1 V sube a 233 cuentas y 0,107 °C. Segunda: como el ADC es uno solo, cada lectura empieza con un cambio de canal y de referencia, y se descarta la primera conversión (tema 28).

El programa lee los tres sensores cada medio segundo y envía una línea de texto. No necesita interrupciones: el tiempo de cálculo es mucho menor que el período.

03 · Paso 1

El cableado

Cableado de los tres sensores El potenciómetro conecta sus extremos a 5 V y GND y su cursor al pin A0. El LM35 conecta +Vs a 5 V, GND a masa y su salida al pin A1. El termistor forma un divisor con una resistencia fija: 5 V, resistencia de 10 kilo ohms, pin A2, termistor, GND. Potenciómetro 10 kΩ LM35 NTC 10 kΩ + R fija 10 kΩ +5 VGNDcursor → A010 kΩ +Vs → 5 VVout → A1GND100 nF a GND (opcional) +5 VR = 10 kΩNTC→ A2GND
  • Potenciómetro: extremos a 5 V y GND, cursor al pin A0. Es un divisor variable: cuando el cursor está en el extremo de GND la tensión es 0 y en el de 5 V, es Vcc.
  • LM35: viéndolo de frente (cara plana hacia vos), de izquierda a derecha son +Vs, Vout y GND. Vout va a A1. Un capacitor de 100 nF cerca del sensor ayuda a estabilizar la lectura cuando el cable es largo.
  • Termistor: 5 V → R fija de 10 kΩ → nodo A2 → NTC → GND. El nodo central es el divisor. Si se invierte el orden (NTC hacia 5 V), el sentido de la variación se invierte y la fórmula cambia.
  • Pin AREF: déjalo libre. Con REFS elegida por programa, el pin queda conectado a la referencia interna y solo se le puede poner un capacitor de 100 nF a masa.

Elegir R fija igual a la resistencia del NTC en la temperatura de interés maximiza la sensibilidad: con 10 kΩ, el centro del rango queda en 25 °C. Si te interesara medir 60 °C, bastaría una R fija de 2,5 kΩ aproximadamente (la resistencia del termistor a esa temperatura).

04 · Paso 2

El potenciómetro

Para leer el potenciómetro se necesita un ADC configurado y una función de lectura. Después, convertir el código en un porcentaje, mapearlo a un rango útil y quitarle el ruido de la última cuenta.

#define F_CPU 16000000UL
#include <avr/io.h>
#include <stdint.h>

#define REF_AVCC   (1 << REFS0)
#define REF_1V1    ((1 << REFS1) | (1 << REFS0))

static void adc_init(void) {
    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);   // divisor 128: 125 kHz
    DIDR0  = (1 << ADC0D) | (1 << ADC1D) | (1 << ADC2D);               // pines A0 a A2 sin buffer digital
}

static uint16_t adc_una(void) {
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC)) { }
    return ADC;
}

static void adc_canal(uint8_t canal, uint8_t ref) {
    ADMUX = ref | (canal & 0x0F);
    (void)adc_una();                       // descarta la primera conversión tras el cambio
}

static uint16_t pot_filtrado(uint16_t lectura) {
    static uint16_t ultimo;
    static uint8_t  inicial = 1;
    int16_t d = (int16_t)lectura - (int16_t)ultimo;
    if (inicial || d > 2 || d < -2) {     // histéresis de 2 cuentas
        ultimo = lectura;
        inicial = 0;
    }
    return ultimo;
}

static uint8_t pot_porcentaje(void) {
    adc_canal(0, REF_AVCC);
    uint16_t crudo = pot_filtrado(adc_una());
    return (uint8_t)((uint32_t)crudo * 100UL / 1023UL);        // 0 a 100
}

Tres decisiones. Una: el porcentaje usa 1023 como divisor para que el extremo dé exactamente 100 (a diferencia de la conversión a volts, que divide por 1024, tema 28). Dos: la histéresis ignora los cambios de ±2 cuentas, que son ruido; solo actualiza cuando el cambio es mayor. Tres: la cuenta usa uint32_t, porque 1023 × 100 no cabe en 16 bits.

Mapear a otro rango

Si el potenciómetro debe regular algo en otra escala (un servo de 0 a 180°, un brillo de 0 a 255), la función estándar es (x − in_min) · (out_max − out_min) / (in_max − in_min) + out_min. Conviene calibrar los extremos reales: un potenciómetro rara vez llega a 0 y 1023 exactos; por ejemplo, 10 y 1013. Con ese rango, la lectura 512 se convierte a 0–255 como (512 − 10) × 255 / 1003 = 127. Y hay que recortar los valores que caen fuera del rango calibrado (constrain) para que no se salgan de la salida.

05 · Paso 3

El LM35

El LM35 entrega 10 mV por cada °C: a 25 °C son 250 mV. Con la referencia de 1,1 V el escalón del ADC es de 1,074 mV, es decir 0,107 °C. Hay una cuenta útil: la tensión en milivolts es numéricamente igual a las décimas de grado (10 mV/°C = 1 mV por cada 0,1 °C). Entonces:

décimas de °C = lectura × 1100 / 1024

Es una multiplicación y una división entera, sin coma flotante. Con 233 cuentas resulta 250 décimas, 25,0 °C. Para ganar más precisión se promedian 16 lecturas, lo que agrega dos bits de resolución efectiva si hay algo de ruido (tema 27). La suma de 16 lecturas tiene 14 bits y se escala con un factor ajustado:

// Devuelve la temperatura en centésimas de grado (2512 = 25,12 °C)
static int16_t lm35_centesimas(void) {
    adc_canal(1, REF_1V1);
    uint32_t suma = 0;
    for (uint8_t i = 0; i < 16; i++) suma += adc_una();
    // 16 lecturas: suma / 16 * 1100 / 1024 décimas -> * 10 centésimas
    return (int16_t)(suma * 1375UL / 2048UL);     // = suma * 11000 / 16384
}

El factor 1375/2048 sale de simplificar 11 000 / 16 384 (se divide por 8). Con 16 368 como máximo de la suma, el producto por 1375 llega a 22,5 millones, que cabe en 32 bits. La resolución del número es de centésimas, pero la exactitud real es de unos ±0,5 °C (la del LM35 típico a 25 °C) más lo que aporte la referencia de 1,1 V, cuya tolerancia es de ±10 %: el número tiene más cifras que verdad. Para una medida absoluta se calibra con un termómetro de referencia, restando un offset medido.

Dos advertencias de hardware. El LM35 en su forma básica solo mide temperaturas positivas, de 2 °C a 150 °C. Y un cable largo lo hace inestable: el LM35 no soporta cargas capacitivas grandes sin una resistencia en serie.

06 · Paso 4

El termistor

Un termistor NTC (negative temperature coefficient) baja su resistencia al subir la temperatura, de manera exponencial. Se mide indirectamente: dentro del divisor, la tensión en A2 es V · Rt / (R + Rt), de modo que:

código = 1024 · Rt / (R + Rt) Rt = R · código / (1024 − código)

La relación entre resistencia y temperatura la describe bien el modelo Beta, con la resistencia R0 a una temperatura T0 (10 kΩ a 25 °C, es decir 298,15 K) y una constante β del fabricante (típicamente 3950 K):

1 / T = 1 / T0 + ln(Rt / R0) / β (T en kelvin; °C = T − 273,15)
#include <math.h>

// Devuelve la temperatura en décimas de grado, o INT16_MIN si el sensor falla.
static int16_t ntc_decimas(uint16_t lectura) {
    if (lectura < 10 || lectura > 1013) return INT16_MIN;     // en corto o desconectado
    float rt = 10000.0f * lectura / (1024.0f - lectura);
    float kelvin = 1.0f / (1.0f / 298.15f + logf(rt / 10000.0f) / 3950.0f);
    return (int16_t)lroundf((kelvin - 273.15f) * 10.0f);
}

El test inicial es una buena práctica de programación defensiva: un código de 0 o 1023 en un divisor significa un sensor en corto o un cable cortado, y convertirlo en grados daría números disparatados (o un logaritmo de cero). La función devuelve un valor centinela para que el programa pueda mostrar «error».

El cálculo con float y logf consume Flash (del orden de un par de kilobytes) y tiempo (cientos de microsegundos en un AVR de 8 bits). Si la memoria es crítica, se reemplaza por una tabla de temperatura frente a lectura con interpolación lineal. Una tabla de 16 puntos equiespaciados (cada 64 cuentas) tiene un error máximo de 2,4 °C en los extremos, porque la curva es muy pronunciada allí. Se mejora con más puntos o con una separación menor donde la curva se curva más.

La sensibilidad no es uniforme: cerca de la mitad del código (512) el escalón vale 0,09 °C, y en 100 sube a 0,36 °C. El divisor es más sensible cuando R fija se parece a Rt. Finalmente, la corriente del divisor calienta el termistor (autocalentamiento): con 5 V y 10 kΩ disipa del orden de 0,6 mW, que causa un error de décimas de grado. Se minimiza alimentando el divisor solo durante la medición.

07 · Paso 5

El programa completo

Para mostrar resultados usamos un transmisor serie mínimo: 9600 baudios, 8 bits sin paridad. Los registros se explican en el tema 32; por ahora basta saber que UBRR0 = 103 da 9600 baudios con 16 MHz y que escribir en UDR0 envía un byte.

#include <util/delay.h>
/* ... adc_init, adc_una, adc_canal, pot_filtrado, pot_porcentaje,
       lm35_centesimas y ntc_decimas, como en los pasos anteriores ... */

static void uart_init(void) {
    UBRR0  = 103;                                     // 9600 baudios con 16 MHz
    UCSR0B = (1 << TXEN0);
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);          // 8 bits de datos
}

static void uart_tx(char c) {
    while (!(UCSR0A & (1 << UDRE0))) { }
    UDR0 = (uint8_t)c;
}

static void uart_texto(const char *s) { while (*s) uart_tx(*s++); }

static void uart_u16(uint16_t v) {
    char buf[5];
    uint8_t n = 0;
    do { buf[n++] = (char)('0' + v % 10); v /= 10; } while (v);
    while (n) uart_tx(buf[--n]);
}

// Imprime un valor con signo y 'dec' decimales implícitos (dec = 1 o 2)
static void uart_fijo(int16_t valor, uint8_t dec) {
    if (valor < 0) { uart_tx('-'); valor = -valor; }
    uint16_t div = (dec == 2) ? 100 : 10;
    uart_u16((uint16_t)valor / div);
    uart_tx(',');
    uint16_t resto = (uint16_t)valor % div;
    if (dec == 2 && resto < 10) uart_tx('0');
    uart_u16(resto);
}

int main(void) {
    adc_init();
    uart_init();
    for (;;) {
        uint8_t  pct = pot_porcentaje();
        int16_t  lm  = lm35_centesimas();
        adc_canal(2, REF_AVCC);
        int16_t  nt  = ntc_decimas(adc_una());

        uart_texto("POT=");  uart_u16(pct);          uart_texto(" %   ");
        uart_texto("LM35="); uart_fijo(lm, 2);       uart_texto(" C   ");
        uart_texto("NTC=");
        if (nt == INT16_MIN) uart_texto("error"); else uart_fijo(nt, 1);
        uart_texto(" C\r\n");
        _delay_ms(500);
    }
}

El programa usa _delay_ms(500) por simplicidad: bloquea la CPU, algo que ya sabés evitar con una base de tiempo (tema 26). Mientras no haya otras tareas, no importa; en un programa más completo se reemplaza por la marca de tiempo con +=. La salida típica en el monitor serie es POT=50 % LM35=25,12 C NTC=24,8 C.

Para el potenciómetro como control de un LED o de un servo, el valor de 0 a 100 alimenta directamente el OCR de la PWM (tema 26): este es el patrón de casi todos los proyectos de entrada analógica y salida PWM.

08 · Paso 6

Verificar

  1. El cero. Leé el canal de GND (MUX = 1111): debe dar 0 o 1. Valores mayores indican ruido o un offset en el montaje.
  2. Los extremos del potenciómetro. Girá a cada tope y anotá las lecturas mínima y máxima: son los extremos de calibración.
  3. El ruido. Con el cursor quieto, imprimí 100 lecturas y mirá cuánto varían. Más de ±3 cuentas indica un problema de cableado o de alimentación.
  4. El LM35. Compará con un termómetro conocido. Apoyá un dedo sobre el sensor: debería subir unos grados en medio minuto.
  5. El termistor en 25 °C. Con R fija de 10 kΩ, la lectura cerca de 512 corresponde a 25 °C. Con el sensor al aire y la habitación a 20–25 °C, la lectura debe estar cerca.
  6. El sensor desconectado. Desconectá el termistor: el programa debe mostrar «error» y no un número.
  7. La coherencia. El LM35 y el termistor, uno junto al otro, deben coincidir en menos de 1 o 2 °C.

Si el LM35 lee un valor absurdo (por ejemplo, 114 °C a temperatura ambiente), la causa más común es un desajuste entre la referencia del programa y la usada en la fórmula: leer con 5 V y convertir como si fueran 1,1 V (o al revés). Sospechá primero de eso.

09 · Analogía con programación

La conversión, la tabla y el filtro

Este programa reproduce los cálculos del taller: la tabla de temperaturas del termistor por el modelo Beta con el error de una tabla de 16 puntos, el efecto del ruido sobre un potenciómetro con tres estrategias (directo, promedio de 8 e histéresis) y la dispersión del LM35 con una lectura simple frente a un promedio de 16.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

import math
import random

random.seed(11)

# 1) termistor NTC en divisor: Vcc - R fija - A2 - NTC - GND
R_FIJA, R0, BETA = 10000.0, 10000.0, 3950.0

def ntc_celsius(lectura):
    rt = R_FIJA * lectura / (1024 - lectura)
    return 1 / (1 / 298.15 + math.log(rt / R0) / BETA) - 273.15

print("lectura   Rt (ohm)   temperatura   grados por cuenta")
for lec in (100, 200, 300, 400, 512, 600, 700, 800, 900):
    rt = R_FIJA * lec / (1024 - lec)
    paso = abs(ntc_celsius(lec + 1) - ntc_celsius(lec - 1)) / 2
    print(f"{lec:7d}  {rt:9.0f}   {ntc_celsius(lec):8.2f} C   {paso:8.3f}")

# tabla de 16 puntos (cada 64 cuentas) con interpolacion lineal, en lugar de log()
TABLA = [ntc_celsius(min(1023, max(1, i * 64))) for i in range(17)]

def ntc_tabla(lectura):
    i = min(15, lectura // 64)
    frac = (lectura - i * 64) / 64
    return TABLA[i] + (TABLA[i + 1] - TABLA[i]) * frac

peor = max(abs(ntc_tabla(n) - ntc_celsius(n)) for n in range(64, 960))
print(f"error maximo de la tabla de 16 puntos entre 64 y 959: {peor:.2f} C")

# 2) potenciometro con ruido: cuantas veces cambia el valor mapeado
def mapear(x, a, b, c, d):
    return (x - a) * (d - c) // (b - a) + c

def lecturas(n, verdadero=512.4, ruido=1.2):
    return [min(1023, max(0, round(random.gauss(verdadero, ruido)))) for _ in range(n)]

def cambios(serie):
    return sum(1 for a, b in zip(serie, serie[1:]) if a != b)

muestras = lecturas(1000)
directo = [mapear(x, 0, 1023, 0, 100) for x in muestras]
promedio = [mapear(sum(muestras[i:i + 8]) // 8, 0, 1023, 0, 100) for i in range(0, 992, 8)]
salida, ultimo = [], muestras[0]
for x in muestras:
    if abs(x - ultimo) > 2:           # histeresis de 2 cuentas
        ultimo = x
    salida.append(mapear(ultimo, 0, 1023, 0, 100))
print()
print("cambios del valor 0-100 en 1000 lecturas con ruido de 1,2 cuentas:")
print("  directo     :", cambios(directo), "de", len(directo) - 1)
print("  prom. de 8  :", cambios(promedio), "de", len(promedio) - 1)
print("  histeresis 2:", cambios(salida), "de", len(salida) - 1)

# 3) LM35 con referencia de 1,1 V: lectura simple frente a promedio de 16
def lm35(lectura):
    return lectura * 1100 // 1024        # decimas de grado

def desviacion(valores):
    m = sum(valores) / len(valores)
    return math.sqrt(sum((v - m) ** 2 for v in valores) / len(valores))

verdadero = 25.0 / 100 * 1024 / 1.1        # 25 C -> 0,25 V -> cuentas
simples = [lm35(max(0, round(random.gauss(verdadero, 0.8)))) / 10 for _ in range(2000)]
prom16 = []
for _ in range(2000):
    suma = sum(max(0, round(random.gauss(verdadero, 0.8))) for _ in range(16))
    prom16.append(suma * 1100 // (1024 * 16) / 10)
print()
print(f"LM35 a 25 C: lectura simple {desviacion(simples):.3f} C de dispersion, promedio de 16: {desviacion(prom16):.3f} C")

Resultado: el termistor da 25,00 °C con 512 cuentas, y el escalón por cuenta pasa de 0,088 °C en el centro a 0,36 °C con 100 cuentas. Con ruido de 1,2 cuentas, el potenciómetro cambia su valor de 0 a 100 en el 35 % de las lecturas si se lee directo, en el 19 % con promedio de 8 y en el 9 % con histéresis de 2 cuentas. La dispersión del LM35 baja de 0,085 a 0,050 °C al promediar 16; no llega al factor 4 teórico porque el resultado se redondea a décimas de grado, lo que agrega su propio error.

El ruido aquí es gaussiano e independiente; los números exactos dependen de la semilla del generador. El orden de magnitud y la comparación entre estrategias son lo que importa.

10 · Exploración interactiva

Tres calculadoras de lectura

Cada herramienta toma un código del ADC y lo convierte en unidades físicas, como lo haría el programa. Sirven para comprobar los números que muestra tu monitor serie.

Banco de sensores

1. Potenciómetro

Tensión en el pin—
Porcentaje del código—
Valor mapeado—
Resolución de la salida—

2. LM35

Temperatura—
Resolución y ruido—
Cuenta entera en C—

3. Termistor NTC

Resistencia del termistor—
Temperatura—
Sensibilidad—

Recorrido guiado

  1. Potenciómetro con código 512 y extremos calibrados 10 y 1013: el valor 0–255 es 127,63, que en C entero queda 127. Con el código 5 (por debajo del extremo) la lectura se recorta a 0.
  2. LM35 con el código 234 y 1,1 V: 25,14 °C y 251 décimas. Cambiá la referencia a 5 V sin cambiar el código: el resultado es 114 °C, un disparate. La conversión debe usar la referencia con que se leyó.
  3. Con 5 V, el escalón de la temperatura sube a 0,488 °C. Con 64 lecturas promediadas, el ruido baja a ~0,06 °C.
  4. Termistor con 512 cuentas: 10 000 Ω y 25 °C, con 0,088 °C por cuenta. Probá 100: 1082 Ω, 85,1 °C y 0,36 °C por cuenta.
  5. Con 1023 el termistor avisa que el sensor está desconectado o el código saturado. Es el caso que el programa debe detectar.
  6. Cambiá β a 4050 con el código 700: la temperatura sube unas décimas. Una diferencia de β entre el dato del fabricante y el real cambia el resultado: por eso se calibra en dos puntos.
Desafío: un termistor para medir de 40 °C a 80 °C

El NTC de 10 kΩ tiene unos 5,3 kΩ a 40 °C y unos 1,27 kΩ a 80 °C (modelo Beta con β = 3950). Con R fija de 10 kΩ, el divisor ofrece lecturas de 1024 × 5,3 / 15,3 = 355 a 1024 × 1,27 / 11,27 = 115: unas 240 cuentas para 40 °C, es decir, 0,17 °C por cuenta. Con una R fija de 2,5 kΩ, el rango de lecturas es de 1024 × 5,3 / 7,8 = 696 a 1024 × 1,27 / 3,77 = 345: 351 cuentas, 0,11 °C por cuenta. Elegir R cerca de la resistencia del NTC en el centro del rango mejora la resolución.

11 · Cierre del bloque 7

Lo aprendido en el bloque

  1. Convertir es muestrear y cuantizar: el escalón (LSB) y la frecuencia de Nyquist fijan lo que se puede medir; el alias no se corrige después.
  2. El ADC del ATmega328P es un SAR de 10 bits con un multiplexor, referencia elegible y un reloj de 125 kHz: 104 µs por conversión.
  3. La referencia es parte de la medición: la ratiométrica cancela las variaciones de Vcc; la interna de 1,1 V da más resolución para señales pequeñas.
  4. El DAC hace el camino inverso: la R-2R exige apareamiento, la PWM filtrada es lenta pero económica y los DAC externos ofrecen exactitud.
  5. Del código a la unidad física se llega con aritmética entera cuidadosa, promedio, histéresis, calibración y detección de fallas del sensor.
  6. El número tiene más cifras que verdad: la resolución del conversor no es la exactitud de la medida.

Con este taller termina el bloque 7. Hasta ahora el microcontrolador se comunicó con el mundo mediante pines individuales. El bloque 8 aborda la comunicación serie: cómo enviar y recibir datos por pocos cables, con UART, I2C y SPI, y cómo conversan los microcontroladores con sensores, pantallas y computadoras.

12 · Comprensión

Confusiones frecuentes

«Más decimales en pantalla significan más exactitud»

La resolución de la cuenta (centésimas) es una cosa; la exactitud del sensor (±0,5 °C del LM35) y de la referencia (±10 % para la de 1,1 V) es otra. Mostrá solo las cifras que el sistema merece.

«El LM35 y el termistor se leen igual»

El LM35 entrega una tensión proporcional a la temperatura; el termistor, una resistencia que hay que convertir en tensión con un divisor y luego en temperatura con una función no lineal.

«El termistor lee 1023, así que hace mucho calor»

Con el divisor de este taller, el código sube al aumentar Rt, es decir al bajar la temperatura, y 1023 significa sensor desconectado. Siempre hay que comprobar los extremos del código.

«Cambio la referencia en el código y todo sigue igual»

Cada referencia tiene su fórmula y su primera lectura es dudosa. Si cambia la referencia hay que descartar una lectura y usar el factor correcto.

«Con promediar basta para quitar el ruido»

Promediar reduce el ruido aleatorio por √N, pero no el offset de la referencia ni el autocalentamiento. Ni sirve si la señal cambia durante el promedio.

13 · Práctica guiada

Predecí antes de comprobar

1. Mapear un potenciómetro

El potenciómetro, calibrado entre 10 y 1013, entrega el código 300. ¿Qué valor da el map() entero a 0–255?

Ver solución

(300 − 10) × 255 / 1003 = 73 950 / 1003 = 73,73 → 73 (la división entera trunca). La tensión en el pin es 300 × 5 / 1024 = 1,465 V.

2. Temperatura del LM35

Con referencia de 1,1 V, el código es 300. ¿Qué temperatura indica?

Ver solución

300 × 1100 / 1024 = 322 décimas = 32,2 °C.

3. Termistor

En el divisor del taller (R fija de 10 kΩ), la lectura es 700. ¿Cuánto vale Rt y por qué la temperatura es menor que 25 °C?

Ver solución

Rt = 10 000 × 700 / 324 = 21 605 Ω, mayor que los 10 kΩ de 25 °C. En un NTC, más resistencia significa menos temperatura: unos 8,6 °C con β = 3950.

4. La sensibilidad cambia

¿Por qué el escalón del termistor es de 0,088 °C en el código 512 y de 0,36 °C en el 100?

Ver solución

Por el divisor: su salida es más sensible a Rt cuando Rt se parece a R fija (centro del código). Cerca de los extremos, la misma variación de resistencia mueve menos la tensión, y además el NTC cambia más rápido que el divisor. Una R fija más cercana a Rt en el rango de interés mejora la resolución.

5. LM35 con 5 V

Se usa el LM35 con la referencia de 5 V. ¿Cuántas lecturas hay que promediar para igualar, en teoría, el escalón de 0,107 °C de la referencia de 1,1 V con una sola lectura?

Ver solución

El escalón con 5 V es 0,488 °C. Relación: 0,488 / 0,107 = 4,55. El ruido baja √N, así que hacen falta N ≈ 21 lecturas (en la práctica 16 a 64, y siempre que haya ruido). Es mucho más eficiente usar la referencia de 1,1 V, que lo consigue sin promediar.

14 · Síntesis

Ideas para recordar

  • El ADC entrega un código; el trabajo del programa es convertirlo en una unidad física con la fórmula correcta para la referencia con que se leyó.
  • Potenciómetro y termistor son ratiométricos con AVcc; el LM35, que entrega una tensión absoluta pequeña, gana resolución con la referencia de 1,1 V.
  • La aritmética entera alcanza: décimas de °C = lectura · 1100 / 1024 con una referencia de 1,1 V; hay que usar uint32_t en los productos.
  • Promediar y la histéresis reducen el ruido de la última cuenta, a costa de tiempo y de respuesta.
  • El termistor exige un divisor, un modelo no lineal (Beta) y la detección de sensor en corto o abierto.
  • La resolución no es la exactitud: calibrá con una referencia conocida y mostrá solo las cifras justificadas.

¿Listo para el bloque 8?

Antes de avanzar, convertí un código dado a grados con cada uno de los tres sensores, explicá por qué la referencia cambia entre ellos y qué haría tu programa si el termistor se desconecta. Si podés justificar las tres respuestas, cerraste el bloque de conversión analógica y digital.

En el próximo tema empieza el bloque de comunicación serie con comunicación serie síncrona y asíncrona: cómo se envían datos bit a bit por un cable, con reloj compartido o sin él.