Documentos de Académico
Documentos de Profesional
Documentos de Cultura
html
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
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.
#int_ccp2
void ccp2_int(){
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
#fuses XT,NOWDT
#byte trisb=0x86
#byte portb=0x06
#byte trisc=0x87
#byte portc=0x07
#define use_portb_lcd TRUE //Configuración puerto b control lcd
#include <lcd.c> //archivo para control del lcd
/******************************************************************************/
/******************* 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(){
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º.
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 TPA81
o 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.
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.
////////////////////////////////////////////////////////////////////////////////
// //
// 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 //
// //
////////////////////////////////////////////////////////////////////////////////
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 di sminuir los tiempos de visualización en
el lcd o disminuir el número de posiciones en los 180º del giro.
#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();
void main()
{
int16 valor_digital;
float valor_analogico;
int luminosidad_der;
int luminosidad_izq;
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
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.
////////////////////////////////////////////////////////////////////////////////
// //
// ROBOT QUE SIGUE FUENTES DE CALOR //
// //
// Uso del sensor térmico TPA81 //
// //
// (c) RobotyPic 2010 //
// //
////////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
/******************* 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
while (1) {
lectura_tpa81( TPA81_ID ); //Lectura de los valores de temperatura
condicion = ((b[1]+b[5]+b[6])/3);