15
http://robotypic.blogspot.com/2012/12/sensor-srf08-con-pic.html Control de velocidad de un motor DC con PIC Se trata de controlar la velocidad de un motor DC con una señal de impulsos. Variando el tiempo en estado alto de la señal con respecto al tiempo en estado bajo conseguiremos reducir la tensión media que le llega al motor y en consecuencia variaremos su velocidad. Para hacer ese control con el PIC, en este proyecto emplearemos el modo PWM (Pulse Width Modulation). Leeremos una tensión con el conversor AD del PIC proporcionada por un potenciómetro como control manual de la velocidad. Este valor determinará el tiempo de los pulsos en estado alto de la señal que controlará la velocidad.

Control de Velocidad de Un Motor DC Con PIC

  • Upload
    julfo05

  • View
    128

  • Download
    4

Embed Size (px)

Citation preview

Page 1: Control de Velocidad de Un Motor DC Con PIC

http://robotypic.blogspot.com/2012/12/sensor-srf08-con-pic.html

Control de velocidad de un motor DC con PICSe trata de controlar la velocidad de un motor DC con una señal de impulsos. Variando el tiempo en estado alto de la señal con respecto al tiempo en estado bajo conseguiremos reducir la tensión media que le llega al motor y en consecuencia variaremos su velocidad.

Para hacer ese control con el PIC, en este proyecto emplearemos el modo PWM (Pulse Width Modulation). Leeremos una tensión con el conversor AD del PIC proporcionada por un potenciómetro como control manual de la velocidad. Este valor determinará el tiempo de los pulsos en estado alto de la señal que controlará la velocidad.

En el modo PWM el PIC compara el valor del registro CCP (en este caso el CCP2) con el valor del timer1. En el registro CCP habremos cargado previamente un valor responsable de la velocidad del

Page 2: Control de Velocidad de Un Motor DC Con PIC

motor. Cuando ambos coinciden, se produce la interrupción con la que gestionaremos el cambio de estado de la señal hasta una nueva comparación con la cuenta del timer 1.

lectura_AD=read_adc();          //Lectura canal analógico

#int_ccp2

void ccp2_int(){

  //Conmutación estado salida CCP2   if(++cambio==1){                     //Modo comparación,conmutación salida a 0    setup_ccp2(CCP_COMPARE_CLR_ON_MATCH);      //carga del ccp2 con valor semiperiodo alto

    ccp_2=lectura_AD;                        }  else{    //Modo comparación, conmutación salida a 1    setup_ccp2(CCP_COMPARE_SET_ON_MATCH);    //Carga del ccp2 con valor del semiperiodo bajo    ccp_2=255-lectura_AD;                  }  //Reinicio del temporizador para nueva comparación  set_timer1(0);                            }

Prog

[+/-] Ver / Ocultar programa completo en C//////////////////////////////////////////////////////////////////////////////////                                                                            ////                  CONTROL VELOCIDAD MOTOR DC CON PIC                        ////                                                                            ////                         (c) RobotyPic 2012                                 ////                                                                            //////////////////////////////////////////////////////////////////////////////////

#include <16f876a.h>                   //Archivo para control del pic 16f876a

#device adc=8                          //Configuración conversor AD a 8 bits

#fuses XT,NOWDT        

#use delay(clock=4000000)              //frecuencia de reloj 4 MHz

#byte trisb=0x86#byte portb=0x06#byte trisc=0x87#byte portc=0x07

Page 3: Control de Velocidad de Un Motor DC Con PIC

#define use_portb_lcd TRUE             //Configuración puerto b control lcd#include <lcd.c>                       //archivo para control del lcd

/***************** Definición de las variables globales ***********************/

int1 cambio=0;                         //Control del cambioint16 lectura_AD;                      //Referencia de velocidad

/********************** Prototipos de las funciones ***************************/

void main (void);                      //función principalvoid ccp2_int (void);                  //función por interrupción

/******************************************************************************//******************* FUNCIÓN GENERACIÓN MODULACIONES PWM **********************/

#int_ccp2

void ccp2_int(){   if(++cambio==1){                          //Conmutación estado salida CCP2      setup_ccp2(CCP_COMPARE_CLR_ON_MATCH);  //Modo comparación, conmutación salida a 0      ccp_2=lectura_AD;                 //carga del ccp2 con valor semiperiodo alto   }      else{      setup_ccp2(CCP_COMPARE_SET_ON_MATCH);  //Modo comparación, conmutación salida a 1      ccp_2=255-lectura_AD;                  //Carga del ccp2 con valor semiperiodo bajo   }   set_timer1(0);                            //Reinicio del temporizador para comparación }   /******************************************************************************//******************** FUNCIÓN PRINCIPAL ***************************************/

void main(){     float velocidad;                          //Porcentaje velocidad         trisc=0x00;                               //Puerto C como salida de datos   port_b_pullups(TRUE);         //Habilitación resistencias pullups puerto b   lcd_init();                               //Inicialización del lcd      setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   //Configuración Timer para comparación   setup_ccp2(CCP_COMPARE_SET_ON_MATCH);     //Modo comparación, conmutación salida a 1         setup_adc_ports(AN0);                     //Canal de entrada analógico AN0   setup_adc(ADC_CLOCK_INTERNAL);     //Fuente de reloj RC para conversor AD      enable_interrupts(int_ccp2);       //habilitación interrupción por comparación   enable_interrupts(GLOBAL);         //Habilitación de toda las interrupciones

Page 4: Control de Velocidad de Un Motor DC Con PIC

       while (true){      set_adc_channel(0);                    //Habiliatación lectura AD      delay_us(20);                          //Estabilización      lectura_AD=read_adc();                 //Lectura canal analógico      velocidad=(lectura_AD/2.55);           //Cálculo % de velocidad         printf(lcd_putc, "\fVelocidad = %3.0f%%", velocidad);   }}

n esta animación se puede ver la simulación bajo proteus.https://www.youtube.com/watch?feature=player_embedded&v=bFHjIhT03C4

Control del sensor térmico TPA81 con PIChttps://www.youtube.com/watch?feature=player_embedded&v=HxPH_0CZu2ghttps://www.youtube.com/watch?feature=player_embedded&v=FHZt6uNfLxg

El TPA81 es un sensor de temperatura sin contacto, controlado mediante bus I2C. Dispone de medida de temperatura ambiente y 8 píxeles alineados de medida a distancia. Junto con un servo controlado por el propio sensor y sus 32 posiciones es posible crear un mapa de temperaturas de 180º.

El TPA81 posee 10 registros, del 0 al 9.

o       Escribir en el registro 0 supone , según su uso, cambiar la dirección  I2C del TPA81 o marcar la posición del servo asociado.

o       Escribir en los registros 1, 2 y 3 supone recalibrar el sensor, lo cual no es aconsejable.o       Escribir en los registros del 4 al 9 no es posible.o       Leer el registro 0 devuelve la revisión del software del TPA81o       Leer el registro 1 nos proporciona la temperatura ambiente.o       Leer los registros 2 al 9 nos informa de las temperaturas correspondientes a los 8 pixeles.

 En este proyecto se pretende mostrar a nivel práctico las principales opciones de funcionamiento de este sensor.

Page 5: Control de Velocidad de Un Motor DC Con PIC

En el momento de conectar el circuito en la pantalla lcd aparece un mensaje de presentación y la versión del software del TPA81.  Posteriormente ejecutará cuatro posibles opciones según el estado de las entradas A0 a A3. Con todas las entradas a 0 (todas las opciones activas), primero aparece la posición del servo, al cabo de 1 segundo, la temperatura ambiente, y un segundo más tarde, las temperaturas de los 8 píxeles. Cambia de posición el servo y se repite el ciclo para las otras 31 posiciones. Cuando alguna de las entradas no está activa, el proceso correspondiente no se realiza. Y cuando ninguna de las opciones está activa (las cuatro entradas a 1) la pantalla lcd muestra el mensaje de presentación.

El cableado se muestra en el esquema siguiente.

Page 6: Control de Velocidad de Un Motor DC Con PIC

En los comentarios en el archivo fuente para el compilador  se intenta explicar el funcionamiento del programa.

[+/-] Ver / Ocultar programa en C

//////////////////////////////////////////////////////////////////////////////// //                                                                            // //     USO DEL SENSOR TPA81 CON PIC 16F876A Y CONTROL DEL SERVO ASOCIADO      ////                                                                            ////      El programa muestra la temperatura ambiente y las temperaturas        ////               de la matriz de pixeles para cada posición                   ////                                del servo                                   ////                                                                            ////                          (c) RobotyPic  2010                               ////                                                                            // //////////////////////////////////////////////////////////////////////////////// 

#include <16F876A.h>                      //PIC a utilizar #fuses XT,NOWDT,NOPROTECT                 //Protecciones#use delay(clock=4000000)                 //Frecuencia cristal de cuarzo#use i2c(master, SCL=PIN_C3, SDA=PIN_C4)  //Configuración comunicación I2C#use standard_io(C)                       #use standard_io(A)#define use_portb_lcd TRUE                //Configuración puerto b para lcd#include <lcd.c>                          //Archivo control lcdint TPA81_ID = 0xD0;                    //Dirección I2C de acceso al TPA81 int b[10];                              //Buffer para datos lectura TPA81int servo;                              //Posición del servoint i;                                  //Posiciones para Buffer de datos    /******************************************************************************//******************** FUNCIÓN MENSAJE PRESENTACIÓN LCD ************************//***** Muestra mensaje de presentación y durante inactividad del proceso ******/

Page 7: Control de Velocidad de Un Motor DC Con PIC

void mensaje_pres (){   printf(lcd_putc,"\fTPA81 y 16F876A");    printf(lcd_putc,"\n (c) RobotyPic "); }/******************************************************************************//******************* FUNCIÓN DE LECTURA DEL SENSOR TPA81 **********************//*Carga valores de temperatura en el buffer b[]y revisión del software en b[0]*/ void lectura_tpa81( byte slaveID ) {    for ( i=0; i<10; i++) {       i2c_start();               //Comienzo de la comunicación I2C ...      i2c_write(slaveID);        //...con la dirección del TPA81...      i2c_write(i);              //...apuntando a la dirección (i) del registro       i2c_start();               //Reinicio      i2c_write(slaveID+1);      //Cambio a función de lectura      b[i] =  i2c_read(0);       //Carga buffer b[] con datos leídos del TPA81      i2c_stop ();               //Finalización de la transmisión      delay_ms(10);    } } /******************************************************************************//********************** FUNCIÓN BARRIDO CON EL SERVO **************************//****************** Control de las posiciones del servo ***********************/void servo_tpa81 ( byte slaveID, byte servo_pos ) {    i2c_start();                  //Comienzo de la comunicación I2C ...   i2c_write(slaveID);           //...con la dirección del TPA81...   i2c_write(0);                 //...apuntando a la posición 0 del registro del TPA81   i2c_write(servo_pos&0x1F);    //escribe posición del servo    i2c_stop ();                  //Finalización de la transmisión} /******************************************************************************//************************ FUNCIÓN PRINCIPAL ***********************************/void main() {       lcd_init();                   //Inicialización lcd   mensaje_pres ();              //Mensaje de bienvenida durante 2 seg.   delay_ms(2000);    //Muestra en pantalla lcd versión del software TPA81 durante 2 seg.   lectura_tpa81( TPA81_ID ); //Lectura de temperaturas y versión software TPA81   printf(lcd_putc,"\f Firmware V.1.%u", b[0]);    delay_ms(2000);       servo=0;                       //Inicialización de la posición del servo   while (1) {          //Con A0 a 0 se medirán temperaturas en diferentes posiciones del servo      if (!input(PIN_A0)){         if (servo==31) servo=0;                //Reinicializa posición servo         servo = servo + 1;                     //Nueva posición del servo         servo_tpa81 ( TPA81_ID, servo );       //Cambio de posición del servo      }                     //Con A1 a 0 se mostrará posición del servo durante 1 seg.      if (!input(PIN_A1)){          printf(lcd_putc,"\f Servo Pos. %u",servo); //Muestra posición servo 1 seg.         delay_ms(1000);

Page 8: Control de Velocidad de Un Motor DC Con PIC

      }                  lectura_tpa81( TPA81_ID );                //Lectura de las temperaturas            //Con A2 a 0 muestra en pantalla tª ambiente durante 1 seg.      if (!input(PIN_A2)){         printf (lcd_putc,"\fT. ambiente %u C", b[1]);         delay_ms(1000);      }               //Con A3 a 0 muestra en pantalla tªs de los 8 pixeles durante 1 seg.      if (!input (PIN_A3)){         printf (lcd_putc,"\f%u %u %u %u\n", b[2], b[3], b[4], b[5]);         printf (lcd_putc,"%u %u %u %u", b[6], b[7], b[8], b[9]);          delay_ms(1000);       }                  //Mientras no haya opción activada muestra mensaje de presentación en lcd      if (input_state(PIN_A0)){         if (input_state(PIN_A1)){            if (input_state(PIN_A2)){               if (input_state(PIN_A3)){               mensaje_pres();               }            }         }      }    }}

Si se quiere reducir el numero de posiciones del servo en los 180º de giro, es decir, en lugar de 32  que lo haga por ejemplo en 8, bastaría con sustituir la línea “servo=servo+1” por “servo=servo+4”. En función del incremento fijado se variará el numero de posiciones a lo largo de los 180º del giro.En el siguiente video se muestra el funcionamiento del proyecto. En realidad, el sensor debería ir montado sobre el servo, pero para una observación más clara se optado por dejarlos por separado. En este caso están seleccionadas solo las opciones para mostrar las temperaturas de los pixeles conforme el servo cambia de posición.

Y en este otro con todas las opciones seleccionadas. En este caso el servo avanza lentamente para poder ver bien todo el proceso. Para acelerarlo bastaría con disminuir los tiempos de visualización en el lcd o disminuir el número de posiciones en los 180º del giro.

Lectura de luminosidad con el conversor A/DSe trata de un sencillo ejemplo de uso del conversor AD del PIC. Mediante un divisor de tensión formado por dos LDR en la entrada analógica obtendremos un valor de tensión proporcional a la diferencia de luminosidad entre ambas LDR. En un display LCD mostraremos los porcentajes de luz de una de las LDR respecto de la otra.

Page 9: Control de Velocidad de Un Motor DC Con PIC

Para configurar el conversor AD del pic primeramente definiremos el número de bits para la conversión. Pueden ser 8, 10, 11 ó 16. En este caso se ha optado por una conversión a 10 bits:

#device adc=10            

Dentro ya de la función principal del programa, definimos el canal de entrada analógico que se va a emplear, el canal al que conectaremos el valor de tensión a medir. Aquí se ha empleado en canal AN0, pin 2 del PIC 16F876A.

setup_adc_ports(AN0);

Se selecciona el tipo de oscilación para el tiempo de conversión, en este caso se ha optado como fuente de reloj RC:

setup_adc(ADC_CLOCK_INTERNAL);

 Finalmente se habilita el canal para la lectura. Hemos quedado que empleabamos el canal AN0.

set_adc_channel(0);  

A partir de este momento, cada vez que queramos optener la lectura ejecutamos la instrucción:

valor_digital=read_adc();

En la variable "valor_digital" optendremos la lectura correspondiente a la tensión analógica en un valor digital de 10 bits, de 000h a 3FFh.

Este es el programa completo.

[+/-] Ver / Ocultar programa en C

Page 10: Control de Velocidad de Un Motor DC Con PIC

//////////////////////////////////////////////////////////////////////////////// //                                                                            // //                         LECTURA DE LUMINOSIDAD                             ////                                                                            ////            Indicación del porcentaje de luminosidad de una LDR             ////                           respecto de la otra.                             ////                                                                            ////                          (c) RobotyPic  2011                               ////                                                                            // ////////////////////////////////////////////////////////////////////////////////

#include <16F876.h>        //Driver del pic#device adc=10             //Configuración conversor AD a 10 bits#fuses XT, NOWDT#fuses#use delay (clock=4000000)#define use_portb_lcd TRUE#include <lcd.c>           //Driver para pantalla lcd

void main()   {   int16 valor_digital;   float valor_analogico;      int luminosidad_der;   int luminosidad_izq;      setup_adc_ports(AN0);            //Canal de entrada analógico AN0   setup_adc(ADC_CLOCK_INTERNAL);   //Fuente de reloj RC      lcd_init();                      //nicialización del LCD      for(;;)      {      set_adc_channel(0);           //Habilitación del canal de lectura 0      delay_us(20);                 //Estabilización      valor_digital=read_adc();                  //Lectura digitalcanal analógico      valor_analogico=5.0*valor_digital/1024.0;  //Equivalencia valor analógico            luminosidad_der=(100*valor_analogico)/5;   //% luminosidad en LDR derecha      luminosidad_izq=100-luminosidad_der;       //% luminosidad en LDR izquierda            //Muestra de porcentajes en LCD      printf(lcd_putc, "\fLuz derecha %3.0d%%", luminosidad_der);      printf(lcd_putc, "\nLuz izqrda. %3.0d%%", luminosidad_izq);            delay_ms(100);                //Retardo hasta siguiente lectura       }   }

     

En la simulación bajo Proteus se puede ver el funcionamiento.

Page 11: Control de Velocidad de Un Motor DC Con PIC

Y en la animación de la demostración de su funcionamiento real.

Page 12: Control de Velocidad de Un Motor DC Con PIC

Robot con sensor térmico TPA81

https://www.youtube.com/watch?feature=player_embedded&v=3XbeWr1D1QM

Consiste en un robot que detecta y sigue focos de calor. De igual manera, como foco de calor que es, es capaz de seguir el calor generado por el cuerpo humano.

Para conseguirlo se ha empleado un sensor térmico TPA81. Cómo se controla uno de estos sensores con un PIC se puede ver en el artículo anterior.  

Los 8 píxeles del sensor estan distribuidos linealmente siguiendo un trazado horizontal. El servo es controlado por la señal que el propio sensor dispone para ello.  Básicamente, el robot intenta que el píxel de mayor temperatura quede entre los dos centrales aumentando o disminuyendo el valor que marca la posición del servo. Cuando el servo llega a la posición extrema, el robot hace un giro de todo el cuerpo para seguir frente al foco de calor. De esta forma da la sensación de que el robot lo sigue.

En los comentarios del programa del PIC desarrollado bajo el compilador PCWHD de CCS se explica la función de las diferentes instrucciones.

[+/-] Ver / Ocultar programa en C

//////////////////////////////////////////////////////////////////////////////// //                                                                            // //                     ROBOT QUE SIGUE FUENTES DE CALOR                       ////                                                                            ////                       Uso del sensor térmico TPA81                         ////                                                                            ////                          (c) RobotyPic  2010                               ////                                                                            // //////////////////////////////////////////////////////////////////////////////// 

#include <16F876A.h>                      //PIC a utilizar 

#fuses XT,NOWDT,NOPROTECT                 //Protecciones

Page 13: Control de Velocidad de Un Motor DC Con PIC

#use delay(clock=4000000)                 //Frecuencia cristal de cuarzo#use i2c(master, SCL=PIN_C3, SDA=PIN_C4)  //Configuración comunicación I2C #use standard_io(C)                       #use standard_io(A)#use standard_io(B)#define GIRO_DERECHA    output_high(PIN_B1),output_low(PIN_B3),output_low(PIN_B2),output_high(PIN_B4)#define GIRO_IZQUIERDA  output_low(PIN_B1),output_high(PIN_B3),output_high(PIN_B2),output_low(PIN_B4)#define PARO            output_low(PIN_B1),output_low(PIN_B3),output_low(PIN_B2),output_low(PIN_B4)int TPA81_ID = 0xD0;                    //Dirección I2C de acceso al TPA81 int b[10];                              //Buffer para datos lectura TPA81int servo;                              //Posición del servoint i;                                  //Posiciones para Buffer de datos   /******************************************************************************//******************* FUNCIÓN DE LECTURA DEL SENSOR TPA81 **********************//*************** Carga valores de temperatura en el buffer b[] ****************/void lectura_tpa81( byte slaveID ) {   for ( i=0; i<10; i++) {       //Contador de posiciones del buffer b[]      i2c_start();               //Comienzo de la comunicación I2C ...      i2c_write(slaveID);        //...con la dirección del TPA81...      i2c_write(i);              //...apuntando a la dirección (i) del registro       i2c_start();               //Reinicio      i2c_write(slaveID+1);      //Cambio a función de lectura      b[i] =  i2c_read(0);       //Carga buffer b[] con datos leídos del TPA81      i2c_stop ();               //Finalización de la transmisión      delay_ms(10);    } }/******************************************************************************//*********************** FUNCIÓN CONTROL DEL SERVO ****************************//****************** Control de las posiciones del servo ***********************/void servo_tpa81 ( byte slaveID, byte servo_pos ) {   i2c_start();                  //Comienzo de la comunicación I2C ...   i2c_write(slaveID);           //...con la dirección del TPA81...   i2c_write(0);            //...apuntando a la posición 0 del registro del TPA81   i2c_write(servo_pos&0x1F);    //escribe posición del servo    i2c_stop ();                  //Finalización de la transmisión}/******************************************************************************//************************ FUNCIÓN PRINCIPAL ***********************************/void main() {   int media_izq;                //El valor medio de b[2] b[3] y b[4]   int media_der;                //El valor medio de b[7] b[8] y b[9]   int condicion;                //Condición para girar sensor térmico     servo=16;                     //Posición 0º del servo       while (1) {             lectura_tpa81( TPA81_ID );       //Lectura de los valores de temperatura

      condicion = ((b[1]+b[5]+b[6])/3);

Page 14: Control de Velocidad de Un Motor DC Con PIC

              //obtine la media de entre b[2], b[3], b[4] y Tª ambiente      media_izq=(b[1]+b[2]+b[3]+b[4])/4;            //obtiene la media de entre b[7], b[8], b[9] y Tª ambiente      media_der=((b[1]+b[7]+b[8]+b[9])/4);           //Comprueba si debe girar a la izquierda      if (media_izq > condicion){  //Si temp. a izquierda es mayor que central...         if (media_izq > media_der){ //...y además es mayor que la derecha...               servo=servo+1;        //... entonces gira el servo una posición               if (servo>=30) {      //Si servo llega al final de su giro...                  servo=16;          //...lo deja en 0º ...                   servo_tpa81 ( TPA81_ID, servo );                  delay_ms(50);                  GIRO_IZQUIERDA;    //... y gira el cuerpo a la izquierda                  delay_ms(800);                  PARO;               }               else servo_tpa81 ( TPA81_ID, servo );  //Sino sólo gira el servo          }       }

      //Comprueba si debe girar a la derecha      if (media_der > condicion){    //Si temp. a derecha es mayor que central...         if (media_der > media_izq){               servo=servo-1;          //... entonces gira el servo una posición               if (servo<=1){          //Si servo llega al final de su giro...                  servo=16;            //...lo deja en 0º ...                   servo_tpa81 (TPA81_ID, servo);                  delay_ms(50);                  GIRO_DERECHA;        //... y gira el cuerpo a la derecha                  delay_ms(800);                  PARO;               }               else servo_tpa81 ( TPA81_ID, servo );  //Sino sólo gira el servo         }      }   }}

Page 15: Control de Velocidad de Un Motor DC Con PIC

                                  Pulsar en la imagen para ampliarla

Los archivos del proyecto se pueden descargar del siguiente enlace: