Diferencia entre revisiones de «Cronometro»

De Proyectos
Ir a la navegación Ir a la búsqueda
Línea 117: Línea 117:
= Código =
= Código =
<br>
<br>
<div class="toccolours mw-collapsible" style="width:400px">
This text is collapsible. {{Lorem}}
</div>
<pre>
<pre>
#include "Wire.h"
#include "Wire.h"

Revisión del 08:21 5 nov 2014

Tareas:

  • terminar punto fusible
  • Apartado lcd
    • Probar integrado i2c con pantalla
    • Añadir info integrado en entrada pantalla

Propósito

Este proyecto se trata de construir un cronometro que desconecte un aparato eléctrico (220V) en un tiempo determinado.
Se podria hacer con un 555 pero para aprender sobre la programación de un microcontrolador y sobre las pantalals LCDs he optado por utilizar un Arduino Leonardo y fabricar un shield que conecte la pantalla, botones, leds, etc.
El objetivo es tener un cronometro al que enchufaremos directamente el aparato a desconectar/conectar, es decir el aparato se alimentará a través del cronometro y un rele conectado al microcontrolador desconectará el aparato.

Circuito



General

Fuente Alimentación

Diseñar una fuente de alimentación para alimentar un arduino a 12V y 500mA. Colocar un fusible en el primario y un interruptor que corte la corriente del primario.
El transformador que he encontrado es de 400 y pico mA Crovisa 12V 5VA

Fusible


El fusible se puede poner en el circuito primario o el secundario. En mi caso lo pondré en el primario y para ello necesito calcular la corriente máxima que circulará por el primario.

Sabemos la corriente que irá por el secundario y la fórmula que relaciona ambas corrientes es:
Vpri⋅Ipri=Vsec⋅Isec

Hay que tener en cuenta que hay una pérdida de poténcia de un 60% del primario al secundario, solo es efectivo un 40% de la energia que transforma:
Vpri⋅Ipri⋅40%=Vsec⋅Isec

Aqui despejamos:
Ipri=Vsec⋅Isec⋅1.4Vpri=12⋅0.416⋅1.4230=30mA

En las hojas de especificaciones nos dicen que la corriente del primario es de 36mA, así que utilizaremos un fusible de ese valor o superior.

Elección Transformador


Voy a necesitar un transformador que el secundario tenga como mínimo el voltaje que alimentará al Arduino (9V) más 3V que es lo que va a caer en el regulador de tensión (7809).
Varduino+Vreg=9+3=12V

Los 12V son en valor eficaz, lo que significa que una vez pasados a valor de pico voy a tener:
Vp=Vef⋅(2)=16.97V

Como en el puente rectificador va a caer voltaje:
Vp−1.4V=15.57V

Este será el voltaje que tendré a la entrada del regulador, y como se ve va de sobras para que en el regulador caigan 3V.

Por lo tanto utilizaré un transformador de 230V en el primario y 12V en el secundario. He escogido un transformador de Crovisa 12V 5VA

Elección Puente Rectificador


Al elegir el puente rectificador tenemos que tener en cuenta la corriente que puede aguantar en conducción y el voltaje que puede aguantar en corte. Como hemos visto en el apartado del transformador tendremos una tensión máxima de unos 17V y la corriente que nos suministrará el transformador es de unos 400mA.
También hay que tener en cuenta la corriente que circulará por el condesador que hace de filtro durante la carga. Este efecto está explicado en un apartado de la entrada Efecto del condensador en la conducción del diodo rectificador y en Corriente Inicial.



En esta imagen se ve en la linea verde la tensión que tiene el condensador con un rizado del 10% de la tensión máxima y la linea roja es la corriente que pasa por el condensador para cargarse. El primer pico que se ve es de 14A (el condensador es un corto circuito y se intenta cargar en el menor tiempo posible, así que pasa la máxima corriente). Los siguientes picos son de unos 4.3A.

El puente rectificador debe poder aguantar unos 14A (mejor más por seguridad) durante un periodo de 6ms como mínimo (es lo que dura el pulso).

El modelo de puente es el W08M. Aguanta una corriente directa de 1.5A, suficiente para nuestros 417mA y un voltaje en inversa 800V. También encontramos el dato de aguanta 50A en picos de 8.3ms, en principio suficiente para aguantar los picos que vemos en la imagen superior.

Cálculos Condensador Filtrado


En la sección Uso práctico del Filtro de la entrada Fuente de Alimentación comento la regla práctica de 1000uF por cada amperio de corriente en la salida.
En este caso tendré unos 400mA como máximo a la salida, por lo tanto escogeré un condensador de 470uF (que es el valor anterior a 1000uF).
También colocaré los condensadores que comenta el usuario Fogonazo en el forosdeelectronica.com con los valores de C2 - 100nF, C3 - 100nF y C4 - uF.

Elección Regulador de Tensión


Necesito un regulador de tensión que entre 9V en la salida y que aguante unos 400mA. El 7809 es un regulador de estas características.

Circuito Proteus

Para poder simular un transformador de 230V/12V se tiene que utilizar la fórmula L2=L1⋅(V2V1)2
Fijamos L1=20mH y entonces calculamos:

L2=20mH⋅(12V230V)2=54μH

Relé


El relé se encargará de encender la carga conectada (una bombilla, insoladora, ...). Utilizaré un relé Serie 32 - Mini-relé para circuito impreso de 6A para poder conectar como máximo 230V⋅6A=1380W.
Debido a que necesito 40mA para poder activar el relé y la salida de un pin de Arduino entrega justo 40mA me quedo corto de corriente (además quiero encender un led cuando se encienda el relé y consume unos 10mA). Utilizaré un transistor controlado por el arduino para commutar el relé. El circuito que resulta está explicado en la sección [[Circuito_Relé | Circuito Relé].
Voy a usar la fuente de 5V que provee el Arduino Leonardo para activar el relé. En cada pin el Arduino Leonardo entrega 5V y 40mA como máximo, pero en el pin de alimentación de 5V tengo más corriente.

  • Utilizando la teoria del apartado Circuito Relé calcularé la resistencia de base.


RB=(VControl−VBE)⋅βIC=(VControl−VBE)⋅β⋅RRELEVRELE=(5−0.6)⋅50⋅1255=5k5Ω

El valor normalizado es 5k6Ω

  • Calculo de la resistencia de masa:


La resistencia a masa la pondré como mínimo de 56kΩ o 100kΩ.

  • Calculo de la resistencia del led:


La tensión de trabajo del led rojo es de 1.5v - 2.2v y consume una corriente entre 10mA y 20mA. Para nuestro caso escogeremos una tensión de 2v y corriente de 15mA.

RLED=VRELE−VLEDILED=5−20.015=200Ω

Pondré una resistencia de 220Ω.

PCB 3D



Gerber



Código


This text is collapsible. Plantilla:Lorem

#include "Wire.h"
#include "lcd_i2c.h"
#include "Bounce.h"

#define RELE 12
#define START 4
#define RESET 5
#define SEG_UP 6
#define SEG_DOWN 7
#define MIN_UP 8
#define MIN_DOWN 9

#define INTERVAL_MILLIS 5

#define E_INICIAL 0
#define E_CONFIG_TIME 1
#define E_CUENTA_ATRAS 2
#define E_RELE_ACTIVADO 3

#define REBOUNCE_TIME 250

LCD_I2C lcd(0x38);

uint8_t state = E_CONFIG_TIME;

Bounce buttonStart = Bounce(START, INTERVAL_MILLIS);
Bounce buttonReset = Bounce(RESET, INTERVAL_MILLIS);
Bounce buttonSegUp = Bounce(SEG_UP, INTERVAL_MILLIS);
Bounce buttonSegDown = Bounce(SEG_DOWN, INTERVAL_MILLIS);
Bounce buttonMinUp = Bounce(MIN_UP, INTERVAL_MILLIS);
Bounce buttonMinDown = Bounce(MIN_DOWN, INTERVAL_MILLIS);

struct tiempo{
  uint8_t horas;
  uint8_t minutos;
  uint8_t segundos;
  uint8_t decimas;
}cuenta = {0,0,0,0};

long milisegundos;

////////////////////////////////////////////
//*************SETUP*********************//
void setup(){
  pinMode(RELE, OUTPUT);
  digitalWrite(RELE, LOW);
  
  for(int i=4; i<10; i++){
    pinMode(i, INPUT_PULLUP);
  }

  lcd.init(0x38);
}
//*************SETUP***********************//
////////////////////////////////////////////
//**************LOOP*********************//
void loop(){
  switch(state){
    case E_INICIAL:{
      imprimirTiempo();
      state = E_CONFIG_TIME;
    }break;
    case E_CONFIG_TIME:{
      configTiempo();
      if(ev_reset()){
        resetTiempo();
        state = E_INICIAL;
      }
      if(ev_start()){
        activarRele();
        state = E_CUENTA_ATRAS;
      }
    }break;
    case E_CUENTA_ATRAS:{
      if(!ev_fin_cuenta_atras() && !ev_reset()){
        cuentaAtras();
      }else{
        desactivarRele();
        resetTiempo();
        state = E_INICIAL;
      }
    }break;
  }
}
//**************LOOP***********************//
////////////////////////////////////////////
boolean ev_start(){
  
  if(buttonStart.update() && buttonStart.read() == LOW){
    return true;
  }
  return false;
}
boolean ev_reset(){

  if(buttonReset.update() && buttonReset.read() == LOW){
    return true;
  }
  return false;
}
void imprimirTiempo(){
  lcd.setCursor(3,0);
  if(cuenta.horas < 10){
    lcd.print("0");
  }
  lcd.print(cuenta.horas);
  lcd.print(":");
  if(cuenta.minutos < 10){
    lcd.print("0");
  }
  lcd.print(cuenta.minutos);
  lcd.print(":");
  if(cuenta.segundos < 10){
    lcd.print("0");
  }
  lcd.print(cuenta.segundos);
  lcd.print(":");
  lcd.print(cuenta.decimas);  
}
void configTiempo(){
  if(buttonMinUp.update() && buttonMinUp.read() == LOW){
    buttonMinUp.rebounce(REBOUNCE_TIME);
    if(cuenta.minutos < 59){
      cuenta.minutos++;
    }else{
      cuenta.minutos = 0;
    }
  }
  if(buttonMinDown.update() && buttonMinDown.read() == LOW){
    buttonMinDown.rebounce(REBOUNCE_TIME);
    if(cuenta.minutos > 0){
      cuenta.minutos--;
    }
  }
  if(buttonSegUp.update() && buttonSegUp.read() == LOW){
    buttonSegUp.rebounce(REBOUNCE_TIME);
    if(cuenta.segundos < 59){
      cuenta.segundos++;
    }else{
      cuenta.segundos = 0;
    }
  }
  if(buttonSegDown.update() && buttonSegDown.read() == LOW){
    buttonSegDown.rebounce(REBOUNCE_TIME);
    if(cuenta.segundos > 0){
      cuenta.segundos--;
    }
  }
  imprimirTiempo();
}
void resetTiempo(){
  cuenta.horas = 0;
  cuenta.minutos = 0;
  cuenta.segundos = 0;
  cuenta.decimas = 0;
}
boolean ev_fin_cuenta_atras(){

  if(cuenta.minutos == 0 && cuenta.segundos == 0 && cuenta.decimas == 0){
    return true;
  }

  return false;
}
void cuentaAtras(){
  int decimasTotales = (((cuenta.minutos*60)+cuenta.segundos)*10)+cuenta.decimas;
  milisegundos = millis();

  if(milisegundos % 100 == 0){
    decimasTotales--;
    cuenta.decimas = decimasTotales % 10;
    cuenta.segundos = ((decimasTotales - cuenta.decimas)/10) % 60;
    cuenta.minutos = ((decimasTotales - cuenta.decimas)/10)/60;
  
    imprimirTiempo();
  }
}
void activarRele(){
  digitalWrite(RELE, HIGH);
}
void desactivarRele(){
  digitalWrite(RELE, LOW);
}


Máquina de estados



Ensamblaje