Está en la página 1de 17

Señal PWM con Arduino y analogWrite

https://programarfacil.com/blog/arduino-blog/pwm-con-arduino-analogico/

Gracias a las señales PWM con Arduino y a la función analogWrite, es muy sencillo


poder controlar el voltaje que sale de un pin. Son las llamadas salidas analógicas.

Las salidas PWM con Arduino son muy útiles, por ejemplo, si quieres controlar la
velocidad de un motor eléctrico, controlar el brillo de un LED o controlar
un servomotor con Arduino.

Las señales PWM con Arduino son muy fáciles de utilizar gracias a


la función analogWrite(). En este tutorial aprenderás todo lo necesario para poder
utilizar señales PWM con Arduino.

Y no sólo es exclusivo de Arduino, también otros microcontroladores o SoC como


el ESP8266, tienen salidas PWM.

Pero vamos a empezar por el principio ¿qué es un señal eléctrica?

Indice de contenidos
1. Qué es una señal PWM
2. Cómo cambiar la frecuencia de una señal PWM con Arduino

Qué es una señal PWM


El término PWM proviene del inglés Pulse Width Modulation que
significa modulación por ancho de pulsos. Una señal PWM es una señal digital
similar al tren de pulsos cuadrados que hemos visto antes.

La principal diferencia con el tren de pulsos es que en la señal PWM, es posible variar
el tiempo que la señal se mantiene en estado alto, pero siempre manteniendo el
periodo constante, tal y como se muestra en la imagen siguiente.
Vuelvo a repetir, el periodo y la frecuencia son constantes. Lo que varía es el tiempo
que está en estado alto (HIGH) y bajo (LOW).

Esta capacidad de variar el tiempo en estado alto, es lo que realmente hace que
la señal PWM sea tan útil y práctica:

 Pueden utilizarse para controlar un servomotor mediante señales pulsantes con


diferentes tiempos en alto.
 Sirven para emular una salida analógica.
 Es muy empleada en algunas fuentes de alimentación en la etapa de regulación.

Si cogemos un periodo de la señal tenemos lo siguiente:

En la imagen se han destacado tres valores de tiempo:

 T : tiempo que la señal se mantiene en estado alto


ON

 T : tiempo que la señal se mantiene en estado bajo


OFF

 T: periodo de la señal.

En la señal anterior se cumple: T = T  + T . Es lógico, el tiempo total (T) es igual al


ON OFF

tiempo que está en estado alto (T ) más el tiempo que está en estado bajo (T )
ON OFF

El ciclo de trabajo o duty cycle de la señal es uno de los conceptos más importantes


de una señal PWM. Este se representa mediante la letra D y se define como la razón
entre el tiempo en estado alto (T ) y el periodo de la señal (T):
ON

Se multiplica por 100 porque se suele expresar en tanto por ciento y representa el
tiempo en el que la señal está en estado alto dentro de un periodo.

Encontrarás el ciclo de trabajo también como ciclo útil, significan lo mismo.


Por ejemplo, un ciclo de trabajo igual a 50% quiere decir que la señal está la mitad del
tiempo en estado alto y la otra mitad en estado bajo. Si es al 25% estará el 25% del
tiempo en estado alto y el 75% en estado bajo.

El ciclo de trabajo permite controlar el voltaje promedio de la señal es decir, variar el


voltaje de salida. Podrías cambiar el voltaje de salida de 5V a 3,75V por ejemplo. Este
parámetro es fundamental cuando la señal PWM se emplea como conversor digital-
analógico.

El voltaje promedio se calcula mediante la siguiente expresión:

Donde:

 V  es el voltaje en estado alto.


H

 V  es el voltaje en estado bajo.


L

Como en las placas Arduino el voltaje en estado bajo es normalmente 0V, la expresión
se simplifica de la siguiente manera:
Donde:

 V  es el voltaje que manejan los pines digitales de la placa. 5V para Arduino


CC

UNO, Arduino MEGA, Arduino Nano, etc… y 3,3V para placas


cómo Wemos, NodeMCU, etc…

Es importante que comprendas que aunque el voltaje promedio sea 4.3 V en realidad
lo que ocurre es que el pin está un tiempo en estado alto y otro en estado bajo. Arduino
es incapaz de variar el voltaje de sus pines, siempre van a 5V.

Señales PWM con Arduino


La teoría está bien, pero si no lo pones en práctica, cómo que no lo terminas de
entender. Y la forma más sencilla que conozco de trabajar con señales PWM es
utilizando un Arduino.

Las placas de Arduino o ESP8266 ya están adaptadas para poder generar una señal
PWM con Arduino de una forma muy sencilla utilizando la función analogWrite()

Según la documentación técnica de Arduino, esta función permite generar señales


PWM con Arduino en todos los pines marcados con el símbolo ~. Es la línea curva
que se pone encima de la ñ.

No todas las placas de Arduino y ESP8266 utilizan los mismos pines PWM. En la


siguiente tabla te dejo la relación de los pines que puedes utilizar con la
función analogWrite() en algunas placas de Arduino y ESP8266. También puedes ver
la frecuencia que utiliza cada pin.

Placa Pines PWM Frecuencia


Uno, Nano, Mini 3, 5, 6, 9, 10, 11 490 Hz (pines 5 y 6: 980 Hz)
Mega 2 – 13, 44 – 46 490 Hz (pines 4 y 13: 980 Hz)
Leonardo, Micro, Yún 3, 5, 6, 9, 10, 11, 13 490 Hz (pines 3 y 11: 980 Hz)
Uno WiFi Rev2, Nano Every 3, 5, 6, 9, 10 976 Hz
Nano 33 BLE/BLE Sense 1 – 13, A0 – A7 500 Hz
NodeMCU (ESP8266) 1-4, 5-8, 12 1 kHz

Si tu placa no aparece en la anterior tabla, ponte en contacto con el vendedor o


fabricante para que te remita a la documentación técnica.

Para generar una señal PWM con Arduino utilizando la función analogWrite(), el


procesador emplea un recurso llamado temporizador o contador de 8 bits (en
inglés timer o counter), un comparador y un valor que representa el ciclo útil de la
señal a generar.

Un temporizador o contador de 8 bits no es más que un entero cuyo valor se va


incrementando de 0 a 255 y una vez alcanza ese valor regresa a 0 para recomenzar el
ciclo. Se incrementa hasta 255, ya que este es el máximo valor que se puede obtener
con 8 bits.

En la siguiente figura, puedes ver la evolución de un contador de estas características.

Al tratarse de una señal digital, los valores son discretos: 0, 1, 2, 3, …, 253, 254,


255. En realidad sería uan especie de escalera
El comparador cuenta con dos entradas y una salida. Este es el encargado de
generar la señal PWM con Arduino utilizando el contador y el valor que representa
al ciclo útil.

El valor que utiliza el comparador para determinar el ciclo útil no se expresa en tanto


por ciento. En su lugar se expresa como un número entre 0 y 255 porque este es el
valor máximo que puede alcanzar el contador (recuerda que es de 8 bits).

Para generar la señal PWM con Arduino, el comparador mantiene su salida en


estado alto (HIGH) mientras el valor del temporizador sea menor que el del ciclo útil.
Una vez el valor del contador supera el valor del ciclo útil, la salida pasa a estado bajo
(LOW).

De esta forma, un valor de 255 de ciclo útil realmente genera un ciclo de trabajo del
100%, mientras que con un valor de 127 se logra un ciclo de trabajo del 50%.

Este proceso se repite infinitamente hasta que el comparador sea desactivado o el


temporizador detenido.

Todo este proceso lo realiza el microcontrolador por sí solo cuando utilizamos la


función analogWrite(). 

Función analogWrite PWM con Arduino


Con respecto a la parte del software, para generar señales PWM con Arduino se utiliza
la función analogWrite(). Esta función admite dos parámetros:
         analogWrite(pin, valor)

Donde:

 pin: es el pin de Arduino por donde queremos sacar la señal. Tiene que estar
marcado con el símbolo ~.
 valor: es el ciclo de trabajo. Puede tomar valores entre 0 (apagado 0V) y 255
(encendido 5V).

El segundo parámetro, ciclo de trabajo, puede tomar valores entre 0 y 255. Eso


significa que si pasas a la función 0, obtendrás 0V que equivale a un ciclo de trabajo
del 0%. Si pones 178, obtendrás un voltaje promedio de 3,5V que equivale a un ciclo
de trabajo del 70%.

La función analogWrite() no tiene ningún vínculo con los pines analógicos de las


placas Arduino (A0, A1, etc.)

En la siguiente tabla tienes un resumen de algunos posibles valores.

Argumento analogWrite() Ciclo de trabajo Voltaje promedio


0 0% 0V
63 25% 1,25 V
76 30% 1,5 V
127 50% 2,5 V
178 70% 3,5 V
191 75% 3,75 V
229 90% 4,5 V
255 100% 5V

Es importante notar que al solo poder establecer valores entre 0 y 255, la resolución
que se obtiene es de 19.6 mV. Eso significa que la mínima variación de voltaje que
podemos lograr con una señal PWM con Arduino es de 19.6 milivoltios.

Esta resolución es más que suficiente para la mayoría de los proyectos. Sin embargo,
puede ser un limitante para proyectos muy exquisitos que requieran una alta precisión.

Los ESP8266 por el contrario, tienen una resolución de 10-bit lo que equivale a un


rango de valores de 0 a 1023 consiguiendo una resolución de 3,22 mV sobre un voltaje
de 3,3V.
Como todo lo que hemos visto hasta ahora no ha sido más que teoría, vamos a
ponerlo en práctica con un ejercicio utilizando una salida PWM con Arduino.

Controlar el brillo de un LED con una señal PWM con


Arduino
Una señal PWM con Arduino puede utilizarse para generar una salida analógica
tomando su valor promedio. Esto no es válido para todas las aplicaciones, sin
embargo, es perfectamente viable para muchos casos comunes como el control de la
iluminación de un LED.

Cuando utilizamos una señal PWM con Arduino para este fin, el LED se enciende
durante el ciclo de trabajo y se apaga durante el resto del periodo. Vamos, que cuando
la señal está en HIGH el LED está encendido y cuando está en LOW se apaga.

Esto sucede a mucha velocidad. La frecuencia de una señal PWM con Arduino es de
490 Hz (980 Hz si utilizas los pines 5 y 6) lo que viene a decir que se encenderá y
apagará 490 veces en un segundo.

El ojo humano es incapaz de detectar estos cambios tan rápidos. El efecto percibido es
que el LED brilla con menor intensidad aunque en realidad se está apagando y
encendiendo muy rápido.

Al variar el ciclo de trabajo (el tiempo que se mantiene en estado HIGH), se percibe
con un aumento o disminución del brillo del LED.

De hecho, el brillo que se percibe es equivalente al de alimentar el LED con el voltaje


promedio de la señal PWM. Entonces si utilizamos una señal PWM con Arduino UNO y
un ciclo de trabajo del 50% será como si el LED recibiera 2.5 voltios y así lo veremos.

Para comprender esto te propongo analizar un caso muy simple, el ejemplo fade que


trae el IDE de Arduino.

El circuito es muy simple. Sólo necesitas este material:


 1x Placa Arduino (da lo mismo si es Arduino UNO, Arduino MEGA o Arduino
Nano)
 1x Resistencia (cualquier valor entre 220 Ω y 1 kΩ es válido)
 1x LED (cualquier tipo y color te vale)

Si utilizas un Arduino MEGA no necesitas montar ningún circuito ya que el LED


integrado en la placa y que está conectado al pin 13 del Arduino MEGA, también es
capaz de generar una señal PWM con Arduino.

Es importante conectar el LED a un pin que sea capaz de generar una señal PWM.
Recuerda que son los que están marcados con el símbolo ~.

Para cargar el ejemplo fade es necesario abrir Arduino IDE e ir


a Archivo>Ejemplos>Basics>Fade.

En el ejemplo se definen 2 variables:


  LED: modificando el valor de esta variable establecemos en que pin se ha
conectado el LED. Una vez más te recuerdo que tiene que ser un pin PWM.
 fadeAmount: permite establecer en cuantas unidades variará el ciclo de trabajo
de la señal PWM con Arduino.

También se declara una variable brightness. Esta variable se utiliza para almacenar el


ciclo de trabajo de la señal PWM con Arduino es decir, que tendrá un valor entre 0 y
255.

Esta variable es la que luego se pasa a la función analogWrite().


int led = 13;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 10;    // how many points to fade the LED by 

En la función setup() simplemente se configura el pin donde está conectado el LED


como salida. Esto no es necesario sin embargo, no es ningún problema hacerlo.
 
void setup() {
  pinMode(led, OUTPUT);
}
 
En cada iteración de la función loop() se incrementa o decrementa el valor de la
variable brightness. Si este se desborda es decir, si se hace mayor que 255 o menor
que 0, el signo de fadeAmount se invierte. De esa forma si el valor estaba aumentando
ahora empieza a disminuir o viceversa.

void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);
 
  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;
 
  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}

Te recomiendo que juegues con los valores de fadeAmount y el delay utilizado en la


función loop() para obtener tiempos y resultados levemente diferentes.
Te advierto que si utilizas un valor de fadeAmount muy grande los cambios de
iluminación serán muy bruscos. Por el contrario, si utilizas un valor pequeño los
cambios de iluminación serán muy suaves dando un efecto realmente vistoso.

En cualquier caso, aquí te dejo el código completo para controlar el brillo de un LED
utilizando una señal PWM con Arduino.

/*
  Fade
 
  This example shows how to fade an LED on pin 9 using the analogWrite()
  function.
 
  The analogWrite() function uses PWM, so if you want to change the pin you're
  using, be sure to use another PWM capable pin. On most Arduino, the PWM pins
  are identified with a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.
 
  This example code is in the public domain.
 
  http://www.arduino.cc/en/Tutorial/Fade
*/
 
int led = 13;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 10;    // how many points to fade the LED by
 
// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}
 
// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);
 
  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;
 
  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}
Cómo cambiar la frecuencia de una señal PWM
con Arduino
Una pregunta que suele llegar de los oyentes, seguidores y alumnos es ¿se puede
cambiar la frecuencia de una señal PWM con Arduino?

Es importante que tengas presente que no existe una función que nos permita
modificar la frecuencia de la señal PWM con Arduino. No digo que sea imposible,
simplemente que no es simple.

¿Recuerdas que te comenté que para generar las señales PWM con Arduino el
procesador utiliza un temporizador? Pues resulta que es posible cambiar la velocidad
a la que este se incrementa provocando que la frecuencia de la señal PWM se
altere.

El problema con esta solución es que estos temporizadores son empleados por otras
funciones dentro del core de Arduino. Por lo tanto, si modificas su comportamiento
puede que algunas funciones dejen de funcionar correctamente.

Dicho esto, no hay una forma sencilla de cambiar la frecuencia de una señal PWM


con Arduino.

Controlar un motor DC con una salida PWM con


Arduino
Los motores de DC tienen una alta inercia. Eso significa que aunque apagues un
motor en marcha, tardan un tiempo en detenerse totalmente. Es el motivo por el cual
cuando desconectas un ventilador de la corriente o lo apagas por su control, tarda
unos segundos en detenerse.

Otro dato curioso es que su velocidad de giro depende del voltaje de


alimentación del motor.

Por ejemplo, un ventilador de ordenador debe alimentarse con 12 voltios sin embargo,
si lo alimentas con 5 voltios también gira pero más lento.

En los catálogos de motores de DC se suelen especificar los parámetros


fundamentales de estos. En la tabla de especificaciones estándar se destacan
los valores máximos de voltaje y velocidad de giro (en revoluciones por
minuto r/min).
También se muestran las gráficas que indican cómo varía la velocidad de giro con
respecto al voltaje y el torque del motor.

A medida que aumenta el voltaje la velocidad aumenta de forma lineal. Ojo, tienes


que tener mucho cuidado porque también aumenta la corriente que circula por el
motor.

Eso significa que si somos capaces de controlar el voltaje que aplicamos a un motor


podemos controlar su velocidad. Eso convierte a la señal PWM con Arduino en una
herramienta hecha a medida para esta tarea.

Este tipo de control es muy común en los ordenadores, donde la velocidad de los
ventiladores depende de la temperatura de los periféricos. Así, por ejemplo, cuando el
disco duro o el procesador se calienta el ventilador gira a mayor velocidad para
refrescar el equipo.

El problema es que los pines digitales de Arduino solo son capaces de manejar 5


voltios y 40 mA como máximo. Esto es una limitación a la hora de controlar cargas
de potencia.

Sin embargo, ya hablamos de controlar voltajes y corrientes altas utilizando


un transistor bipolar o BJT. Precisamente, un transistor y una señal PWM con
Arduino nos permite controlar la velocidad del ventilador de una forma muy sencilla.
Esquema eléctrico control motor DC con señal PWM con
Arduino
Para montar el siguiente proyecto vas a necesitar el siguiente material:

 1x Arduino UNO o MEGA *


 1x Potenciómetro
 2x Resistencias **
 1x Diodo
 1x Transistor bipolar (Cualquiera vale, un 2n2222 es una buena opción para
motores pequeños)
 1x Motor
 1x Fuente de alimentación externa ***

* Puedes utilizar cualquier placa Arduino ya sea UNO, Nano e incluso un ESP8266.

** Las resistencias tienen que tener una razón de 100 entre ellas.

*** La fuente de alimentación es para alimentar el motor y debe coincidir con el voltaje
nominal del motor.

Este sería el circuito que tienes que montar.


En esta configuración, el transistor BJT se comporta como un interruptor que es
controlado por el pin digital 6 de la placa. Cuando se pone un estado alto (HIGH), el
interruptor se cierra encendiendo el motor. Si pones un estado bajo (LOW) este se
abre apagando el motor.

La resistencia R3 actúa como pull-down para evitar que el pin de control del


transistor quede flotante cuando Arduino es reiniciado o apagado. Es importante que
esta resistencia sea mucho mayor que R1, de lo contrario el circuito no funcionará
correctamente.

Esto se debe a que parte de la corriente que activa el transistor se drena por la
resistencia R3 y este no se activa totalmente. En este caso yo he usado un factor de
100.

R3 = R1 x 100 = 220 x 100 = 22 kΩ

También hay un potenciómetro a la entrada analógica A0 que permite establecer


la velocidad del motor. Un mayor voltaje en A0 indica una mayor velocidad.

Vamos a dar funcionalidad a todo esto a través del código que veremos a continuación.

Código control motor DC con señal PWM con Arduino


Realmente es sencillo poder controlar la velocidad de un motor DC con una señal
PWM con Arduino. Como verás más adelante, sólo ocupa unas pocas líneas de
código.

En primer lugar he definido las constantes MOTOR y POT. La primera indica a qué pin


se ha conectado el motor, y la segunda el pin del potenciómetro.

También se han declarado las variables raw_pot y duty para almacenar las lecturas


analógicas y el ciclo útil de la señal PWM respectivamente.
 
#define MOTOR 6 // pin al que se ha conectado el motor.
#define POT A0  // pin al que se ha conectado el potenciometro
 
int raw_pot; // almacenar el valor del potenciometro
 
int duty;   // ciclo util de la PWM
 
En la función setup() se configura el pin del motor como salida y se pone en estado
bajo. Esto es para garantizar que el motor esté apagado antes de la primera lectura
analógica.
void setup() {
  // apago el motor poniendo el pin en estado bajo
  pinMode(MOTOR, OUTPUT);  
  digitalWrite( MOTOR, LOW );
}

En la función loop() se implementa el sistema de control que permite variar la


velocidad del motor mediante el potenciómetro. Utiliza el siguiente algoritmo:

1. Leer potenciómetro
2. Cambiar de rango de 0-1023 (entrada analógica) a 0-255 (salida PWM)
3. Cambiar ciclo de trabajo señal PWM

En el paso 2 se utiliza la función map() para el cambio de rango. Esta función requiere


5 parámetros:
1 map( x,  fromLow, fromHigh, toLow, toHigh);
Donde:

 x: valor a cambiar de rango


 fromLow: mínimo valor del rango al que pertenece ‘x’
 fromHigh: máximo valor del rango al que pertenece ‘x’
 toLow: mínimo valor del rango al que se desea convertir ‘x’
 toHigh: máximo valor del rango al que se desea convertir ‘x’

El valor retornado por la función es el valor adaptado al rango deseado.


void loop() {
  raw_pot = analogRead(POT);
 
  duty = map(raw_pot, 0, 1023, 0, 255); // mapeo el valor de la lectura al rango 0-255
 
  analogWrite( MOTOR, duty );     // actualizar ciclo de trabajo
 
  delay(30);
}

A continuación tienes el código completo. Siéntete libre de utilizarlo como quieras.


 
#define MOTOR 6 // pin al que se ha conectado el motor.
#define POT A0  // pin al que se ha conectado el potenciometro
 
int raw_pot; // almacenar el valor del potenciometro
 
int duty;   // ciclo util de la PWM
 
void setup() {
  // apago el motor poniendo el pin en estado bajo
  pinMode(MOTOR, OUTPUT);  
  digitalWrite( MOTOR, LOW );

}
 
void loop() {
  // put your main code here, to run repeatedly:
  
  raw_pot = analogRead(POT);
 
  duty = map(raw_pot, 0, 1023, 0, 255); // mapeo el valor de la lectura al rango 0-
255
 
  analogWrite( MOTOR, duty );     // actualizar ciclo de trabajo
 
  delay(30);
}

Ahora carga el código y podrás controlar el motor a través del potenciómetro gracias a
una señal PWM con Arduino. Sería relativamente sencillo utilizar un sensor como
el DS18B20 para que, según la temperatura, varíe la velocidad del motor.

También podría gustarte