Hola compañeros,
Creo este post porque me parece que el otro post, por tener una fecha de inicio antigua, no tiene la difusión que necesito y que puedan pensar los entendidos que no hay avances en el.
Este es el post original: https://todomarino.com/comunidad/temas/Inicio-proyecto-de-Arduino.107844/
Y ahora continuaré con este y a ver si tengo suerte.
Ahora de lleno en este apasionante mundo que nos acorta las horas de sueño. Increíble despertarte a media noche y pensar "Y si modifico esto en el código", y como no lo hagas ya no duermes en toda la noche.
Ahora necesitaría una ayuda. He hecho todo lo que buenamente he podido aprovechando códigos de compañeros, aprendiendo lo que quieren decir e intentando adaptarlos a mis necesidades.
De momento tengo programado y funcionando pero sin tenerlo montado en su ubicación definitiva:
- Arduino Mega 2560
- Pantalla lcd i2C 2004
- Reloj i2c
- Sensor ultrasonidos HC-SR04 (Depósito de relleno) y en espera de un segundo
- 3 peristálticas con tip-120
- Módulo relé de 5 V y 8 canales
- 2 sensores DS 18b20 (Dallas)
- 2 sondas de nivel para el sump (de momento y en espera de ultrasonidos)
He intentado incorporar pulsadores para ejecutar un menú pero no consigo hacerlo funcionar. Me explico: Pulsadores con pantalla y nada más funcionan, pero cuando tienen que interactuar con todo lo demás, no me hacen ni caso. Me he olvidado de la posibilidad de poder modificar valores de horas de puesta en marcha y otras cosas, pero me gustaría poder parar bombas para dar de comer, limpiar el skimmer, etc.
He adquirido un teclado matricial 4x3 que es muy económico y tiene muchas posibilidades y con solo pulsar una tecla preestablecida efectuaría la parada de bombas y a los 10 minutos las accionaría de nuevo. Pero me pasa lo mismo, solo con los relés funciona bien pero cuando hay más cosas no se por donde tirar.
Así que después de este rollo, solicito la ayuda de algún alma caritativa que me pueda supervisar el código para que funcione el menú.
Muchas gracias.
Mi código:
Creo este post porque me parece que el otro post, por tener una fecha de inicio antigua, no tiene la difusión que necesito y que puedan pensar los entendidos que no hay avances en el.
Este es el post original: https://todomarino.com/comunidad/temas/Inicio-proyecto-de-Arduino.107844/
Y ahora continuaré con este y a ver si tengo suerte.
Ahora de lleno en este apasionante mundo que nos acorta las horas de sueño. Increíble despertarte a media noche y pensar "Y si modifico esto en el código", y como no lo hagas ya no duermes en toda la noche.
Ahora necesitaría una ayuda. He hecho todo lo que buenamente he podido aprovechando códigos de compañeros, aprendiendo lo que quieren decir e intentando adaptarlos a mis necesidades.
De momento tengo programado y funcionando pero sin tenerlo montado en su ubicación definitiva:
- Arduino Mega 2560
- Pantalla lcd i2C 2004
- Reloj i2c
- Sensor ultrasonidos HC-SR04 (Depósito de relleno) y en espera de un segundo
- 3 peristálticas con tip-120
- Módulo relé de 5 V y 8 canales
- 2 sensores DS 18b20 (Dallas)
- 2 sondas de nivel para el sump (de momento y en espera de ultrasonidos)
He intentado incorporar pulsadores para ejecutar un menú pero no consigo hacerlo funcionar. Me explico: Pulsadores con pantalla y nada más funcionan, pero cuando tienen que interactuar con todo lo demás, no me hacen ni caso. Me he olvidado de la posibilidad de poder modificar valores de horas de puesta en marcha y otras cosas, pero me gustaría poder parar bombas para dar de comer, limpiar el skimmer, etc.
He adquirido un teclado matricial 4x3 que es muy económico y tiene muchas posibilidades y con solo pulsar una tecla preestablecida efectuaría la parada de bombas y a los 10 minutos las accionaría de nuevo. Pero me pasa lo mismo, solo con los relés funciona bien pero cuando hay más cosas no se por donde tirar.
Así que después de este rollo, solicito la ayuda de algún alma caritativa que me pueda supervisar el código para que funcione el menú.
Muchas gracias.
Mi código:
Código:
///////////////////////////////////////////////////////////
// //
// PROYECTO ARDUINO ANTONIO RIVEROLA //
// //
///////////////////////////////////////////////////////////
// Librerías
#include <Wire.h> //Libreria de comunicacion I2C
#include <LiquidCrystal_I2C.h> //Libreria para LCD
#include <OneWire.h> //Temperatura
#include <DallasTemperature.h> //Temperatura
#include <Ultrasonic.h> //Sensor distancia ultrasonido
#include <Keypad.h> //Teclado matricial 4x3
///////////////////////////////////////////////////////////
// Definimos las constantes: //
///////////////////////////////////////////////////////////
//Definimos los PINS
#define TEMP 2
#define LUZSUMP 3
#define PIN_D_NIVEL_SUMP 7
#define PIN_D_NIVEL_MAX 8
//Ultrasonido pin 9
//Ultrasonido pin 10
#define NIVEL_SUMP_MAX 13
#define CALENTADOR 22
#define VENTILADOR 24
#define RELE_PERISTALTICAS 26
#define BOMBAS_MOVIM 28
#define SKIMMER 30
#define BOMBA_SUBIDA 32
#define BOMBA_RELLENO_SUMP 34
#define BOMBA_RELLENO 36
#define ONE_WIRE_BUS 2 //temperatura, pin de entrada
#define Reloj 0x68 // Reloj
int pin_peristaltica1 = 14;//PERISTALTICA 1
int pin_peristaltica2 = 15;//PERISTALTICA 2
int pin_peristaltica3 = 16;//PERISTALTICA 3
LiquidCrystal_I2C lcd(0x27,20,4); //Selecciona la dirección 0x27 para el LCD con 4 lineas
//y 20 caracteres
Ultrasonic ultrasonico(9,10); //Declaramos el sensor ultrasonico en los Pines Digitales elegidos
OneWire oneWire(ONE_WIRE_BUS); //temperatura
DallasTemperature sensors(&oneWire); //temperatura
///////////////////////////////////////////////////////////
// Variables del programa //
///////////////////////////////////////////////////////////
char* reef = " RIVEROLA REEF"; //Selecciona el nombre/version del programa
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
int Retraso=5000;
//Definimos las constantes del teclado matricial
const byte ROWS = 4; //cuatro filas
const byte COLS = 3; // tres columnas
// Matriz
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'#','0','*'}
};
//Conexiones ROW0, ROW1, ROW2 and ROW3 y COL0, COL1 y COL2 en los pienes
byte rowPins[ROWS] = {37, 39, 41, 43}; //conexiones de 4 filas del keypad
byte colPins[COLS] = {45, 47, 49}; //conexiones de 3 columnas del keypad
// Creamos el Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
///////////////////////////////////////////////////////////
//Realizamos el setup de todos los componentes //
///////////////////////////////////////////////////////////
void setup()
{
sensors.begin();
Wire.begin();
Serial.begin(9600);
lcd.init(); //Inicia el LCD
lcd.backlight(); //Activa iluminacion LCD
// Pines de entrada digitales
pinMode (PIN_D_NIVEL_SUMP, INPUT); //Sonda nivel relleno sump
pinMode (PIN_D_NIVEL_MAX, INPUT); //Sonda nivel relleno sump, nivel maximo
//Pines de salida del rele
pinMode(NIVEL_SUMP_MAX , OUTPUT); //Indica nivel alto en el sump
pinMode(LUZSUMP , OUTPUT); //Luz Sump
pinMode(CALENTADOR, OUTPUT); //Calentador
pinMode(VENTILADOR, OUTPUT); //Ventilador
pinMode(RELE_PERISTALTICAS, OUTPUT);//Rele del trasnformador de 12V para Peristalticas
//y luz sump
pinMode(BOMBAS_MOVIM, OUTPUT); //Bombas movimiento Urna
pinMode(SKIMMER, OUTPUT); //Bombas del skimmer
pinMode(BOMBA_SUBIDA, OUTPUT); //Bomba subida
pinMode(BOMBA_RELLENO_SUMP, OUTPUT); //Bomba de relleno al sump
pinMode(BOMBA_RELLENO, OUTPUT); //Bomba emergencia por si se queda vacio el deposito
//de relleno (solo vacaciones)
//Pines de salida Peristalticas
pinMode(pin_peristaltica1, OUTPUT);
pinMode(pin_peristaltica2, OUTPUT);
pinMode(pin_peristaltica3, OUTPUT);
if (minute < 2) Retraso=1000;
else if (hour < 5) Retraso=10000;
else Retraso=3000;
//No entiendo como funciona este punto
/* byte n;
for(n=31; n < 46; n = n + 2)
{
digitalWrite( n, HIGH);
} */
//Las bombas y skimmner tienen que estar activados
digitalWrite(BOMBAS_MOVIM ,HIGH);
digitalWrite(SKIMMER,HIGH);
digitalWrite(BOMBA_SUBIDA,HIGH);
/*
// la primera vez debemos poner en hora, activa esta parte y luego vuelve a quitarla
second = 50;
minute = 51;
hour = 19;
dayOfWeek = 4;
dayOfMonth = 11;
month = 7;
year = 13;
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
*/
}
///////////////////////////////////////////////////////
// //
// Entramos en el bucle del codigo principal //
// //
///////////////////////////////////////////////////////
void loop()
{
infolcd(); //Envía la información a la pantalla LCD
getDateDs1307
(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); //Obtenemos la hora
sensors.requestTemperatures(); //Activa los sensores de temperatura
Temperatura(); //Control de la temperatura
MirarNiveles(minute, hour); //Niveles del sump
Relleno(); //Nivel del deposito de relleno
Peristalticas(second, minute, hour); //Puesta en marcha peristalticas en segundos
Menu(); //Menu
}
/////////////////
// FUNCIONES //
/////////////////
// Convierte números normales decimales a BCD (binario decimal codificado)
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convierte BCD (binario decimal codificado) a números normales decimales
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(Reloj);
Wire.write(0);
Wire.write(decToBcd(second));
Wire.write(decToBcd(minute));
Wire.write(decToBcd(hour));
Wire.write(decToBcd(dayOfWeek));
Wire.write(decToBcd(dayOfMonth));
Wire.write(decToBcd(month));
Wire.write(decToBcd(year));
Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(Reloj);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(Reloj, 7);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
//Dibujamos la pantalla fecha y temperaturas
void infolcd(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print(reef);
lcd.setCursor(0,1);
lcd.print(" ");
if (hour<10)
{
lcd.print("0");
lcd.print(hour,DEC);
}
else
{
lcd.print(hour, DEC);
}
lcd.print(":");
if (minute<10)
{
lcd.print("0");
lcd.print(minute,DEC);
}
else
{
lcd.print(minute, DEC);
}
// Esto pone nombre del dia
lcd.print(" ");
switch (dayOfWeek)
{
case 1:
lcd.print(" Lunes");
break;
case 2:
lcd.print(" Martes");
break;
case 3:
lcd.print("Miercoles");
break;
case 4:
lcd.print(" Jueves");
break;
case 5:
lcd.print(" Viernes");
break;
case 6:
lcd.print(" Sabado");
break;
case 7:
lcd.print(" Domingo");
break;
}
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print(" FECHA: ");
if (dayOfMonth < 10) lcd.print("0");
lcd.print(dayOfMonth, DEC);
lcd.print("/");
if (month < 10) lcd.print("0");
lcd.print(month, DEC);
lcd.print("/");
lcd.print("20");
if (year < 10) lcd.print("0");
lcd.print(year, DEC);
lcd.print(" ");
// TEMPERATURAS
lcd.setCursor(0,3);
lcd.print("T1:");
lcd.print(sensors.getTempCByIndex(0)); //Index 0 , es el primer sensor
lcd.print("\337");
lcd.print(" T2:");
lcd.print(sensors.getTempCByIndex(1)); //Index 1 , es el segundo sensor
lcd.print("\337");
p(); // Pausa 3 segundos
}
// Pausa 3 segundos:
void p ()
{
delay (3000);
}
//////////////////////////////////////////////////////////////
// FUNCION MENU //
//////////////////////////////////////////////////////////////
void Menu ()
{
float t0 = 0;
sensors.requestTemperatures();
t0 = sensors.getTempCByIndex(0);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(reef);
lcd.setCursor(0,1);
lcd.print(" ");
if (hour<10)
{
lcd.print("0");
lcd.print(hour,DEC);
}
else
{
lcd.print(hour, DEC);
}
lcd.print(":");
if (minute<10)
{
lcd.print("0");
lcd.print(minute,DEC);
}
else
{
lcd.print(minute, DEC);
}
// Esto pone nombre del dia
lcd.print(" ");
switch (dayOfWeek)
{
case 1:
lcd.print(" Lunes");
break;
case 2:
lcd.print(" Martes");
break;
case 3:
lcd.print("Miercoles");
break;
case 4:
lcd.print(" Jueves");
break;
case 5:
lcd.print(" Viernes");
break;
case 6:
lcd.print(" Sabado");
break;
case 7:
lcd.print(" Domingo");
break;
}
//Teclado matricial 4x3
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
case '1': // Comida: Paramos bombas de movimiento y de subida
lcd.setCursor(0,2);
lcd.print("PARO PARA DAR COMIDA");
digitalWrite(BOMBAS_MOVIM, LOW);
digitalWrite(BOMBA_SUBIDA, LOW);
delay (600000);
digitalWrite(BOMBAS_MOVIM, HIGH);
digitalWrite(BOMBA_SUBIDA, HIGH);
break;
case '2': //Limpieza skimmer
lcd.setCursor(0,2);
lcd.print("PARO LIMPIAR SKIMMER");
digitalWrite(SKIMMER, LOW);
delay (600000);
digitalWrite(SKIMMER, HIGH);
break;
case '3': //Cambio calcetin sump
lcd.setCursor(0,2);
lcd.print("PARO LIMPIAR BAJANTE");
digitalWrite(BOMBA_SUBIDA, LOW);
delay (600000);
digitalWrite(BOMBA_SUBIDA, HIGH);
break;
case '4': //Limpieza sump
lcd.setCursor(0,2);
lcd.print(" PARO LIMPIEZA SUMP ");
lcd.setCursor(0,3);
lcd.print(" PULSA 5 AL ACABAR ");
digitalWrite(BOMBA_SUBIDA, LOW);
digitalWrite(SKIMMER, LOW);
digitalWrite(CALENTADOR, LOW);
break;
case '5': //Restaurar sump
digitalWrite(BOMBA_SUBIDA, HIGH);
digitalWrite(SKIMMER, HIGH);
if(t0 < 24.70)
{
digitalWrite (CALENTADOR, HIGH);
}
if(t0 > 25.00)
{
digitalWrite (CALENTADOR, LOW);
}
break;
}
}
}
//////////////////////////////////////////////////////////////////
// //
// COMPRUEBA EL NIVEL DE AGUA DEL SUMP Y DEPOSITO DE RELLENO //
// //
//////////////////////////////////////////////////////////////////
void MirarNiveles(int minutos, int horas)
{
int InicioNiveles1 = 600; // 10:00
int FinalNiveles1 = 602; // 10:05
int InicioNiveles2 = 1200; // 20:00
int FinalNiveles2 = 1202; // 20:05
int Tiempo;
Tiempo=(horas*60+minutos); lcd.clear();
lcd.setCursor(0,0);
lcd.print(reef);
if (digitalRead(PIN_D_NIVEL_MAX)==HIGH) // La bolla no esta activa, funcionamiento normal
{
digitalWrite(NIVEL_SUMP_MAX,LOW);
if (digitalRead(PIN_D_NIVEL_SUMP)==HIGH)
{
lcd.setCursor(0,1);
lcd.print(" SUMP BAJO ");
}
else
{
lcd.setCursor(0,1);
lcd.print(" SUMP OK ");
}
if (Tiempo >= InicioNiveles1 && Tiempo <= FinalNiveles1) //Damos la orden de encendido
//y apagado
if (digitalRead(PIN_D_NIVEL_SUMP)==HIGH) // La bolla esta activa y cierra las
//electrovalvulas
{
digitalWrite(BOMBA_RELLENO_SUMP,HIGH);
lcd.setCursor(0,1);
lcd.print(" SUMP BAJO ");
}
else
{
digitalWrite(BOMBA_RELLENO_SUMP,LOW);
lcd.setCursor(0,1);
lcd.print(" SUMP OK ");
}
if (Tiempo == FinalNiveles1)
digitalWrite(BOMBA_RELLENO_SUMP,LOW);
if (Tiempo >= InicioNiveles2 && Tiempo <= FinalNiveles2) //Damos la orden de encendido
//y apagado
if (digitalRead(PIN_D_NIVEL_SUMP)==HIGH) // La bolla esta activa y la bomba llena el sump
{
digitalWrite(BOMBA_RELLENO_SUMP,HIGH);
lcd.setCursor(0,1);
lcd.print(" SUMP BAJO ");
}
else // El sump esta lleno y cierra la bomba
{
digitalWrite(BOMBA_RELLENO_SUMP,LOW);
lcd.setCursor(0,1);
lcd.print(" SUMP OK ");
}
if (Tiempo == FinalNiveles2)
digitalWrite(BOMBA_RELLENO_SUMP,LOW);
}
else
{
digitalWrite(BOMBA_RELLENO_SUMP,LOW); //Sump demasiado lleno hay que programar la alarma
digitalWrite(NIVEL_SUMP_MAX,HIGH);
lcd.setCursor(0,1);
lcd.print(" ALARMA SUMP ");
}
}
// DEPOSITO DE RELLENO
//Medidas = 42*21*42, 0,88 litros/cm. Total = 37 litros
void Relleno()
{
int Nivel1 = 45; //Hay que ajustar los cm exactos del nivel cuando este puesto en su sitio
int Nivel2 = 15;
int CmAgua;
float Litros;
CmAgua=54-ultrasonico.Ranging(CM);
Litros=CmAgua*0.88;
lcd.setCursor(0,2);
lcd.print("RELLEN");
lcd.print(" ");
lcd.print(Litros); //Indica los litros que quedan en el deposito de relleno
lcd.print("L");
lcd.print(" ");
lcd.print((Litros/37)*100); //Indica el porcentaje del deposito de relleno, cuanto queda
lcd.print("% ");
//lcd.print(ultrasonico.Ranging(CM));
//lcd.print(" cm");
lcd.setCursor(0, 3); //Dibuja una barra de nivel con lo que queda del deposito
lcd.print("MIN "); //Con un minimo y un maximo
if (Litros > 3) lcd.print((char)255);
if (Litros > 6) lcd.print((char)255);
if (Litros > 9) lcd.print((char)255);
if (Litros > 12) lcd.print((char)255);
if (Litros > 15) lcd.print((char)255);
if (Litros > 18) lcd.print((char)255);
if (Litros > 21) lcd.print((char)255);
if (Litros > 24) lcd.print((char)255);
if (Litros > 27) lcd.print((char)255);
if (Litros > 30) lcd.print((char)255);
if (Litros > 33) lcd.print((char)255);
if (Litros > 36) lcd.print((char)255);
lcd.setCursor(17, 3);
lcd.print("MAX");
if (Nivel1 <= ultrasonico.Ranging(CM))// && Tiempo <= FinalNiveles1)
{
digitalWrite(BOMBA_RELLENO,HIGH);
lcd.setCursor(0,2);
lcd.print("RELLEN");
lcd.print(" ");
lcd.print(Litros);
lcd.print("L");
//lcd.print(ultrasonico.Ranging(CM));
//lcd.print(" cm");
}
if (Nivel2 >= ultrasonico.Ranging(CM))// && Tiempo <= FinalNiveles1)
{
digitalWrite(BOMBA_RELLENO,LOW);
lcd.setCursor(0,2);
lcd.print("RELLEN");
lcd.print(" ");
lcd.print(Litros);
lcd.print("L");
//lcd.print(ultrasonico.Ranging(CM));
//lcd.print(" cm");
}
p(); // Pausa 3 segundos
}
/////////////////////////////////////////////////////////
// PERISTALTICAS //
/////////////////////////////////////////////////////////
void Peristalticas(int segundos, int minutos, int horas)
[FONT=Lucida Sans Unicode]//El tiempo se establece en segundos para mayor precisión
//Aun hay que precisar el tiempo necesario para cada peristaltica[/FONT]
{
int InicioPeristaltica1=72000; //72000 = 20:00
int FinPeristaltica1=72060; //72060 = 20:01
int InicioPeristaltica2=72300; //72300 = 20:05
int FinPeristaltica2=72360; //72360 = 20:06
int InicioPeristaltica3=72600; //72600 = 20:10
int FinPeristaltica3=72660; //72660 = 20:11
int Tiempo;
Tiempo=((horas*3600)+(minutos*60)+segundos);
digitalWrite(RELE_PERISTALTICAS, LOW); //PERISTALTICA 1
if (Tiempo >= InicioPeristaltica1 && Tiempo <= FinPeristaltica1)//Damos la orden de encendido
//y apagado
{
digitalWrite(RELE_PERISTALTICAS, HIGH);
digitalWrite(pin_peristaltica1, HIGH);
}
else
{
digitalWrite(pin_peristaltica1, LOW);
digitalWrite(RELE_PERISTALTICAS, LOW);
}
//PERISTALTICA 2
if (Tiempo >= InicioPeristaltica2 && Tiempo <= FinPeristaltica2) //Damos la orden de
//encendido y apagado
{
digitalWrite(RELE_PERISTALTICAS, HIGH);
digitalWrite(pin_peristaltica2, HIGH);
}
else
{
digitalWrite(RELE_PERISTALTICAS, LOW);
digitalWrite(pin_peristaltica2, LOW);
}
//PERISTALTICA 3
if (Tiempo >= InicioPeristaltica3 && Tiempo <= FinPeristaltica3) //Damos la orden de
//encendido y apagado
{
digitalWrite(RELE_PERISTALTICAS, HIGH);
digitalWrite(pin_peristaltica3, HIGH);
}
else
{
digitalWrite(RELE_PERISTALTICAS, LOW);
digitalWrite(pin_peristaltica3, LOW);
}
}
////////////////////////////////////////////////////////////
// CONTROL TEMPERATURAS //
////////////////////////////////////////////////////////////
void Temperatura()
{
float t0 = 0;
float t1 = 0;
sensors.requestTemperatures();
t0 = sensors.getTempCByIndex(0);
t1 = sensors.getTempCByIndex(1);
//Configuracion de la temperatura
if(t0 < 24.70)
{
digitalWrite (CALENTADOR, HIGH);
}
if(t0 > 25.00)
{
digitalWrite (CALENTADOR, LOW);
}
if(t0 > 25.40)
{
digitalWrite (VENTILADOR, HIGH);
}
if(t0 < 25.10)
{
digitalWrite (VENTILADOR, LOW);
}
}