Una practica muy común de las personas que estamos en el mundo de la electrónica es ir a los depositos de chatarra, o como en México les decimos a las chacharas para buscar componentes eléctricos/electrónicos que nos puedan servir para nuestros proyectos, en estos depositos por lo general lo que abundan son los motores, podemos encontrar de todo tipo y tamaño, estan los tipicos motores que eran utilizados en los reproductores de cd, motores sin escobillas, motores a pasos, motoreductores, y en menor medida servomotores, con suerte puedes encontrar todavia la etiqueta que te indica el modelo del motor, pero por lo menos en mi caso, los que he encontrado o no traen la etiqueta o la traen rota y no puedes ver las caracteristicas del motor, pero por el precio al que los venden bien vale la pena arriesgarse.
Y es en estos casos donde necesitamos contar con un metodo para poder variar la velocidad de los motores, pues muchas veces no tienen la relación que necesitamos, a menos que quieras comprar un kit de engranes, tu mejor opción es el PWM, pero el PWM va mucho más allá del control de motores, solo por mencionar algunos ejemplos de donde se puede encontrar o utilizar el PWM tenemos:
• Dimmer LED, • Fuentes conmutadas, • Cargadores de baterias, • Controladores proporcionales, • Control de velocidad de motores, • Control de giro de servomotores, • Generador de señales analógicas, y muchas otras aplicaciones.

IMPORTANTE:

Este proyecto utiliza un microcontrolador de microchip, por lo que es necesario tener un programador de picmicros o cualquier microcontrolador con o sin modulo CCP.

 

Teoría:

¿Que es PWM?
PWM son las siglas de Pulse Width Modulation ó en español Modulación por ancho de pulso.

¿Modulación?
Estoy seguro que si algún ingeniero en telecomunicaciones leyera esto, lo más seguro es que pegaría el grito en el cielo por lo que voy a decir, pero básicamente modular significa modificar, por ejemplo en la radio es común oír la frase frecuencia modulada o amplitud modulada en el primer caso lo podemos traducir como frecuencia modificada esto es, vamos a modificar la frecuencia de la señal, mientras que la segunda modifica la amplitud, teniendo esto en mente supongo que ya es claro hacia donde va la modulación por ancho de pulso, y si, tienes razón lo que hacemos es modificar el ancho de pulso de la señal.

Para poder entender de que va esto de PWM, primero tenemos que dejar unas cuantas cosas claras, al día de hoy no conozco ningún microcontrolador que pueda mandar a la salida señales analógicas, a no ser que se utilice un DAC, o una red R/2R, tal vez arduino si pueda, he visto que solo basta meterlo al microondas por 1 - 2 minutos y listo sale analógico*, entonces para poder mandar señales analógicas se necesitaría utilizar mas componentes, es aquí donde reside toda la gracia del PWM.

Como ya lo mencione, nuestro microcontrolador solo es capaz de enviar a sus pines de salidas ya sea un 0 correspondiente a Vss o 1 correspondiente a Vdd, lo que hace el PWM es darle la posibilidad al microcontrolador de mandar cualquier valor que vaya desde Vss hasta Vdd, ¿genial no?

La pregunta obvia que salta de inmediato es ¿como logra esto?, pues bien la respuesta la podemos encontrar en el diagrama del modulo CCP:

En caso de que haya dudas vamos a analizar el diagrama:

Lo primero que debe quedar claro es que función ocupa cada registro, para este caso son tres:
•CCPR1L (Duty cycle)
•PR2 (Periodo)
•TMR2 (Timer)

El registro CCPR1L controla el Ciclo de trabajo, es un registro de 10 bits, el valor de este registro se le pasa a un registro de solo lectura CCPR1H, este se compara con el valor del registro TMR2 en caso de ser iguales pone la salida del flip flop en bajo.

¿Ciclo de trabajo?
El ciclo de trabajo o Duty cycle es el porcentaje que va a tener la señal activa o apagada dentro de un periodo.

El registro PR2 corresponde al periodo de la señal, este es comparado con el valor del TMR2, en caso de ser iguales pone la salida del flip flop en alto.

Así se lee el diagrama y así es como el PWM logra mandar señales analógicas, ingenioso ¿no lo crees?.

No sé por que me da la impresión de que todavía no esta claro como funciona el PWM, pues bueno eso quiere decir que tenemos que desmenuzar su funcionamiento.

Desmenuzando el PWM

NOTA: El microcontrolador se encarga de todo esto, por lo tanto no es necesario leerlo al menos que quieras entender mejor como funciona el PWM.

¿Como es posible que mediante un contador y dos registros podamos mandar señales analógicas?

La respuesta es simple, esto lo logra modificando el tiempo en el cual la señal se mantiene en alto o en bajo, recuerden que el periodo es el inverso de la frecuencia, la unidad del periodo es el segundo, aquí empieza a surgir la relación con el tiempo, por otro lado el ciclo de trabajo no es otra cosa que el ancho de pulso.

Utilizando un contador (timer) de 8 bits, podemos contar desde el 0 hasta el 255, viéndolo de forma gráfica tendríamos lo siguiente:

Cada 255 ciclos el contador se reinicia y empieza de nuevo a contar, el tiempo que le toma depende de la frecuencia de trabajo del microcontrolador, por ahora para dejar las cosas claras vamos a poner una frecuencia de trabajo de 4Mhz, el contador no usa prescaladores, por lo tanto la relación es 1:1.
Calculando Tosc = 4/4Mhz = 1 µseg, esto quiere decir que el contador se reinicia cada 255µseg, dicho de otra forma tenemos un periodo de 255µsegundos que corresponde a una frecuencia de 3.92Khz

Si quisieramos tener un ciclo de trabajo del 50%, entonces tendriamos que hacer que el microcontrolador pase de alto a bajo en 127, puesto que 127 corresponde a la mitad.

Para un ciclo de trabajo del 25% tendríamos que poner en bajo la salida a los 63 pulsos de reloj:

Para un ciclo de trabajo del 80% tendríamos que poner en bajo la salida a los 204.8 ciclos, aquí tendremos que redondear para arriba o para abajo, en este caso como es .8 lo voy a redondear a 205.
Seguramente ya te habrás dado cuenta que entre mayor sea el numero de bits del periodo vamos a tener un rango mayor de porcentajes de ancho de pulso, a esto se le conoce como Resolución.

Y así es como un microcontrolador puede no solo mandar 0 o 5 Volts, si no que gracias al PWM podemos enviar señales de cualquier valor, no hay que olvidar que entre mas bits tenga el contador mayor resolución vamos a tener a la salida, y lo mejor de todo es, que caso de que nuestro microcontrolador no cuente con un modulo CCP podemos hacer el PWM mediante software, solo necesitas un contador y dos registros, genial ¿no?.

Espero con esto hayan quedado despejadas todas las dudas, y si no es el caso, lo último que se me ocurre es que veas al PWM como un potenciometro digital.

*Leyenda urbana vista por primera vez en https://edx-twin3.org
*Nada personal Arduino, lo que pasa es que eres magico y en una de esas si resulta ser cierto el mito.

Hardware:

El diagrama de conexión está creado en diptrace, presiona sobre la imagen para descargarlo.

Lista de materiales:

• Microcontrolador (PIC12F683)
• Regulador de voltaje (LM7805)
• 1 resistencias de 330 Ω @ 1/4 watt
• 1 diodo emisor de luz (LED)
• Capacitor electrolítico de 1µF @ 16 Volts
• Pila o batería de 9 Volts

Código ASM:

Como ya es costumbre no utilizo el archivo de definiciones inc, en un tutorial explique el porque hago esto, pero no hay porque preocuparse, siempre les pongo de lado derecho que registro corresponde para que lo puedan implementar sin mayor problema.

NOTA: El código no utiliza las definiciones del archivo inc.

Pues bien, lo primero que vamos hacer es implementar un dimmer led automático para ello vamos a utilizar el modulo CCP del microcontrolador, en mi caso, estoy utilizando el PIC12F683 los registros que utiliza son solo cuatro:

• PR2 (Periodo)
• T2CON (Contador)
• CCPR1L (Ancho de pulso 8 MSB)
• CCP1CON (Configuración del modulo y 2 LSB del ancho del pulso)

Con un periodo de aproximadamente 1ms es suficiente, ya si lo quieren más rápido o lento solo modifique el valor de PR2.
Vamos a necesitar dos variables, la primera es para expandir o contraer el ancho de pulso, y la segunda es una técnica que se me ocurrió, es como un switch virtual, no es lo más eficiente pero me ha salvado más de una vez, así que se las comparto porque soy muy buena gente.


clrf 0x20 ;Control CCPR1L
movlw 0x01
movwf 0x21 ;Switch 1 - incremento, 0 - decremento

Programa principal:


movlw .14 ;Frecuencia aprox 1kHz periodo aprox 1 ms
movwf 0x92 ;PR2
bsf 0x12,2 ;TMR2 ON
;Incrementando el ciclo de trabajo cada desborde de reloj
principal btfss 0x0C,1 ;TMR2IF
goto $-1
bcf 0x0C,1 ;TRM2IF = 0
movf 0x20,0
movwf 0x13 ;CCPR1L
btfsc 0x21,0
goto $+2
goto decremento
incfsz 0x20,1
goto principal
swapf 0x21,1
;Como estamos usando las intrucciones incfsz va a pasar de 0xFF a 0x00 y de 0x00 a 0xFF por lo tanto va a poducir un parpadeo.
movlw 0xFF ;Evita el parpadeo
movwf 0x20 ;Evita el parpadeo
goto principal
decremento decfsz 0x20,1
goto principal
swapf 0x21,1
goto principal

Esto sería todo, ya tenemos un dimmer led automático, lo puedes utilizar por ejemplo en tu próximo proyecto para indicar que esta encendido tu circuito.

PWM mediante software

Ahora para tod@s aquellas personas que están utilizando un microcontrolador sin modulo CCP y de echo tambien para los que si lo tengan, vamos a crear un PWM mediante software, estoy completamente seguro que esto les va a ser de utilidad puesto que ya no van a tener la limitación de solo utilizar los módulos disponibles del microcontrolador, de echo si quieren pueden hacer que todas las salidas cuenten con PWM.
El objetivo es el siguiente:

Ya vimos que mediante un contador y dos registros podemos crear el PWM, la mala noticia es que debemos pagar un precio ALTO, si implementamos el PWM por software no vamos a poder utilizar interrupciones porque debemos estar comparando el contador, así que tengan esto en cuenta antes de utilizar esta técnica.

El TMR0 va a ser nuestro contador, por lo tanto los prescaladores van a ser nuestros periodos, los registros 0x20 y 0x21 continúan con la misma función.

Calculamos periodos máximos y minímos:

Máxima frecuencia = 256*1µseg*2 = 256µseg = 1.9531Khz (Prescalador 1:2)
Miníma frecuencia = 256*1µseg*256 = 65.536mseg = 15 Hz (Prescalador 1:256)

Si necesitan frecuencias menores pueden utilizar el timer de 16 bits, solo tengan en cuenta que van a tener que concatenar registros para el ancho del pulso.

Máxima frecuencia = 65536*1µseg*1 = 65.536ms = 15 Hz (Prescalador 1:1)
Miníma frecuencia = 65536*1µseg*8 = 524.288ms = 1.90 Hz (Prescalador 1:8)

NOTA 1: Estos limites solo son validos para una frecuencia de trabajo de 4 Mhz, pueden subir a 8Mhz para alcanzar otro rango de frecuencias.

NOTA 2: Pueden alcanzar frecuencias de 20Khz pero su ciclo de trabajo se vería gravemente afectado, en fin si les sirve carguen 235 en el registro TMR0 y quiten las secuencias de incremento y decremento.


;Variables generales
clrf 0x20 ;Control ancho de pulso
movlw 0x01
movwf 0x21 ;Switch 1 - incremento, 0 - decremento
;Programa principal
clrf 0x05 ;Limpiamos las salidas
verifica btfss 0x0B,2 ;T0IF=1?
goto $-1 ;Esperamos el primer desborde para empezar bien el PWM :)
bcf 0x0B,2 ;T0IF=0
bsf 0x05,0 ;GPIO Puerto de salida GP0
clrf 0x01 ;TMR0
;Empezamos a modificar el ancho de pulso
movf 0x20,0
xorwf 0x01,0
btfss 0x03,2
goto $-3
bcf 0x05,0 ;Apagamos la señal
btfsc 0x21,0
goto $+2
goto decremento
incfsz 0x20,1
goto verifica 
swapf 0x21,1
movlw 0xFF ;Evita el blink de cambio
movwf 0x20 ;Evita el blik de cambio
goto verifica
decremento decfsz 0x20,1
goto verifica
swapf 0x21,1
goto verifica

Con esto acabamos de hacer un dimmer led automático sin contar con un modulo CCP.
Si se fijan bien el que logra la magia es la xor porque prácticamente el código es el mismo que utilizamos en la primera parte.

Resultado y palabras finales:

Aquí pongo las salidas de los diferentes métodos que utilizamos.

PWM mediante modulo CCP

Si por algún motivo no obtuvieron el mismo resultado les dejo los archivos para que lo prueben en su hardware.
Archivo con código asm: pwm_ccp.asm
Archivo Hex: pwm_ccp.hex

PWM mediante software

Si por algún motivo no obtuvieron el mismo resultado les dejo los archivos para que lo prueben en su hardware.
Archivo con código asm: pwm.asm
Archivo Hex: pwm.hex

Esto sería todo en cuanto a este tutorial sobre PWM, espero les sea de utilidad los códigos, ya solo queda modificarlos para adaptarlos a sus necesidades, por cierto, no se olviden de ir a las chacharas a comprar todo tipo de motor para que experimenten, porque solo así van a aprender, solo una última sugerencia.
Si no tienen para comprar motores no se lo quiten a la licuadora, ese no les va a servir.
No se olviden de recomendar esta pagina en facebook, twitter, google plus o cualquier otra red social, foro, pagina web, o medio de comunicación, también pueden seguirme en twitter @edx_twin3 donde pongo las ultimas noticias sobre la página.
Como siempre cualquier duda, sugerencia, comentario, etc ...., la pueden enviar ya sea mediante la pagina de contacto, mediante correo electrónico edx@edx-twin3.org o utilizando el blog.
Por último pero no menos importante cualquier donativo es de gran ayuda para seguir haciendo tutoriales como este, gracias :1.