R.26 Medidor de velocidad de un Motor DC 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:


En algunos casos, puede interesarnos leer únicamente 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:


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 óptico donde una rueda plástica con agujeros va interrumpiendo el haz de luz generado por un led infrarrojo, generando así una señal cuadrada o digital la cual puede ser leída 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.

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:


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.

Primero, tenermos en C Compiler el codigo mostrado:


Código escrito para mayor facilidad al momento de pasarlo a su equipo de preferencia. 

Código escrito:

#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);

     

    }

   

}



Evidencias de practicas realizada en clase junto con el docente. 


Corriendo queda:






Comentarios

Entradas populares