martes, 8 de noviembre de 2011

Control de Temperatura por PWM usando PIC (Pic C CCS)


Control de Temperatura por PWM usando PIC (Pic C CCS) con protección contra cortocircuito.


Imagen del circuito





Imagen de Muestra del Circuito de Control y Potencia en Proto




Parto de dos sencillas ideas:

  1. Un MOSFET permite la coducción de corriente de Source a Drain en proporción directa al voltaje existente en la base, por tanto se dice que el MOSFET es un dispositivo controlado por voltaje a diferencia del BJT que es controlado por corriente. (MOSFET)
  2. Un microcontrolador puede ser programado para mandar una señal PWM a frecuencia y DutyCicle variables. Si sabemos que podemos variar el voltaje promedio de esa señal PWM a la salida del microcontrolador (de 0v a 5v), amplificando esa señal y mandándola a la base de un MOSFET lograríamos controlar en cierto rango controlar la corriente que pasa de Source a Drain en el mismo.
Con las dos ideas anteriores podemos partir para hacer un controlador de corriente, pero para hacer esto un poco más práctico, si hacemos pasar esta corriente controlada por una resistencia de carga haríamos que esta se calentara, logrando ahora un control de la temperatura de la resistencia al variar la corriente que pasa a través de esta.

Bien, para que todo esto funcione, dividiré el desarrollo del proyecto en dos etapas:

  1. Etapa de control
  2. Etapa de Potencia (se incluye la protección contra cortos)




Etapa de Control

Material:
  • 4 potenciometros de 1kohm
  • 2 leds
  • 3 resistencias 330 ohms
  • 1 pic16f887
  • 1 pantalla lcd (JHD 162A)
  • 1 LM35 (sensor de Temperatura de Precisión)


Usando un microcontrolador PIC 16f887 lograremos hacer un control del DutyCicle del PWM conforme a la temperatura. Conforme la temperatura aumenta el DutyCicle del PWM disminuirá de tal forma que cuando la resistencia llegue a la temperatura deseada el DutyCicle será 0% por tanto la corriente que pasará a través de la resistencia será 0A haciendo que la temperatura se mantenga estable en ese punto, hasta que esta se enfríe y la señal PWM vuelva a polarizar el MOSFET.

He aquí el esquemático:

IMG1: Control de Temperatura, Etapa de Control

Como se muestra en la imagen IMG1 pueden armar el circuito de control de temperatura y simularlo en Isis Proteus descargando los archivos de DESCARGA1

Al momento de simularlo pueden:

  1. Variar la frecuencia de la señal PWM por medio del potenciómetro conectado a RA0.
  2. Variar la Temperatura por medio del sensor LM35 y ver como el DutyCicle del PWM disminuye conforme la temperatura se acerca al SetPoint (Temperatura deseada)
  3. Variar el SetPoint de 0ºC a 150ºC por medio del potenciómetro conectado a RA1.
IMG2: Muestra de la Simulación en Proteus


Codificación en C (Pic C de CCS):
Pantalla muestra del Codigo en PIC C de CCS PCWHD




/*
Hazael Fernando Mojica García
Carlos Alfredo Alanis González
Adriana Rodríguez Liñán
San Nicolás de los Garza 3/Nov/2011
*/

/*
Programa de Control de Temperatura con un PIC
Permite variar el DutyCicle y Frecuencia de una señal PWM
que controla la corriente que recibe una resistencia de carga

La Temperatura a la que llega dicha resistencia se puede variar de 0 a 150ºC (SetPoint)
La frecuencia del PWM va de 0Hz a 1KHz (Teoricamente ya que practicamente nunca baja de 477Hz)

INFO:
El comportamiento es simple, por medio del sensor LM35 se procede a medir la temperatura
si esta no ha llegado aún a la temperatura deseada (SetPoint) manda un PWM con un DutyCicle
proporcional a la diferencia entre la temperatura medida y la deseada, si la diferencia es grande
el DutyCicle tambíen lo será y viceversa
Al llegar a la teperatura deseada el Control la mantiene.

El circuito está diseñado sólo para calentar no para enfriar por tanto
si se elige un SetPoint abajo de temperatura ambiente, el DutyCicle siempre
permanecerá en 0%.

*/


#include <16f887.h>                   //Nuestro pic
#device adc = 10                       //Convertidor AD a 10bits
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay (clock=8000000)            //Fosc=8Mhz
#include <lcd.c>                      //Libreria de la lcd

//Declaracion de variables publicas
float TOC;
float Prescaler;


//Prototipos de Funciones
void Refresh_lcd(float _Frecuencia_, float _DutyCicle_, float _SP_, float _Temperatura_);
float Get_Lectura(int channel);
float Relacion_LineaRecta_m(float m, float valorEjeIndep);
float Calcula_PR2(float _Frecuencia);
void Refresh_PWM_Duty(float _DCValue);
void Refresh_PWM_Frec(float _Period2);
float Calcula_Value_DC(float _SP_, float _Temp_);
float CalculaPendiente (float Xmin, float Ymin, float Xmax, float Ymax);


void main()
{
   //int i = 0;

   float Value_DC = 0.0;
   float bits_frecuencia = 0.0;
   float bits_temperatura = 0.0;
   float bits_setPoint = 0.0;
   float bits_dutyCicle = 0.0;
   float SetPoint = 150.0;         //Valor que se desea de Temperatura
   float DutyCicle = 0.0;
   float Frecuencia = 0.0;
   float Temperatura = 0.0;
   float mFrec = 0.977517106;       //Pendiente de la recta para Frecuencia m = (1000 - 0)/(1023 - 0)
   float mT = 0.65625;                  //Pendiente de la temperatura m = ( 21 - 0 ) / ( 32 - 0 )
   float mVDC = 0.0;                 
   //float mDC = 0.000977517065;      //Pendiente de la recta para DutCicle m = (1 - 0)/(1023 - 0)
   float mDC = 0.392156862;         //Pendiente de la recta para DutCicle m = (100 - 0)/(255 - 0)
   float mSP = 0.146627566;         //Pendiente de la recta para SetPoint m = (150 - 0)/(1023 - 0)
  
  

   float Period2 = 0.0;
   float PWMValue = 0.0;
   float Period2_ = 0.0;      //Valor de Period2 inmediato anterior
   float PWMValue_ = 0.0;     //Valor de PWMValue inmediato anterior

   TOC = 0.000000125;                     // TOC = 1 / clock = 1 / 8000000
   Prescaler = 16.0;

   //Programar el oscilador interno del pic y usar CCP afecta al PWM
   //setup_oscillator(OSC_8MHZ|OSC_INTRC);   //Programamos oscilador interno del Pic a 8MHZ
   //setup_oscillator(OSC_8MHZ);
   set_tris_b(0);                            //Puerto B como salida
   output_low(PIN_C2);                       // Set CCP1 output low
   setup_ccp1(CCP_PWM);                      // Configure CCP1 as a PWM
   lcd_init();                               //Inicializamos LCD
   lcd_putc("Iniciando...");                //"Hola Mundo"
                      
  
   //Frecuencia del PWM
   setup_timer_2(T2_DIV_BY_16, 249, 1);  // 500 Hz
   set_pwm1_duty(500);
  
  
   delay_ms(5);
  
   while(1)
   {
  
      output_toggle(PIN_B5);              //Parpadeamos Led, output_toggle cambia el estado logico del pin pasado de parametro
    
      //Obtenemos las lecturas del convertidor A/D para cada parametro de entrada (frecuencia, temperatura y setPoint)
      bits_frecuencia = Get_Lectura(0);
      bits_temperatura = Get_Lectura(1);
      bits_setPoint = Get_Lectura(4);
    
      //Obtenemos el valor del eje dependienta pasando el valor del eje independiente (bits) y el valor de la pendiente
      Frecuencia = Relacion_LineaRecta_m(mFrec, bits_frecuencia);
      SetPoint = Relacion_Linearecta_m(mSP, bits_setPoint);
      Temperatura = Relacion_Linearecta_m(mT, bits_temperatura);
    
      //Calculamos el valor del DC
      Value_DC = Calcula_Value_DC(SetPoint, Temperatura);
    
      mVDC = CalculaPendiente(0, 0, SetPoint, 255);//Calculamos la pendiente
    
      bits_dutyCicle = Relacion_Linearecta_m(mVDC, Value_DC);
    
      DutyCicle = Relacion_Linearecta_m(mDC, bits_dutyCicle);

      PWMValue = bits_dutyCicle;
  
      Period2 = Calcula_PR2(Frecuencia);

    
    
      if(PWMValue != PWMValue_)
         {Refresh_PWM_Duty(PWMValue);}
        
      if(Period2 != Period2_)
         {Refresh_PWM_Frec(Period2);}
    
      Refresh_lcd(Frecuencia, DutyCicle, SetPoint, Temperatura);

      PWMValue_ = PWMValue;
      Period2_ = Period2;
    
      delay_ms(10);                     //Esperamos a lo sonso 250 ms
   }
}

//Metodo que calcula y regresa la pendiente para una recta que posee los puntos
//(Xmax,Ymax) y (Xmin,Ymin)
float CalculaPendiente (float Xmin, float Ymin, float Xmax, float Ymax)
{
   float m = 0.0;
   float num = 0.0;
   float den = 0.0;
    
   num = Ymax - Ymin;
   den = Xmax - Xmin;
  
   m = num / den;

   return m;
}


//Metodo que calcula el valor del DutyCicle que se enviará
//No es más que la diferencia entre el valor de temperatura que
//se desea (SetPoint _SP_) y el valor de temperatura actual (_Temp_)
float Calcula_Value_DC(float _SP_, float _Temp_)
{
   float Value_DC = 0.0;
   Value_DC = _SP_ - _Temp_;
  
   if(Value_DC < 0)
   { Value_DC = 0; }

   return Value_DC;
}

//Asigna un nuevo valor de DutyCicle al PWM usado
void Refresh_PWM_Duty(float _DCValue)
{
   set_pwm1_duty((int)_DCValue);
}

//Asigna un nuevo valor de frecuencia al PWM
void Refresh_PWM_Frec(float _Period2)
{
   setup_timer_2(T2_DIV_BY_16, _Period2, 1);
}


//Calcula el valor del Periodo(PR2) para la frecuencia
//pasada de parametro
float Calcula_PR2(float _Frecuencia)
{
   float _PR2 = 0.0;
   float div = 0.0;
  
   div = _Frecuencia * 4 * TOC * Prescaler;
   _PR2 = (1 / div) - 1;
  
   if(_PR2 < 0.0)
     { _PR2 = 0.0;}

   return _PR2;
}

//Metodo que regresa el valor del eje dependiente para un valor
//del eje independiente (valorEjeIndep) de una recta de pendiente m
//que pasa por el origen
float Relacion_LineaRecta_m(float m, float valorEjeIndep)
{
   float Valor = 0.0;
   Valor = (m * valorEjeIndep);        //Calculamos el Valor del eje dependiente
   return Valor;
}

//Obitiene una lectura del canal analógico pasado de parámetro
float Get_Lectura(int channel)
{
   float medicion=0;                     //variable entera que contendra la medicion del convertidor AD
   int1 done = 0;                        //Contendra 1 si el convertidor terminó de convertir
  
   setup_adc (adc_clock_internal);     //Usando el oscilador interno
   setup_adc_ports (all_analog);       //Todo el puerto analogico como entrada analogica   
   set_adc_channel (channel);          //Establecemos el canal de lectura analogica
   delay_ms(1);                       //a small delay is required after setting the channel
   medicion=read_adc ();               // Hace conversión AD
   done = adc_done();                  //done = 1 si el convertidor termino de convertir
   while(!done)
   {
      done = adc_done();               //Mientras no acabe de convertir se seguira ciclando
   }
   setup_adc (adc_off);                //detenemos al convertidor
   return medicion;                    //Regresamos la medicion
}


//Reasigana los valores en la pantalla lcd
void Refresh_lcd(float _Frecuencia_, float _DutyCicle_, float _SP_, float _Temperatura_)
{
   lcd_putc("\f");
   printf(lcd_putc,"F:%4.1f DC:%4.1f", _Frecuencia_,_DutyCicle_);
   lcd_putc("%");
   lcd_putc("\n");
   printf(lcd_putc,"SP:%4.1f T:%4.1f", _SP_, _Temperatura_);
}






Descarga2: Codigo en C para PIC C de CCS




Con respecto a la codificación cabe aclarar ciertas cosas:

  1. Se dejan comentadas ciertas lineas de codigo que no se usaron al final debido a que causaban errores o no era conveniente usarlas, esto por si alguien que desea modificar el código no cometa el mismo error.
    1. Oscilador Interno: Aún no estoy muy seguro del porque, pero la linea: //setup_oscillator(OSC_8MHZ|OSC_INTRC);   //Programamos oscilador interno del Pic a 8MHZ Me ocasionó que el PWM se saliera de control y actuara como loco.
  2. Se necesitan hacer calibraciones en la variable mT (linea 67) del programa de acuerdo a tu circuito y dispositivos (esta variable representa la pendiente que se forma en la recta Temperatura vs Bits del ADC), es sencillo, sigue estos pasos:
    1. Una vez tengas el circuito armado, cambia la linea 135 de codigo en el programa:
      1. Refresh_lcd(Frecuencia, DutyCicle, SetPoint, Temperatura);
      2. por: Refresh_lcd(Frecuencia, DutyCicle, SetPoint, bits_temperatura);
    2. Compila y programa el PIC
    3. Conectalo a VCC (5v) y ponlo a funcionar.
    4. Veras que en la pantalla LCD se mostrarán ahora los bits que arroja el convertidor analógico digital, si estas a Temperatura ambiente normalmente no pasan de 45 bits (si pasa de 45 es porque estas a una temperatura mayor no que este mal ok!!!). T: 45 como se ve en la simulación en ISIS IMG3. A este valor le llamaremos bits_Temperatura
    5. Mide el voltaje (con un Voltímetro) que te entrega el LM35 y deduce la temperatura a la que te encuentras. Ejemplo: si dice 0.021V están a 21ºC, si dice 0.035V estan a 35ºC que calor!!!!. A este valor le llamaremos Temperatura
    6. Haz la división sencilla de de Temperatura entre bits_Temperatura: Temperatura / bits_Temperatura.
    7. Coloca el valor de esa división en la linea correspondiente (linea 66), así: float mT = Valor_Division;
      1. Ejemplo: Para Temperatura = 21ºC y bits_Temperatura = 32, Valor_División = Temperatura / bits_Temperatura = 0.65625, por tanto la linea 65 es : float mT = 0.65625;
    8. Regresas la linea 135 a su valor original, compilas y Voila!!!!, ya tienes tu etapa de control lista.

IMG3: Calibrando el sensor de Temperatura
Si no tienes PIC C de CCS puedes descargarlo de aqui:
DESCARGA3: PIC C CCS






Etapa de Potencia

Como he explicado anteriormente esta etapa de potencia es muy sencilla, tomamos un MOSFET, sabemos que el MOSFET es un dispositivo controlado por voltaje, es decir, la corriente que pase de Source a Drain será proporcional al voltaje aplicado al Gate del mismo, sabiendo que el voltaje promedio que entrega un PWM depende de su DutyCicle donde un DutyCicle de 0% es 0V y uno de 100% es igual al voltaje por el cual es generado entonces podemos controlar la corriente. Esto lo hace fabuloso para poder usar un microcontrolador o algún otro dispositivo digital para generar y manipular esta señal y dado que el Gate del MOSFET está aislado físicamente del Source y Drain no tendremos que preocuparnos por aislar lo demás.


Hablando un poco sobre la Etapa de Potencia y la protección contra cortocircuito:




MATERIAL:



  • 2 resistencias 5Kohm
  • 1 interruptor (push button)
  • 1 relevador 
  • 1 transistor 2n3904 (o uno de mayor potencia, nosotros usamos un MOSFET IRF640)
  • 1 MOSFET IRFZ44
  • 1 Transformador 120V - 24V de 2Amperes
  • 2 Amplificadores Operacionales LM741
  • Puente de diodos de 4Amper
  • Una resistencia de Parrilla eléctrica, o regadera eléctrica (corta un pedazo de aprox unos 10cm y soldale cables para la protoboard)



IMG4: Diagrama de Protección contra Corto (el voltaje de alimentación
puede ser cualquier valor, siempre que los componentes lo permitan
se ejemplifica con 12V, para este proyecto se usan 24V) 


IMG5: Esquemático completo de la Etapa de Potencia con Protección contra Cortocircuitos
IMG7: Rectificación de Corriente Alterna

IMG8: Etapa de Potencia sin Proteccion contra Cortocircuitos


En la imagen IMG5 se aprecia la etapa de potencia completa, estamos emulando el voltaje promedio entregado por el PWM por medio del potenciómetro arriba a la derecha, este varía de 0 a 5v y es incrementado hasta 24v por medio de los amplificadores operacionales que no hacen otra cosa que llevarlo a saturación, si observamos con atención la salida de estos va directo al gate del MOSFET de Potencia IRFZ44, si no se requiere la protección contra cortocircuitos pueden quitarla y conectar el source del IRFZ44 directo a la salida del lado positivo del capacitor rectificador, después de los diodos tal como muestra la imagen IMG8.

Funcionamiento:

Como se puede observar en la figura, los 12V están conectados a la bobina del relevador y esta línea continua hacia el colector del transistor. La salida de nuestro circuito deberá de estar conectada al polo de nuestro relevador normalmente abierto. Así en un principio cuando no está polarizado nuestro transistor a la salida tendremos 0V.

Una vez que se presiona el push button el transistor se polariza, cerrando el circuito y la bobina del relevador se magnetizará, conmutando hacia el polo normalmente abierto, por lo cual ahora tendremos un voltaje a la salida de nuestro circuito.

Al tener un voltaje en la salida este se realimenta hacia la base del transistor manteniéndolo polarizado, por lo tanto no es necesario mantener presionado el push button.

Es importante aclarar que la protección contra cortocircuito solo se realiza después del relevador. Recordando que un cortocircuito sucede en el momento en que se cierra un circuito sin ninguna resistencia de por medio, es decir conectar la salida de nuestro circuito directamente a tierra. Observando la ley de Ohm:

I = V / R

Si la resistencia es igual a 0Ω, la corriente se dispararía hacia infinito.

En el momento que esto sucede, conectar la salida directamente a tierra, la base de nuestro transistor detecta 0V, por lo tanto se despolariza abriendo nuevamente el circuito e impidiendo que la bobina del relevador continúe magnetizada, regresando el polo a normalmente cerrada.

IMG: Implementando el circuito








Circuito Completo


Combinando ambas etapas obtenemos el circuito completo:


Esquemático del Circuito Completo

40 comentarios:

  1. Excelente trabaajo men sigue asi (Y)

    ResponderEliminar
  2. Cual es la etapa de potencia en este proyecto o mas bien en que consiste ??

    ResponderEliminar
  3. Tengo un problema con la pantalla, realice el mismo procedimiento que tu, grabe el programa al pic, solo que lo cambie por el 16f877a, que tiene la misma configuracion que el que tu utilizas, pero al realizarlo en el protoboard muestra la primera mitad de la pantalla.Cambie la pantalla por otras del mismo tipo creyendo que ese era el problema y np sucedio nada.
    Quizas puede ser que no tiene el cristal de cuarso adecuado,o como decias tu que se debia realizar un cambio al programa, que no supe hacerlo.
    Ojalas que puedas guiarme por si tienes alguna idea.
    Gracias.

    ResponderEliminar
    Respuestas
    1. Por lo del cristal, no estoy seguro, ya que en este proyecto uso el oscilador RC interno del PIC.

      Aqui: http://hzsquare.blogspot.fr/2011/10/hola-mundo-con-pic16f887-y-lcd-jhd-162a.html

      Un tipo definio algunas contantes extras para poder hacer un cambio de PIC

      Eliminar
  4. Buenas, enhorabuena por el blog en primer lugar. Estoy realizando tu proyecto y tengo unas dudas. En la etapa de control, en lista de materiales aparecen algunos elementos que no encuentro en ISIS...
    -4 Potenciometros??? Por lo que veo solo necesitamos 3 no??
    -3 Resistencias de 330 ohms, para donde?potenciomentrOs?(En ISIS no aparecen en ningun lado)
    -2 leds? tambien me sobra uno...

    Muchas gracias por compartir esta información y creo que volveremos a hablar...jejeje
    Un saludo!!!

    ResponderEliminar
    Respuestas
    1. Tienes mucha razon amigo Anónimo, sólo se necesitan 3 Potenciometros, 2 resistencias 330ohms y un led.

      Una de las resistencias van en serie con el led que sale del PIC para absorber la corriente de sobra (se me olvido simularla en ISIS).
      La otra, me parece que la use para el MCLR (Master Clear o Master Reset) del PIC y para programarlo por ICSP, circuito que no pude simular en ISIS(programacion del micro me refiero).

      Jaja,, no sé de donde salio ese cuarto potenciometro.
      Después modificaré la entrada.

      Muchas gracias por los comentarios.

      Eliminar
    2. Gracias a ti por responder y compartir la información. Seguramente tendrás noticias mías ya que me voy a poner a construirlo. Tenia ganas de montar algo asi y me será muy útil. He pedido el mismo PIC que pussite en la lista, espero no tener problemas con él, ya que programar no es lo mio.
      un saludo

      Eliminar
  5. Hola amigoo esta genial tu proyecto... yo estoy haciendo algo parecido para mi proyecto de grado de la universidad.. tu codigo lo entiendo muy bien.. lo que no entiendo es la parte de los calculos.
    Para que usas bit de temperatura, frecuencia, setpoint y duty cycle?
    y si porfavor te dieras el tiempo de explicarme la parte de las pendientes que no la entendi muy bien como por ejemplo esa de 21 ºC y 32 bits.. donde sacas esos valores?

    Un saludo desde MI PERU..

    ResponderEliminar
  6. Salut Anonimo!

    Las variables bits_x (como bits_temperatura)
    son los valores en bits (10 bits, numero entero de 0 a 1023)
    Puedes observar en esta parte como obtiene las lecturas del ADC:
    bits_frecuencia = Get_Lectura(0);
    bits_temperatura = Get_Lectura(1);
    bits_setPoint = Get_Lectura(4);
    (NOTA: no se que tenía en la cabeza cuando programé eso que los metí en float, con int es mas que suficiente)

    Por tanto:

    *bits_frecuencia: contiene el valor del ADC conectado al potenciometro pot_frecuencia (ajustas la frecuencia a la que deseas trabajar el PWM, no cambia en nada visible el funcionamiento pero era parte de mi proyecto poder variar la frecuencia!)

    *bits_temperatura: contiene el valor del ADC conectado al LM35.

    *bits_SetPoint: contiene el valor del ADC conectado al potenciometro pot_setpoint. El set point es la temperatura deseada, la puedes ajustar de 0 a 150 ºC (Obviamente no podrás enfriar la resistencia, lo más que podrás bajar la temperatura es a temperatura ambiente)


    Si vez bien, en esta parte se obtienen lo valores reales de la temperatura, frecuencia, y setpoint:
    Frecuencia = Relacion_LineaRecta_m(mFrec, bits_frecuencia);
    SetPoint = Relacion_Linearecta_m(mSP, bits_setPoint);
    Temperatura = Relacion_Linearecta_m(mT, bits_temperatura);

    NOTA: La relación linea recta es la mas sencilla. Es decir estamos suponiendo que un valor dado de bits (dados por el potenciometro/LM35 y el ADC) es directamente proporcional al valor deseado en temperatura, frecuenciay SetPoint (temperatura deseada en la resistencia). SI GRAFICAMOS ESO OBTENEMOS UNA LINEA RECTA QUE EN EL MEJOR DE LOS CASOS PASA POR 0, SIMPLIFICANDO AUN MAS TODO. DE ALLI SU NOMBRE.
    NOTA: Si los potenciometros usados son lineales esto quedaría de pelos, pero los mas baratos son logaritmicos, con lo que ese calculo no resulta muy exacto pero nos sirve bien.

    Las pendientes de las rectas (mT, mFrec...) fueron obtenidas de manera experimental, dígase a prueba y error e interpolando.

    Lo que trato de decir que 21ºC = 32bits es que a 21º de temperatura obtengo 32bits en el ADC. Una lectura experimental con voltímetro en mano, termómetro y viendo los bits obtenidos. SIP, estabamos a 21º en el laboratorio ese día!!!

    Espero responder tus dudas, gracias por comentar amigo anonimo peruano.

    Saludos Mexico y Peru desde la Francia.
    À bientôt!

    ResponderEliminar
  7. Señor el transformador que aparece en el circuito de potencia de cuanto es??

    ResponderEliminar
  8. Brother muy buenas tardes..soy aprendiz del lenguaje c y tu proyecto me esta ayudando mucho para entender el funcionamiento de un programa..solo tengo una duda..al compilar el programa q muestras me resulta un archivo .HEX diferente al otro q muestras..nose si estare compilando mal o a q se debe ya q al mandarle eso al pic, este se vuelve loco y no me lee los valores de potenciometro bien..sino me da valores grandisimos...te agradeceria mucho si me puedieras ayudar. Gracias
    Saludos

    ResponderEliminar
    Respuestas
    1. Este proyecto es algo complicado en sí, intenta mas sencillo para que puedas ver si tienes algun error, como este:

      http://hzsquare.blogspot.fr/2011/10/convertidor-ad-con-pic16f887-y-lcd-jhd.html

      Lo mas seguro es que haya algo mal conectado en la proto, se que el codigo es funcional :D

      Solo no desesperes, intentando un poco diario y con una buena dosis de café todo es posible

      Eliminar
    2. Gracias por tu respuesta capo, y por el link,lo q sucede es q lo estoy simulando igual q tú en el isis.

      Estoy usando el pic 16F877A y gracias a tu aporte he notado q la configuración de entradas analógicas para el 887A y el 887 son parecidas ya q en tu aporte funcionan perfectamente,y por un momento pense q esa era mi problema.

      Lo q he notado ahora esq al mostrar en el lcd los "bits_x" estos me muestran esa falla,por lo q asumo q desde ahi viene el problema, lo q sucede es q al variar cualqier entrada sea set point o temperatura , el lcd me muestra numeros q no estan en progresion tipo 84016.0 -> 0.3 -> 84724941 -> -16106 ...etc

      Espero me puedas ayudar, la unica variacion q le hcie a tu programa original fue la del cambio del pic por un 16F877A, espero me puedas responder capo.

      Gracias, y e café esta siendo de mucha ayuda :)

      Eliminar
    3. Ese tipo de errores por lo general suceden por el ADC, los ADC de los pics han de usar el método de aproximaciones sucesivas, así que si el valor de la señal cambia antes de que termine de convertir a digital dicho valor los errores aparecen, hay circuitos para mantener estable una señal o programar una funcion sencilla que descarte esos valores (algo como una variable que guarda el valor anterior y verifica que el valor siguiente sea coherente, o si hay valores imposibles como los negativos, los descarte).

      Te recomiendo usar potenciometros lineales en lugar de los convencionales logaritmicos si deseas mas precisión.


      http://www.dea.icai.upcomillas.es/romano/sp/sisper_adc.pdf

      Eliminar
  9. Hola, lo primero darte la enhorabuena por el trabajo y agradecerte que compartas conocimientos, tengo el mismo proyecto que has explicado pero yo lo voy a hacer con Arduino, ya tengo todo pero me falta la etapa de potencia. La voy a hacer con relé de estado sólido y que me corte o no la línea de 220V de una resistencia siliconada calefactora, el relé aislará la señal pwm con los 220v.

    ResponderEliminar
    Respuestas
    1. Suena bien tu proyecto Forrest, nosotros pensamos también usar un Relay de estado Sólido (que no no es mas que un MOSFET y un Emisor IR), pero el precio de los componentes nos detuvo.

      Saludos.

      Eliminar
  10. Que tal Hazael,saludos desde México. Vi tu proyecto y esta interesante, quise hacerle algunas modificaciones y tengo algunas dudas, que ojala pudieras ayudar a resolver.
    1.- Como le harías si en lugar de usar un potenciometro para seleccionar la temperatura deseada, solo pongo un push botton que tenga programado cierto valor, este valor lo colocaría tal cual en el valor de set point?
    2.- como le haría para saber la relación de bits que arroja el Convertidor AD de acuerdo a la temperatura sin usar el display?
    3.- De donde sale el valor de 100 para calcular la pendiente del dutycicle y porque le asignas 255 bits en lugar de 1023?

    Agradecería tu pronta respuesta.

    ResponderEliminar
    Respuestas
    1. Hola.

      1.- Bueno, lo mas rapido, para poder usar un Push en lugar del pot, yo crearia una funcion que estuviera constantemente leyendo el pin del push y cuando haya detectado que se ha hecho un "click" entonces sumar un valor constante (10 por ejemplo) al valor de bits_temperatura y ya no usar bits_temperatura = Get_Lectura(1); en el loop infinito.
      Obviamente que si bits_temperatura sobrepasa 1023 la tienes que regresar a 0.

      2.- Por medio de la funcion Relacion_LineaRecta_m, ya te doy la pendiente mT que es la que corresponde a la relacion ADC vs Temperatura. Ahora si no quieres usar una LCD, puedes poner un FT232 y mandar todo por serial a la PC para alli ver los valores y ya cuando no necesites ver los valores simplemente los sacas del circuito. (Lo usas solo para debuggear pues :P

      3.- Recuerda que la resolución del PWM en los CCP de este PIC es de 8bits (so 0 to 255 my friend) no lo confundas con el ADC. Y el 100 no recuerdo de donde sale :v creo que todo lo saque a prueba y error, y arriba de un valor de 100 para el DutyCycle del PWM me daba cosas extrañas.

      Espero te sirva.

      Saludos

      Eliminar
  11. Agradezco tu pronta respuesta.PEro no quedo claro, a ver si me puedo explicar mejor.

    1.-Efectivamente ya programe lo del push buttom,todo el tiempo espera a ser oprimido,
    cuando se oprime, en lugar de leer el ADC (bits_setPoint = Get_Lectura(4);)
    quiero asignarle a la variable bits_setPoint un valor unico, por ejemplo
    150, el valor maximo que manejas tu. LA pregunta es: ¿hago la igualacion bits_setPoint = 150;
    directamente o tengo que hacer algun tipo de conversión previa y como se haría, ya que en tu proyecto originalmente
    la haces con una entrada analogica que despues convierte a Digital?

    2.- Me queda claro que al cambiar Refresh_lcd(... Temperatura); por Refresh_lcd(... bits_temperatura);
    yo puedo visualizar los
    bits asignados a determinada temperatura, sin embargo ¿que es lo que haces para decir que
    a 21 grados corresponden 32 bits sin tener que usar un lcd para visualizarlo? o sea, matemati
    camente como haces la relacion o interpolacion, con que valores?

    3.- cheque la hoja de caracterizticas y dice "10-bit PWM, max. frequency 20 kHz" entonces supongo te equivocaste? :P jeje

    GRacias por responder, espero quede pronto el circuito y compartir mis resultados.

    ResponderEliminar
  12. 1.- Si deseas modificar de alguna manera externa el valor de la temperatura deseada debes de colocar directamente el valor de la temperatura en SetPoint. Por ejemplo cuando presionas el push haces SetPoint = 150.

    2.- La relación matemática para calcular el valor de temperatura a partir del ADC obedece a una relación en línea recta y =mx +b (m: pendiente, b: constante).
    Donde si colocas por ejemplo el ADC en el eje X, y el valor de temperatura en el eje Y a cada punto del ADC le corresponde un valor de temperatura (recuerda que para cierto rango de valores el LM35 es lineal, el potenciomentro no, pero supones que lo es para cuestiones practicas.)

    3.- :v la verdad no recuerdo porque deje el PWM con 255, deseguro me equivoqué, pero en los clusters dañados de mi cerebro tengo algo que me dice que fue por alguna razón :P (o estaba borracho)

    Saludos.

    ResponderEliminar
  13. Hola amigo buenas noches! hay alguna manera de acoplar este montaje para una resistencia de calor de corriente alterna? es para una resistencia de las duchas calentadoras

    ResponderEliminar
    Respuestas
    1. Hola Mariemilia.

      Si es una simple resistencia, claro (no importa si es CA o CD, sigue siendo una resistencia). La respuesta es si.

      La que uso para este proyecto era para una parrilla electrica de CA.

      Saludos.

      Eliminar
  14. PODRIAS EXPLICARME PORQUE ESTE PROYECTO NO SIRVE PARA CONTROLAR LA CORRIENTE DE UNA PLACA PELTIER PARA ENFRIAR? TENGO UNA PLACA DE 12 V 9A

    ResponderEliminar
  15. Hola.

    Emmm... cuando dije que no servía para controlar una Peltier?

    Puedes usarlo, la peltier es más complicada que una resistencia, nunca lo he intentado, pero hasta donde tengo entendido, controlando la cantidad de energía inyectada a la Peltier se puede controlar la velocidad y nivel de enfriamiento/calentamiento de la misma.
    Básico, si puedes con una fuente de poder (que permita variar el voltaje/corriente de salida) controlar el cambio de temperatura de la Peltier entonces también podrás usar el dispositivo aquí mencionado.
    Solo ten cuidado de no inyectar más de 12V a tu Peltier so pena de muerte para la misma, busca un transformador adecuado.

    ResponderEliminar
  16. hola y como modifico para que en vez que caliente, enfrie?
    Gracias...

    ResponderEliminar
    Respuestas
    1. Por desgracia, las limitaciones físicas de este proyecto hacen que solo pueda calentar.

      Quizá colocando a un lado una celda Peltier la cual la puedas activar por medio del PIC y un Relay funcione para tus propósitos (eso o un ventilador).

      Eliminar
  17. me pregunto sobre la imagen IMG5 ese puente rectificador si esta bien conectado mis conosimientos dicen que no los 2 positibos de los diodos tendrian que ir al positibo del condensador electrolitico y los 2 negatibos restantes de los diodos a masa ; salbo que aya alguna razon que desconosca responder si es correcto el error a velazqueztecnico@hotmail.com

    ResponderEliminar
    Respuestas
    1. Efectivamente está mal, increíble que el error salgs hasta ahora. Gracias por avisar. Saludos.

      Eliminar
  18. Hola, se puede manejar temperatura más alta? En caso afirmativo, qué debería modificar para llegar a 480º C? Es para una estación de soldadura por aire.

    ResponderEliminar
    Respuestas
    1. Intenta reemplazando la resistencia por un Contacto
      (http://mlm-s2-p.mlstatic.com/contacto-electrico-sencillo-aterrizado-mixto-20a-surtek-hm4-18036-MLM20148318239_082014-F.jpg)

      Y el transformador tendría que manejar un voltaje mayor, 48V quizá.

      En el contacto podrías conectar el calentador que necesites alimentar (un cautín o pistola de aire).

      480ºC podrían ser alcanzables, pero ocupas mucha energía, ten cuidado si usas una protoboard, usa cables gruesos (calibre #20 mínimo),

      Eliminar
    2. Gracias por la pronta respuesta, el calentador que voy a usar trabaja con 24 VAC. El transformador que tengo es de 12 + 12 V. y 10 A, puedo usarlo?, o es mucha corriente? Debería modificar algo de la programación? Disculpa por molestar pero mis conocimientos de electrónica son muy básicos.

      Eliminar
  19. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  20. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  21. Buenas... Disculpe seria tan amable de re subir el código por que MEGAUPLOAD ya no existe :(... O si no es mucha molestia mandarlo a mi correo personal.
    Espero su pronta respuesta, para hacerle llegar mi correo.
    Antemano gracias.

    ResponderEliminar
  22. Buenas tardes,

    He montado todo el circuito y lo he programado. Necesitaria saber que libreria para el LCD has usado, ya que me parpadea rapidamente.

    Un saludo

    ResponderEliminar
    Respuestas
    1. Se usa la librería propia de CCS, checa el manual de ccs, allí hacen referencia a todas sus librerías

      Eliminar
    2. Buenos dias,

      Vale yo tambien estoy usando la libreria LCD del css. He probado un archivo.HEX que descargue junto con el diseño de proteus y al cargarlo al pic si se obtienen lecturas.
      Sin embargo he probado a compilar el programa en C que tienes en el blog y no se obtienen lecturas . Hay que modificar algo en ese codigo?.
      Por otro lado cargue el HEX que cargue me parpadea la pantalla.

      Un saludo

      Eliminar
  23. Buenas tardes,
    He montado tu proyecto y va todo ok. La unica pregunta que queria hacerte es de que manera pueda conseguir mas ciclo de trabajo del pwm con menor diferencia de tenperatura.

    Un saludo

    ResponderEliminar