Saltar al contenido principal
LibreTexts Español

26.1: Introducción

  • Page ID
    82444
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Así como nos gustaría leer el estado de los interruptores simples de encendido/apagado, también necesitamos leer datos continuamente variables (es decir, analógicos). Por lo general, esto significa el voltaje de salida causado por alguna forma de sensor como un sensor de temperatura, sensor de fuerza, sensor de luz, etc. Muy a menudo se colocan dispositivos pasivos simples como celdas CdS o FSR en una red de puente resistivo, cuyo voltaje de salida se desplazará con los cambios en el ambiente. Una aplicación aún más sencilla sería el uso de un potenciómetro conectado a una fuente de voltaje fijo. La posición del bote sería controlada por el usuario y podría representar un ajuste de casi cualquier parámetro concebible como volumen, brillo, retardo de tiempo, frecuencia, etc. Para leer cantidades analógicas, el ATMega 328P contiene un solo convertidor analógico a digital de 10 bits multiplexado a través de seis entradas canales. En la placa Arduino Uno, las entradas a estos ADC se encuentran en los pines etiquetados A0 a A5. El entorno de desarrollo de Arduino contiene dos funciones útiles para acceder a tesis, a saber, analogRead () y AnalogReference (). Las descripciones de las funciones en línea se repiten a continuación:

    Figura\(\PageIndex{1}\): analogRead and analogReference docs

    AnalogRead () 1

    Descripción

    Lee el valor del pin analógico especificado. La placa Arduino contiene un convertidor analógico a digital de 10 bits de 6 canales (8 canales en el Mini y Nano, 16 en el Mega). Esto significa que mapeará voltajes de entrada entre 0 y 5 voltios en valores enteros entre 0 y 1023. Esto produce una resolución entre lecturas de: 5 voltios/1024 unidades o, 0.0049 voltios (4.9 mV) por unidad. El rango de entrada y la resolución se pueden cambiar usando AnalogReference ().

    Se necesitan aproximadamente 100 microsegundos (0.0001 s) para leer una entrada analógica, por lo que la velocidad máxima de lectura es de aproximadamente 10,000 veces por segundo.

    Sintaxis

    AnalogRead (pin)

    Parámetros

    pin: el número del pin de entrada analógica para leer (0 a 5 en la mayoría de las placas, 0 a 7 en el Mini y Nano, 0 a 15 en el Mega)

    Devoluciones

    int (0 a 1023)

    Nota

    Si el pin de entrada analógica no está conectado a nada, el valor devuelto por analogRead () fluctuará en función de una serie de factores (por ejemplo, los valores de las otras entradas analógicas, qué tan cerca está su mano de la placa, etc.).

    Descripción

    Configura el voltaje de referencia utilizado para la entrada analógica (es decir, el valor utilizado como la parte superior del rango de entrada). Las opciones son:

    • DEFAULT: la referencia analógica predeterminada de 5 voltios (en placas Arduino de 5V) o 3.3 voltios (en placas Arduino de 3.3 V)
    • INTERNO: una referencia incorporada, igual a 1.1 voltios en el ATmega168 o ATmega328 y 2.56 voltios en el ATmega8 (no disponible en el Arduino Mega)
    • INTERNAL1V1: una referencia incorporada de 1.1V (solo Arduino Mega)
    • INTERNAL2V56: una referencia incorporada de 2.56V (solo Arduino Mega)
    • EXTERNO: se utiliza como referencia el voltaje aplicado al pin AREF (0 a 5V solamente).

    Sintaxis

    AnalogReference (tipo)

    Parámetros

    type: qué tipo de referencia usar (DEFAULT, INTERNAL, INTERNAL1V1, INTERNAL2V56, o EXTERNO).

    Devoluciones

    Ninguno.

    Nota

    Después de cambiar la referencia analógica, las primeras lecturas de AnalogRead () pueden no ser precisas.

    Advertencia

    ¡No uses nada menos de 0V o más de 5V para el voltaje de referencia externo en el pin AREF! Si está utilizando una referencia externa en el pin AREF, debe establecer la referencia analógica en EXTERNAL antes de llamar a analogRead (). De lo contrario, cortocircuitará juntos el voltaje de referencia activo (generado internamente) y el pin AREF, posiblemente dañando el microcontrolador en su placa Arduino.

    Alternativamente, puede conectar el voltaje de referencia externo al pin AREF a través de una resistencia de 5K, lo que le permite cambiar entre voltajes de referencia externos e internos. Tenga en cuenta que la resistencia alterará el voltaje que se usa como referencia porque hay una resistencia interna de 32K en el pin AREF. Los dos actúan como un divisor de voltaje, así, por ejemplo, 2.5V aplicados a través de la resistencia producirán 2.5 * 32/(32+5) = ~2.2V en el pin AREF.

    La función analogRead () se utiliza mejor como una “instantánea” de conversión única. Esto es bueno para una interfaz de usuario simple y aplicaciones básicas de sensores. En términos generales, analogReference () se llama una vez durante la fase de configuración e inicialización del programa. Además, a menos que haya una razón convincente para hacer lo contrario, el modo predeterminado es el mejor lugar para comenzar. Esto producirá un rango de entrada de pico a pico de 5 voltios con una resolución de bits de poco menos de 4.9 milivoltios (5/1024). Es importante señalar que este rango va de 0 voltios a 5 voltios, no −2.5 voltios a +2.5 voltios. Dependiendo de la amplitud y rango de frecuencia de la señal del sensor, es posible que se requiera algún circuito de procesamiento de entrada para aplicar un desplazamiento de CC, amplificar o reducir la intensidad de la señal, filtrar los extremos de frecuencia, etc.

    El código para AnalogReference () es casi tan simple como se pone. Simplemente establece (y oculta) una variable global a la que accederá la función analogRead ():

    uint8_t analog_reference = DEFAULT;
    
    void analogReference(uint8_t mode)
    {
        analog_reference = mode;
    }
    

    La función analogRead () es un poco más interesante (en realidad, 10 bits más interesantes). Del capítulo anterior vimos que existen varios registros asociados al sistema ADC. Para la operación de conversión única, los registros importantes incluyen ADCSRA (registro de estado y control ADC A) y ADMUX (registro de selección de multiplexor ADC). Los bits de registro se repiten a continuación para mayor comodidad:

    Tabla\(\PageIndex{1}\): Brocas ADC.
    Registrar Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
    ADCSRA ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
    ADMUX REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0

    También recuerde que los registros ADCH y ADCL contienen los bytes alto y bajo del resultado, respectivamente. Para ADCSRA, la configuración de ADEN habilita el ADC. Al establecer ADSC se inicia una conversión. Permanecerá en uno hasta que se complete la conversión, el hardware lo restablecerá a cero. ADIF y ADIE se utilizan con un modo basado en interrupciones no discutido aquí. ADATE significa AD Auto Trigger Enable que permite activar el ADC desde una señal externa (nuevamente, no se discute aquí). AdPSx son bits pre-escaladores que establecen la velocidad de conversión. Consulte el capítulo anterior para más detalles.

    Para ADMUX, RefSX establece la fuente de voltaje de referencia donde 00 = usar pin AREF, 01 = usar VCC, 10 = reservado, 11 = usar referencia interna de 1.1 voltios. Ajustar ADLAR a la izquierda ajusta la palabra de 10 bits dentro de los registros de resultados ADCH y ADCL (es decir, justifica a la izquierda, dejando los seis bits inferiores sin usar). Borrar este bit deja el resultado justificado correctamente (es decir, los seis bits superiores no se utilizan). Los cuatro bits MUxx seleccionan qué canal de entrada se utiliza para la conversión. Por ejemplo, para leer desde el canal 5, establezca estos bits en el patrón 0101.

    Otros registros están disponibles como ADSRB y ACSR que son útiles para otros modos de operación. Sin embargo, no son necesarios para el propósito actual.

    El código sigue, limpiado para facilitar la lectura. El código original contiene un número considerable de # ifdef s por lo que funciona con diferentes microcontroladores.

    int analogRead(uint8_t pin)
    {
        uint8_t low, high;
    
        if (pin >= 14) pin -= 14; // allow for channel or pin numbers
    
        // set the analog reference, input pin and clear left-justify (ADLAR)
        ADMUX = (analog_reference << 6) | (pin & 0x07);
    
        // start the conversion
        sbi(ADCSRA, ADSC);
    
        // ADSC is cleared when the conversion finishes
        while (bit_is_set(ADCSRA, ADSC));
    
        // read low and high bytes of result
        low = ADCL;
        high = ADCH;
    
        // combine the two bytes
        return (high << 8) | low;
    }
    

    Echemos un vistazo más de cerca. Primero, se declaran dos bytes sin signo para contener el contenido de los registros de resultados altos y bajos; luego se traduce el argumento pin. Tenga en cuenta el uso indocumentado de cualquiera de los números de canal o pin. Siempre tenga cuidado al usar funciones indocumentadas.

    uint8_t low, high;
    
    if (pin >= 14) pin -= 14; // allow for channel or pin numbers
    

    En este punto se establece la referencia (observe cómo el analog_reference global se desplaza hasta los bits RefSX). El número de pin es ANDed con 0x07 para seguridad y OR en ADMUX. Tenga en cuenta que el resultado se justificará a la derecha ya que no se establece ADLAR.

    ADMUX = (analog_reference << 6) | (pin & 0x07);
    

    La conversión se inicia configurando el bit AD Start Conversion. sbi () es una macro que reduce a una sola instrucción de “set bit” en el ensamblaje. Luego esperamos hasta que se borre el bit ADSC, lo que significa que la conversión está completa. El bucle while se conoce correctamente como un bucle “busy-wait”; el código simplemente “se sienta” en ese bit, verificándolo una y otra vez hasta que finalmente se borre. Esto hace que el bucle salga. Nuevamente, bit_is_set () es una macro que devuelve true si el bit bajo prueba se establece en uno y false si está claro.

    // start the conversion
    sbi(ADCSRA, ADSC);
    
    // ADSC is cleared when the conversion finishes
    while ( bit_is_set(ADCSRA, ADSC) );
    

    La conversión ya está completa. ADCL debe leerse primero, ya que al hacerlo bloquea tanto los registros ADCL como ADCH hasta que se lea ADCH. Hacer lo contrario podría resultar en valores espurios. Los dos bytes se combinan entonces en un único resultado entero de 16 bits mediante ORing el byte bajo con el byte alto desplazado a la izquierda. Como los datos en los registros de resultados estaban justificados a la derecha, los seis bits superiores serán ceros en el entero devuelto, resultando en un rango de salida de 0 a 1023.

    low = ADCL;
    high = ADCH;
    
    // combine the two bytes
    return (high << 8) | low;
    

    Dados los valores predeterminados del preescalador y la sobrecarga de llamadas a funciones, la tasa de conversión máxima es de aproximadamente 10 kHz, lo que es perfectamente aceptable para una amplia variedad de usos. La función es bastante básica y sencilla de usar tal cual. Utilice esta función como guía si desea producir datos justificados a la izquierda (set ADLAR bit) u otras modificaciones simples. Si el tiempo es esencial y los ciclos de máquina no se pueden perder con el bucle de espera ocupado visto anteriormente, una versión basada en interrupciones o una versión de ejecución libre puede ser una mejor opción.


    1. http://arduino.cc/en/Reference/AnalogRead
    2. http://arduino.cc/en/Reference/AnalogReference

    This page titled 26.1: Introducción is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.