Enfriador para acuario casero con Arduino
En un acuario comunitario de agua caliente la temperatura adecuada para los peces está en el rango de 24 a 28 Grados Celsius. En invierno no hay problema, con el calentador se mantiene a la temperatura adecuada, pero en verano necesita un enfriador.
He construido uno que voy a mostrar. Se trata de un ventilador que se pondrá en marca cuando la temperatura pase de un umbral. El ventilador saca el aire por un extremo de la tapa del acuario hacia el exterior y entra por otra obertura en el extremo opuesto, se puede ver en el vídeo siguiente, lo que hará que el aire se cargue de humedad y al ser expulsado al exterior provoque la bajada de la temperatura debido a la evaporación.
La temperatura de activación se programa por medio de dos botones y la velocidad del ventilador es proporcional a la necesidad de la refrigeración, es decir, cuanto más alta la temperatura del agua con respecto a la de activación con más fuerza gira el ventilador, de 0 a 20, siendo 0 apagado y 20 la velocidad máxima.
Primeras pruebas ya instalado en el acuario:
Estas son las últimas pruebas antes de montarlo en placa:
Fotos una vez montado en placa:
Últimas pruebas antes de ponerlo en el acuario:
Haciendo las últimas mejoras:
Con las librerías que facilitan tanto el trabajo de programación y los componentes electrónicos que tenemos al alcance tan económicos, resulta muy fácil hacer cosas como ésta, que pueden ser muy útiles y además pasarlo muy bien creándolas, como ha sido mi caso.
He construido uno que voy a mostrar. Se trata de un ventilador que se pondrá en marca cuando la temperatura pase de un umbral. El ventilador saca el aire por un extremo de la tapa del acuario hacia el exterior y entra por otra obertura en el extremo opuesto, se puede ver en el vídeo siguiente, lo que hará que el aire se cargue de humedad y al ser expulsado al exterior provoque la bajada de la temperatura debido a la evaporación.
La temperatura de activación se programa por medio de dos botones y la velocidad del ventilador es proporcional a la necesidad de la refrigeración, es decir, cuanto más alta la temperatura del agua con respecto a la de activación con más fuerza gira el ventilador, de 0 a 20, siendo 0 apagado y 20 la velocidad máxima.
Primeras pruebas ya instalado en el acuario:
Componentes utilizados comprados en ebay baratos, pongo los enlaces para el que quiera verlos o comprarlos en ebay:
- Arduino Nano o compatible.
- Sensor de temperatura con sonda DS18B20.
- Transistor NPN de propósito general.
- Transistor mosfet canal P como el IRFI9Z34G o cualquiera similar.
- Ventilador, yo he usado uno de cpu potente de 12 V.a
- Display 7 segmentos tres dígitos ánodo común. Cátodo común serviría también
- 3 resistencias de 100 Ω.
- 1 resistencias de 10 KΩ.
- 1 resistencia de 4,7 KΩ.
- 1 resistencia de 1 KΩ.
- Un diodo tipo 1N4007.
- Dos pulsadores mini.
- Un condensador electrolítico de 2200 µF, opcional.
- Alimentador de 12 V.
Manejamos el ventilador con una salida digital de Arduino en modo PWM conectada a los transistores que lo accionan mediante 12 voltios, este es el esquema:
En un principio utilicé un módulo IRF520, como éstos como estos que se pueden comprar en ebay, pero lo quemé en las primeras pruebas, aunque creo que fue culpa mía que lo conecté mal por descuido. De todas formas queda mejor como lo he hecho, con el mosfet canal P, el NPN y las dos resistencias. Ojo con el patillaje de los transistores, hay que mirar el datasheet y no fiarse del dibujo anterior, cambian según la referencia que usemos, en este caso es un c33725. Estas dos páginas me han ayudado para diseñar esta parte:
Como conectar un mosfet de potencia a un microcontrolador
Controladores básicos (Drivers)
El diodo lo ponemos como protección y el condensador, aunque no es absolutamente necesario, hace que la señal de PWM se aplane y se parezca más a una media del voltaje entre picos, de forma que no se produzcan ruidos parásitos desagradables para los oídos en el ventilador.
El sensor de temperatura, que realmente es un termómetro digital con unas prestaciones asombrosas (véase el datasheet) sobre todo por el precio, está conectado en modo parásito porque así ahorramos circunfería, alimentado por la salida del Nano de 3V, que a su vez está alimentado por su entrada Vin mediante un alimentdor de 12 V, enlace para comprarlo en ebay. El sensor puede funcionar con 5V pero para qué gastar más.
Esquema de conexión del termómetro:
Hay que tener cuidado con el Nano cuando lo conectamos con una fuente externa por Vin y al mismo tiempo a través del USB, ya que se nos puede quemar el regulador de voltaje en los momentos de conexión y desconexión. Cuando conectamos el USB es más seguro tener desconectada la entrada Vin y al revés, si conectamos por Vin es más seguro tener desconectado el USB. En caso de necesitar las dos conexiones yo alimento por el pin de 5V, mediante un alimentador de 5V claro.
Por supuesto también hay que tener todas las tierras de diferentes voltajes conectadas en común.
En cuanto al display hay mucha información en la red al respecto, véase display 7 segmentos anodo comun 3 digitos. Lo alimento directamente de las salidas digitales del Arduino. Lo más correcto sería poner 8 resistencias de unos 220 Ω para los siete segmentos y el punto decimal, pero para simplificar yo lo he hecho poniendo tres resistencias de 100 Ω al común de cada dígito, de esa manera también puede funcionar y simplificamos la circuitería.
Estuve probando al pricipio alguna librería, pero no me convencieron, así que lo he programado yo mismo. Hay que activar sucesivamente cada dígito, solamente un dígito activo en cada instante, apagamos uno y encendemos el siguiente, configurando en cada instante los segmentos correcpondientes. Aquí se puede ver un display manejado por un PIC 16f84.
En el código, que pongo a continuación, se pueden ver los pines utilizados. Está redactado intentando que sea didáctico, muy comentado y con nomenclatura lo más afín posible a su cometido.
La temperatura de activación se edita mediante los pulsadores y se guarda en la propia eeprom del micro usando la librería EEPROM. Se usa la librería OnWire para comunicar con el termómetro y también la DallasTemperature para ortener la temperatura, ésta última se usa en modo asíncrono para no apagar el display durante mucho tiempo.
El código:
En un principio utilicé un módulo IRF520, como éstos como estos que se pueden comprar en ebay, pero lo quemé en las primeras pruebas, aunque creo que fue culpa mía que lo conecté mal por descuido. De todas formas queda mejor como lo he hecho, con el mosfet canal P, el NPN y las dos resistencias. Ojo con el patillaje de los transistores, hay que mirar el datasheet y no fiarse del dibujo anterior, cambian según la referencia que usemos, en este caso es un c33725. Estas dos páginas me han ayudado para diseñar esta parte:
Como conectar un mosfet de potencia a un microcontrolador
Controladores básicos (Drivers)
El diodo lo ponemos como protección y el condensador, aunque no es absolutamente necesario, hace que la señal de PWM se aplane y se parezca más a una media del voltaje entre picos, de forma que no se produzcan ruidos parásitos desagradables para los oídos en el ventilador.
El sensor de temperatura, que realmente es un termómetro digital con unas prestaciones asombrosas (véase el datasheet) sobre todo por el precio, está conectado en modo parásito porque así ahorramos circunfería, alimentado por la salida del Nano de 3V, que a su vez está alimentado por su entrada Vin mediante un alimentdor de 12 V, enlace para comprarlo en ebay. El sensor puede funcionar con 5V pero para qué gastar más.
Esquema de conexión del termómetro:
Hay que tener cuidado con el Nano cuando lo conectamos con una fuente externa por Vin y al mismo tiempo a través del USB, ya que se nos puede quemar el regulador de voltaje en los momentos de conexión y desconexión. Cuando conectamos el USB es más seguro tener desconectada la entrada Vin y al revés, si conectamos por Vin es más seguro tener desconectado el USB. En caso de necesitar las dos conexiones yo alimento por el pin de 5V, mediante un alimentador de 5V claro.
Por supuesto también hay que tener todas las tierras de diferentes voltajes conectadas en común.
En cuanto al display hay mucha información en la red al respecto, véase display 7 segmentos anodo comun 3 digitos. Lo alimento directamente de las salidas digitales del Arduino. Lo más correcto sería poner 8 resistencias de unos 220 Ω para los siete segmentos y el punto decimal, pero para simplificar yo lo he hecho poniendo tres resistencias de 100 Ω al común de cada dígito, de esa manera también puede funcionar y simplificamos la circuitería.
Estuve probando al pricipio alguna librería, pero no me convencieron, así que lo he programado yo mismo. Hay que activar sucesivamente cada dígito, solamente un dígito activo en cada instante, apagamos uno y encendemos el siguiente, configurando en cada instante los segmentos correcpondientes. Aquí se puede ver un display manejado por un PIC 16f84.
En el código, que pongo a continuación, se pueden ver los pines utilizados. Está redactado intentando que sea didáctico, muy comentado y con nomenclatura lo más afín posible a su cometido.
La temperatura de activación se edita mediante los pulsadores y se guarda en la propia eeprom del micro usando la librería EEPROM. Se usa la librería OnWire para comunicar con el termómetro y también la DallasTemperature para ortener la temperatura, ésta última se usa en modo asíncrono para no apagar el display durante mucho tiempo.
El código:
#include <EEPROM.h> #include <OneWire.h> #include <DallasTemperature.h> const int pintermometro = A0; const int pulsador1 = A1; const int pulsador2 = A2; const int pinventilador = 11; const int se = 6; //segmento e pata 1 const int sd = 5; //segmento d pata 2 const int sp = 4; //segmento pundo pata 3 const int sc = 3; //segmento c pata 4 const int sg = 2; //segmento g pata 5 const int sb = 7; //segmento b pata 7 const int d3 = 8; //digito 3 pata 8 const int d2 = 9; //digito 2 pata 9 const int sf = 10; //segmento f pata 10 const int sa = A3; //segmento a pata 11 const int d1 = 12; //digito 1 pata 12 const int tempmax = 340; const int tempmin = 250; int tempdisparo = 280; int direeprom = 0; //guardaremos tempdisporo en la eeprom float temperatura = 0; int decimal, unidad, decena = 0; unsigned long tiempo, tiempoaux, tiempoboton; int nivel, decenanivel, unidadnivel = 0; //nivel de fuerza del ventilador, 0 apagado int retardoboton = 300; //evita rebotes del boton int aux , aux2; OneWire buslectura(pintermometro); DallasTemperature medidor(&buslectura); void setup() { //Serial.begin(9600); // para adepuracion //pinMode(pulsador1,INPUT); //no es necesario, es el estado por defecto //pinMode(pulsador2,INPUT); //no es necesario, es el estado por defecto digitalWrite(pulsador1, HIGH); //esto activa las resistencias internas de pull up digitalWrite(pulsador2, HIGH); // Asignación de las salidas digitales pinMode(se, OUTPUT); //segmento e (1) pinMode(sd, OUTPUT); //segmento d (2) pinMode(sp, OUTPUT); //segmento pundo (3) pinMode(sc, OUTPUT); //segmento c (4) pinMode(sg, OUTPUT); //segmento g (5) pinMode(sb, OUTPUT); //segmento b (7) pinMode(d3, OUTPUT); //digito 3 (8) pinMode(d2, OUTPUT); //digito 2 (9) pinMode(sf, OUTPUT); //segmento f (10) pinMode(sa, OUTPUT); //segmento a (11) pinMode(d1, OUTPUT); //digito 1 (12) analogWrite(pinventilador,0); //lo inicializamos como salida y ponemos a 0, ventilador parado //inicializamos digitos en apagado digitalWrite (d1, 0); digitalWrite (d2, 0); digitalWrite (d3, 0); medidor.begin(); medidor.setWaitForConversion(false); //no esperamos, lo hacemos asincrono preparatemperatura(); //llamamos al sensor para leer la temperatura //saludamos para dar tiempo al sensor tiempoaux = millis(); do { digitalWrite (sp, 1); //desactivado punto dcimal activa(1, 0, 0, 1, 0, 0, 0); //escribe H enciendeyapaga(1); activa(0, 1, 1, 0, 0, 0, 0); //escribe E enciendeyapaga(2); activa(1, 0, 1, 1, 0, 0, 0); //escribe Y enciendeyapaga(3); } while (millis() - tiempoaux < 1000); miratemperatura(); //leemos la temperatura tiempo = millis(); EEPROM.get(direeprom,aux); if (aux < tempmin || aux > tempmax) { //miramos si teníamos tempdisparo guardada EEPROM.put(direeprom,tempdisparo); } else { tempdisparo = aux; } } void loop() { //muesra la temperatura escribe(decena); enciendeyapaga(1); //visualiza digito1 escribe(unidad); digitalWrite (sp, 0); //pone punto decimal enciendeyapaga(2); //visualiza digito2 digitalWrite (sp, 1); //quita punto dcimal escribe(decimal); enciendeyapaga(3); //visualiza digito3 if (millis() - tiempo >= 900) { //damos tiempo al sensor miratemperatura(); //leemos la temperatura tiempoaux = millis(); // mostramos F y nivel o OFF if (nivel != 0) { do { activa(0,1,1,1,0,0,0); //escribe F enciendeyapaga(1); if (decenanivel > 0) { escribe(decenanivel); //decena de nivel enciendeyapaga(2); } escribe(unidadnivel); //unidad de nivel enciendeyapaga(3); } while ((millis() - tiempoaux < 400) && (digitalRead(pulsador1))); //mas tiempo para el sensor } else { do { activa(0, 0, 0, 0, 0, 0, 1); //escribe O enciendeyapaga(1); activa(0, 1, 1, 1, 0, 0, 0); //escribe F enciendeyapaga(2); activa(0, 1, 1, 1, 0, 0, 0); //escribe F enciendeyapaga(3); } while ((millis() - tiempoaux < 400) && (digitalRead(pulsador1))) ; //mas tiempo para el sensor } preparatemperatura(); //llamamos al sensor para nueva lectura tiempo = millis(); } sienfriamos(); //se activa o desactiva el ventilador if (!digitalRead(pulsador1) || !digitalRead(pulsador2)) { //editamos temperatura de activacion tiempoboton = millis(); //para retardo pulsacion boton pidetempactivacion(); EEPROM.put(direeprom,tempdisparo);//solo graba si el dato es diferente del guardado no malgasta eeprom } } void preparatemperatura() { //preparamos lectura medidor.requestTemperatures(); } void miratemperatura() { //leemos //Serial.print("Temperatura:"); temperatura = medidor.getTempCByIndex(0); //Serial.print(temperatura); //serial.println("ºC"); temperatura = temperatura * 10; //tratamos tres digitos decena = temperatura / 100; unidad = (temperatura - (decena * 100)) / 10; decimal = temperatura - (decena * 100) - (unidad * 10); //Serial.println(decena); //Serial.println(unidad); //Serial.println(decimal); } void escribe(int n) { //configura cada numero para activarlo en un digito switch (n) { case 0: activa(0, 0, 0, 0, 0, 0, 1); break; case 1: activa(1, 0, 0, 1, 1, 1, 1); break; case 2: activa(0, 0, 1, 0, 0, 1, 0); break; case 3: activa(0, 0, 0, 0, 1, 1, 0); break; case 4: activa(1, 0, 0, 1, 1, 0, 0); break; case 5: activa(0, 1, 0, 0, 1, 0, 0); break; case 6: activa(0, 1, 0, 0, 0, 0, 0); break; case 7: activa(0, 0, 0, 1, 1, 1, 1); break; case 8: activa(0, 0, 0, 0, 0, 0, 0); break; case 9: activa(0, 0, 0, 1, 1, 0, 0); break; default: activa(1, 1, 1, 1, 1, 1, 1); } } void activa(boolean a, boolean b, boolean c, boolean d , boolean e, boolean f, boolean g) { //activa los leds de un digito digitalWrite (sa, a); digitalWrite (sb, b); digitalWrite (sc, c); digitalWrite (sd, d); digitalWrite (se, e); digitalWrite (sf, f); digitalWrite (sg, g); } void enciendeyapaga(int n) { //enciende y apaga cada digito switch (n) { case 1: digitalWrite (d1, 1); digitalWrite (d1, 0); break; case 2: digitalWrite (d2, 1); digitalWrite (d2, 0); break; case 3: digitalWrite (d3, 1); digitalWrite (d3, 0); break; } } void pidetempactivacion() { int decenadisparo, unidaddisparo, decimaldisparo = 0; int parpadeo = 170; //tiempo de encendido int parpadeo2 = 130; //tiempo de apagado int contador = 0; int veces = 8; //veces que realizamos el parpadeo boolean salir = false; do { contador++; if (contador > veces) { salir = true; } decenadisparo = tempdisparo / 100; unidaddisparo = (tempdisparo - (decenadisparo * 100)) / 10; decimaldisparo = (tempdisparo - (decenadisparo * 100) - (unidaddisparo * 10)); //muesra la temperatura de disparo parpadeando rápido tiempoaux = millis(); do { escribe(decenadisparo); enciendeyapaga(1); //visualiza digito1 escribe(unidaddisparo); digitalWrite (sp, 0); //pone punto decimal enciendeyapaga(2); //visualiza digito2 digitalWrite (sp, 1); //quita punto dcimal escribe(decimaldisparo); enciendeyapaga(3); //visualiza digito3 if (miraboton()) { contador = 0; break; } } while (millis() - tiempoaux < parpadeo); tiempoaux = millis(); do { escribe(10); //esto escrive el default (nada,efecto apagado) if (miraboton()) { contador = 0; break; } } while (millis() - tiempoaux < parpadeo2 && (millis() - tiempoboton > retardoboton)); //durante la pulsacion del boton (su retardo), no parpadea, queda fijo sienfriamos(); //que se active o apague el ventilador aunque estemos editando la temperatura } while (!salir) ; } bool miraboton() { // comprobamos qué botón se ha pulsado para aumentar o disminuir tempdisparo if (millis() - tiempoboton > retardoboton) { //hay que eliminar rebotes del boton if (!digitalRead(pulsador1)) { tiempoboton = millis(); //vovemos a retardar pulsacion boton if (tempdisparo < tempmax) { tempdisparo++; } return true; } if (!digitalRead(pulsador2)) { tiempoboton = millis(); //vovemos a retardar pulsacion boton if (tempdisparo > tempmin) { tempdisparo--; } return true; } } return false; } void sienfriamos() { aux = (int)temperatura ; if (aux > tempdisparo && aux < 400) { //Activa ventilador si temperatura pasa umbral y si es coherente < 40; if (aux > tempdisparo + 20) { aux2 = 255; //acotamos hasta 255 } else { aux2 = map(aux, tempdisparo, tempdisparo + 20, 0, 255); //pone en marcha el ventilador } analogWrite(pinventilador, aux2); nivel = map(aux2, 1, 255, 1, 20); //nivel de fuerza del ventilador para mostrarlo en el display decenanivel = nivel / 10; unidadnivel = nivel - (decenanivel * 10); //Serial.println(aux2); //para depuracion } else { analogWrite(pinventilador, 0); //para el ventilador; nivel = 0; //nivel a mostrar 0 decenanivel = 0; unidadnivel = 0; } }Código para descargar: Refrescator.ino
Estas son las últimas pruebas antes de montarlo en placa:
Fotos una vez montado en placa:
Últimas pruebas antes de ponerlo en el acuario:
Finalmente, una vez instalado en el acuario, ha funcionado tan bien que me ha sorprendido gratamente. Le he dejado puesto un ventilador de PC sencillo que casi no hace ruido y me mantiene el acuario a 27 grados:
Ya tengo una nueva versión de este circuito: Refrescator 3.0
Comentarios
Publicar un comentario