Вы находитесь на странице: 1из 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 seal de impulsos. Variando el tiempo en estado alto de la seal con respecto al tiempo en estado bajo conseguiremos reducir la tensin 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 tensin con el conversor AD del PIC proporcionada por un potencimetro como control manual de la velocidad. Este valor determinar el tiempo de los pulsos en estado alto de la seal 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

motor. Cuando ambos coinciden, se produce la interrupcin con la que gestionaremos el cambio de estado de la seal hasta una nueva comparacin con la cuenta del timer 1. lectura_AD=read_adc(); //Lectura canal analgico

#int_ccp2 void ccp2_int(){ //Conmutacin estado salida CCP2 if(++cambio==1){ //Modo comparacin,conmutacin salida a 0 setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); //carga del ccp2 con valor semiperiodo alto ccp_2=lectura_AD; } else{ //Modo comparacin, conmutacin 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 comparacin set_timer1(0); }

Prog

[+/-] Ver / Ocultar programa completo en C //////////////////////////////////////////////////////////////////////////////// // // // CONTROL VELOCIDAD MOTOR DC CON PIC // // // // (c) RobotyPic 2012 // // // //////////////////////////////////////////////////////////////////////////////// #include <16f876a.h> #device adc=8 #fuses XT,NOWDT #use delay(clock=4000000) #byte #byte #byte #byte trisb=0x86 portb=0x06 trisc=0x87 portc=0x07 //frecuencia de reloj 4 MHz //Archivo para control del pic 16f876a //Configuracin conversor AD a 8 bits

#define use_portb_lcd TRUE #include <lcd.c>

//Configuracin puerto b control lcd //archivo para control del lcd

/***************** Definicin de las variables globales ***********************/ int1 cambio=0; int16 lectura_AD; //Control del cambio //Referencia de velocidad

/********************** Prototipos de las funciones ***************************/ void main (void); void ccp2_int (void); //funcin principal //funcin por interrupcin

/******************************************************************************/ /******************* FUNCIN GENERACIN MODULACIONES PWM **********************/ #int_ccp2 void ccp2_int(){ if(++cambio==1){ //Conmutacin estado salida CCP2 setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); //Modo comparacin, conmutacin salida a 0 ccp_2=lectura_AD; //carga del ccp2 con valor semiperiodo alto } else{ setup_ccp2(CCP_COMPARE_SET_ON_MATCH); 1 ccp_2=255-lectura_AD; bajo } set_timer1(0); comparacin } //Carga del ccp2 con valor semiperiodo

//Modo comparacin, conmutacin salida a

//Reinicio del temporizador para

/******************************************************************************/ /******************** FUNCIN PRINCIPAL ***************************************/ void main(){ float velocidad; trisc=0x00; port_b_pullups(TRUE); lcd_init(); //Porcentaje velocidad //Puerto C como salida de datos //Habilitacin resistencias pullups puerto b //Inicializacin del lcd //Configuracin Timer para comparacin //Modo comparacin, conmutacin salida a

setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); setup_ccp2(CCP_COMPARE_SET_ON_MATCH); 1

setup_adc_ports(AN0); setup_adc(ADC_CLOCK_INTERNAL); enable_interrupts(int_ccp2); enable_interrupts(GLOBAL);

//Canal de entrada analgico AN0 //Fuente de reloj RC para conversor AD //habilitacin interrupcin por comparacin //Habilitacin de toda las interrupciones

while (true){ set_adc_channel(0); delay_us(20); lectura_AD=read_adc(); velocidad=(lectura_AD/2.55);

//Habiliatacin lectura AD //Estabilizacin //Lectura canal analgico //Clculo % de velocidad

printf(lcd_putc, "\fVelocidad = %3.0f%%", velocidad); } } n esta animacin se puede ver la simulacin bajo proteus.

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

Control del sensor trmico TPA81 con PIC


https://www.youtube.com/watch?feature=player_embedded&v=HxPH_0CZu2g https://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 pxeles 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 o o o o o Escribir en el registro 0 supone , segn su uso, cambiar la direccin I2C del TPA81 o marcar la posicin del servo asociado. Escribir en los registros 1, 2 y 3 supone recalibrar el sensor, lo cual no es aconsejable. Escribir en los registros del 4 al 9 no es posible. Leer el registro 0 devuelve la revisin del software del TPA81 Leer el registro 1 nos proporciona la temperatura ambiente. Leer los registros 2 al 9 nos informa de las temperaturas correspondientes a los 8 pixeles.

En este proyecto se pretende mostrar a nivel prctico las principales opciones de funcionamiento de este sensor.

En el momento de conectar el circuito en la pantalla lcd aparece un mensaje de presentacin y la versin del software del TPA81. Posteriormente ejecutar cuatro posibles opciones segn el estado de las entradas A0 a A3. Con todas las entradas a 0 (todas las opciones activas), primero aparece la posicin del servo, al cabo de 1 segundo, la temperatura ambiente, y un segundo ms tarde, las temperaturas de los 8 pxeles. Cambia de posicin 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 presentacin. El cableado se muestra en el esquema siguiente.

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 posicin // // 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) //Configuracin comunicacin I2C #use standard_io(C) #use standard_io(A) #define use_portb_lcd TRUE //Configuracin puerto b para lcd #include <lcd.c> //Archivo control lcd int TPA81_ID = 0xD0; //Direccin I2C de acceso al TPA81 int b[10]; //Buffer para datos lectura TPA81 int servo; //Posicin del servo int i; //Posiciones para Buffer de datos /******************************************************************************/ /******************** FUNCIN MENSAJE PRESENTACIN LCD ************************/ /***** Muestra mensaje de presentacin y durante inactividad del proceso ******/

void mensaje_pres (){ printf(lcd_putc,"\fTPA81 y 16F876A"); printf(lcd_putc,"\n (c) RobotyPic "); } /******************************************************************************/ /******************* FUNCIN DE LECTURA DEL SENSOR TPA81 **********************/ /*Carga valores de temperatura en el buffer b[]y revisin del software en b[0]*/ void lectura_tpa81( byte slaveID ) { for ( i=0; i<10; i++) { i2c_start(); //Comienzo de la comunicacin I2C ... i2c_write(slaveID); //...con la direccin del TPA81... i2c_write(i); //...apuntando a la direccin (i) del registro i2c_start(); //Reinicio i2c_write(slaveID+1); //Cambio a funcin de lectura b[i] = i2c_read(0); //Carga buffer b[] con datos ledos del TPA81 i2c_stop (); //Finalizacin de la transmisin delay_ms(10); } } /******************************************************************************/ /********************** FUNCIN BARRIDO CON EL SERVO **************************/ /****************** Control de las posiciones del servo ***********************/ void servo_tpa81 ( byte slaveID, byte servo_pos ) { i2c_start(); //Comienzo de la comunicacin I2C ... i2c_write(slaveID); //...con la direccin del TPA81... i2c_write(0); //...apuntando a la posicin 0 del registro del TPA81 i2c_write(servo_pos&0x1F); //escribe posicin del servo i2c_stop (); //Finalizacin de la transmisin } /******************************************************************************/ /************************ FUNCIN PRINCIPAL ***********************************/ void main() { lcd_init(); //Inicializacin lcd mensaje_pres (); //Mensaje de bienvenida durante 2 seg. delay_ms(2000); //Muestra en pantalla lcd versin del software TPA81 durante 2 seg. lectura_tpa81( TPA81_ID ); //Lectura de temperaturas y versin software TPA81 printf(lcd_putc,"\f Firmware V.1.%u", b[0]); delay_ms(2000); servo=0; while (1) { //Inicializacin de la posicin del servo

//Con A0 a 0 se medirn temperaturas en diferentes posiciones del servo if (!input(PIN_A0)){ if (servo==31) servo=0; //Reinicializa posicin servo servo = servo + 1; //Nueva posicin del servo servo_tpa81 ( TPA81_ID, servo ); //Cambio de posicin del servo } //Con A1 a 0 se mostrar posicin del servo durante 1 seg. if (!input(PIN_A1)){ printf(lcd_putc,"\f Servo Pos. %u",servo); //Muestra posicin servo 1 seg. delay_ms(1000);

} 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 ts 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 opcin activada muestra mensaje de presentacin 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, bastara con sustituir la lnea servo=servo+1 por servo=servo+4. En funcin 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 debera ir montado sobre el servo, pero para una observacin ms clara se optado por dejarlos por separado. En este caso estn seleccionadas solo las opciones para mostrar las temperaturas de los pixeles conforme el servo cambia de posicin.

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 bastara con disminuir los tiempos de visualizacin en el lcd o disminuir el nmero de posiciones en los 180 del giro.

Lectura de luminosidad con el conversor A/D


Se trata de un sencillo ejemplo de uso del conversor AD del PIC. Mediante un divisor de tensin formado por dos LDR en la entrada analgica obtendremos un valor de tensin 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.

Para configurar el conversor AD del pic primeramente definiremos el nmero de bits para la conversin. Pueden ser 8, 10, 11 16. En este caso se ha optado por una conversin a 10 bits: #device adc=10 Dentro ya de la funcin principal del programa, definimos el canal de entrada analgico que se va a emplear, el canal al que conectaremos el valor de tensin a medir. Aqu se ha empleado en canal AN0, pin 2 del PIC 16F876A. setup_adc_ports(AN0); Se selecciona el tipo de oscilacin para el tiempo de conversin, 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 instruccin: valor_digital=read_adc(); En la variable "valor_digital" optendremos la lectura correspondiente a la tensin analgica en un valor digital de 10 bits, de 000h a 3FFh. Este es el programa completo. [+/-] Ver / Ocultar programa en C

//////////////////////////////////////////////////////////////////////////////// // // LECTURA DE LUMINOSIDAD // // Indicacin del porcentaje de luminosidad de una LDR // respecto de la otra. // // (c) RobotyPic 2011 // //////////////////////////////////////////////////////////////////////////////// #include <16F876.h> //Driver del pic #device adc=10 //Configuracin conversor AD a 10 bits #fuses XT, #fuses #use delay (clock=4000000) #define use_portb_lcd #include <lcd.c> //Driver para pantalla lcd

// // // // // // // //

NOWDT

TRUE

void int16 float int int setup_adc_ports(AN0); setup_adc(ADC_CLOCK_INTERNAL); lcd_init(); //Canal de //Fuente entrada de

main() { valor_digital; valor_analogico; luminosidad_der; luminosidad_izq; analgico reloj del AN0 RC LCD

//nicializacin

for(;;) { set_adc_channel(0); //Habilitacin del canal de lectura 0 delay_us(20); //Estabilizacin valor_digital=read_adc(); //Lectura digitalcanal analgico valor_analogico=5.0*valor_digital/1024.0; //Equivalencia valor analgico luminosidad_der=(100*valor_analogico)/5; luminosidad_izq=100-luminosidad_der; //Muestra printf(lcd_putc, printf(lcd_putc, delay_ms(100); de "\fLuz "\nLuz //% luminosidad en LDR derecha //% luminosidad en LDR izquierda en LCD luminosidad_der); luminosidad_izq); siguiente lectura } }

porcentajes derecha %3.0d%%", izqrda. %3.0d%%", //Retardo hasta

En la simulacin bajo Proteus se puede ver el funcionamiento.

Y en la animacin de la demostracin de su funcionamiento real.

Robot con sensor trmico 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 trmico TPA81. Cmo se controla uno de estos sensores con un PIC se puede ver en el artculo anterior. Los 8 pxeles del sensor estan distribuidos linealmente siguiendo un trazado horizontal. El servo es controlado por la seal que el propio sensor dispone para ello. Bsicamente, el robot intenta que el pxel de mayor temperatura quede entre los dos centrales aumentando o disminuyendo el valor que marca la posicin del servo. Cuando el servo llega a la posicin extrema, el robot hace un giro de todo el cuerpo para seguir frente al foco de calor. De esta forma da la sensacin de que el robot lo sigue.

En los comentarios del programa del PIC desarrollado bajo el compilador PCWHD de CCS se explica la funcin de las diferentes instrucciones. [+/-] Ver / Ocultar programa en C //////////////////////////////////////////////////////////////////////////////// // // // ROBOT QUE SIGUE FUENTES DE CALOR // // // // Uso del sensor trmico TPA81 // // // // (c) RobotyPic 2010 // // // //////////////////////////////////////////////////////////////////////////////// #include <16F876A.h> #fuses XT,NOWDT,NOPROTECT //PIC a utilizar //Protecciones

#use delay(clock=4000000) //Frecuencia cristal de cuarzo #use i2c(master, SCL=PIN_C3, SDA=PIN_C4) //Configuracin comunicacin 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(P IN_B4) int TPA81_ID = 0xD0; //Direccin I2C de acceso al TPA81 int b[10]; //Buffer para datos lectura TPA81 int servo; //Posicin del servo int i; //Posiciones para Buffer de datos /******************************************************************************/ /******************* FUNCIN 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 comunicacin I2C ... i2c_write(slaveID); //...con la direccin del TPA81... i2c_write(i); //...apuntando a la direccin (i) del registro i2c_start(); //Reinicio i2c_write(slaveID+1); //Cambio a funcin de lectura b[i] = i2c_read(0); //Carga buffer b[] con datos ledos del TPA81 i2c_stop (); //Finalizacin de la transmisin delay_ms(10); } } /******************************************************************************/ /*********************** FUNCIN CONTROL DEL SERVO ****************************/ /****************** Control de las posiciones del servo ***********************/ void servo_tpa81 ( byte slaveID, byte servo_pos ) { i2c_start(); //Comienzo de la comunicacin I2C ... i2c_write(slaveID); //...con la direccin del TPA81... i2c_write(0); //...apuntando a la posicin 0 del registro del TPA81 i2c_write(servo_pos&0x1F); //escribe posicin del servo i2c_stop (); //Finalizacin de la transmisin } /******************************************************************************/ /************************ FUNCIN 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; //Condicin para girar sensor trmico servo=16; while (1) { //Posicin 0 del servo

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

//Lectura de los valores de temperatura

//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 adems es mayor que la derecha... servo=servo+1; //... entonces gira el servo una posicin 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 slo 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 posicin 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 slo gira el servo } } } }

Pulsar en la imagen para ampliarla

Los archivos del proyecto se pueden descargar del siguiente enlace:

Вам также может понравиться