Hola sigo trabajando en un proyecto para hacer un termostato con seteo y autonivelacion de tempertarura, en este momento tengo varios problemas, estoy simulando con proteus y tambien en una placa de desarrollo para PIC. Estoy trabando con un display LCD 16x2, hay dos menus, el primero, que seria el estado normal, es asi, solo muestra la temperatura medida y la seteada. Cuando presiono un pulsador, entra a otro menu, que me permite setear la temperatura con un potenciometro.
Hice una lista de problemas que tengo en el entrenador y en el simulador:
1-La temperatura que muestra el LCD en la simulación da saltos incorrectos, cosa que en el entrenador no pasa. En el entrenador la temperatura aumenta bien, en pasos de 0,5 grados, pero en la simulación, hace saltos de 1 grado en algunas situaciones, por ejemplo cuando pasa los 22°C, pasa a 22,5°, pero de ahí pasa a 23,5° y después a 24,5° y así.
2-Si saco la parte de redondear, y quiero que me muestre la temperatura del sensor con todos los decimales, en el entrenador funciona pero en la simulación no. Por ejemplo, en la simulación, seteo el sensor en 0,7° y me marca 1°, cuando estoy en 25,0° me marca 25,4°, en el entrenador no pasa eso.
Hasta ahora, esos problemas los considero del simulador, no de software.
3-Pero hay algo que pasa en los dos, en la simulación y en el entrenador. La temperatura medida y seteada, se mezclan. Es asi, cuando yo presiono el pulsador para setear la temperatura, y no muevo el pote, pero si el trimmer (que simula el LM35), y vuelvo a presionar el pulsador para salir del modo set up, me aparecen como si la temperatura seteada y la medida fueran la misma, hasta que mueva el trimmer, ahí es cuando se “actualiza” y muestra el valor correcto de temperatura medida.
También pasa cuando presiono para setear, dejo el valor que esta y vuelvo a presionar. La temp. seteada y temp. medida aparecen iguales.
Eso pasa cuando la función de redondeo esta activa. Probando sin hacer el redondeo, las temperaturas no se mezclan, asique el problema tiene que estar en el redondeo o en algo similar.
Cuando pongo para redondear solo la temp set, y dejo que la temperatura media muestre los decimales, no pasa esto, no se mezclan los valores. Asique el problema debe estar en que cuando pongo para setear la temperatura, se mezclan los datos de medidos y seteados.
Estoy programando en el PIC16F1519, con MPLABX y XC8
Quisiera ver si me pueden ayudar en el tema de las lecturas ADC,que se mezclan.
ADJUNTO MI CODIGO:
/*
* File: codigo.c
* Author: MR X
*
* Termosatato con seteo y autonivelacion de temperatua
*
*
*/
#include <xc.h>
#include "Ejercicio7.h"
#include "drv_lcd.h"
//Definición de E/S
#define calefactor RD0 //RD0
#define enfriador RD1 //RD1
#define pote RA0 //Potenciometro
#define lm35 RA1 //Sensor de Temperatura LM35
#define button_set RB0 //Pulsador para Setear Temperatura
//Variables Boton Set
int t_antirrebote = 0; //Tiempo para antirrebote
int flag_modosetup = 0; //Activa/Desactiva el modo set up
//Varibles Potenciometro Set
float temp_set = 25.0; //Temperatura a setear //Inicia a una temp default de 25.0 °C
char vector_set [16];
//Redondeo
float temp_round = 0.0; //Redondeo de temperatura
//Sensor LM35
float temp_med = 0.0; //Temperatura medida (LM35)
int time_muestreo = 0; //Tiempo de muestreo (100ms)
int flag_temp = 0; //Avisa cuando realizar la medicion
//Variables LCD
char vector1 [16]; //Contiene el valor de Tset y Tmed
//Funciones
int lectura_ADC(); //Canal a leer
int visualLCD(); //Visualizacion LCD
float redondeo(float temp); //Redondeo pasos de 0,5°C
void main(void)
{
//Oscilador
OSCCON = 0x6A; //4MHz
//Puertos
ANSELA = 0x03; //RA0 y RA1 Analogico
ANSELB = 0x00;
ANSELC = 0x00;
ANSELD = 0x00;
ANSELE = 0x00;
TRISA = 0x03; //RA0 y RA1 Entrada
TRISB = 0x03; //RB0 y RB1 Entrada
TRISC = 0x00;
TRISD = 0x00;
TRISE = 0x00;
PORTA = 0x00; //Limpiar Puertos
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
//LCD Configuracion
LCD_init(); //Inicializar LCD
__delay_ms(10);
//Interrupcion
INTCON = 0xB0; //0b10110000
OPTION_REG = 0x01; //PS 1:4 //T=(4/Fosc)*Prescaler*(255-TMR0)
TMR0 = 5; //(255-5) -> Interrupcion cada 1 ms
while(1)
{
//Lectura Temperatura - Sensor LM35
if(flag_temp == 1) //Bandera leer temperatura
{
if(flag_modosetup == 0) //Modo setup desactivado
{
temp_med = (lectura_ADC(1)*5.001/1023)*100; //Formula convercion
// redondeo(temp_med); //Pasos 0,5°C
// temp_med = (float)temp_round; //Temp redondeada
}
}
visualLCD(); //Visualizacion LCD
}
}
int lectura_ADC(int canal) //Seleccion de Canal
{
if(canal == 0){ADCON0 = 0x01;} //Lectura del Canal 0
if(canal == 1){ADCON0 = 0x05;} //Lectura del Canal 1
ADCON1 = 0x80; //Configuracion ADC
ADCON0bits.GO_nDONE = 1; //Iniciamos Conversion
while(ADCON0bits.GO_nDONE == 1){} //Conversion
flag_temp = 0; //Bajo bandera lectura sensor
return ((ADRESH<<8) + ADRESL); //Resultado
}
visualLCD()
{
if(flag_modosetup == 0) //Modo setup desactivado
{
LCD_setCursor(0,0); //Ubicacion de Cursor
LCD_print(" "); //16 Espacios limpian el LCD - BORRAR - provisorio
LCD_setCursor(0,1);
sprintf(vector1,"Temp: %.1f/%.1f ", temp_med, temp_set);
LCD_print(vector1);
}
if(flag_modosetup == 1) //Modo setup activado
{
flag_temp = 0; //Deshabilito lectura temperatura
temp_set = (lectura_ADC(0)*30.001/1023.0); //Formula Conversion
redondeo(temp_set); //Pasos 0,5°C
temp_set = (float)temp_round; //Temp redondeada
LCD_setCursor(0,0); //LCD
LCD_print(" Setear Temp ");
sprintf(vector_set," Temp: %.1f ",temp_set);
LCD_setCursor(0,1);
LCD_print(vector_set);
}
}
float redondeo(float temp)
{
int trunk = temp; //Truncar decimales de temperatura
float digito = temp - trunk; //Devuelve la diferencia de los decimales
if((digito > 0.0)&&(digito < 0.4)) //Rango 0
{
temp_round = trunk;
}
if((digito > 0.4)&&(digito < 0.7)) //Rango 0,5
{
temp_round= (trunk + 0.5);
}
if(digito >= 7) //Rango 1
{
temp_round=(trunk + 1.0);
}
return (float)temp_round; //Devuelve temperatura redondeada
}
void __interrupt() isr(){
//Interrupcion Externa - RB0
if(INTF == 1)
{
INTE = 0; //Deshabilito Int. Externa
}
//Interrupcion por Timer
if(TMR0IF == 1)
{
//Configuracion Pulsador Set Up
if(INTE == 0) //Int. Externa Deshabilitada
{
t_antirrebote++; //Tiempo de espera
if(t_antirrebote == 100) //150ms
{
if(button_set == 0) //RB0 - Pull Down
{
flag_modosetup = !flag_modosetup; //Activa/Desactiva modo Set Up
INTE = 1; //Habilita Int. Externa
INTF = 0; //Baja bandera de Int. Externa
t_antirrebote = 0; //Limpia tiempo antirrebote
}
if(button_set == 1){t_antirrebote = 90;} //Error - Reinicia tiempo
}
}
//Lectura Sensor LM35
time_muestreo++;
if(time_muestreo == 100) //Timer para muestreo de LM35 - 100 ms
{
flag_temp = !flag_temp; //Des/Habilita lectura
time_muestreo = 0; //Reinicio tiempo
}
TMR0IF = 0; //Bajo bandera Timer0
}
}
//Fin del Codigo
SIMULACION PROTEUS

Cualquier consulta sobre el codigo, me avisan y si me pueden dar una mano se los voy a agradecer.
