Acuariofilia Madrid

Versión completa: Rellenador de acuario basado en Arduino
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Páginas: 1 2
Pues aquí os dejo el esquema de montaje y el sketch para montar un rellenador de acuario basado en Arduino como prometí a Unay hace algunos meses y más recientemente a Carlos70 en éste post.

La necesidad de hacerlo así, vino tras varios desastres por desborde de agua en mi acuario ya que, las boyas de nivel que suelen traer estos sistemas (en mi caso el de TMC de una sola boya), viene intercalada en la misma linea de alimentación que la bomba de subida de agua, y la boya tiene que soportar más amperaje y voltaje que para el que fué diseñada, y con el tiempo y más tarde o temprano todas acaban quemámdose y quedando sus contactos "pegados" haciendo que no corte la bomba, y esto conlleva a un desborde de agua en nuestro acuario. Un mal diseño que segurmente viene por ahorrar costes y po vender boyas a cascoporro a posteriori.


El diseño está formado por un Arduino Nano que por su tamaño cabe en una caja no mas grande que una cajetilla de tabaco, una resistencia de 10k y un relé de estado sólido (son menos susceptibles a interferencias), todo ésto lo podemos colocar como he dicho en una pequeña cajita. Aparte y ya fuera de la caja, nos haría falta una boya de nivel de líquidos, en este caso y para un montaje de una sola boya ésta tendría que ser NC (normalmente cerrada), una bomba de subida de agua que no necesariamente tendría que ser de 12v como llevan estos sistemas ya que, como vamos a accionarla mediante un relé podría ser perfectamente de 230v, y ya por último un trasformador DC de 9v o 12v para alimentar el Arduino. Aconsejo que fuese de 9v, he podido comprobar que a este voltaje, Arduino trabaja de manera más estable.


Os dejo con el esquema de montaje:

İmage



Como podéis ver, es bastante sencillo, los pines digitales utilizados son el pin D2 para la boya y el pin D5 para el relé.

En el caso del pin D2, el de la boya, este va permanentemente conectado a masa (GND) con una resistencia de 10k, con esto forzaremos a "LOW" ese pin y evitaremos que por alguna interferencia hiciera una lectura erronea y se activase en falso nuestro relé activando la bomba de agua.

Nuestra boya tendrá dos contactos, uno de ellos tendrá que ir igualmente al pin D2 y el otro al pin de alimentación de 5v que proporciona Arduino.


Nuestro relé se conectará como otros tantos módulos de Arduino, tendrémos que proporcionarle alimentación a traves de masa y de los 5v que nos proporciona Arduino, y el pin restante iría conectado al pin D5 que es el que hemos seleccionado para este montaje y es el que activaría o desactivaría el relé.


El paso siguiente sería alimentar nuestro Arduino, aconsejo una fuente DC de 9v, y tendríamos que conectar el negativo a masa y el positivo al pin "Vin" de nuestro Arduino Nano.


Ya sólo quedaría conectar nuestra bomba al relé, para ello, uno de los dos cables de alimentación de nuestra bomba tendrémos que seccionarlo y cada extremo seccionado iría conectado a nuestro relé.





Con todo ésto la parte de montaje estaría completada, sólo quedaría cargar nuestro sketch en Arduino.

El skecht completo a cargar es el siguiente:

Código:
const int boya = 2;
int rele_bomba = 5;
int tiempo_actual_1 = 0;
int tiempo_actual_2 = 0;
int tiempo_resultante = 0;
int estado_boya = 0;

void setup() {
  Serial.begin(115200);
  pinMode(boya, INPUT);
  pinMode(rele_bomba, OUTPUT);
}

void loop() {
  estado_boya = digitalRead(boya);

  if (estado_boya == LOW) {
    tiempo_actual_1 = millis();
    digitalWrite(rele_bomba, LOW);
  }

  else {
    tiempo_actual_2 = millis();
    tiempo_resultante = tiempo_actual_2 - tiempo_actual_1;

      if (tiempo_resultante >= 1000) {
        digitalWrite(rele_bomba, HIGH);
        delay(10000);   // Unico parametro a modificar segun necesidades
      }
  }
}



El sketch es de lo más sencillo, mis conocimientos sobre programación se limitan en el entorno de Arduino y de una forma muy básica, me queda aún mucho que aprender -laughbounce2.gif.


Paso a describiros un poco por encima el skecht.

La primera parte...

Código:
const int boya = 2;
int rele_bomba = 5;
int tiempo_actual_1 = 0;
int tiempo_actual_2 = 0;
int tiempo_resultante = 0;
int estado_boya = 0;

...como véis no contiene librerías, todo se hace a través de la función "millis()", y en esta seccion declaramos las constantes y variables que vamos a utilizar con los nombres que le he dado y asigno los pins 2 y 5 que son los que vamos a utilizar.



La siguiente parte es la del "setup"...

Código:
void setup() {
  Serial.begin(115200);
  pinMode(boya, INPUT);
  pinMode(rele_bomba, OUTPUT);
}

...es un setup muy sencillo, tan solo establecemos la velocidad del puerto y configuramos el pin D2 que pertenece al de la boya como entrada para que pueda leer el estado de al boya y el pin D5 como salida para que active el relé.



Ahora explicaré el "loop"...

Código:
estado_boya = digitalRead(boya);


...con esta orden le decimos a Arduino que lea el estado de la boya. Si el circuito está cerrado será un "HIGH" y si está abierto será un "LOW".

Y aquí vienen las condiciones para que que según la lectura del estado de la boya, Arduino actue en consecuencia....

Código:
if (estado_boya == LOW) {
    tiempo_actual_1 = millis();
    digitalWrite(rele_bomba, LOW);
  }

...si la lectura de la boya es "LOW", le decimos a Arduino que guarde los millis() actuales en la variable "tiempo_actual_1 = millis();", como está en LOW, le decimos que no actue y mantenga en LOW (apagado) el relé a través de la orden "digitalWrite(rele_bomba, LOW);".



Gracias a RoFran, la continuación desde aquí del código ha sido simplificada y mejora por él, siendo ahora más comprensible -notworthy.gif-notworthy.gif-notworthy.gif

La continuación del código es para cuando la boya cierre el circuito y haga un "HIGH"...

Código:
else {
    tiempo_actual_2 = millis();
    tiempo_resultante = tiempo_actual_2 - tiempo_actual_1;

      if (tiempo_resultante >= 1000) {
        digitalWrite(rele_bomba, HIGH);
        delay(10000);   // Unico parametro a modificar segun necesidades
      }
  }
}

...en este caso, si la lectura del estado de la boya es "HIGH", le decimos a través de la variable "tiempo_actual_2 = millis();" que vuelva a guardar el estado actual de millis()", y le decimos que la tercera variable "(tiempo resultante)", es el resultado de restar el tiempo_actual_2 menos el tiempo_actua_1 con esta orden "tiempo_resultante = tiempo_actual_2 - tiempo_actual_1;"

Si este resultado es inferior a 1000 milisegundos (1 segundo), no actuará y el relé permancecerá desactivado, pero si por el contrario el tiempo resultante es igual o superior a 1000 milisegundos, en ese momento activará el relé con la orden "digitalWrite(rele_bomba, HIGH);" y mantendrá la bomba encendida durante 10 segundos inyectando agua en el acuario, delay(10000);.



Varias aclaraciones:

1ª.- Dejamos un desfase de 1 segundo para que se active el relé para evitar que por cualquier falso contacto de nuestra boya por el motivo que sea, la bomba se active incecesariamente.

Es más, si observáis los que tengáis un rellenador comercial ya bien sea TMC, BLAU, etc, observaréis que la bomba de agua no se activa o desactiva immediatamente si accionemos la boya manualmente, hay un tiempo de desfase que creo que las marcas lo han diseñado así para evitar estos problemas que os he comentado, y que a través de código he intentado imitar.

2ª.- El tiempo que está inyectando agua la bomba es relativo, yo en mi intento de minizar mis instalaciones y que quede todo lo más invisible posible, tengo hecha una reducción del tubo de subida de agua al acuario, siendo éste de un diámetro similar como a un tubo de silicona de nuestros sistemas de CO2, por lo cual tarda más tiempo en subirme el nivel. Si vosotros utilizáis un tubo de más sección y acorde a la boca de salida de la bomba, es posible que tarde menos en alcanzar el nivel deseado.

Así que recordar que quién se atreva con este brico tendrá que jugar con este parámetro, éste está indicado en el código, solo sería hacer varias pruebas.

Como guía, yo una vez se activa la bomba, el nivel sube 2 mm en una superficie de acuario de 80x40, suficiente para que no vuelva a activarse hasta pasadas unas 4 o 6 horas dependiendo de la evaporación. Como os digo, hacer pruebas y dejarlo a vuestro gusto.




Sé que os acabo de soltar una parrafada enorme para algo muy sencillo -pardon.gif.

Pero yo cuando empecé a trastear con Arduino hacía un copia pega de los códigos que veía colgados en distintos sitios y sin entender muy bien que es lo que hacía, así que este post es un intento de quién no entienda sobre el tema pueda entender que hace cada linea del código.

Quién sepa más sobre Arduino se quedará sólo con el esquema de montaje y el código y le sobrarán las explicaciones.

Aún así, la idea principal es que fuera fácil de realizar y sobre todo efectivo, yo llevo casi dos años así y me he olvidado de los desbordes de agua, ahora duermo tranquilo Big Grin.

Así que está hecho para todos los públicos -laughbounce2.gif-laughbounce2.gif.



Por supuesto, quién quiera corregir algún error, mejorar el código o aportar alguna idea más, es libre de hacerlo, como os he dicho, sé lo justito, así que si alguien puede aportar está en su derecho.





Un saludo -hi.gif.
IMPRESIONANTE!
-notworthy.gif-notworthy.gif-notworthy.gif-notworthy.gif-notworthy.gif
(14-09-2018, 01:34 AM)Unay escribió: [ -> ]IMPRESIONANTE!
-notworthy.gif-notworthy.gif-notworthy.gif-notworthy.gif-notworthy.gif

Gracias Unay, la explicaión quizás si se salga un poco de lo normal, pero el brico es de lo más sencillo -glare.gif, es nivel -1 de Arduino -nosweat.gif. Aún así me alegro y te agradezco que te guste tanto -good.gif.


Saludos -hi.gif.
(14-09-2018, 01:38 AM)Davidmadrid escribió: [ -> ]...es nivel -1 de Arduino -nosweat.gif

Justo lo que necesitamos muchos Big Grin
Y a partir de ahí, ya ir aprendiendo

Gracias a ti! Acabará cayendo el sistemita -good.gif
Muy buen post, super util para los que como yo no tenemos ni idea de estos temas podamos ver algo de luz y empezar a aprender. Un saludo
Excelente David ahí te va un +1 buen trabajo -good.gif
Este me lo guardo para cuando monte mi sistema. Aún estoy evaluando como hacerlo, si comprar uno (probablemente Blau de dos notas) o montar un sistema propio.
+1.. Gracias!!
Muy bien explicado... casi casi lo entiendo hasta yo! -rofl.gif -notworthy.gif -notworthy.gif

Un pregunta de "nivel -5" -nosweat.gif estos inventos ¿los utilizáis para compensar la evaporación o también para automatizar los cambios de agua? Entiendo que para ello tenéis un contenedor permanente con agua para el sistema en el armario (?) y lo vais llenando con agua ¿sin tratar/destilada...? -hi.gif
Dionaea, te cuento lo que yo sé.
Se utiliza para compensar evaporación. Pero también lo puedes usar para facilitar el relleno en los cambios de agua.
Necesitas un contenedor cerca del acuario. En mi caso tengo un bidón de 10 litros, pero no descarto que cuando lo ponga en marcha meta algo más grande.
El agua es sin tratar, ten en cuenta que metes poco agua cada día, y que el tratamiento que puedas ponerle desaparece en un par de días si no usas el agua en el acuario.
(14-09-2018, 11:14 AM)Dionaea escribió: [ -> ]Muy bien explicado... casi casi lo entiendo hasta yo! -rofl.gif -notworthy.gif -notworthy.gif

Un pregunta de "nivel -5" -nosweat.gif estos inventos ¿los utilizáis para compensar la evaporación o también para automatizar los cambios de agua? Entiendo que para ello tenéis un contenedor permanente con agua para el sistema en el armario (?) y lo vais llenando con agua ¿sin tratar/destilada...? -hi.gif

Éste en concreto sí, es para compensar la evaporación de agua y mantener un nivel constante de agua. Viene muy bien para plantados o gambarios que, por exceso de evaporación podemos crear una acumulación de sales excesiva.

Aún así, con Arduino podemos hacer ésto y mucho más, como automatizar los cambios de agua, controlar temperatura, co2, iluminación y en definitiva todo lo que se nos ocurra. Yo tuve mi época en la que controlaba todo con Arduino, ahora sólo lo utilizo para el rellenador de agua.

Sólo hacer una búsqueda en esta misma sección y veréis los magníficos proyectos que hay en ella, sin ir más lejos buscar "CAO 1" de Antonio Castro, un controlador de acuario completísimo, entre otros magníficos aportes de otros usuarios claro.

Esta sección de Arduino fué durante mucho tiempo una de las glorias de este foro Smile.
Ok! gracias Carlos y David! siempre que os leía lo de los rellenadores me quedaba con la duda... yo lo hago manual a jarrazos -nosweat.gif pero, claro, evapora poco...

Sí David, tengo fichados los "Grandes temas Arduino" del foro, aunque no me entero de nada jajaja (no por mal explicados, si no que yo para estos temas... mal... me quedo en principiante de principiante de electricidad: soy capaz de montar un casquillo, un enchufe o un interruptor -nosweat.gif) De momento tampoco lo he necesitado, entiendo que para grandes instalaciones o el mantenimiento de determinadas especies es muy práctico. -hi.gif
Muy buenas instrucciones..............aunque a la mayoría nos suene a chino cantonés

+1 y añadido al Recopilatorio de bricos de electricidad -hi.gif
Acabo de leerlo en diagonal... por si ayuda te comento lo que veo ya que, aunque de Arduino no sé nada, de C (aunque oxidado) y programación si sé algo.

"LOW" y "HIGH" parecen constantes booleanas... ¿donde están definidas? Igualmente aunque desconozco los parámetros necesarios para el procedimiento "digitalWrite" (tampoco veo donde está definido) veo que niegas estas constantes al introducirlas. ¿Por qué haces esto? ¿Le envías un mensaje FALSO al relé para que se encienda? Parece contradictorio.

Por otro lado, y relacionado, "estado_boya" tiene que ser una variable booleana por lo que solo puede almacenar dos estados: VERDADERO o FALSO

¿Por qué digo esto último? Pues dado que "estado_boya" solo puede tener dos valores la estructura de control "if" se puede mejorar usando un "if-else". Incluso si pudiera tener más valores, que no lo creo, me plantearía usar "switch-case". Cualquiera de estas dos opciones sería más eficiente.

Te pongo como lo dejaría yo ese trozo (lo he escrito al vuelo, espero que compile):

Código:
void loop() {
  estado_boya = digitalRead(boya);

  if (estado_boya == LOW) {
    tiempo_actual_1 = millis();
    digitalWrite(rele_bomba, !LOW);
  }

  else {
    tiempo_actual_2 = millis();
    tiempo_resultante = tiempo_actual_2 - tiempo_actual_1;

      if (tiempo_resultante >= 1000) {
        digitalWrite(rele_bomba, !HIGH);
        delay(10000);   // Unico parametro a modificar segun necesidades
      }
  }
}

También he quitado la primera condición en el "if" anidado porque siempre se cumpliría (estado_boya == HIGH ya se evaluó en el "if" superior que ahora es el "else").
(15-09-2018, 12:14 AM)RoFran escribió: [ -> ]Acabo de leerlo en diagonal... por si ayuda te comento lo que veo ya que, aunque de Arduino no sé nada, de C (aunque oxidado) y programación si sé algo.

"LOW" y "HIGH" parecen constantes booleanas... ¿donde están definidas? Igualmente aunque desconozco los parámetros necesarios para el procedimiento "digitalWrite" (tampoco veo donde está definido) veo que niegas estas constantes al introducirlas. ¿Por qué haces esto? ¿Le envías un mensaje FALSO al relé para que se encienda? Parece contradictorio.

Por otro lado, y relacionado, "estado_boya" tiene que ser una variable booleana por lo que solo puede almacenar dos estados: VERDADERO o FALSO

¿Por qué digo esto último? Pues dado que "estado_boya" solo puede tener dos valores la estructura de control "if" se puede mejorar usando un "if-else". Incluso si pudiera tener más valores, que no lo creo, me plantearía usar "switch-case". Cualquiera de estas dos opciones sería más eficiente.

Te pongo como lo dejaría yo ese trozo (lo he escrito al vuelo, espero que compile):

Código:
void loop() {
  estado_boya = digitalRead(boya);

  if (estado_boya == LOW) {
    tiempo_actual_1 = millis();
    digitalWrite(rele_bomba, !LOW);
  }

  else {
    tiempo_actual_2 = millis();
    tiempo_resultante = tiempo_actual_2 - tiempo_actual_1;

      if (tiempo_resultante >= 1000) {
        digitalWrite(rele_bomba, !HIGH);
        delay(10000);   // Unico parametro a modificar segun necesidades
      }
  }
}

También he quitado la primera condición en el "if" anidado porque siempre se cumpliría (estado_boya == HIGH ya se evaluó en el "if" superior que ahora es el "else").



Cierto y muy cierto, es lo que tiene aprender por uno mismo las cosas -dontknow.gif, tengo la mania de ir anidando "if" como si no hubiera un mañana, solo me planteo introducir un "else" cuando aquello empieza a desmadrarse -laughbounce2.gif.

Aún así es algo tan sencillo que lo hice tan rápido que cuando vi que funcionaba lo dejé tal cual y no me paré a ver donde podría simplificar el código.


Por otro lado, hasta ahora y dentro de lo que es Arduino, jamás he visto declarar un "digitalWrite" ni un "HIGH o LOW", mis conocimientos sobre programación empiezan y acaban con Arduino, y lo que sé sobre él es de manera muy básica para hacer funcionar las 6 o 7 cosas que hace tiempo controlaba con él, así que supongo que si nunca se declaran es porque debe se algo intríseco de Arduino y su IDE de compilación.


Respecto a por que niego los HIGH y LOW a la hora de hacer funcionar el relé tiene fácil explicación, y es que los relés que compro suelen ser de manufacturación china, y al menos en mi caso siempre han funcionado con la lógica de activación invertida, siendo un HIGH lo que debería ser un LOW y viceversa, así que tomé por costumbre negar la acción por "estética y no llegar a confusiones". Quizás debería de quitar esa negación del código, si a alguien le surje después el mismo problema que a mí, ya le daremos solución.



Por lo pronto y para que no sea más confuso este post en algo tan simple y sencillo, voy a modificar mi primera entrada con tu aporte y haciéndote referencia.




Y como no, un +2 por pararte a revisar el código -good.gif-good.gif-good.gif





PD: Tu modificación en el código compila perfectamente y funciona, lo he cargado en Arduino y funiona igual de bien que el antiguo -good.gif




Saludos -hi.gif.




Actualizada la primera entrada con la aportación de RoFran -good.gif-good.gif-good.gif
-notworthy.gif-notworthy.gif-notworthy.gif

Muchas gracias, esto para nivel novato viene de perlas para no escapar en póst más complejos similares. -laughbounce2.gif

Cito a Dionaea totalmente, y reparto +2 -good.gif
Páginas: 1 2