Estimado moderador,
Me ajuste a los ciclos descriptos en el manual de Bosch, pero, para proteger el compresor de sobrecalentamiento,
escribí un ciclo para que se apague cada 30 minutos de encendido y descanse por 5 minutos, independientemente de que si llegó
a la temperatura correcta o no. Esta es una medida de seguridad... si se quedó sin gas y no es eficiente el compresor, que no se queme.
Al ser microcontrolado todo y bajo demanda, los ciclos no son del todo fijos, sino que tienen variaciones dependiendo de las condiciones
o demanda. Creo personalmente que es más eficiente en cuanto a consumo de energía.
El comportamiento del ciclo de deshielo cuando se fue la energía es seteable (grabable en la EEPROM), para poder configurar si lo
queremos o no.
Publico el código en PICC del proyecto por si alguien tiene el mismo problema. Tengo también los diseños en eagle de todas las placas
de control que diseñé.
Reemplacé mi email con xxxx... por motivos obvios... no quiero que mi casilla se llene de spam.
Espero que le sirva a alguien. Este código tiene la virtud de estar probado por el tiempo... 5 años de perfecto funcionamiento en
mi heladera lo atestiguan.
Me quedaron cosas en el tintero que en un momento quise escribir. Por ejemplo el buzzer sacarlo por PWM para que suene encendido/apagado
y no un tono continuo como ahora.
En la sección del forzador (fan) se podría juntar estadísticas, en conjunto con las estadísticas de ciclo de compresor. Si ambos pasan demasiado tiempo
encendidos, se perdió la eficiencia (probablemente se descargó el gas) y estaría bueno imprimir un mensaje de error en el display LCD.
#define CLOCK_SPEED 4000000 // Reloj a 4 Mhz (mas que suficiente y mas estable)
#define INTS_PER_SECOND 15 // (4000000/(4*256*256)) // Para interrupt timer0
#define USAR_WDT // Comentar si no queremos usar WDT
// Ver parametro WDT_TIMEOUT en la inicializacion
#define BITS_ADC 10 // Resolucion ADC de 10 bits
#define FAC_ADC 0.004882813 // Convertir ADC a volts 5/1024
#define T_HEL 7 // Canal ADC del termistor de la heladera
#define T_FRE_EV 6 // Canal ADC termistor del evaporador (freezer)
#define T_FRE 5 // Canal ADC termistor freezer
#define T_HEL_R2 10000 // Valor de la resistencia R2 en termistor heladera
// Constantes para el termistor del freezer para polinomio Steinhart/Hart
#define T_FRE_a 1.3089E-03
#define T_FRE_B 2.3286E-04
#define T_FRE_C 1.0230E-07
// Constantes para el termistor de 10 --heladera-- para polinomio Steinhart/Hart
#define T_HEL_a 1.6441E-03
#define T_HEL_B 1.4214E-04
#define T_HEL_C 5.2878E-07
#define USAR_LCD // Comentar si no queremos output a LCD
#define USAR_SERIAL // Comentar si no queremos output a serial
#define BOTON1 0 // Canal ADC del boton 1 de la botonera
#define BOTON2 1 // Canal ADC del boton 2 de la botonera
#define BOTON3 2 // Canal ADC del boton 3 de la botonera
#define COMPRESOR PIN_D4 // Relay que controla el compresor
#define HEATER PIN_D5 // Relay que controla el calentador del evaporador
#define TRAY PIN_D6 // Relay que controla el calentador de la bandeja
#define FAN PIN_D7 // Relay que controla el ventilador
#define PUERTA_HEL PIN_C5 // Puerta heladera
#define PUERTA_FRE PIN_C4 // Puerta del freezer
#define BUZZER PIN_C3 // Chicharra de puertas abiertas
#define ARRANQUE 60 // Numero de segundos antes de arrancar
#define TEMP_FRE_MAX -20 // Temperatura maxima de freezer
#define TEMP_FRE_MIN -27 // Temperatura minima de freezer
#define TEMP_FRE_MIN_NOFAN -25 // Temperatura Freezer minima sin fan
#define TEMP_MIN_EV -42 // Temperatura minima del evaporador
#define TEMP_HEL_MAX_DEF 8 // Temperatura minima heladera por default
#define TEMP_HEL_MIN_DEF 4 // Temperatura maxima heladera por default
#define TEMP_MAX_SET 15 // Temperatura maxima seteable para la heladera
#define TEMP_MIN_SET -5 // Temperatura minima seteable para la heladera
#define TEMP_MAX_DES 4 // Temperatura maxima del evaporador en deshielo
#define COMP_MAX_ON 1800 // Tiempo en seg maximo de encendido de compresor
#define COMP_MIN_OFF 300 // Segundos minimos de descanso de compresor
#define FAN_MAX_OFF 1800 // Segundos del ventilador sin hacer nada
#define CICLO_MIN_FAN 60 // Segundos de encendido del fan
#define TIEMPO_COMP_MAX 72000 // Tiempo maximo para descongelar
#define TIEMPO_COMP_MED 32400 // Tiempo medio para descongelar
#define TIEMPO_COMP_MIN 21600 // Tiempo min para descongelar
#define TIEMPO_PUERTAS_AB 900 // Tiempo maximo puertas abiertas p/descongelar
#define T_ULT_DESH_MIN 1100 // Tiempo minimo ultimo deshielo
#define T_MAX_PUER_ABIERTAS 40 // Tiempo maximo puertas abiertas
#define T_DESC_DESHIELO 600 // Tiempo de descanso antes del deshielo
#define T_MAX_DESHIELO 4800 // Tiempo maximo de deshielo
#define T_DESHIELO_TRAY 600 // Tiempo de deshielo del tray al final del ciclo
#define MS_MUESTRA_P 13 // Tiempo de muestreo puertas
#define PANTALLA_MAX 12 // Numero de pantallas de info a mostrar
#define TMOUT_TMP_SET 40 // Timeout seteo de temperatura
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=CLOCK_SPEED)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#device adc=BITS_ADC
#elif defined(__PCH__)
#include <18F452.h>
#ifdef USAR_WDT
#fuses HS,WDT128,NOPROTECT,NOLVP,NOBROWNOUT
#else
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#endif
#device adc=BITS_ADC
#use delay(clock=CLOCK_SPEED)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#rom int 0xf00000={1,2,3,4}
#endif
#include <bootloader.h>
#include <math.h> // Incluir funciones matematicas
#ifdef USAR_LCD
#include "C:\docs\pic\picc\18f452\heladera_4MHZ\lcd.c" // Cargar driver LCD
#endif
// Para interrupt reloj
long long seconds = 0; // A running seconds counter
BYTE int_count; // Number of interrupts left before a second has elapsed
float temp_hel; // Temperatura heladera
float temp_ev; // Temperatura evaporador (se usa para descongelado)
float temp_fre; // Temperatura freezer
long long te_compresor; // Tiempo de encendido del compresor
long long ta_compresor; // Tiempo de apagado de compresor
long long t_compresor_total; // Tiempo total de encendido de compresor
long long te_fan; // Tiempo de encendido del compresor
long long ta_fan; // Tiempo de apagado de compresor
long long t_fan_total; // Tiempo total de encendido de compresor
long long te_deshielo; // Tiempo de comienzo de deshielo
long long ta_deshielo; // Tiempo de apagado de deshielo
long long t_ultimo_deshielo; // Tiempo del ultimo deshielo
long long t_puertas_abiertas; // Tiempo total de puertas abiertas
int1 compresor_encendido; // Compresor encendido = 1, apagado = 0
int1 fan_encendido; // Ventilador encendido = 1, apagado = 0
signed int deshielo_arranque; // Descongelar al arrancar, 1 = encendido, 0 = apagado
signed int temp_max_hel; // Temperatura maxima heladera
signed int temp_min_hel; // Temperatura minima heladera
long cant_deshielos; // Cantidad de deshielos
void espera (long segundos)
{
long i;
for (i=0; i < segundos * 5; ++i)
{
delay_ms (200);
#ifdef USAR_WDT
restart_wdt ();
#endif
}
}
/*
void test ( )
{
#ifdef USAR_SERIAL
printf ("Relay 1 prendido\n\r");
#endif
#ifdef USAR_LCD
printf (lcd_putc, "\fRelay 1\nPrendido");
#endif
output_low (COMPRESOR);
espera (4);
output_high (COMPRESOR);
#ifdef USAR_LCD
printf (lcd_putc, "\fRelay 1\nApagado");
#endif
#ifdef USAR_LCD
printf ("Relay 1 apagado\n\r");
#endif
espera (4);
}
*/
#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
// For this program this is apx 76 times
if(--int_count==0) { // per second.
++seconds;
int_count=INTS_PER_SECOND;
}
}
// Esta rutina espera la cantidad de segundos definida en ARRANQUE
// antes de encender la heladera para evitar posibles picos de tension
// despues de un corte de energia
void arrancar ( ) {
long i;
for (i = ARRANQUE; i > 0; --i) {
espera (1);
#ifdef USAR_LCD
printf (lcd_putc, "\fEncendido en\n%Lu segundos",i);
#endif
#ifdef USAR_SERIAL
printf ("%Lu seg para arrancar\n\r",i);
#endif
}
}
// Funcion polinimio de Steinhart-Hart para resolver curva de temperatura
// de termistores
// Si el parametro termistor es igual a 0, se trata del termistor de la
// heladera, si es igual a 1, es el termistor de freezer
float steinhart (float R1, int1 termistor){
float lnRes, lnRes3, temp, TempC ;
lnRes = log(R1);
lnRes3 = lnRes * lnRes * lnRes;
if (termistor == 0)
temp = T_HEL_a + T_HEL_B * lnRes + T_HEL_C * lnRes3;
else
temp = T_FRE_a + T_FRE_B * lnRes + T_FRE_C * lnRes3;
TempC = 1 / temp - 273.15; // Cero absoluto
return (TempC);
}
void temperaturas ( ) {
long res;
float R1;
#ifdef USAR_WDT
restart_wdt ();
#endif
// Leemos temperatura heladera
set_adc_channel (T_HEL);
delay_ms(10);
res = read_adc();
R1=((T_HEL_R2 *5) / (res * FAC_ADC)) - T_HEL_R2;
temp_hel = steinhart (R1, 0); // Llamar con 0 para heladera y con 1 para freezer
// Leemos temperatura freezer (evaporador)
set_adc_channel (T_FRE_EV);
delay_ms (10);
res = read_adc();
R1=((T_HEL_R2 *5) / (res * FAC_ADC)) - T_HEL_R2;
temp_ev = steinhart (R1, 1); // Llamar con 0 para heladera y con 1 para freezer
// Leemos temperatura freezer (evaporador)
set_adc_channel (T_FRE);
delay_ms (10);
res = read_adc();
R1=((T_HEL_R2 *5) / (res * FAC_ADC)) - T_HEL_R2;
temp_fre = steinhart (R1, 1); // Llamar con 0 para heladera y con 1 para freezer
}
void inicializar ()
{
// Setear todos los pines como output para evitar ruido
output_float (PIN_A0);
output_float (PIN_A1);
output_float (PIN_A2);
output_float (PIN_A3);
output_float (PIN_A4);
output_float (PIN_A5);
output_float (PIN_A6);
output_float (PIN_B0);
output_float (PIN_B1);
output_float (PIN_B2);
output_float (PIN_B3);
output_float (PIN_B4);
output_float (PIN_B5);
output_float (PIN_B6);
output_float (PIN_B7);
output_float (PIN_C0);
output_float (PIN_C1);
output_float (PIN_C2);
output_float (PIN_C3);
output_float (PIN_C4);
output_float (PIN_C5);
output_float (PIN_C6);
output_float (PIN_C7);
output_float (PIN_D0);
output_float (PIN_D1);
output_float (PIN_D2);
output_float (PIN_D3);
output_float (PIN_D4);
output_float (PIN_D5);
output_float (PIN_D6);
output_float (PIN_D7);
output_float (PIN_E0);
output_float (PIN_E1);
output_float (PIN_E2);
t_compresor_total = 0; // Inicializar tiempo total de encendido de compresor
ta_compresor = 0; // inicializamos tiempo apagado de compresor
te_compresor = 0; // Inicializamos tiempo de apagado del compresor
compresor_encendido = 0; // Seteamos el compresor en apagado
t_ultimo_deshielo = 0; // Inicializar tiempo ultimo deshielo
t_puertas_abiertas = 0; // Tiempo total de puertas abiertas
output_low (COMPRESOR); // Apagamos el compresor
output_low (FAN); // Apagamos el ventilador
output_low (HEATER); // Apagamos la resistencia de deshielo
output_low (TRAY); // Apagamos la resistencia de drenaje
output_low (BUZZER); // Apagamos la chicharra
fan_encendido = 0; // Seteamos el fan en apagado
te_fan = 0; // Resetamos Tiempo Encendido de ventilador
ta_fan = 0; // Reseteamos Tiempo Apagado de ventilador
t_fan_total = 0; // Reseteamos tiempo total del ventilador
cant_deshielos = 0; // Reseteamos cantidad de deshielos
temp_max_hel = read_eeprom (1); // Leemos las temperaturas de la EEPROM
temp_min_hel = read_eeprom (0);
deshielo_arranque = read_eeprom (2); // Leemos deshielo arranque
// Si las temperaturas estan fuera de rango, setear defaults
if (temp_max_hel > TEMP_MAX_SET || temp_max_hel < TEMP_MIN_SET)
temp_max_hel = TEMP_HEL_MAX_DEF;
if (temp_min_hel > TEMP_MAX_SET || temp_min_hel < TEMP_MIN_SET)
temp_min_hel = TEMP_HEL_MAX_DEF;
// Si el seteo de descongelar al arrancar esta mal, inicializarlo
if (deshielo_arranque < 0 || deshielo_arranque > 1)
deshielo_arranque = 1;
// Hacemos sonar el buzzer!
output_high (BUZZER);
delay_ms (500);
output_low (BUZZER);
#ifdef USAR_WDT
restart_wdt ();
#endif
}
void cont_compresor (int1 i) {
if (i == 1) {
compresor_encendido = 1; // Ponemos la bandera de compresor encendido
te_compresor = seconds; // Empezamos a contar los segundos
output_high (COMPRESOR); // Encendemos el compresor
}
if (i == 0) {
compresor_encendido = 0;
output_low (COMPRESOR);
ta_compresor = seconds;
t_compresor_total = t_compresor_total + (ta_compresor - te_compresor);
}
}
void cont_fan (int1 i) {
if (i == 1) {
fan_encendido = 1; // Ponemos la bandera de ventilador encendido
te_fan = seconds; // Empezamos a contar los segundos
output_high (FAN); // Encendemos el ventilador
lcd_init ();
delay_ms (20);
}
if (i == 0) {
fan_encendido = 0;
output_low (FAN); // Apagamos el ventilador
ta_fan = seconds;
t_fan_total = t_fan_total + (ta_fan - te_fan);
lcd_init ();
delay_ms (20);
}
}
void descongelar (void) {
int1 terminado=0;
long i;
cont_compresor (0); // Apagamos el compresor
output_low (FAN); // Apagamos el ventilador
t_compresor_total = 0; // Reseteamos tiempo de compresor encendido
t_puertas_abiertas = 0; // Reseteamos tiempo total de puertas abiertas
// 5 minutos de descanso
++cant_deshielos;
delay_ms (10);
for (i=T_DESC_DESHIELO; i > 0; --i) {
#ifdef USAR_LCD
printf (lcd_putc, "\fDeshielo-Espera\n%ld segundos",i);
#endif
#ifdef USAR_SERIAL
printf ("\fDeshielo-Espera %ld segundos\n\r",i);
#endif
espera (1);
}
lcd_init ();
delay_ms (20);
// Mientras que el sensor de temperatura del evaporador no llegue a los
// 3 grados centigrados, calentar resistencia de evaporador y de dreno
te_deshielo = seconds;
output_high (HEATER); //Encendemos el heater
#ifdef USAR_LCD
printf (lcd_putc, "\fEncendiendo\nheater");
#endif
#ifdef USAR_SERIAL
printf ("\fEncendiendo heater...\n\r");
#endif
espera (2); // Para que se alcance a leer en el display
// Esperamos 10 segundos para evitar golpe
for (i=10; i > 0; --i) {
#ifdef USAR_LCD
printf (lcd_putc, "\fEspera\n%ld segundos",i);
#endif
#ifdef USAR_SERIAL
printf ("\fEspera %ld segundos\n\r",i);
#endif
espera (1);
}
lcd_init ();
delay_ms (20);
output_high (TRAY); // Encendemos el tray
#ifdef USAR_LCD
printf (lcd_putc, "\fEncendiendo\ntray");
#endif
#ifdef USAR_SERIAL
printf ("\fEncendiendo tray...\n\r");
#endif
espera (2); // Para que se alcance a leer en el display
while (!terminado) {
temperaturas ();
if ((temp_ev > TEMP_MAX_DES) || (seconds-te_deshielo) > T_MAX_DESHIELO) {
terminado = TRUE;
output_low (HEATER); // Apagamos el heater
}
#ifdef USAR_LCD
printf (lcd_putc, "\fDeshielo T:%f\nSeg: %Lu", temp_ev, seconds-te_deshielo);
#endif
#ifdef USAR_SERIAL
printf ("\fDeshielo.T %f Segundos: %Lu\n\r", temp_ev, seconds-te_deshielo);
#endif
espera (1);
}
ta_deshielo = seconds;
t_ultimo_deshielo = (ta_deshielo - te_deshielo);
// La resistencia de dreno tiene que quedar encendida 10 minutos mas
for (i = T_DESHIELO_TRAY; i > 1; --i) {
#ifdef USAR_LCD
printf (lcd_putc, "\fDeshielo-Tray\n%ld Tot %Lu",i, t_ultimo_deshielo);
#endif
#ifdef USAR_SERIAL
printf ("\fDeshielo-Tray %ld Seg - Tot %Lu\n\r",i, t_ultimo_deshielo);
#endif
espera (1);
}
output_low (TRAY); // Apagamos la resistencia de dreno
}
int1 leer_puertas (VOID)
{
int1 muestra1, muestra2, muestra3, muestra4;
int1 puerta_ab_hel, puerta_ab_fre;
int1 resultado;
muestra1 = input (PUERTA_HEL); // Tomamos 3 muestras de 15 milisegundos de la puerta de la heladera
delay_ms (MS_MUESTRA_P); // para evitar la cuadrada de 50Hz
muestra2 = input (PUERTA_HEL);
delay_ms (MS_MUESTRA_P);
muestra3 = input (PUERTA_HEL);
delay_ms (MS_MUESTRA_P);
muestra4 = input (PUERTA_HEL);
if (muestra1 || muestra2 || muestra3 || muestra4)
puerta_ab_hel = TRUE;
else
puerta_ab_hel = FALSE;
muestra1 = input (PUERTA_FRE); // Tomamos 3 muestras de 15 milisegundos de la puerta de la heladera
delay_ms (MS_MUESTRA_P); // para evitar la cuadrada de 50Hz
muestra2 = input (PUERTA_FRE);
delay_ms (MS_MUESTRA_P);
muestra3 = input (PUERTA_FRE);
delay_ms (MS_MUESTRA_P);
muestra4 = input (PUERTA_FRE);
if (muestra1 || muestra2 || muestra3 || muestra4)
puerta_ab_fre = TRUE;
else
puerta_ab_fre = FALSE;
if (puerta_ab_hel || puerta_ab_fre)
resultado = 1;
else
resultado = 0;
#ifdef USAR_WDT
restart_wdt ();
#endif
return (resultado);
}
int1 leer_boton (int canal_adc)
{
long res;
#ifdef USAR_WDT
restart_wdt ();
#endif
set_adc_channel (canal_adc);
delay_ms(10);
res = read_adc();
if (res > 1000)
{
delay_ms (150); // Debounce del pobre
#ifdef USAR_WDT
restart_wdt ();
#endif
return (1);
}
else
return (0);
}
void seteos_varios (VOID)
{
int1 pb1, pb2, pb3, salir1, salir2, desc;
long long te_temp; // Tiempo en el que comenzamos a setear la temperatura
signed int temp_min_ori;
signed int temp_max_ori;
signed int deshielo_arranque_ori;
salir1 = FALSE;
salir2 = FALSE;
desc = FALSE;
te_temp = seconds;
temp_min_ori = temp_min_hel;
temp_max_ori = temp_max_hel;
deshielo_arranque_ori = deshielo_arranque;
#ifdef USAR_LCD
lcd_init (); // Inicializar Display LCD
delay_ms (10);
#endif
while (!salir1)
{
#ifdef USAR_WDT
restart_wdt ();
#endif
pb1 = leer_boton (BOTON1); // Leemos los botones de la botonera
pb2 = leer_boton (BOTON2);
pb3 = leer_boton (BOTON3);
// Seteamos temperatura minima
while (!salir2)
{
#ifdef USAR_WDT
restart_wdt ();
#endif
#ifdef USAR_LCD
printf (lcd_putc, "\fTEMP MINIMA:\n%d", temp_min_hel);
#endif
#ifdef USAR_SERIAL
printf ("\fTEMP MINIMA: %d\n\r", temp_min_hel);
#endif
pb1 = leer_boton (BOTON1); // Leemos los botones de la botonera
pb2 = leer_boton (BOTON2);
pb3 = leer_boton (BOTON3);
if (pb1)
salir2 = TRUE;
if (pb2)
{
--temp_min_hel;
if (temp_min_hel < TEMP_MIN_SET)
temp_min_hel = TEMP_MIN_SET;
}
if (pb3)
{
++temp_min_hel;
if (temp_min_hel > TEMP_MAX_SET)
temp_min_hel = TEMP_MAX_SET;
}
if ((seconds - te_temp) > TMOUT_TMP_SET)
salir2 = TRUE;
}
// Seteamos temperatura maxima
salir2 = FALSE;
while (!salir2)
{
#ifdef USAR_WDT
restart_wdt ();
#endif
#ifdef USAR_LCD
printf (lcd_putc, "\fTEMP MAXIMA:\n%d", temp_max_hel);
#endif
#ifdef USAR_SERIAL
printf ("\fTEMP MAXIMA: %d\n\r", temp_max_hel);
#endif
pb1 = leer_boton (BOTON1); // Leemos los botones de la botonera
pb2 = leer_boton (BOTON2);
pb3 = leer_boton (BOTON3);
if (pb1)
salir2 = TRUE;
if (pb2)
{
--temp_max_hel;
if (temp_max_hel < TEMP_MIN_SET)
temp_max_hel = TEMP_MIN_SET;
}
if (pb3)
{
++temp_max_hel;
if (temp_max_hel > TEMP_MAX_SET)
temp_max_hel = TEMP_MAX_SET;
}
if ((seconds - te_temp) > TMOUT_TMP_SET)
salir2 = TRUE;
}
if (pb1){
salir1 = TRUE;
}
if ((seconds - te_temp) > TMOUT_TMP_SET)
salir1 = TRUE;
// Preguntamos si queremos un ciclo de descongelado manual
salir2 = FALSE;
while (!salir2)
{
#ifdef USAR_WDT
restart_wdt ();
#endif
#ifdef USAR_LCD
printf (lcd_putc, "\fDeshielo ahora?\n");
if (desc == TRUE)
printf (lcd_putc, "SI");
else
printf (lcd_putc, "NO");
#endif
#ifdef USAR_SERIAL
printf ("\fDescongelar ahora?");
if (desc == TRUE)
printf ("SI\n\r");
else
printf ("NO\n\r");
#endif
pb1 = leer_boton (BOTON1); // Leemos los botones de la botonera
pb2 = leer_boton (BOTON2);
pb3 = leer_boton (BOTON3);
if (pb1)
salir2 = TRUE;
if (pb2)
--desc;
if (pb3)
++desc;
if ((seconds - te_temp) > TMOUT_TMP_SET) {
salir2 = TRUE;
desc = FALSE;
}
}
// Preguntamos si queremos setear deshielo al arranque
salir2 = FALSE;
while (!salir2)
{
#ifdef USAR_WDT
restart_wdt ();
#endif
#ifdef USAR_LCD
printf (lcd_putc, "\fDeshielo arranq?\n");
if (deshielo_arranque == TRUE)
printf (lcd_putc, "SI");
else
printf (lcd_putc, "NO");
#endif
#ifdef USAR_SERIAL
printf ("\fDeshielo al arranque?");
if (deshielo_arranque == TRUE)
printf ("SI\n\r");
else
printf ("NO\n\r");
#endif
pb1 = leer_boton (BOTON1); // Leemos los botones de la botonera
pb2 = leer_boton (BOTON2);
pb3 = leer_boton (BOTON3);
if (pb1)
salir2 = TRUE;
if (pb2)
deshielo_arranque = 0;
if (pb3)
deshielo_arranque = 1;
if ((seconds - te_temp) > TMOUT_TMP_SET) {
salir2 = TRUE;
deshielo_arranque = TRUE;
}
}
}
if ((seconds - te_temp) > TMOUT_TMP_SET)
{
#ifdef USAR_LCD
printf (lcd_putc, "\fTIMEOUT\nseteos");
#endif
#ifdef USAR_SERIAL
printf ("TIMEOUT en seteos!\n\r");
#endif
espera (2);
}
if (temp_max_hel <= temp_min_hel)
{
#ifdef USAR_LCD
printf (lcd_putc, "\fERROR: temp min\n>= temp max!");
#endif
#ifdef USAR_SERIAL
printf ("ERROR: temp min => que temp max!\n\r");
#endif
temp_min_hel = temp_min_ori;
temp_max_hel = temp_max_ori;
espera (2);
}
// Escribimos en la EEPROM los valores
#ifdef USAR_WDT
restart_wdt ();
#endif
// Escribimos en la EEPROM los valores solo si cambiaron
if (temp_min_hel != temp_min_ori)
write_eeprom (0, temp_min_hel);
if (temp_max_hel != temp_max_ori)
write_eeprom (1, temp_max_hel);
if (deshielo_arranque != deshielo_arranque_ori)
write_eeprom (2, deshielo_arranque);
// Si elegimos que descongele manualmente... hacerlo
if (desc == TRUE)
descongelar ();
}
void main(void) {
int_count=INTS_PER_SECOND;
long long te_puertas_abiertas;
long long mostrar_info;
int1 puertas_abiertas;
int1 salir;
int1 pb1;
int1 pb2;
int1 pb3;
int pantalla;
long long dias, horas, minutos, segundos;
inicializar (); // Inicializar variables y relays
set_timer0 (0);
setup_counters (RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts (INT_RTCC);
enable_interrupts (GLOBAL);
te_puertas_abiertas = 0;
pantalla = 1;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports (ALL_ANALOG);
#ifdef USAR_WDT
// #define WDT_TIMEOUT 4 // default es de 7 segundos
setup_wdt (WDT_ON);
#endif
#ifdef USAR_LCD
lcd_init (); // Inicializar Display LCD
delay_ms (10);
#endif
#ifdef USAR_SERIAL
printf ("\r\nControl para heladera Bosch KSU-66 disenado, construido y programado por:\r\n");
printf ("Fernan Rodriguez Cespedes - xxxxxxx@xxxxx.com\r\n\r\n");
#endif
// Esta rutina nos avisa si se restarteo el procesador por Watchdog Timer o no
switch ( restart_cause() )
{
case WDT_TIMEOUT:
{
#ifdef USAR_LCD
printf (lcd_putc, "\fError\nRestart por WDT!");
#ifdef USAR_SERIAL
printf("\r\nReinicio por timeout del watchdog!\r\n");
#endif
espera (2);
break;
}
case NORMAL_POWER_UP:
{
#ifdef USAR_LCD
printf (lcd_putc, "\fEncendido\nnormal!");
#endif
#ifdef USAR_SERIAL
printf("\r\nEncendido normal!\r\n");
#endif
break;
}
}
// Si el seteo de descongelar al arrancar esta encendido, hacerlo. Si no, arrancar normalmente.
if (deshielo_arranque == TRUE)
descongelar ();
else
arrancar (); // Segundos antes de arrancar para proteger
// el compresor de un pico de tension si se fue la luz
mostrar_info = seconds - 4;
for (;;)
{
// test ();
#ifdef USAR_WDT
restart_wdt ();
#endif
temperaturas (); // Leer las temperaturas de los termistores NTC
// Seccion del compresor
if (temp_fre >= TEMP_FRE_MAX) // Si la temperatura del freezer es > limite
if (compresor_encendido == FALSE) // Si el compresor esta apagado...
if (seconds - ta_compresor > COMP_MIN_OFF) // Si el periodo de descanso se cumplio, encendemos
cont_compresor (TRUE);
if (compresor_encendido == TRUE) // Si el tiempo de enc compresor > maximo o si la temperatura < maximo, apagamos el compresor
if ((seconds - te_compresor) > COMP_MAX_ON || temp_fre <= TEMP_FRE_MIN)
cont_compresor (FALSE);
if (compresor_encendido == TRUE) // Si el fan esta apagado, la temperatura no va a llegar nunca abajo de los -25 en freezer
if (fan_encendido == FALSE) // asi es que apagamos el compresor
if (temp_ev <= TEMP_MIN_EV && temp_fre <= TEMP_FRE_MIN_NOFAN)
cont_compresor (FALSE);
// Fin seccion compresor
// Seccion ventilador (FAN)
if (fan_encendido == FALSE)
{
if (temp_hel >= temp_max_hel) // Si la temperatura de la heladera es mayor
cont_fan (TRUE); // que el maximo permitido, encendemos el FAN
if (compresor_encendido == TRUE && fan_encendido == FALSE) // Si el compresor esta encendido y el
cont_fan (TRUE); // ventilador esta apagado, prendemos el ventilador
}
if (fan_encendido == TRUE)
if (temp_hel <= temp_min_hel) // Si la temp es menor que el min, y el ciclo minimo se cumplio, lo apagamos
if ((seconds - te_fan) > CICLO_MIN_FAN)
cont_fan (FALSE);
if (fan_encendido == FALSE) // Encender el ventilador por timeout
if ((seconds - ta_fan) > FAN_MAX_OFF)
cont_fan (TRUE);
// Se podria agregar una seccion que cuente cuantos segundos estuvo
// encendido el ventilador. Si prendio demasiado, hay problemas.
// Fin seccion ventilador
// Seccion descongelado
if (t_ultimo_deshielo < T_ULT_DESH_MIN) // Si el tiempo del ultimo deshielo es menor al minimo
if (t_compresor_total > TIEMPO_COMP_MAX) // Si el tiempo total del compresor es mayor que el tiempo maximo, descongelamos
descongelar ();
if (t_ultimo_deshielo > T_ULT_DESH_MIN)
if (t_compresor_total > TIEMPO_COMP_MED)
descongelar ();
if (t_puertas_abiertas > TIEMPO_PUERTAS_AB)
if (t_compresor_total > TIEMPO_COMP_MIN)
descongelar ();
// Fin seccion descongelado
#ifdef USAR_WDT
restart_wdt ();
#endif
// Seccion puertas
puertas_abiertas = leer_puertas ();
if (puertas_abiertas)
{
salir = FALSE;
te_puertas_abiertas = seconds;
cont_fan(FALSE); // Apagamos el ventilador
#ifdef USAR_LCD
printf (lcd_putc, "\fPUERTAS\nABIERTAS");
#endif
#ifdef USAR_SERIAL
printf ("PUERTAS ABIERTAS\n\r");
#endif
while (!salir)
{
if ((seconds - te_puertas_abiertas) > T_MAX_PUER_ABIERTAS)
output_high (BUZZER);
puertas_abiertas = leer_puertas ();
if (puertas_abiertas == FALSE)
{
salir = TRUE;
output_low (BUZZER);
t_puertas_abiertas = t_puertas_abiertas + (seconds - te_puertas_abiertas);
}
#ifdef USAR_WDT
restart_wdt ();
#endif
}
//printf ("Test point 1\r\n");
cont_fan (TRUE); // Hacemos un ciclo de ventilador
mostrar_info = seconds - 4;
}
// Fin seccion puertas
// Seccion botonera (la ultima uffffff!!!! lo que costo llegar hasta aca!!!!)
pb1 = leer_boton (BOTON1); // Leemos los botones de la botonera
pb2 = leer_boton (BOTON2);
pb3 = leer_boton (BOTON3);
// Si presionamos el Push Button 1 (pb1) entonces nos metemos en el modo
// de setear la temperatura. La misma se escribe a EEPROM interna para que
// no se pierda en un reset.
if (pb1)
seteos_varios (); // Ojo que esta es la temp a la que dispara el FAN, descongelado manual y descongelado al arranque
// Si presionamos los otros dos botones, incrementamos o decrementamos la
// variable pantalla, para que el display LCD nos muestre otra info.
// PANTALLA_MAX es el numero maximo de pantallas disponibles
if (pb2) {
--pantalla;
if (pantalla < 1)
pantalla = PANTALLA_MAX;
mostrar_info = seconds - 4; // Hacemos que el display muestre al toque para que parezca responsivo
}
if (pb3) {
++pantalla;
if (pantalla > PANTALLA_MAX)
pantalla = 1;
mostrar_info = seconds - 4;
}
// Fin seccion botonera! Chaaa chaaaaaaannnn!!!!
// Mostramos info nueva solo cada 4 segundos... es una heladera cheee!!!!
if (mostrar_info < seconds - 3)
{
mostrar_info = seconds;
#ifdef USAR_LCD
if (pantalla == 1)
printf (lcd_putc, "\fTemps - H:%f\nE:%f F:%f", temp_hel, temp_ev, temp_fre);
if (pantalla == 2)
printf (lcd_putc, "\fCompresor = %d\nVent = %d", compresor_encendido, fan_encendido);
if (pantalla == 3)
{
segundos = t_ultimo_deshielo;
minutos = segundos / 60;
segundos %= 60;
horas = minutos / 60;
minutos %= 60;
printf (lcd_putc, "\fTiempo ult desh\n%02Lu:%02Lu:%02Lu", horas, minutos, segundos);
}
if (pantalla == 4)
{
segundos = seconds;
minutos = segundos / 60;
segundos %= 60;
horas = minutos / 60;
minutos %= 60;
dias = horas / 24;
horas %= 24;
printf (lcd_putc, "\fTiempo encendido\n%Lu:%02Lu:%02Lu:%02Lu", dias, horas, minutos, segundos);
}
if (pantalla == 5)
{
segundos = t_compresor_total;
minutos = segundos / 60;
segundos %= 60;
horas = minutos / 60;
minutos %= 60;
dias = horas / 24;
horas %= 24;
printf (lcd_putc, "\fTot COMP enc\n%Lu:%02Lu:%02Lu:%02Lu", dias, horas, minutos, segundos);
}
if (pantalla == 6)
{
segundos = t_fan_total;
minutos = segundos / 60;
segundos %= 60;
horas = minutos / 60;
minutos %= 60;
dias = horas / 24;
horas %= 24;
printf (lcd_putc, "\fTot FAN enc\n%Lu:%02Lu:%02Lu:%02Lu", dias, horas, minutos, segundos);
}
if (pantalla == 7)
{
segundos = t_puertas_abiertas;
minutos = segundos / 60;
segundos %= 60;
horas = minutos / 60;
minutos %= 60;
printf (lcd_putc, "\fTotal puertas ab\n%02Lu:%02Lu:%02Lu", horas, minutos, segundos);
}
if (pantalla == 8)
printf (lcd_putc, "\fTemp max %d\nTemp min %d", temp_max_hel, temp_min_hel);
if (pantalla == 9)
{
if (compresor_encendido)
printf (lcd_putc, "\fTiempo enc COMP\n%Lu", seconds - te_compresor);
else
printf (lcd_putc, "\fTiempo apag COM\n%Lu",seconds - ta_compresor);
}
if (pantalla == 10)
{
if (fan_encendido)
printf (lcd_putc, "\fTiempo enc FAN\n%Lu", seconds - te_fan);
else
printf (lcd_putc, "\fTiempo apag FAN\n%Lu", seconds - ta_fan);
}
if (pantalla == 11)
printf (lcd_putc, "\fCant deshielos\n%ld", cant_deshielos);
if (pantalla == 12)
printf (lcd_putc, "\fxxxxxx@\nyahoo.com");
#endif
#ifdef USAR_SERIAL
printf("\n\rUptime: %Lu seconds.\n\r",seconds);
printf ("Temperaturas -> hel:%f ev:%f fre:%f\n\r", temp_hel, temp_ev, temp_fre);
printf ("Comp = %d - Fan = %d\n\r", compresor_encendido, fan_encendido);
printf ("TE comp = %Lu - TA comp = %Lu\n\r", seconds - te_compresor, seconds - ta_compresor);
printf ("TE fan = %Lu - TA fan = %Lu\n\r", seconds - te_fan, seconds - ta_fan);
printf ("T_COMP_TOTAL = %Lu T_FAN_TOTAL = %Lu\n\r", t_compresor_total, t_fan_total);
printf ("Tiempo ultimo deshielo = %Lu\n\r", t_ultimo_deshielo);
printf ("Total puertas abiertas %Lu\n\r", t_puertas_abiertas);
printf ("Pantalla %d - Deshielos = %ld\n\r", pantalla, cant_deshielos);
printf ("temp_max_hel %d temp_min_hel %d\n\r", temp_max_hel, temp_min_hel);
#endif
}
}
}