Medición de entradas analógicas.

Ya hemos indicado que los puertos analógicos se suelen utilizar para comprobar el nivel de tensión que ofrece un dispositivo o sensor o la tensión que se le ofrece al mismo para cierto proceso; así que, por un lado compara la tensión que llega del sensor (cuando está configurado como entrada), a la vez que controla su comportamiento; y por otro lado, proporciona el comportamiento correcto a la tensión correcta, según verás en otras prácticas.

Para esta práctica vamos a conectar un único potenciómetro al arduino como puedes ver en la imagen.

Conexión y lectura del potenciómetro a un pìn analógico.

Conexión y lectura del potenciómetro a un pìn analógico.

Observa que al variar el potenciómetro, el monitor serial nos proporciona datos de la entrada, ya que la variación de la tensión del potenciómetro se aplica a la entrada analógica 0. Y como ya he comentado en la clase anterior, cada puerto analógico tiene una resolución de 1024 bytes, de ahí que el mayor valor obtenido sea 1023 y el menor sea 0.

En cuanto al código, ya debería de dejar de tener secretos para tí. Las dos primeras variables del tipo int, son para declarar el puerto analógico a usar pot y la otra val, para almacenar el valor que irá tomando el puerto en cada movimiento del potenciómetro.

En el setup() incluyo la conexión Serial.begin(9600) para que me hago un rastreo de 9600 baudios.

En el loop() asigno el valor de la variable val al puerto 0 (pot). A continuación utilizo una Serial.println(val), para que me indique los valores que coge el potenciómetro en cada desplazamiento.

Y para terminar una función delay con 200ms permitirá que el estado del monitor serie cambie continuamente de estado con el cambio de posisicón del potenciómetro.

Convertidor analógico - digital.

La tensión analógica de entrada se convierte en un valor binario de entre 0 y 1023 o dicho de otro modo, tiene una resolución de 10 bits.

El microcontrolador de Arduino UNO contiene internamente un conversor analógico a digital de 6 canales. El conversor tiene una resolución de 10 bits, devolviendo enteros entre 0 y 1023. Los pines analógicos de Arduino también tienen todas las funcionalidades de los pines digitales. Por lo tanto, si necesitamos más pines digitales podemos usar los pines analógicos.

Convertidor analógico digital en Arduino UNO rev3.
El datasheet de ATmega advierte de hacer lecturas rápidas entre pines analógicos (analogRead). Esto puede causar ruido eléctrico e introducir jitter en el sistema analógico. Se aconseja que después de manipular pines analógicos (en modo digital), añadir un pequeño retraso antes de usar analogRead() para leer otros pines analógicos.

Un microcontrolador solo entiende señales digitales (1 y 0), por lo tanto para poder leer señales analógicas necesitamos los convertidores Analógico a Digital (ADC). Esta conversión consiste en la transcripción de señales analógicas en señal digital, con el propósito de facilitar su procesamiento (codificación, compresión, etcétera) y hacer la señal resultante (digital) más inmune al ruido y otras interferencias a las que son más sensibles las señales analógicas.

El ATMega328p, al igual que toda la gama ATMega de Atmel y otros microcontroladores, tienen un ADC integrado y no necesita ningún hardware adicional, esto nos permite simplemente conectar un sensor analógico. El ADC interno del microcontrolador tiene una resolución de 10 bits, esto significa que la tensión analógica de entrada se convierte en un valor numérico entre 0 y 1023. Aunque el ATmega328P tiene 6 pines que son capaces de ser utilizados como pines de entrada analógicos (Port C), sólo hay un ADC en el microcontrolador, pero entre el ADC y los pines hay un multiplexor analógico, esto permite que podamos elegir qué pin está conectado al ADC, es decir, aunque podemos utilizar todos los pines, sólo se puede leer el valor de uno de ellos a la vez, para casi todas las aplicaciones esto es más que suficiente, pero en algunos casos limitados que necesitan lecturas ADC de alta velocidad se podría necesitar el uso de ADC externos. En el caso de la ATmega328P los pines que se pueden utilizar una entrada analógica son todos los del puerto C.

También se puede cambiar la tensión máxima (siempre por debajo de Vcc) que utiliza el ADC como referecia, es la llamada tensión de referencia y es la tensión contra la que todas las entradas analógicas hacen las conversiones.

Esta tensión de referencia se toma del pin AREF. Reducir el voltaje máximo del ADC tiene sentido para mejorar la resolución del ADC:

Con 5V la resolución es de 5/1023 = 4,88 mV para cada valor, pero para un sensor que no pasa de 3.3V la resolución es de 3.3/1023 = 3.22mV.

El ADC interno también se puede utilizar en un modo de 8 bits, donde sólo se utilizan los 8 bits más significativos de la resolución de 10 bits completa, esto podría ser útil cuando se trabaja en ambientes ruidosos y sólo necesita 8 bits de resolución, el uso de este modo es un plus debido a que no es necesario dedicar más tiempo de CPU calculando los 10 bits completos. El ADC también puede configurarse para que lleve a cabo una conversión y detenerse o puede ser configurado para funcionar en un modo de funcionamiento libre, la primera opción es la mejor opción cuando queremos leer diferentes pines, y el segundo es mejor cuando sólo tenemos que leer un pin y esto puede ahorrar algo de tiempo entre las conversiones.

También tenemos que tener cuidado de la frecuencia máxima de trabajo del ADC, este valor se especifica en la ficha técnica y es de 200 kHz, este es el valor del reloj interno de la circuitería del ADC y se genera dividiendo el reloj principal ATmega, que en el caso del UNO es 16 MHz

Este divisor del reloj se realiza mediante pre-escaladores y sólo hay un rango limitado de valores, por lo que la frecuencia máxima que podemos utilizar y estar dentro de la frecuencia máxima de trabajo es 125 kHz. El siguiente pre-escalador supone usar el ADC a 250 kHz, en este caso no se puede garantizar la resolución de 10 bits, pero si una resolución de 8 bits.

De todas formas en caso de necesitar un ADC más rápido se podría usar uno externo.

El ADC puede trabajar en dos modos:

● single conversion mode.
● free running mode.

En modo single conversion el ADC hace una sola conversión y para, pero en modo free running el ADC está continuamente convirtiendo, es decir, hace una conversión y luego comienza con la siguiente.

El ADC en microcontroladores AVR utiliza una técnica conocida como aproximación sucesiva mediante la comparación de la tensión de entrada con la mitad de la tensión de referencia generada internamente. La comparación continúa dividiendo de nuevo la tensión y actualizando cada bit del registro ADC a 1 si el voltaje es HIGH en la comparación o 0 en el otro caso. Este proceso se realiza 10 veces (por cada bit de resolución del ADC) y genera como resultado la salida binaria.

Convertidor analógico digital en Q.
El Arduino UNO Q es un dispositivo muy diferente a los Arduinos tradicionales como el UNO Rev3. Su convertidor analógico-digital (ADC) es bastante más potente, pero también tiene una particularidad importante que debes conocer: necesitas configurar los pines de forma especial para usarlos como entradas analógicas.

El corazón del UNO Q no es un solo microcontrolador, sino un sistema híbrido que combina un potente procesador (que corre Linux) con un microcontrolador STM32U585, que es el encargado de manejar las funciones de Arduino, incluyendo el ADC. Estas son las características más destacadas de su conversor:

● Resolución de 14 bits: A diferencia de la resolución de 10 bits (0-1023) del UNO Rev3, el ADC del UNO Q tiene una resolución de 14 bits. Esto significa que puede leer valores mucho más precisos, en un rango de 0 a 16.383.

● Precisión muy alta: Gracias a su alta resolución, la sensibilidad del ADC es de aproximadamente 200 µV por unidad (LSB). Esto lo hace ideal para proyectos que requieren mediciones muy finas, como la lectura de señales biomédicas (por ejemplo, un ECG).

Otro cambio importante es que en el UNO Q, la función pinMode() no puede configurar un pin como entrada analógica.

En el UNO Rev3, simplemente llamabas a analogRead(pin) y el pin se configuraba automáticamente para ello.

En el UNO Q, debes configurar el pin en modo analógico usando las funciones específicas del microcontrolador STM32 (la HAL, o capa de abstracción de hardware) antes de poder leerlo correctamente.

La forma más directa de conseguirlo es inicializar el pin en modo analógico. Debes usar una función (que normalmente se escribe una sola vez) para desactivar las funciones digitales del pin y configurarlo para que sea usado por el ADC. Esto se hace con una función de inicialización como HAL_GPIO_Init().

Para leer el valor analógico, una vez configurado el pin, puedes usar la función estándar analogRead(pin) para obtener el valor de 14 bits.

// UNO_Q_Potentiometer_Reader.ino // Lectura de potenciómetro en Arduino UNO Q #include "Arduino_RouterBridge.h" // Definición del pin analógico para el potenciómetro const int POT_PIN = A0; void setup() { // Inicializa la comunicación con el monitor serie (UNO Q) Monitor.begin(); // Mensaje de inicio Monitor.println("=== LECTURA DE POTENCIÓMETRO EN UNO Q ==="); Monitor.println("Gira el potenciómetro para ver el cambio de valor"); Monitor.println(); // ¡IMPORTANTE! NO usar pinMode para pines analógicos en UNO Q // El pin se configura automáticamente al llamar a analogRead() } void loop() { // Lee el valor del potenciómetro (0-1023 en UNO Q) int sensorValue = analogRead(POT_PIN); // Convierte el valor a voltaje (3.3V de referencia) float voltage = (sensorValue / 1023.0) * 3.3; // Muestra los valores en el monitor serie Monitor.print("Valor digital: "); Monitor.print(sensorValue); Monitor.print(" | Voltaje: "); Monitor.print(voltage, 2); Monitor.println(" V"); // Pausa para evitar saturar el monitor delay(500); } Arduino (UNO Q)

Conmutación.

En esta práctica vamos a crear un circuito conmutado con dos pulsadores para que cuando presionemos uno, se encienda un led y al pulsar el otro se apague. También haremos que los botones sean correlativos, es decir que si se pulsa uno u otro, el otro pulsador actúe en consecuencia (apagándo o encendiendo el Led).

circuito conmutado

circuito conmutado en Arduino UNO Rev3

Conectándo dos pulsadores, a los pines 2 y 3, se desea controlar el encendido del led conectado al pin13. El funcionamiento es similar a una conmutada en una vivienda en donde al pulsar cualquiera de los interruptores se enciende o apaga el Led. Así pues con los dos pulsadores se puede controlar el encendido o apagado del Led.

El montaje del circuito es muy sencillo. Utilizaremos como puedes ver los siguientes componentes:

● 1 Led rojo
● 3 resistencias de 10KΩ
● 2 pulsadores.

En cuanto a los pulsadores hay que decir que los pulsadores suelen ser NA (normalmente abierto) y las pistas se unen en un extremo con el otro, pero en los lados están abierto.

pulsador NA en arduino

Pulsador típico NA usado en Arduino UNO.

Fijate que los pines del pulsador están conectado por la cara inferior entre la parte superior y la parte inferior indicando mediante un código que cualquiera de ellos es un mismo terminal. En el otro lado ocurre lo mismo con los terminales superior e inferior, pero teniendo en cuenta que cuando se presione el pulsador se cortocircuitarán los pines laterales del pulsador.

Como puedes ver del PIN2 y el PIN3 digital de arduino, se sacan dos conectores que conectarán a las partes inferiores de los pulsadores. Por la parte superior se conectarán los pines de los pulsadores en paralelo y, por un lado irán a negativo GND, y por el otro lado se conectará el Led (el cátodo a la resistencia de 10KΩ y al pin13); las otras dos resistencias de 10KΩ son resistencias de protección del los puertos de la placa Arduino.

Circuito montado en Arduino UNO

Montaje del circuito en Arduino UNO.

// Código para ARDUINO UNO Rev3 int led = 13; int pulsador1 = 2; int pulsador2 = 3; boolean encendido = 0; void setup() { // Establezco las variables como salida y entradas pinMode(led, OUTPUT); pinMode(pulsador1, INPUT_PULLUP); pinMode(pulsador2, INPUT_PULLUP); } void loop() { // comprobamos si está presionado algún pulsador if(digitalRead(pulsador1) == LOW || digitalRead(pulsador2) == LOW) { if(encendido == 0) { encendido = 1; digitalWrite(led, HIGH); } else { encendido = 0; digitalWrite(led, LOW); } } while(digitalRead(pulsador1) == LOW || digitalRead(pulsador2) == LOW) { // Espera a que se suelte el pulsador } } Arduino (UNO R3)

En el anterior bloque empezamos por declarar las variables globales que usaremos en nuestro Sketch.

Después escribimos el setup. Dentro del mismo tenemos que declarar los pines del Led y de los pulsadores como salida y entradas respectivamente, ya que el led es una salida del PIN13 y los pulsadores se tienen que declarar como entradas porque harán control del sistema.

Para terminar, el loop crearemos la programación para realizar la función de que cuando se pulsa un pulsador, se encienda el led y, si está encendido, se apague. Para realizar la estructura, voy a realizar una estructura con condicionales IF de la forma que si el pulsador1 o pulsador2 no están pulsado (y el led está apagado), entonces se encienda.

Además se ha incluido dos condiciones que se han unido mediante || que es el operador OR y su significado implica que para devolver un true se debe de cumplir una condición u otra.

Para terminar he incluido un bucle while que hará que el código se desarrolle como queremos, porque sin él, el código no pararía de ejecutarse.

La variable encendido sirve para indicar si el led está encendido o apagado, de tal forma que el primer if detecta si se ha pulsado alguno de los dos pulsadores y el segundo se utiliza para cambiar el valor de la variable encendido; es decir, si vale 0, entonces se activa la salida poniendo la variable a 1. Si no, apaga la salida poniendo la variable a 0.

Código para Arduino UNO Q.
A continuación te muestro el código equivalente para Arduino UNO Q.

// Código para ARDUINO UNO Q // Control de LED con dos pulsadores (Adaptado para UNO Q) #include "Arduino_RouterBridge.h" int led = 13; int pulsador1 = 2; int pulsador2 = 3; boolean encendido = 0; void setup() { // En UNO Q usamos Monitor en lugar de Serial Monitor.begin(); Monitor.println("Sistema iniciado - UNO Q"); // Configuración de pines para UNO Q pinMode(led, OUTPUT); // ¡IMPORTANTE! En UNO Q NO se usa pinMode para entradas analógicas // Pero para entradas digitales SÍ se usa pinMode pinMode(pulsador1, INPUT_PULLUP); pinMode(pulsador2, INPUT_PULLUP); } void loop() { // Comprobamos si está presionado algún pulsador if(digitalRead(pulsador1) == LOW || digitalRead(pulsador2) == LOW) { if(encendido == 0) { encendido = 1; digitalWrite(led, HIGH); Monitor.println("LED ENCENDIDO"); } else { encendido = 0; digitalWrite(led, LOW); Monitor.println("LED APAGADO"); } } // Espera a que se suelte el pulsador while(digitalRead(pulsador1) == LOW || digitalRead(pulsador2) == LOW) { // Pequeña pausa para evitar saturar el procesador delay(10); } } Arduino (UNO Q)

Notas importantes para el UNO Q:

● Monitor vs Serial: En UNO Q se usa Monitor en lugar de Serial para la comunicación con el monitor serie.

● Biblioteca RouterBridge: Es necesaria para la comunicación entre el microcontrolador STM32 y el procesador Linux.

● Pines digitales: Para entradas digitales (como los pulsadores), la configuración es igual que en UNO R3.

● Mensajes de depuración: Se han añadido mensajes por el monitor serie para ver el estado del LED.

● Anti-rebote: Se ha añadido un pequeño delay(10) dentro del while para evitar saturar el procesador.

Comparte este conocimiento en redes sociales