Autor Tema: Error en placa termostato incubadora  (Leído 2009 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Error en placa termostato incubadora
« en: 11 de Noviembre de 2015, 16:47:27 »
Hola amigos del foro, estoy desarrollando un termostato para incubadora, basado en el ds1820, el tema es que el display que muestra la temperatura parpadea y no se porque, me ayudan?
video:
codigo
Código: [Seleccionar]
#include <16F628A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD 
//#device adc=8//La resolución del módulo A/D es de 8 bits.               
#use delay(int=4000000)
#byte PORTA = 5
char Decena,Unidad,TempBin,AuxBin,var=0,TempSeteo=37,Actualizar=1,TempAnterior=0,MostrarSeteo=0,Seteando=0,i=0;
int8 ValorADC=0;
#include <Display.c>   
//#include <Display_Punto.c>
#include <1wire.c>
#include <1820.c>
#int_TIMER1
Void TIMER1_isr(void)
{
TempBin=ds1820_read();
AuxBin=TempBin%100;//Resto de la division por 100
Decena=AuxBin/10;
Unidad=AuxBin%10;
Mostrar_Numero();
//if(!(bit_test(PORTA,5)))
//{
//set_adc_channel(3);
//delay_us(20);
//ValorADC=read_adc();
//delay_ms(5);
//TempSeteo=(ValorADC/255)*43+37;
//AuxBin=TempSeteo%100;//Resto de la division por 100
//Decena=AuxBin/10;
//Unidad=AuxBin%10;
//}
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
}
void main()
{
  // setup_adc_ports(sAN3|VSS_VDD);
   //setup_adc(ADC_CLOCK_INTERNAL);
   //set_adc_channel(3);
   //delay_ms(5);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   #use delay (clock=4000000)         //Fosc=4Mhz
   set_tris_b(0x00);            //portb como salida
   set_tris_a(0x38);            //porta como Entrada
   enable_interrupts(INT_TIMER1);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8); //
   set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
   enable_interrupts(GLOBAL);   //activadas interrupciones
   while(1){
   Mostrar_Numero();
   }
}
Código: [Seleccionar]
Mostrar_Numero(void)
{
int Tabla7seg[10]={0xEE,0x82,0xDC,0xD6,0xB2,0x76,0x7E,0xC2,0xFE,0xF6};   //7seg hex 0-9
      output_b(Tabla7seg[Unidad]);      //muestra por portb digito 7 segmentos
      output_a(0x01);
      delay_ms(5);   
      output_a(0x00);
     //--------------
      output_b(Tabla7seg[Decena]);      //muestra por portb digito 7 segmentos
      output_a(0x02);
      delay_ms(5);
      output_a(0x00);


      //-----------------
     // output_b(Tabla7seg[Centena]);      //muestra por portb digito 7 segmentos
     // output_a(0x04);
      //delay_ms(15);
      //output_a(0x00);
 
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error en placa termostato incubadora
« Respuesta #1 en: 11 de Noviembre de 2015, 20:35:01 »
En ves de cada ves que entras a la interrupcion mostras todos los numeros, trata de que cada ves que entras a la interrupcion mostrar 1 solo. Eso te va a llevar a una interrupcion mas rapida. Mostras 1, salis, entras y ahora mostras el otro, salis, entras a la interrupcion y comenzs de vuelta.
Solo necesitas calcular de nuevo los valores cuando sea necesario ( suponete cada 100 veces que entra a la interrupcion - digamos cada 0.5s o 1s ). Trata de actualizarlos siempre cuando empeces el ciclo de muestra.

Nunca debes poner delays en la interrupcion, empecemos por ahi. Intenta hacerlo de la forma que te dije arriba. Y no se exactamente cuanto tiempo tiene tu timer pero trata de que sea menos.. que se produzca una interrupcion cada 10/25ms masomenos haciendo lo que dije al comienzo.

Y otra cosa, si tu interrupcion se encarga del display, no lo hagas tambien en el while.
« Última modificación: 11 de Noviembre de 2015, 20:39:00 por KILLERJC »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2979
Re:Error en placa termostato incubadora
« Respuesta #2 en: 11 de Noviembre de 2015, 21:40:33 »
Hola moe, como te ha dicho quita los delay de la interrupción ( y ser posible no los uses nunca una vez entres en el while(1)), deberías tener una tasa de refresco de unos 4ms y estas poniendo dos delay de 5ms osea un retarde de 10ms, además como también te han dicho, quita el refresco del display del while1 porque entonces esos 10ms son prácticamente continuos.

Par verlo bien sin parpadeos debes de refrescar cada 4ms y tienes 10ms, que además cuando se ejecutan con el while y salta la interrupción (si es que salta mientras esta en los delay) se pisan.

Un saludo
Visita mi canal para aprender sobre electrónica y programación:

https://www.youtube.com/channel/UCxOYHcAMLCVEtZEvGgPQ6Vw

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #3 en: 12 de Noviembre de 2015, 10:47:31 »
En ves de cada ves que entras a la interrupcion mostras todos los numeros, trata de que cada ves que entras a la interrupcion mostrar 1 solo. Eso te va a llevar a una interrupcion mas rapida. Mostras 1, salis, entras y ahora mostras el otro, salis, entras a la interrupcion y comenzs de vuelta.
Solo necesitas calcular de nuevo los valores cuando sea necesario ( suponete cada 100 veces que entra a la interrupcion - digamos cada 0.5s o 1s ). Trata de actualizarlos siempre cuando empeces el ciclo de muestra.

Nunca debes poner delays en la interrupcion, empecemos por ahi. Intenta hacerlo de la forma que te dije arriba. Y no se exactamente cuanto tiempo tiene tu timer pero trata de que sea menos.. que se produzca una interrupcion cada 10/25ms masomenos haciendo lo que dije al comienzo.

Y otra cosa, si tu interrupcion se encarga del display, no lo hagas tambien en el while.
Hola Killer, mi interrupcion esta calculada para que se de cada 500 ms, al poner un delay de unos ms en la interrupcion no afectaria ya que esta se da cada 500 ms de todas manera lo voy a sacar. El muestreo lo hago en la interrupcion y en el while porque sino me muestra solo la decena en el display, no es logico lo se pero, pero es asi y no se la razon.
por otro lado si fijo los valores de las decenas y unidades con antelacion, el display las muestra sin parpadeos

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #4 en: 12 de Noviembre de 2015, 10:51:46 »
Hola moe, como te ha dicho quita los delay de la interrupción ( y ser posible no los uses nunca una vez entres en el while(1)), deberías tener una tasa de refresco de unos 4ms y estas poniendo dos delay de 5ms osea un retarde de 10ms, además como también te han dicho, quita el refresco del display del while1 porque entonces esos 10ms son prácticamente continuos.

Par verlo bien sin parpadeos debes de refrescar cada 4ms y tienes 10ms, que además cuando se ejecutan con el while y salta la interrupción (si es que salta mientras esta en los delay) se pisan.

Un saludo
gracias por responder, le voy a sacar la rutina de muestreo de la interrupcion, el tema no es que se vea con parpadeo es que se apaga periodicamente el display, con el codigo que paso a continuacion solo muestra las decenas y se apaga periodicamente
Código: [Seleccionar]
#include <16F628A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD 
//#device adc=8//La resolución del módulo A/D es de 8 bits.               
#use delay(int=4000000)
#byte PORTA = 5
char Decena,Unidad,TempBin,AuxBin,var=0,TempSeteo=37,Actualizar=1,TempAnterior=0,MostrarSeteo=0,Seteando=0,i=0;
int8 ValorADC=0;
#include <Display.c>   
//#include <Display_Punto.c>
#include <1wire.c>
#include <1820.c>
#int_TIMER1
Void TIMER1_isr(void)
{
TempBin=ds1820_read();
AuxBin=TempBin%100;//Resto de la division por 100
Decena=AuxBin/10;
Unidad=AuxBin%10;
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
}
void main()
{
  // setup_adc_ports(sAN3|VSS_VDD);
   //setup_adc(ADC_CLOCK_INTERNAL);
   //set_adc_channel(3);
   //delay_ms(5);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   #use delay (clock=4000000)         //Fosc=4Mhz
   set_tris_b(0x00);            //portb como salida
   set_tris_a(0x38);            //porta como Entrada
   enable_interrupts(INT_TIMER1);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8); //
   set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
   enable_interrupts(GLOBAL);   //activadas interrupciones
   while(1){
   Mostrar_Numero();
   }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error en placa termostato incubadora
« Respuesta #5 en: 12 de Noviembre de 2015, 11:00:20 »
Citar
Hola Killer, mi interrupcion esta calculada para que se de cada 500 ms, al poner un delay de unos ms en la interrupcion no afectaria ya que esta se da cada 500 ms de todas manera lo voy a sacar. El muestreo lo hago en la interrupcion y en el while porque sino me muestra solo la decena en el display, no es logico lo se pero, pero es asi y no se la razon.
por otro lado si fijo los valores de las decenas y unidades con antelacion, el display las muestra sin parpadeos

Si afecta... totalmente, primero por que no tiene sentido alguno que tengas 500ms y muestres cada 500ms !, segundo.. el delay dentro si afecta, haciendo que funcione no a 500ms sino a 515ms + tiempo de las instrucciones, mientras estas en la interrupcion estan desactivadas las interrupciones asi que debes salir lo mas rapido posible!.

Como te decia yo tenes una interrupcion rapida, y solo calculas los valores cada 0.5s tal cual vos queres.

Citar
gracias por responder, le voy a sacar la rutina de muestreo de la interrupcion, el tema no es que se vea con parpadeo es que se apaga periodicamente el display, con el codigo que paso a continuacion solo muestra las decenas y se apaga periodicamente

Es culpa de tu interrupcion...

Código: C
  1. TempBin=ds1820_read();
  2. AuxBin=TempBin%100;//Resto de la division por 100
  3. Decena=AuxBin/10;
  4. Unidad=AuxBin%10;
  5. set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR

seguro que ds1820_read() es super lento... hasta seguro que tiene un while dentro.
El calculo por la cantidad que  es, creo que esto seria mas corto (habria que probarlo exactamente cual es mas rapido):

Código: C
  1. while( TempBin>100 ) TempBin-=100;
  2. while( TempBin>10) TempBin-=10; Decena++
  3. Unidad = TempBin

el set_timer1() iria al comienzo del codigo.
Tu problema esta en tu rutina de lectura del ds1820

Si pasas el codigo vamos a ver el error, sino ya sabes que es eso, y que debes quitarlo de ahi.
« Última modificación: 12 de Noviembre de 2015, 11:11:33 por KILLERJC »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #6 en: 12 de Noviembre de 2015, 12:43:45 »
Difinitivamente es la lectura del ds1820 la que esta tardando, porque si le pongo valores fijas a las unidades y decenas, estas se muestran sin problema este es el codigo
Código: [Seleccionar]
float ds1820_read()
{
 int8 busy=0, temp1, temp2;
 signed int16 temp3;
 float result;

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0x44);

 while (busy == 0)
 busy = onewire_read();

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0xBE);
 temp1 = onewire_read();
 temp2 = onewire_read();
 temp3 = make16(temp2, temp1);
 
 result = (float) temp3 / 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution
 
 delay_ms(25);
 return(result);
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error en placa termostato incubadora
« Respuesta #7 en: 12 de Noviembre de 2015, 13:19:37 »
Quitalo y ponelo en el while a eso.

Eso si, podes llegar a tener problemas si la interrupcion sucede en un momento en el que se este asignando el valor result a TempBin. No creo que suceda pero deberias tenerlo en cuenta.

Por lo de mostrar los display en la interrupcion, ya te dije cual es el problema y como solucionarlo.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #8 en: 12 de Noviembre de 2015, 16:29:57 »
Lo puse en el while y sige haciendo lo mismo para solucionarlo de una manera aceptable le saque el while a la rutina de lectura del ds1820, ahora casi no se nota el parpadeo, me parece que lo voy a dejar asi, igual me falta la parte de seteo de temperatura

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error en placa termostato incubadora
« Respuesta #9 en: 12 de Noviembre de 2015, 16:51:16 »
No deberias sacarlo, ya que justamente tenes que esperar hasta que el ds1820 se libere/termine de realizar lo que sea que este haciendo. Pero bueno.
Es tu decision que hacer. Con lo dicho por juanjo y por mi deberias ya poder armarlo sin errores, y funcionando bien.


Lo unico que vas a lograr es que si agregas un poco mas de codigo en el main tus problemas sigan.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #10 en: 13 de Noviembre de 2015, 18:32:43 »
El tema es que mientras se este ejecutando la rutina del ds1820 con el while el refresco no se va a hacer, por eso se apaga el display, cual seria la forma de evitar eso¿? La verdad ya hice todo lo que me han dicho, por eso recurri es ese metodo pero a lo mejor no estoy viendo algo
Código: [Seleccionar]
#include <16F88.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD 
//#device adc=8//La resolución del módulo A/D es de 8 bits.               
#use delay(int=4000000)
#byte PORTA = 5
char Decena=0,Unidad=0,TempBin,AuxBin,TempSeteo=37;
int8 ValorADC=0;
#include <Display.c>   
#include <1wire.c>
#include <1820.c>
#int_TIMER1
Void TIMER1_isr(void)
{
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
if((bit_test(PORTA,3)))TempBin=ds1820_read();
else TempBin=TempSeteo;
if(!(bit_test(PORTA,5)))
   {
   TempSeteo=TempSeteo+1;
   if(TempSeteo==86)TempSeteo=30;
   }
if(!(bit_test(PORTA,6)))
   {
   TempSeteo=TempSeteo-1;
   if(TempSeteo==29)TempSeteo=85;
   }
AuxBin=TempBin%100;//Resto de la division por 100
Decena=AuxBin/10;
Unidad=AuxBin%10;
}
void main()
{
   setup_comparator(NC_NC_NC_NC);
   #use delay (clock=4000000)         //Fosc=4Mhz
   set_tris_b(0x00);            //portb como salida
   set_tris_a(0x38);            //porta como Entrada
   enable_interrupts(INT_TIMER1);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_4); //
   set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
   enable_interrupts(GLOBAL);   //activadas interrupciones
   while(1){
   Mostrar_Numero();
   }
}
cual es el error en este codigo que no me permite dejarle el while a la rutina del ds1820?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error en placa termostato incubadora
« Respuesta #11 en: 13 de Noviembre de 2015, 20:59:04 »
El while debe estar por algo.
EL tema es que el while podes pensarlo como algo que tarda tiempo. Ahora supone que vos ademas de la lectura del ds empezas a meter codigo ahi dentro por que tenes que hacer algo...  Eso tendria el mismo efecto que tu while.

Citar
El tema es que mientras se este ejecutando la rutina del ds1820 con el while el refresco no se va a hacer, por eso se apaga el display, cual seria la forma de evitar eso¿?

Te quoteo mi respuesta:

En ves de cada ves que entras a la interrupcion mostras todos los numeros, trata de que cada ves que entras a la interrupcion mostrar 1 solo. Eso te va a llevar a una interrupcion mas rapida. Mostras 1, salis, entras y ahora mostras el otro, salis, entras a la interrupcion y comenzs de vuelta.
Solo necesitas calcular de nuevo los valores cuando sea necesario ( suponete cada 100 veces que entra a la interrupcion - digamos cada 0.5s o 1s ). Trata de actualizarlos siempre cuando empeces el ciclo de muestra.

Nunca debes poner delays en la interrupcion, empecemos por ahi. Intenta hacerlo de la forma que te dije arriba. Y no se exactamente cuanto tiempo tiene tu timer pero trata de que sea menos.. que se produzca una interrupcion cada 10/25ms masomenos haciendo lo que dije al comienzo.

Y otra cosa, si tu interrupcion se encarga del display, no lo hagas tambien en el while.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #12 en: 14 de Noviembre de 2015, 11:39:49 »
El procedimiento de multiplexado lo hago en el main y se realiza permanentemente, solo es interrumpido por la interrupcion que lee el ds 1820 cada 500ms y actualiza el valor a mostrar

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Error en placa termostato incubadora
« Respuesta #13 en: 14 de Noviembre de 2015, 13:51:43 »
Ya te respondi el por que no. Es mas actualmente tu interrupcion del timer tiene poco sentido (como para hacerlo como interrupcion ya que no es 500ms exacto o proximo).

Vos pediste una solucion, yo te di una solucion en el cual el programa o lo que sea no va a afectar en el multiplexado de los displays, los cuales se van a actualizar a un ratio constante siempre, vos no lo queres hacer entonces no tengo mas nada para decir. Si estas feliz como funciona el programa adelante.
« Última modificación: 14 de Noviembre de 2015, 14:03:25 por KILLERJC »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:Error en placa termostato incubadora
« Respuesta #14 en: 14 de Noviembre de 2015, 17:38:42 »
Te agradezco mucho las respuestas, vamos a ver que sale, gracias de nuevo, tema cerrado


 

anything