Cuando empiezas un proyecto como hobby nunca sabes cómo va a terminar.... es el caso de este proyecto, en el que la idea inicial era hacer una incubadora que mantuviera unas condiciones de temperatura constantes para poder criar pollitos sin necesidad de su madre. Toda esta idea cambió en el momento en el que planteé el sistema para aportar calor (o frio), y es que en la zona donde vivo es muy normal tener días de verano con hasta 45ºC, algo que esta mas cerca de cocer el pollito que de incubarlo... En este momento es cuando empecé a trastear con "Celulas Peltier", unos "cacharros" que ya conocía pero con los que nunca me había parado a experimentar para conocer de que eran capaces. Para abreviar (ya que lo explicaré más adelante) decir que estas celulas peltier tienen un rendimiento muy bajo, pero son capaces de aportar bastante frío a superficies pequeñas, un frio que era incluso excesivo para incubar huevos pero que para tener bebida fresquita a mano era ideal, es por ello que me decanté por construir una pequeña nevera, algo a lo que le voy a sacar seguro mucho mas partido.

Maker cooler

Lista de materiales

Los materiales que se van a utilizar en este proyecto son muy comunes, por lo que no son difíciles de encontrar, además muchos de ellos pueden sustituirse por otros sin que esto suponga un problema. Estos son los materiales que he utilizado yo.

ELECTRÓNICA

 

ESTRUCTURA

  • PVC Rigido (se puede sustituir por marquetería)
  • MDF de 10mm para la base
  • MDF de 3mm para separar la electrónica
  • Lamina de poliespán (como aislante)
  • Piezas impresas en 3D

Diseño de la estructura

Para la estructura he utilizado una plancha de PVC semi-rigida, madera MDF (en varios grosores) y piezas imrpesas en 3D para hacer las uniones. Me he decantado por el PVC por ser un elemento muy económico y facil de trabajar, yo lo he cortado con una CNC laser, pero es posible cortarlo con sierras o cizallas. Por supuesto, si no disponeis de este material podeis sustituirlo por madera o incluso cartón grueso, al final todo va a ir aislado y reforzado, el recubrimiento externo aunque aporta resistencia es mas que nada estético.

Estructura externa

La estructura está fabricada en PVC rígido, aunque se puede fabricar en cualquier material que tenga consistencia suficiente, como por ejemplo contrachapado o MDF, el grosor que he utilizado yo y para el que están preparado los diseños es 3mm, si se usa un grosor diferente habrá que modificar los diseños para adapatarlos al nuevo grosor.

estructura externaLas piezas de PVC podeís descargarlas en formato .dxf o .dwg, ambas son editables y podési configurar los diseños a vustro gusto.

Descarga de las piezas en formato .dwg aqui

Descarga de las piezas en formato .dxf aqui

Separadores

Internamiente se ha creado un separador y una base para la electrónica, estas partes las he creado usando MDF de 3mm para el separador y de 10mm para la base donde está alojada toda la electrónica. En la siguiente imágen puede verse la base con algunos de los componetes sobre ella.

base

Piezas impresas en 3D

Las piezas impresas en 3D son fundamentales para la unión de cada una de las partes, he creado patas para la base donde encajan los paneles laterales, escuadras para unir los perfiles e incluso la carcada donde se pueden embutir la pantalla del tipo LCD Smart Controller.

piezas impresas

Las piezas imprimibles necesarias para el proyecto se pueden descargar aqui

 El numero de piezas que deben imprimirse de cada una son:

  • Escuadra --> x10
  • Esquina apoyo --> x4
  • Esquinera --> x4
  • Esquinera abajo --> x4
  • Pantalla Soporte --> x1
  • Tirador --> x1

 

Electrónica

La parte electrónica puede parecer compleja, pero no lo es, tan solo tiene un ArduinoMEGA para realizar todo el control, un sensor DHT22 para las medidas de temperatura y humedad, un relé para activar elementos de potencia, una fuente de alimentación de 12V y la parte más compleja que consiste en una LCD con encoder, sumbador y lector de tarjeta SD como las que se usan en las impresoras 3D. Esta última parte la he simplidicado muchisimo, ya que he creado un conector a medida para simplemente conectar la LCD al ArduinoMEGA usando los pines de abajo, esto simplifica mucho el trabajo y permite tener ina interface LCD muy útil para nuestros problectos.

electronica

Apadtador para la pantalla

Como he comentado, uno de los pilares de este proyecto es el adaptador que he creado para conterconectar el ArduinoMEGA y la pantalla LCD de forma sencilla, esto va a ahorrar mucho trabajo y a eliminar todos esos problemas que pueden surgir a la hora de puentear con cables las conexiones entre los dispositivos.

adaptador pantalla

electronica conectadaEste conector no está a la venta por ser algo que está construido a medida para una aplicación concreta, pero no os preocupéis por ello, es muy sencillo mandarlo a fabricar teniendo simplemente que comprar los conectores (que se encuentran muy facil y son muy económicos). Os dejo los archivos para fabricar la placa, si teneis algun problema con esta parte simplemente escribirme y os ayudaré en lo que necesiteis.

Podéis descargar los archivos gerber, de esquemático y placa diseñados con Eagle aqui

 

Programa de control

El programa de control para gestionar el funcionamiento de la nevera puede parecer complejo, pero viendolo por partes se entiende bastante bien, ya que este progrma no es más que la suma de varios programas trabajando en conjunto. En primer lugar tenemos una parte en la que leemos la temperatura de la nevera con el sensor DHT22 y actuamos sobre la regulación, teniendo en cuenta una temperatuara maxima "Tmax" y una  temperatura minima "Tmin", lo de temperatura minima y máxima lo he establecido para dar una funcionalidad extra, ya que si se quiere mantener algo más caliente sería posible añadiendo una pequeña resistencia, con esto es muy sencillo reconvertir la nevera a una incubadora, algo que será muy útil para bastante gente.

void control_incubadora()
{
    t = dht.readTemperature();
    h = dht.readHumidity();
  
    if (t>= Tmax)  //Si la temperatura es mayor que Tmax --> Encendemos el ventilador
    {
      digitalWrite(ventilador,HIGH);
    }
    else if (t<= Tmin)  //Si la temperatura es menor que Tmin --> Encendemos el calefactor
    {
      digitalWrite(calefactor,HIGH);
    }
    else   //Si tenemos cualquier otra condición apagamos todo
    {
      digitalWrite(calefactor,LOW);
      digitalWrite(ventilador,LOW);
    }
    refrescoT = millis();  //Inicializamos el tiempo de refresco

    //Muestra datos en el puerto serie
    Serial.print ("Temperatura: ");
    Serial.print (t);
    Serial.println(" ºC");
    Serial.print ("Humedad: ");
    Serial.print (h);
    Serial.println(" %");
}

La segunda parte del programa lo que trata es de mostrar en pantalla los datos o menús que se han creado en el sistema para monitorizar o cambiar los valores de temperatura minima o máxima, esto se ha hecho mediante un "Switch" que mostrará una u otra pantalla en función de en que parte del menú nos encontremos. Esta función se ejecutará cada 0.5 segundos, refrescando el menú de la LCD.

void refresco_lcd ()
{
  switch (menuLCD) 
  {
    case 1:
      //MENU PRINCIPAL
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("CONTROL NEVERA");
      lcd.setCursor(0, 2);
      lcd.print("Temp. Actual: ");
      lcd.setCursor(15, 2);
      lcd.print(t,1);
      lcd.setCursor(19, 2);
      lcd.print("C");
      lcd.setCursor(0, 3);
      lcd.print("Humedad actual: ");
      lcd.setCursor(15, 3);
      lcd.print(h,1);
      lcd.setCursor(19, 3);
      lcd.print("%");
      lcdT = millis();
    break;

    case 2:
    //MENU PARA CAMBIAR MAXIMOS Y MINIMOS
    if (flechaLCD == 1)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("CONTROL MAX. Y MIN");
      lcd.setCursor(0, 1);
      lcd.print(">TEMP MAXIMA:");
      lcd.setCursor(15, 1);
      lcd.print(TmaxLCD);
      lcd.setCursor(0, 2);
      lcd.print(" TEMP MINIMA:");
      lcd.setCursor(15, 2);
      lcd.print(TminLCD);
      lcd.setCursor(0, 3);
      lcd.print(" ATRAS");
    }
    else if (flechaLCD == 2)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("CONTROL MAX. Y MIN");
      lcd.setCursor(0, 1);
      lcd.print(" TEMP MAXIMA:");
      lcd.setCursor(15, 1);
      lcd.print(TmaxLCD);
      lcd.setCursor(0, 2);
      lcd.print(">TEMP MINIMA:");
      lcd.setCursor(15, 2);
      lcd.print(TminLCD);
      lcd.setCursor(0, 3);
      lcd.print(" ATRAS");
    }
    else if(flechaLCD == 3)
    {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("CONTROL MAX. Y MIN");
      lcd.setCursor(0, 1);
      lcd.print(" TEMP MAXIMA:");
      lcd.setCursor(15, 1);
      lcd.print(TmaxLCD);
      lcd.setCursor(0, 2);
      lcd.print(" TEMP MINIMA:");
      lcd.setCursor(15, 2);
      lcd.print(TminLCD);
      lcd.setCursor(0, 3);
      lcd.print(">ATRAS");
    }
      lcdT = millis();
    break;  
  }
}

Y por último, queda el control de los menús y el cambio de los valores máximos y mínimos, esto se hace cone el encoder y el boton que trae el propio encoder, el boton tiene la función de "seleccionar" y "deseleccionar" mientras que el enconder permite moverse por las opciones de menú o incrementar o decrementar los valores de temeperatura máximos y mínimos, dependiendo si están seleccionados o nó las distintas opciones.

Para esto se ha dividido el progrmana en 2, uno para actualizar el botón y otro para el encoder.

void actualizaBoton ()
{
  if (!digitalRead(Boton)&& menuLCD==1 && flechaLCD==1 && !select)
  {
    menuLCD = 2;
    TmaxLCD = Tmax;
    TminLCD = Tmin;
    tone(Zumbador,1000,100);
    delay (300);
    return 0;
  }
  else if(!digitalRead(Boton)&& menuLCD==2 && flechaLCD==1 && !select)
  {
    select = 1;
    tone(Zumbador,1000,100);
    delay (300);
    return 0;
  }
  else if(!digitalRead(Boton)&& menuLCD==2 && flechaLCD==1 && select)
  {
    Tmax = TmaxLCD;
    select = 0;
    tone(Zumbador,1000,100);
    delay (300);
    return 0;
  }
  else if(!digitalRead(Boton)&& menuLCD==2 && flechaLCD==2 && !select)
  {
    select = 1;
    tone(Zumbador,1000,100);
    delay (300);
    return 0;
  }
  else if(!digitalRead(Boton)&& menuLCD==2 && flechaLCD==2 && select)
  {
    Tmin = TminLCD;
    select = 0;
    tone(Zumbador,1000,100);
    delay (300);
    return 0;
  }
  else if(!digitalRead(Boton)&& menuLCD==2 && flechaLCD==3 && !select)
  {
    menuLCD = 1;
    flechaLCD = 1;
    tone(Zumbador,1000,100);
    delay (300);
    return 0;
  }
}

 

void actualizaEncoder ()
{
      if (digitalRead(EncoB) == LOW) 
    {
      if (flechaLCD == 1 && !select)
      {
        flechaLCD = 3;
        return 0;
      }
      else if (flechaLCD == 1 && select)
      {
        TmaxLCD --;
        return 0;
      }
      if (flechaLCD == 2 && !select)
      {
        flechaLCD = 1;
        return 0;
      }
      else if (flechaLCD == 2 && select)
      {
        TminLCD --;
        return 0;
      }
       else if (flechaLCD == 3 && !select)
      {
        flechaLCD = 2;
        return 0;
      }
    } 
    else 
    {
      if (flechaLCD == 1 && !select)
      {
        flechaLCD = 2;
        return 0;
      }
      else if (flechaLCD == 1 && select)
      {
        TmaxLCD ++;
        return 0;
      }
      if (flechaLCD == 2 && !select)
      {
        flechaLCD = 3;
        return 0;
      }
      else if (flechaLCD == 2 && select)
      {
        TminLCD ++;
        return 0;
      }
       else if (flechaLCD == 3 && !select)
      {
        flechaLCD = 1;
        return 0;
      }
    }
}

Todas estas partes están gestionadas por un programa principal donde tan solo se han declarado las variables, configurado los pines y establecido el flujo de programa, en el que basicamente llamar cada cierto tiempo la función para el refresco de la pantalla y la lectura de temperatura, al mismo tiempo que se espera a que sea pulsado el botón o cambie el estado del encoder para poder actuar.

#include "DHT.h"
#include <LiquidCrystal.h> // Entre los símbolos <> buscará en la carpeta de librerías configurada
 
#define ventilador 2
#define calefactor 3
#define DHTpin 4

//ENCODER
#define EncoA 49
#define EncoB 45
#define Boton 23
#define Zumbador 25

#define DHTtipo DHT22

//Inicializamos la librería indicando los pins de la interfaz
LiquidCrystal lcd(27, 29, 33,31, 35, 37);   //RS, Enable, D4, D5, D6, D7
   
DHT dht (DHTpin, DHTtipo);  //Le pasamos la información del pin donde esta conectado el sensor y el tipo

float t = 0;  //Almacena la temperatura leida
float h = 0;  //Almacena la humedad leida

int Tmax = 30;  //Temperatura maxima
int Tmin = 27;  //Temperatura minima

boolean estA = LOW;  //Estado encoder A
boolean estB = LOW;  //Estado encoder B
int encoderPinALast = LOW;
//boolean estBoton = HIGH;  //Estado del boton

/*   TEMPORIZACIONES   */
double refrescoT = 0;  //Almacena el tiempo para refresco de temperatura
#define T_temp 5000    //Tiempo para el refresco de temperatura

double menuT = 0;      //Almacena el tiempo para mostrar el menu
#define T_menu 5000    //Tiempo que se mostrará el menu

double lcdT = 0;       //Almacena el tiempo para refrescar la LCD
#define T_lcd 500      //Tiempo para refrescar la LCD
int menuLCD = 1;
int flechaLCD = 1;
int TmaxLCD = Tmax;
int TminLCD = Tmin;
boolean select = LOW; //Variable que indica si esta seleccionado alguna opcion del menu

char dato_serie;
 
void setup()
{
  pinMode (ventilador,OUTPUT);
  pinMode (calefactor,OUTPUT);

  pinMode (EncoA,INPUT_PULLUP);
  pinMode (EncoB,INPUT_PULLUP);
  pinMode (Boton,INPUT_PULLUP);
  pinMode (Zumbador, OUTPUT);

  dht.begin();  //Inicializamos el sensor de temperatura/humedad

  // Configuramos las filas y las columnas del LCD en este caso 16 columnas y 2 filas
  lcd.begin(20,4); //longitud de fila y num de columna
  intro_lcd();

  Serial.begin(9600);
}


void loop()
{
  //Parte que controla la actualización de temperatura y control de ventilador y calefactor
  if (millis()> refrescoT +T_temp)
  {
   control_incubadora();
  }
  //Refresco de pantalla
  if (millis()> lcdT +T_lcd)
  {
   refresco_lcd();
  }
  

//Actucaiones si se pulsa el boton
  actualizaBoton();

//Actuaciones del encoder
estA = digitalRead(EncoA);
  if ((encoderPinALast == LOW) && (estA == HIGH) && menuLCD ==2) 
  {
    actualizaEncoder();
    delay(10);
  }
  encoderPinALast = estA;
}

Este programa puede resultar un poco confuso al principio, pero si se analiza por partes estoy seguro que lo conprenderéis. Os dejo el programa que he utilizado completo y dividido por partes para que lo compileis y trasteeis con el, si teneis alguna duda podeis consultar lo que necesitéis.

Descarga el programa completo del frigorifico aqui

 

Video con el montaje completo

 

 

Deja tus comentarios

Enviar un comentario como invitado

0
terminos y condiciones.

Gente en la conversación