Fuente de corriente constante multipropósito

Este es un circuito que se puede utilizar tanto para controlar LEDs, como para la carga de una batería, la alimentación de un circuito o bien como una herramienta para nuestro laboratorio, es muy útil ya que para aquellos que trabajamos mucho con leds y demás nos viene bien una fuente de corriente constante como probador de leds.
También nos puede servir para cargar baterías, aunque debemos modificar el valor de la resistencia tanto en resistencia como en potencia.
El calculo para obtener la corriente de salida deseada será el mencionado en el diagrama, donde Vref para el LM317 será de 1.25V, en nuestro caso empleamos un LM317T el cual posee un encapsulado TO220 y puede drenar hasta 1,5A, montado en un disipador de calor.
En este circuito no es necesario el disipador ya que nosotros solo necesitamos 10mA, por lo que también podría cambiarse el LM317T por un LM317L que es de encapsulado TO92 y nos puede erogar hasta 100mA.
Al tratarse de una corriente de hasta 30mA para leds de alto brillo estándar, tal vez se podría reemplazar las resistencias de 240 Ohms, por un potenciómetro (con una resistencia en serie para limitar el consumo) o bien por una llave selectora y diferentes grupos de resistencias donde se pueda setear por ejemplo 10, 20 y 30mA.
La tensión de alimentación va desde los 3.6V hasta los 9V sin presentar alteraciones en la corriente de disipación por lo que también lo hace un dispositivo portátil.
A continuación mostraré el circuito simulado comprobando los cálculos de corriente, en nuestro caso utilizamos dos resistencias de 240 Ohms en paralelo para obtener 120 Ohms.
Las resistencias son de 1/4W.



Aquí podemos ver la versión con una selectora de 3 vías donde podemos darle diferentes valores de resistencia para obtener diferentes corrientes de salida.
Los valores que se encuentran en el circuito son teóricos, por lo que se deben usar resistencias con tolerancia al 1% para encontrar los valores normalizados, o bien, se debe realizar previamente una red serie/paralelo para lograr los valores más próximos. También se puede utilizar un preset para cada valor, pero hay que tener en cuenta la corriente que va a atravesar el preset.

Temporizador cuadruple

Se encuentra desarrollado para manejar 4 tiempos independientes de 1 minuto hasta 200 minutos, pudiendo manejar una salida aislada de potencia electrónica o contacto seco. 
En este post las salidas poseen una resistencia con un LED, ya que quedara a elección del desarrollador que interfaz utilizara.
El circuito funciona con 5V regulados (es preferente utilizar un 7805 o similar) o bien 3 pilas con un final de 4,5V.
El programa no utiliza ningún timer, lo que lo hace mas sencillo de comprender para aquellos que recién se inician.
El flow de este programa es muy sencillo y secuencial, básicamente se setea cada temporizador y luego se presiona Ok para que comiencen, posee una parada de emergencia con el botón stop.
La secuencia seria: "ingresar valor de temporizador 1" aqui se presina el boton Up o Dowm para los minutos, luego si se presiona Ok, pasara al siguiente temporizador, otra vez Up o Dowm y Ok, luego con el temporizador 3 y luego el 4, una vez seteados los cuatro valores se presiona Ok para que se inicien y comenzaran las cuentas regresivas, si por algún motivo se debe parar de emergencia solo se debe apretar el botón de Stop.
La secuencia para cargar cada valor de temporizacion se realiza con un SwitchCase, donde se incrementara una variable que seleccionara cada Case a medida que se presione el Ok, excepto cuando se esten ejecutando los temporizadores ya que ahí solamente se podrá salir por la parada de emergencia o al finalizar el ultimo temporizador, para ello se utiliza un flag que sera verdadero o falso y habilitara o no el pulsador Ok. 
El bucle de 1 minuto se realiza con dos lazos for concentricos, y notase que dentro del mismo se sitúa la lectura del botón de parada de emergencia, esto es así porque si se situaria fuera del mismo, se leería este botón cada 1 minuto, de esta forma se lee cada 100ms. Cada botón cuenta con una segunda lectura del mismo luego de unos mili-segundos para garantizar el anti-repique. La función decremento del tiempo (botón Down) posee una validación para cuando llegue a 0 y no pase a valores negativos.


#include <16F883.h>
#FUSES NOWDT
#FUSES INTRC_IO
#FUSES MCLR
#use delay(int=4000000)
#include <LCD.C>
void main(){
   INICIO:
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc,"  PRESIONE OK    ");
   lcd_gotoxy(1,2);        
   printf(lcd_putc,"PARA CONFIGURAR  ");   
   int1 run=1;
   int8 funcion=0, 
        tTimer1=0, 
        tTimer2=0, 
        tTimer3=0, 
        tTimer4=0,
        tMinutos=0,
        i=0, j=0;
   while(TRUE){
      if(input(PIN_C2)==1&&run){
         delay_ms(100);
         if(input(PIN_C2)==1&&run){
            funcion++;
            delay_ms(200);
            if(funcion>6)
               funcion=1;
         }    
      }
      switch(funcion){
      case 1:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer1++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer1>0)
                  tTimer1--;
               delay_ms(100);
            }
         }
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");
         lcd_gotoxy(1,2);        
         printf(lcd_putc,"Timer 1: %2u min  ",tTimer1);
         break;
      case 2:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer2++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer2>0)
                  tTimer2--;
               delay_ms(100);
            }
         }         
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");         
         lcd_gotoxy(1,2); 
         printf(lcd_putc,"Timer 2: %2u min  ",tTimer2);
         break;
      case 3:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer3++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer3>0)
                  tTimer3--;
               delay_ms(100);
            }
         }           
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");         
         lcd_gotoxy(1,2);        
         printf(lcd_putc,"Timer 3: %2u min  ",tTimer3);
         break;
      case 4:
         if(input(PIN_C0)==1){
            delay_ms(100);
            if(input(PIN_C0)==1){
               tTimer4++;
               delay_ms(100);
            }
         }
         if(input(PIN_C1)==1){
            delay_ms(100);
            if(input(PIN_C1)==1){
               if(tTimer4>0)
                  tTimer4--;
               delay_ms(100);
            }
         }          
         lcd_gotoxy(1,1);
         printf(lcd_putc,"   TIEMPO DE    ");        
         lcd_gotoxy(1,2);        
         printf(lcd_putc,"Timer 4: %2u min  ",tTimer4);
         break;
      case 5:
         lcd_gotoxy(1,1);  
         printf(lcd_putc,"  PRESIONE OK    ");
         lcd_gotoxy(1,2);        
         printf(lcd_putc," PARA COMENZAR   ");
         break;
      case 6:
         if(tTimer1<tMinutos+1)
            output_low(PIN_C4);
         else
            output_high(PIN_C4);
         if(tTimer2<tMinutos+1)
            output_low(PIN_C5);
         else
            output_high(PIN_C5);            
         if(tTimer3<tMinutos+1)
            output_low(PIN_C6);
         else
            output_high(PIN_C6);            
         if(tTimer4<tMinutos+1)
            output_low(PIN_C7);
         else
            output_high(PIN_C7);  
         if(input_state(PIN_C4)==0&&
            input_state(PIN_C5)==0&&
            input_state(PIN_C6)==0&&
            input_state(PIN_C7)==0)
            goto INICIO;            
         for(i=0;i<4;i++){
            for(j=0;j<114;j++){
               delay_ms(100);
               if(input(PIN_C3)==1){
                  delay_ms(100);
                  if(input(PIN_C3)==1){
                     output_low(PIN_C4);
                     output_low(PIN_C5);
                     output_low(PIN_C6);
                     output_low(PIN_C7);
                     run=1;
                     goto INICIO;
                     delay_ms(100);
                  }
               }
               run=0;
               lcd_gotoxy(1,1);  
               printf(lcd_putc," PRESIONE STOP   ");
               lcd_gotoxy(1,2);        
               printf(lcd_putc," PARA CANCELAR   ");
            }
         }
         tMinutos++;          
         break;         
      }
   }
}