Saltar al contenido
Control Automático Educación

Medidor de Velocidad de un Motor DC con PIC

Bienvenidos Controleros y Controleras, en esta entrada vamos a aprender a usar como implementar un medidor de velocidad con PIC (Medidor RPM) empleando para ello las interrupciones del microcontrolador PIC, donde emplearemos la detección de interrupcion por Flancos.

Antes de comenzar te hago la invitación para que veas todo nuestro Curso gratuito de microcontroladores PIC

Y que te suscribas al canal si te gusta la programación de microcontroladores y la teoría de control.

Medidor de Velocidad con PIC

Los microcontroladores pueden ser empleados en diversas aplicaciones para la automatización de procesos, en esta entrada veremos como podremos aplicar lo aprendido hasta este momento en nuestro curso para realizar un tacometro digital con pic y lcd que puede ser muy util para conocer en todo momento la velocidad de un motor DC.

Para poder realizar un contador de RPM con el PIC deberemos recordar lo aprendido en la entrada de interrupciones y la entrada de PWM (modulación por ancho de pulso).

Como deseamos medir las RPM de un motor dc empleando el compilador PIC C (CCS C) vamos a introducir una nueva interrupción del microcontrolador conocida como la interrupción de flanco de subida y flanco de bajada.

Interrupción por Flanco de Subida y Flanco de Bajada

Sabemos que el microcontrolador generalmente trabaja con señales binarias o señales digitales de 0v y 5v (0 lógico y 1 lógico) y por lo general estas señales pueden ser representadas por un tren de pulsos:

Señal Digital

En algunos casos, puede interesarnos leer unicamente los flancos de subida o los flancos de bajada de algún tren de pulsos que esté entrando al microcontrolador como lo vemos en la siguiente imagen

Flancos de Subida y Bajada

Este tipo de señales es bastante común en sensores del tipo encoders, los cuales son muy utilizados para medir posición o velocidad angular, incluso estos eran empleados en los Mouse antiguos de nuestra computadora para poder determinar la posición del cursor.

Un encoder o codificador es un dispositivo de retroalimentación electromecánica empleado para proporcionar información sobre la posición, la velocidad, el conteo o la dirección convirtiendo el movimiento en una señal eléctrica para ser leída por un dispositivo de control como por ejemplo el microcontrolador PIC.

Los encoders generalmente se componen de una carcasa de plástica o de metal para proteger la electrónica, generalmente operando con principios magnéticos u ópticos y una variedad de opciones para su montaje según lo requiera la aplicación.

A continuación vemos un encoder optico donde una rueda plastica con agujeros va interrumpiendo el haz de luz gerado por un led infrarojo, generando asi una señal cuadrada o digital la cual puede ser leida para determinar la posición o velocidad de un elemento específico y la cual es leída empleando la interrupción de flanco de subida o flanco de bajada.

Encoder

Para configurar la lectura de la  INTERRUPCIÓN POR FLANCO DE SUBIDA en el Compilador CCS C Compiler debemos utilizar el siguiente comando:

ext_int_edge(L_TO_H);

Para configurar la lectura del INTERRUPCIÓN POR FLANCO DE BAJADA en el Compilador CCS C Compiler debemos utilizar el siguiente comando:

ext_int_edge(H_TO_L);

Medidor de Velocidad de un Motor DC con PIC

Si dominas este ejemplo, estarás en la capacidad de hacer un control de velocidad de un motor DC con PIC (Tacometro con PIC), dado que uno de los factores más importantes en este tipo de aplicaciones es poder realizar un medidor de RPM con PIC 16F877A, 16F887, 18F4550 o cualquier otro PIC.

Vamos a realizar un medidor de Velocidad de un Motor DC con PIC, utilizando como sensor un Encoder de 10 Pulsos por Revolución. Esta práctica la realizaremos directamente en proteus.

El proteus directamente posee un MOTOR que ya tiene integrado un encoder y puedes buscarlo con el nombre de MOTOR-ENCODER. En nuestro curso gratuito de Arduino empleamos un motor con encoder integrado para realizar la medición de velocidad DC con Arduino.

El diagrama esquemático del sensor de velocidad RPM de un Motor DC con Microcontrolador PIC implementado en Proteus es:

Velocidad de un Motor DC con PIC y Encoder

En el diagrama anterior podemos ver que a través de un potenciometro, regularemos la velocidad del motor 12V DC, utilizando un mosfet en la etapa de potencia.

Como ya sabemos el motor tiene acoplado un Encoder que entrega un tren de pulsos. Ese tren de pulsos debe ser conectado en el PIN RB0 del PIC y por medio de la interrupción Externa y por lectura bien sea del flanco de subida o flanco de Bajada, se debe calcular la velocidad en RPM (Revoluciones por Minuto) y mostrarlas en una pantalla LCD.

Para eso vamos a necesitar configurar el MOTOR-ENCODER del proteus dando doble click y colocando los 10 pulsos.

La idea general aquí, es que cada vez que se detecte alguno de los flancos (Puedes escoger el que tu desees, subida o bajada) el microcontrolador incremente un contador dentro de la rutina de interrupción.

Pasado 1 segundo, se observa cuantas veces se detectó el flanco seleccionado multiplicamos por 60 para hacer la conversión a minutos y finalmente dividimos por la resolución del encoder que en este caso es 10.

Esta misma práctica también la hicimos en nuestro curso de MicroPython donde realizamos un Tacometro con la Raspberry Pi Pico.

Código – Medidor de Velocidad de un Motor con PIC

Click aqui para descargar los archivos del medidor de velocidad del motor DC

#INCLUDE <16F887.h>
#DEVICE ADC=10
//#USE DELAY(CLOCK=4000000) //Crystal Interno 4MHz
#use delay(clock=4000000,crystal)//Crystal Externo 4MHz
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#INCLUDE <LCD.C>

#BYTE PORTA= 5
#byte PORTB= 6
#byte PORTC= 7
#BYTE PORTD= 8

long contador=0;
int16 duty=0;
int Timer2,Poscaler;
double RPM;

//Interrubción por cambio en RB0
#INT_EXT 
ext_isr()
{
 contador++;
}
void main()
{
   //Configura los Puertos del PIC
   set_tris_a(0x01);
   set_tris_b(0x01); //RB0 como entrada
   set_tris_d(0);
   
   //Configura la Entrada Analoga
   setup_adc_ports(sAN0);              //Configurar ADC (Lectura de temperatura)
   setup_adc(adc_clock_internal);      //Reloj interno para la conversion analoga digital)
   
   //Configura el PWM
   // Generemos una Señal cuadrada de 1 Khz
   Timer2=249;    //Se carga timer 2 con 249 como lo vimos en la pagina
   //Preescaler=4;  //Preescaler solo puede tomar valores de: 1 - 4 - 16
   //Para el preescaler colocamos "t2_div_by_4"
   Poscaler=1;  //Preescaler solo puede tomar valores de: 1
   
   setup_timer_2(t2_div_by_4,Timer2,Poscaler);   //Configuracion de Timer 2 para establecer frec. PWM a 1kHz
   setup_ccp1(ccp_pwm);                //Configurar modulo CCP1 en modo PWM
   
   //Habilita las Interrupcciones
    enable_interrupts(int_ext); //Activa interrupcion por RB0
    ext_int_edge(L_TO_H);    //Activa interrupción por flanco de subida
    enable_interrupts(global); //Habilita interrupciones de forma global
    
    lcd_init(); 
    lcd_gotoxy(1,1);
    LCD_PUTC("VELOCIDAD MOTOR");
    
    //Hace por siempre
    while(1)
    {
     
     //Lectura del Potenciometro
     set_adc_channel(0);   //Escoge el canal 0 de los puertos analogos
     delay_us(100);       
     duty=read_adc();      //Almacena en duty el valor del voltaje del pot
     set_pwm1_duty(duty);//10 bits= 1023 y 8bit= 255
      
     //Espera por 1 segundo
     delay_ms(999);
     
     //Despues de 1 segundo multiplica el valor de los pulsos contados en 
     //contador y los multiplica por 60 (para pasarlo a minutos) y lo divide
     //por el numero de pulsos que tiene el encoder, en este caso el encoder
     //da 10 pulsos en 1 giro completo
     RPM=contador*60/10;
     
     //Reinicia el contador de Pulsos
     contador=0;
     
     //Visualiza la Velocidad
     lcd_gotoxy(1,2);
     printf(lcd_putc,"RPM: %f   ",RPM);
     
    }
   
}

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.

Entradas relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Comentarios (4)

hola, trato de hacer un control digital de velocidad a un motor dc, sé que debo medir la velocidad del motor para eso uso un sensor de efecto hall y una rueda dentada con 30 imanes, el tiempo de establecimiento del sistema es de 1.5 seg, por lo tanto teniendo en cuenta nyquist el periodo de muestreo es de 150ms, mi duda es ¿para ese periodo de muestreo cual seria la mejor forma de medir las RPM teniendo en cuenta que el motor va de 20 a 300RPM?

Responder

Tengo una duda, al querer usar el LCD con la librería modificada de tu canal (I2C), me da error, al iniciar el lcd (lcd_init()) me sale el mensage, a numeric expression must apper here, no sé bien como funciona la librería pero tengo entendido que se ocupa el RB0 para la comunicación i2c, entonces, puede ser que sea por ello que no me deje usarla?, o como puedo cambiar el pin de interrupcion, que sea otro de los disponibles (RB4 – RB7) en caso de un PIC18F4550? saludos

Responder

Estas usando la librería modificada del LCD por I2C??? En ese caso la función de inicialización debes colocar la dirección I2C y debes colocar el tamaño del LCD, por ejemplo para un LCD16x2 en la dirección 0x4E, sería:
lcd_init(0x4E,16,2);

Responder

Es cierto, se me había pasado, agradezco tu respuesta

Responder