Sei sulla pagina 1di 6

1. Programa en C del reloj- termómetro- luxómetro.

#include <16F877A.h>
#device adc=10
#use delay(clock=4000000)
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES RESERVED //Used to set the reserved FUSE bits
#define LCD_ENABLE_PIN PIN_B3
#define LCD_RS_PIN PIN_B2
#define LCD_RW_PIN PIN_B1
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7

#include <LCD.c>
#include <ds1307.c>
#include <stdint.h> //Libreria estándar para definir tipos de datos enteros

uint8_t dia=21,mes=6,anio=17,dow=0,hora=15,minuto=52,segundo=0;

float temp_c;
float temp_f;
float l_v;
uint16_t luz_lux,luz_wcm2;
uint8_t contador=0; //Para controlar el bucle de ajustes si llega a hasta 10 sale del bucle

void main()
{

setup_adc_ports(AN0_AN1_AN3); //tres canales analógicos habilitados


setup_adc(ADC_CLOCK_DIV_2); //Clock del ADC es 4Mhz/2
lcd_init();
printf(lcd_putc,"CRISTIAN LIPA\n");
printf(lcd_putc,"LUX TEM DATE TIME");
delay_ms(1000);
lcd_putc("\f"); //Borrar Display
ds1307_set_date_time(dia,mes,anio,dow,hora,minuto,segundo); //Grabar fecha y hora en el IC DS1307

while(1){
set_adc_channel(0); //Se selecciona canal AN0
delay_ms(1);
l_v=(float)read_adc()*5000/1023; //En milivoltios a la salida del LDR
luz_lux=25*l_v/(5000-l_v)-6;
luz_wcm2=luz_lux*79; //0.0079W/m2 eficiencia solar aproximada
set_adc_channel(1); //Se selecciona canal AN0
delay_ms(1);
temp_c=((float)read_adc()*5000/1023)/10; //Temperatura del LM35 en Celcius
temp_f=temp_c*9/5+32;
ds1307_get_date(dia,mes,anio,dow); //Obtiene la fecha
ds1307_get_time(hora,minuto,segundo); //Obtiene la hora
lcd_gotoxy(1,1);
printf(lcd_putc,"%02u/%02u/20%02u\n",dia,mes,anio); //Imprime en el display la fecha
printf(lcd_putc,"%02u:%02u:%02u",hora,minuto,segundo); //Imprime en el display la hora
delay_ms(500);
lcd_putc("\f");
lcd_gotoxy(1,1);
printf(lcd_putc,"T=%uC T=%uF\n",(uint8_t)temp_c,(uint8_t)temp_f); //Imprime en el display la temperatura
printf(lcd_putc,"L=%luL %luW/cm2",luz_lux,luz_wcm2); //Imprime en el display la intensidad de luz
delay_ms(500);
lcd_putc("\f");

if(input_state(PIN_A4)==0){ //Si se presiona puls1


while(contador<10){
delay_ms(500);

while(input_state(PIN_A4)){ //Configura solo la hora


lcd_gotoxy(1,1);
printf(lcd_putc,"Ajustes-Hora");
lcd_gotoxy(1,2);
printf(lcd_putc,"%02u",hora);
if(input_state(PIN_A5)==0){
if(hora<23){hora++;}else hora=0; //Se incrementa el número de horas cada vez que se presione puls2
}
delay_ms(200);
}
lcd_putc("\f");
delay_ms(300);

while(input_state(PIN_A4)){ //Configura solo los minutos


lcd_gotoxy(1,1);
printf(lcd_putc,"Ajustes-Minuto");
lcd_gotoxy(3,2);
printf(lcd_putc,":%02u",minuto);
if(input_state(PIN_A5)==0){
if(minuto<59){minuto++;}else minuto=0; //Se incrementa el número de minutos cada vez que se presione puls2
}
delay_ms(200);
}
lcd_putc("\f");
delay_ms(300);

while(input_state(PIN_A4)){ //Configura solo los segundos


lcd_gotoxy(1,1);
printf(lcd_putc,"Ajustes-Segundo");
lcd_gotoxy(6,2);
printf(lcd_putc,":%02u",segundo);
if(input_state(PIN_A5)==0){
if(segundo<59){segundo++;}else segundo=0; //Se incrementa el número de segundos cada vez que se presione
puls2
}
delay_ms(200);
}
lcd_putc("\f");
delay_ms(300);
while(input_state(PIN_A4)){ //Configura solo el dia del 0 al 31
lcd_gotoxy(1,1);
printf(lcd_putc,"Ajustes-Dia");
lcd_gotoxy(9,2);
printf(lcd_putc,"%02u",dia);
if(input_state(PIN_A5)==0){
if(dia<31){dia++;}else dia=0; //Se incrementa el número de dias cada vez que se presione puls2
}
delay_ms(200);
}
lcd_putc("\f");
delay_ms(300);

while(input_state(PIN_A4)){ //Configura el mes


lcd_gotoxy(1,1);
printf(lcd_putc,"Ajustes-Mes");
lcd_gotoxy(11,2);
printf(lcd_putc,"/%02u",mes);
if(input_state(PIN_A5)==0){
if(mes<12){mes++;}else mes=0; //Se incrementa el número de meses cada vez que se presione puls2
}
delay_ms(200);
}
lcd_putc("\f");
delay_ms(300);

while(input_state(PIN_A4)){ //Configura el año


lcd_gotoxy(1,1);
printf(lcd_putc,"Ajustes-Anio");
lcd_gotoxy(14,2);
printf(lcd_putc,"/20%02u",anio);
if(input_state(PIN_A5)==0){
if(anio<99){anio++;}else anio=0; //Se incrementa el número de años solo será desde 2000 hasta 2099
} //cada vez que se presione puls2
delay_ms(200);
}
lcd_putc("\f");
delay_ms(300);

while(input_state(PIN_A4)){ //Es alerta antes de guardar cambios


contador++; //Si se presiona rápidamente puls1
delay_ms(300); //volvera al estado de configuración
if(contador==10)break; //Si no pasara a guardar los cambios
lcd_gotoxy(1,1);
printf(lcd_putc,"Se guardaran\n");
printf(lcd_putc,"Los cambios\n");
}
lcd_putc("\f");

}
contador=0;
lcd_putc("\f"); //Desde aqui ya no se puede cancelar
lcd_gotoxy(1,2); //Solo esperar a que se guarden los cambios
printf(lcd_putc,"Guardando.");
delay_ms(500);
lcd_gotoxy(1,2);
printf(lcd_putc,"Guardando..");
delay_ms(500);
ds1307_set_date_time(dia,mes,anio,dow,hora,minuto,segundo); //Con esta función se guardan los cambios

lcd_gotoxy(1,2);
printf(lcd_putc,"Guardando...");
delay_ms(500);
lcd_putc("\f");

lcd_gotoxy(1,2);
printf(lcd_putc,"Listo"); //mesaje de que se guardaron los cambios satisfactoriamente
lcd_putc("\f");
}

2. Descripción del funcionamiento del programa del reloj.

Para el funcionamiento del reloj se esta haciendo uso 3 funciones las cuales son:

 ds1307_set_date_time(dia,mes,anio,dow,hora,minuto,segundo)
 ds1307_get_date(dia,mes,anio,dow)
 ds1307_get_time(hora,minuto,segundo)

Las cuales están definidas en la librería <ds1307.c> y usan la interfaz serial I2C. La primera
función nos sirve para configurar fecha y hora colocando en cada variable el valor que
corresponda (dow será siempre=0). La segunda y tercera función nos obtiene datos de
fecha y tiempo las cuales se guardan en las variables que tienen como argumento dichas
funciones.

Inicialmente se establece datos iniciales para la fecha y la hora los cuales son:

dia=21,mes=6,anio=17,dow=0,hora=15,minuto=52,segundo=0

Seguidamente viene un bucle infinito donde se imprime primero datos del reloj, en la
primera fila la fecha en formato dd/mm/aa y en la segunda fila el tiempo en formato de
HH/mm/ss de 24horas. Luego de medio segundo se imprimen datos de temperatura y luz.
Esto se repite hasta que se presione el pulsador puls1 el cual está conectado al pin RA4

Si se presiona puls1, se termina el bucle y se entra en el modo ajustes o configuración. En


el bucle de ajustes o configuración se puede modificar tanto la fecha como el tiempo.
Existen tantos 6 bucles cada uno para un campo específico y los cuales se intercambian
pulsando puls1. Las modificaciones de los campos se hacen presionando puls2 el cual está
conectado al pin RA5. Este pulsador incrementará los valores de los campos hasta el
máximo valor y empezará de nuevo. También puede dejarse presionado puls2 si se desea
hacer incrementos rápidos de los campos.

Después de haber llegado hasta el último campo que es el año, y si se presiona


seguidamente puls1 pasará a un bucle donde indicará un mensaje de: “Se guardarán Los
cambios”, por tanto solo tenemos 3 segundo para presionar nuevamente puls1 y cancelar
los cambios realizados si nos hemos equivocado, caso contrario pasará a otro bucle donde
empezará a guardar los cambios mediante los mensajes “Guardando…” y “Listo”.

Después de guardar los cambios se regresa al bucle principal donde se repite nuevamente
todo. Para salir del bucle de ajustes o configuración hay una variable llamada contador que
se incrementa cada 300ms cuando llega hasta 10 indicando que ha pasado los 3 segundos
para cancelar los cambios, de no haber hecho caso no habrá marcha atrás y saldrá del
bucle. Pasado segundo y medio saldrá del bucle no sin antes haber guardado los cambios.

3. Descripción del funcionamiento del programa del termómetro.

Para el funcionamiento del termómetro se lee el valor analógico proporcionado por el


LM35 por el canal AN1, antes se hace la lectura del LDR por el canal AN0. Por tanto una
vez leído el LDR se hace cambio de canal al AN1 y se espera 1ms de retardo para dar
tiempo al cambio. Para convertir a digital se una la función “read_adc()” y como el ADC es
de 10 bits de resolución, se tendrá 1024 combinaciones. Para convertir estas
combinaciones a valores en milivoltios se las divide entre 1023, que es el máximo valor, y
se les multiplica por 5000. Esto mismo se aplica para la lectura del LDR.

Ya teniendo el valor en milivoltios y como cada 10mv del sensor LM35 equivale a 1°C. Por
tanto el valor en milivoltios obtenido es dividido entre 10 y asi se consigue convertir a
grados Celsius y se guarda en la variable temp_c. En la variable temp_f se guarda en
Fahrenheit usando la equivalencia “C/5=(F-32)/9” encontrada en los libros de física.

Estas dos variables son del tipo float pero son impresas en el Display LCD en formato %02u
que es para tipos “unsigned short int” (8 bits).

4. Descripción del funcionamiento del programa del luxómetro.

Como el LDR solo nos proporciona una resistencia variable, entonces hay que usarla junto
con una resistencia en configuración de un divisor de tensión, tal y como se observa en el
esquemático que se hizo anteriormente.

La relación Lux VS Resistencia de LDR se puede aproximar a:


Lux=500000/RLDR(Ω)…………………………………………………………………………………………….(1)
Si se despeja la resistencia del LDR de la ecuación de esta configuración
RLDR=(5*R/Vanalog_read)+R………………………………………………………………………………………(2)
Donde RLDR es resistencia en el LDR, R=10K y Vanalog_read es el valor medido en voltios
en el canal AN0.

Reemplazando (2) en (1) se obtiene la relación de lux y valor analógico medido. En


resultados experimentales se tuve que ajustar esta relación multiplicando por un factor de
0.5 y restando 6. De esta manera se logró ajustarlo en el rango de 0 lux hasta 100lux.

La fórmula quedó así:


Lux=50*0.5*V/(5000-V)
Donde V esta en mili voltios y es el que se mide en el canal AN0

Para convertirlo a W/cm2 se multiplica por la eficiencia de la lámpara. En nuestro caso


multiplicación por la eficiencia del sol que es de aproximadamente 79(w/cm2)/lux.
Los datos se guardan en “luz_lux” y “luz_wcm2” que son enteros sin signo de 16 bits
Estas dos variables son del tipo enteras sin signo de 16bits y son impresas en la Display
LCD en formato %lu que es para tipos “unsigned long int”.

Potrebbero piacerti anche