lunes, 8 de diciembre de 2014

Modulación por ancho de pulsos. PWM en Arduino

Hola de nuevo,

Bueno una semana sin ordenador, así que una semana casi en blanco. Vamos al lío.

Hoy vamos a explicar un nuevo concepto. Para realizar esta entrada necesitaremos:

- 1 x arduino UNO o compatible,
- 1  x Resistencia de 220ohms, si empezáis podéis comprar un lote de varios valores, por ejemplo como este lote de 400 resistencias, por poco más de 2 €
- 1 x Led, del color que más os guste. Os recomiendo un kit de varios colores si todavía estáis empezando,
- 1 x Protoboard, o placa de prototipos, para realizar los montajes de forma sencilla y sin soldaduras.

PWM, (pulse-width modulación), o modulación por ancho de pulsos.

Esta técnica modifica el ciclo de trabajo de una señal periódica, es decir la relación entre el tiempo que está en su parte positiva y el que está en su parte negativa. La fórmula que lo rige:

Donde:


D = \frac{\tau}{T}



D es el ciclo de trabajo
\tau es el tiempo en que la función es positiva (ancho del pulso)
T es el período de la función

Un gráfico de ejemplo:


¿Qué usos se le da a este tipo de señales? Algunos de ellos son:

- Generar señales de audio.
- Variar la velocidad de los motores
- Generar una señal analógica , si se filtra la salida digital
- Generar una señal modulada, para por ejemplo pilotar un LED infrarrojo de un control remoto,
- Variar la luminosidad de un led,

Hay muchas aplicaciones que se puede dar a este tipo de modulación de señales.

Para nuestro ejemplo vamos a diseñar un "dimmer" muy sencillo que ilumine el led al 10%, variando el ciclo de carga de la señal que haremos llegar al led. Lo que hará nuestro algoritmo es encender y apagar el LED, pero con una frecuencia tan alta, que nuestro ojo no percibe el parpadeo, sino una menor luminosidad. Variando el ancho del pulso incrementaríamos el ciclo de carga, pasaría mayor tiempo encendido y por tanto dará la sensación de mayor luminosidad.

El hardware del ejemplo, será nuestro archiconocido LED rojo, conectado al Arduino en su pin 9 a través de una resistencia de 220Ω. Por si hay alguna duda, algo como esto:


El algoritmo de lo que queremos hacer sería:

- programar el led 9 como salida
- Encender el led, ponerlo a "1"
- Esperar durante 100  μs,
- Apagar el led,
- Esperar durante 900 μs,
- Repetir indefinidamente,

Una propuesta para nuestro programa sería esta:


void setup()
{
  pinMode(9, OUTPUT); // Definimos el pin 9 como salida
}
void loop() {
  digitalWrite(9, HIGH); // Ponemos el pin a 1
  delayMicroseconds(100);// Aprox un ciclo de carga del 10% para un 1KHz
  digitalWrite(9, LOW);
  delayMicroseconds(900);
}


Puedes descargarlo aquí.

Ejemplo 1_4 dimmer con delays

El programa es muy sencillo, y podemos realizar pruebas con la luminosidad final del led, tan solo variando los tiempos de delay.


Así si queremos una luminosidad del 50%, generaríamos una onda cuadrada con un ciclo de carga del 50%, es decir colocando 500 y 500 en cada delay.  Para un 25%, 250 y 750 respectivamente , y así para cualquier combinación que queramos. Recuerda volver a cargar el programa después de cada cambio para hacerlo efectivo.

Pros y contras

Dejando de lado la incomodidad de cambiar el ciclo a mano y volver a cargar el programa, esta manera de trabajar generando la onda de esta manera, tiene varios inconvenientes:

- El ciclo de trabajo está calculado aproximadamente  y se vería afectado por cualquier interrupción en el programa, a no ser que las anulemos, y si las deshabitamos...

- El Arduino no podrá hacer otra cosa mientras se ocupe del tren de impulsos, por lo que no resulta excesivamente práctico.

Algo positivo que se me ocurre de esta manera de proceder, es que podemos implementarlo en cualquier salida digital del Arduino.

Veamos entonces otra forma de implementarlo.

analogWrite()

Esta función tiene la siguiente sintaxis:

analogWrite (pin,valor)

Donde los parámetros son:

pin: el pin que usaremos,
valor: ciclo de carga, entre 0 y 255. (0 siempre apagado, 255 siempre encendido, 127 al 50%, etc...)

Esta función genera en el pin especificado una señal cuadrada cuyo ciclo de carga variará entre entre 0 y el 100% (valores entre 0 y 255). En el Arduino UNO los pins que pueden ejecutar esta función son los pins 3, 5, 6, 9, 10 y 11. 

La frecuencia de la señal cuadrada es de aproximadamente 490 Hz, excepto en los pies 5 y 6 que será de aproximadamente 980 Hz.  

Como quedaría el programa entonces:

const int ledPin = 9;
const int DutyCicle = 255;/* Usaremos un valor de 25 para un 10%, 
67 para un 25%, 127 para un 50% y 255 para un 100% */

void setup()
{   
  pinMode(ledPin, OUTPUT); // Definimos el pin 9 como salida 
}
void loop()
{
  analogWrite(ledPin,DutyCicle);//asignamos pin 9 un ciclo carga del 10% aprox
                    //el valor de un 10% estaría entre un valor de 25
}


Puedes descargarlo aquí:

Ejemplo 1_4b dimmer con analogWrite

Ahora podemos variar nuestra luminosidad (ciclo de carga o duty cicle), tan solo variando un parámetro. Prueba los siguientes valores:

- 0, siempre apagado,
- 63, un 25% de luminosidad,
- 127, un 50%
- 255, un 100% siempre encendido,

Recuerda volver a cargar el programa tras el cambio de valor.

Un apunte más, este tipo de control sobre la luminosidad de un LED, (o cualquier tipo de carga) es mucho más eficiente que hacerlo intercalando un potenciómetro, puesto que aquí no hay perdida de potencia en forma de disipación de calor que si se daría en un potenciómetro o carga resistiva.

Un video de ejemplo:








1 comentario: