Академический Документы
Профессиональный Документы
Культура Документы
html
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
/***************** 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
/******************************************************************************/ /******************** 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
//Canal de entrada analgico AN0 //Fuente de reloj RC para conversor AD //habilitacin interrupcin por comparacin //Habilitacin de toda las interrupciones
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
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);
//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.
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 } }
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
//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 } } } }