El uso de las entradas y salidas analógicas en Arduino, está basado en tres funciones analogWrite(), analogRead() y analogReference(). Y podemos ayudarnos con dos funciones adicionales que nos facilitan la interpretación de las lecturas analógicas que son las funciónes map() y constrain().
Señales analógicas y señales digitales
Una señal analógica es un tipo de señal que cambia sus valores de forma continua a través del tiempo. Y una señal digital puede representar cambios de valores pero no los realiza de forma continua, sino que usa una codificación digital binaria (unos y ceros). Por lo que solo representa algunos valores.
Una señal analógica puede ser representada de forma digital, usando un procedimiento que se denomina conversión analógico digital, este consiste en tomar medidas de la señal analógica cada cierto tiempo y representar cada medida con valores digitales. Un ejemplo sencillo lo podemos ver en la siguiente gráfica.
Donde podemos representar los valores que tiene una señal analógica por medio de cuatro bits, y de esa forma tendríamos una señal digital, que representa la señal analógica. A medida que tengamos mas valores (bits) para representar la señal analógica, mas real sera su representación.
Arduino usa 10 bits para realizar la conversión analógica digital de una señal analógica, y convierte los valores de la señal de entrada entre 0 y 5 voltios, a valores entre 0-1023.
Lectura de valores analógicos en Arduino
La función analogRead()
Devuelve el valor leído del pin de entrada analógico (A0, A1,…A5) que se le ha indicado. Este valor se obtiene mapeando proporcionalmente la entrada analógica obtenida (que puede tener cualquier valor entre 0 y un voltaje llamado voltaje de referencia, el cual por defecto es 5 V) a un valor entero entre 0 y 1023. Por lo que podríamos detectar cambios en la señal analógica de entrada de hasta (resolución de lectura que es 5V/1024) 0,004883 V. La sintaxis es la siguiente:
NombreVariable = analogRead(pin); Donde pin: es el pin analogico donde conectamos la señal A0, A1, A2, A3, A4, A5
La variable donde vamos a guardar el valor de la lectura debe ser una variable tipo entero (int).
Algo que debemos tener en cuenta en nuestros sketchs es que al microcontrolador le toma cerca de 100 microsegundos (0.0001 s) el leer un entrada analógica, así que la máxima frecuencia de lectura es de 10,000 lecturas por segundo.
Ejemplo 1 – Leer un potenciómetro
int valorPot=0; //variable para guardar el valor leído del potenciómetro void setup(){ Serial.begin(9600); //Inicio el monitor serial } void loop(){ valorPot=analogRead(A2); //Leo la entrada analógica A2 Serial.println(valorPot); //Imprimo el valor leído en el monitor serial delay(1000); //Espero 1 segundo para hacer la siguiente lectura }
Para que nos sirve la función analogReference()
Configura el voltaje de referencia usado por la entrada analógica, que por defecto está configurado a 5 voltios. Las opciones son, DEFAULT (ajusta el voltaje de referencia a 5V), INTERNAL (ajusta el voltaje de referencia a 1.1V) y EXTERNAL (usa el voltaje aplicado al pin AREF como voltaje de referencia). La sintaxis será la siguiente:
analogReference(tipo); Donde tipo: es DEFAULT (5V), INTERNAL (1,1V), EXTERNAL
Modificar el voltaje de referencia implica que la resolución de lectura será mayor, pero también que solo podemos leer señales analógicas dentro del rango de voltaje definido por 0 y el voltaje de referencia. Por ejemplo, para un voltaje de referencia de 1.1V, la resolución de lectura será de 1.1V/1024, es decir, de 0,001074 V.
Existen un par de funciones que resultan muy útiles cuando trabajamos con entradas analógicas, y estas son map() y Constrain().
La útil función map()
Escala un número de un rango a otro rango. Esto es, el valor fromLow será escalado a toLow, y el valor de fromHigh será escalado a toHigh, y todos los valores entre estos límites, etc. Esta función no admite decimales, estos serán truncados. La sintaxis es la siguiente:
NombreVariable = map(value, fromLow, fromHigh, toLow, toHigh); donde value: es el número a escalar fromLow: el límite inferior del actual rango de valores fromHigh: el límite superior del actual rango de valores toLow: el límite inferior del rango deseado de valores toHigh: el límite superior del rango deseado de valores
Ejemplo 2 – Conversión de valor de voltaje
/* Escala un valor de entrada analógico 10bits (0 a 1023) a 0 a 500ºC Un sensor de temperatura tiene una señal de salida de 0 a 5V que representa una temperatura de 0 a 500ºC */ void setup() { Serial.begin(9600); } void loop() { int valor = analogRead(A0); //Lee la entrada analógica y la guarda en la variable valor delayMicroseconds(100); //Espera 100 microsegundos por la conversión analógica digital Serial.print(valor); //Escribe la lectura Serial.print(“ “); //Escribe un par de espacios valor = map(valor, 0, 1023, 0, 500); //Escala la variable de 0-1023 a 0-500 Serial.println(valor); //Escribe el valor de la temperatura }
Y la función constrain()
Limita un número a estar dentro de un rango. Si el valor a limitar es superior al límite superior b, entonces la función devuelve b, y si es inferior al límite inferior a, entonces devuelve a. Esta función trabaja con todos los tipos de datos y la sintaxis es:
NombreVariable = Constrain(x,a,b); donde x: es el número a limitar a: el límite inferior del rango b: el límite superior del rango
Escritura de valores analógicos en Arduino
¿Como funciona analogWrite()?
Coloca en el pin seleccionado una señal equivalente a un voltaje. Esta señal equivalente, es una señal PWM, cuya magnitud podemos variar de acuerdo a un parámetro de tipo “byte” (con valores entre 0 y 255). No todos los pines digitales pueden generar señales PWM: en la placa Arduino UNO por ejemplo solo son los pines 3, 5, 6, 9, 10 y 11 (están marcados en la placa con el simbolo ᷉ al lado del número de la entrada digital). Cada vez que se ejecute esta función se regenerará la señal. Esta función no tiene valor de retorno, y su sintaxis es muy sencilla:
analogWrite(pin,valorPWM); Donde pin: es el número de pin con capacidad para PWM 3, 5, 6, 9, 10, y 11 (en Arduino UNO) valorPWM: es un numero entre 0 y 255
¿Y qué es PWM?
Una señal PWM es una señal digital cuadrada que simula ser una señal analógica. El valor simulado de la señal analógica dependerá de la duración que tenga el pulso digital (es decir, el valor HIGH de la señal PWM). Si el segundo parámetro de esta función vale 0, significa que su pulso no dura nada (es decir, no hay señal) y por tanto su valor analógico “simulado” será el mínimo (0V). Si vale 255, significa que su pulso dura todo el período de la señal (es decir, es una señal continua) y por tanto su valor analógico “simulado” será el máximo ofrecido por la placa (5V). Cualquier otro valor entre estos dos extremos (0 y 255) implica un pulso de una longitud intermedia (por ejemplo, el valor 128 generará una onda cuadrada cuyo pulso es de la misma longitud que la de su estado bajo) y por tanto, un valor analógico “simulado” intermedio (en el caso anterior, 2,5 V).
Ejemplo 3 – Controlar el brillo de un LED
int brillo = 127; void setup(){ pinMode(9, OUTPUT); //El LED está conectado al pin 9 (PWM) analogWrite(9, brillo); //Enciende el LED a aproximadamente la mitad del voltaje } void loop(){}
Ejemplo 4 – Controlar el brillo de un LED con un potenciómetro
/* Escala un valor de entrada analógico 10bits (0 a 1023) a 8 bits (0 a 255) */ void setup() {} void loop() { int valor = analogRead(A0); //Lee la entrada analógica y la guarda en la variable val delayMicroseconds(100); //Espera por la conversión analógico digital valor = map(valor, 0, 1023, 0, 255); //Escala la variable de 0-1023 a 0-255 analogWrite(9, valor); //Escribe el valor escalado en la salida analógica }
Ejercicios
Para realizar los ejercicios utilizaremos el siguiente circuito
Ejercicio 1: Encender un led con voltaje variable
Hacer que uno o varios Leds se enciendan incrementando su brillo de cero al máximo de forma cíclica. Para ello debemos usar la funcion de analogWrite(), para variar la señal PWM.
Ejercicio 2: Lectura analógica
Leer el voltaje del potenciómetro, y escalarlo de 0 a 100 y mostrar el valor antes de escalar y después de escalado en el monitor serial.
Ejercicio 3: Encender un led y variar el brillo con el potenciómetro
Hacer que el Led se encienda incrementando su brillo dependiendo del valor del potenciómetro. El brillo mínimo será de un 50% del máximo.
Ejercicio 4: Medidor de intensidad
Encender los leds de acuerdo al valor leído en el potenciómetro, y de acuerdo a las siguientes premisas.
- El led verde estará encendido cuando el valor de entrada se encuentre entre el 5 y el 50%.
- El led amarillo se encenderá cuando el valor de entrada se encuentre entre el 51 y el 80%.
- El led rojo se encenderá cuando el valor de entrada se encuentre entre el 81 y el 100%.
Y con los ejercicios hemos culminado la lección, espero te allá sido de provecho.
Y si aun no te has suscrito a nuestro boletín? Suscríbete y te mantendré informado de la ultimas publicaciones y entregas especiales. Y si tienes alguna pregunta o comentario acerca del post no dudes en hacerla.