Hola, alguno sabe como podría hacer que cuando se apriete un interruptor y pase un día se active la electrovalvula (el relay especificamente)? La idea de mi proyecto es hacer que por día se usen una cierta cantidad de litros (por ejemplo 5L) y cuando esta se sobrepasa se corta el relay y no saldra más agua hasta el otro día. Tiene que ser flexible porque yo tengo que poder usar esos 5L cuando quiera durante el día pero una vez que se terminan tengo que esperar al dia siguiente (sabes como se programaría eso? yo lo hice con un evento de alarma pero no creo que sea lo mas conveniente porque si se llega a desconectar el arduino la alarma ya no funciona, es decir tiene que esperarse un dia mas y yo no quiero esto). Y entonces las tres variables que se tendrian que cumplir para que se encienda la electrovalvula es si hay cantidad de litros para usar, si paso un dia y si se toco el interruptor (como hago lo del interruptor?).
Paso el codigo a continuación:
//Librerias
#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <EEPROM.h>
//Definimos variables
int electro_in1 = 12;
int electro_in2 = 11;
byte sensorInterrupt = 0; // 0 = digital pin 2
byte sensorPin = 2;
float calibrationFactor = 7.5;
volatile byte pulseCount;
float flowRate;
float totalLitres;
unsigned long oldTime;
float volumen = 0;
float volumenMaximo = 5; //CAMBIAR ESTO DEPENDIENDO LOS LITROS MÁXIMOS
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void setup()
{
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the status LED line as an output
pinMode(electro_in1, OUTPUT);
pinMode(electro_in2, OUTPUT);
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
pinMode(sensorPin, INPUT);
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
totalLitres = 0.0;
oldTime = 0;
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
//Para el RTC
setSyncProvider(RTC.get);
Alarm.alarmRepeat(00, 28, 10, ReiniciarVolumen); // Evento diario, podriamos ponerla a las 00,00,01. ESTO ME GUSTARIA CAMBIAR
}
void loop()
{
Alarm.delay(1000);
if (volumen < volumenMaximo)
if((millis() - oldTime) > 1000) // Only process counters once per second
{
detachInterrupt(sensorInterrupt);
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
// Add the millilitres passed in this second to the cumulative total
totalLitres += flowRate / 60;
volumen = totalLitres;
unsigned int frac;
Serial.print ("Caudal: ");
Serial.print (flowRate,3);
Serial.print ("L/min\tVolumen: ");
Serial.print (volumen,3);
Serial.println (" L");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}
if (volumen >= volumenMaximo){
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
}
}
void ReiniciarVolumen() // de las alarmas!!!
{
//Aca podria ir lo del boton para iniciar la electrovalvula
if ( /* boton apretado && */ volumen < volumenMaximo){
digitalWrite(electro_in1, LOW);
digitalWrite(electro_in2, LOW);
}
else {
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
}
}
DETALLES:
-Tengo Arduino UNO
-Componentes ultilizados: (Relay 5V, Electrovalvula de 220v, Reloj DS1307, Caudalimetro YF-S201)
Desde ya muchisimas gracias!! Si no me explique bien diganme que no entendieron! Cualquier ayuda me es muy útil!
tener una variable como byte solo te permite 0 a 255 de tu contador lo que para un caudalimetro es poco.
La pasé a unsigned int lo que te da 0 a 65525.
He agregado un pulsador al pin 3 y lo debes conectar directamente entre GND y pin 3
Veamos como se comportan las 3 situaciones.
//Librerias
#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <EEPROM.h>
//Definimos variables
int electro_in1 = 12;
int electro_in2 = 11;
byte sensorInterrupt = 0; // 0 = digital pin 2
const byte sensorPin = 2;
const byte pulsadorPin = 3; // conectar aqui el pulsador entre pin y GND
float calibrationFactor = 7.5;
volatile unsigned int pulseCount;
float flowRate;
float totalLitres;
unsigned long oldTime;
bool estado, estadoAnt = false;
float volumen = 0;
float volumenMaximo = 5; //CAMBIAR ESTO DEPENDIENDO LOS LITROS MÁXIMOS
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void setup()
{
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the status LED line as an output
pinMode(electro_in1, OUTPUT);
pinMode(electro_in2, OUTPUT);
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
pinMode(sensorPin, INPUT);
pinMode(pulsadorPin, INPUT_PULLUP); // pulsador entre pin 3 y GND.
digitalWrite(sensorPin, HIGH);
pulseCount = 0;
flowRate = 0.0;
totalLitres = 0.0;
oldTime = 0;
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
//Para el RTC
setSyncProvider(RTC.get);
Alarm.alarmRepeat(00, 28, 10, ReiniciarVolumen); // Evento diario, podriamos ponerla a las 00,00,01. ESTO ME GUSTARIA CAMBIAR
}
void loop() {
estado = digitalRead(pulsador);
if (estado && estadoAnt) {
flag = true;
}
estadoAnt = estado;
if (volumen < volumenMaximo)
if ((millis() - oldTime) > 1000) { // Only process counters once per second
detachInterrupt(sensorInterrupt);
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Add the millilitres passed in this second to the cumulative total
totalLitres += flowRate / 60;
volumen = totalLitres;
// unsigned int frac;
Serial.print ("Caudal: ");
Serial.print (flowRate,3);
Serial.print ("L/min\tVolumen: ");
Serial.print (volumen,3);
Serial.println (" L");
if (volumen > volumenMaximo ){/* boton apretado && */
flag = true;
}
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
oldTime = millis();
}
if (flag)
ControlValvula();
Alarm.delay(1000);
}
// de las alarmas!!!
void ReiniciarVolumen() {
flag = true;
}
void ControlValvula() {
//Aca podria ir lo del boton para iniciar la electrovalvula
if (flag) {
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
flag = false;
}
else {
digitalWrite(electro_in1, LOW);
digitalWrite(electro_in2, LOW);
}
}
Las cosas funcionan cuando todas las condiciones son correctas.
Verificaste que el pulsador actúe como se espera?
Lo conectaste entre GND y el PIN3?
Prueba con esto
//Librerias
#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <EEPROM.h>
//Definimos variables
int electro_in1 = 12;
int electro_in2 = 11;
byte sensorInterrupt = 0; // 0 = digital pin 2
const byte sensorPin = 2;
const byte pulsadorPin = 3; // conectar aqui el pulsador entre pin y GND
float calibrationFactor = 7.5;
volatile unsigned int pulseCount;
float flowRate;
float totalLitres;
unsigned long oldTime;
bool estado, estadoAnt = false;
float volumen = 0;
float volumenMaximo = 5; //CAMBIAR ESTO DEPENDIENDO LOS LITROS MÁXIMOS
bool flag = false;
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void setup() {
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the status LED line as an output
pinMode(electro_in1, OUTPUT);
pinMode(electro_in2, OUTPUT);
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
pinMode(sensorPin, INPUT);
pinMode(pulsadorPin, INPUT_PULLUP); // pulsador entre pin 3 y GND.
pulseCount = 0;
flowRate = 0.0;
totalLitres = 0.0;
oldTime = 0;
// The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
// Configured to trigger on a FALLING state change (transition from HIGH
// state to LOW state)
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
//Para el RTC
setSyncProvider(RTC.get);
Alarm.alarmRepeat(00, 28, 10, ReiniciarVolumen); // Evento diario, podriamos ponerla a las 00,00,01. ESTO ME GUSTARIA CAMBIAR
}
void loop() {
estado = digitalRead(pulsador);
if (estado && estadoAnt) {
flag = true;
}
estadoAnt = estado;
if (volumen < volumenMaximo)
if ((millis() - oldTime) > 1000) { // Only process counters once per second
detachInterrupt(sensorInterrupt);
flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Add the millilitres passed in this second to the cumulative total
totalLitres += flowRate / 60;
volumen = totalLitres;
// unsigned int frac;
Serial.print ("Caudal: ");
Serial.print (flowRate,3);
Serial.print ("L/min\tVolumen: ");
Serial.print (volumen,3);
Serial.println (" L");
if (volumen > volumenMaximo ){ /* boton apretado && */
flag = true;
}
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
oldTime = millis();
}
if (flag)
ControlValvula();
Alarm.delay(1000);
}
// de las alarmas!!!
void ReiniciarVolumen() {
flag = true;
}
void ControlValvula() {
//Aca podria ir lo del boton para iniciar la electrovalvula
if (flag) {
digitalWrite(electro_in1, LOW);
digitalWrite(electro_in2, LOW);
flag = false;
}
else {
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
}
}
Hola, ahi anda 10 puntos. El problema es que no se apaga nunca la electrovalula (el relay). Probe cambiando flag a false, sacandolo del if, etcetera pero nunca se apaga (llega al limite y sigue tirando agua). Saludos!
Ahí le cambie un par de cosas y anduvo. Lo que no esta haciendo es que si se desconecta puedo usar 5L de nuevo, se podría guardar Volumen como variable en la EEPROM? o como se haria para que guarde o verifique volumen de antes (con volumen me refiero a cantidad de litros usada). Saludos, grande surbyte!!
//Librerias
#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <EEPROM.h>
//Definimos variables
int electro_in1 = 12;
int electro_in2 = 11;
byte sensorInterrupt = 0; // 0 = digital pin 2
const byte sensorPin = 2;
const byte pulsadorPin = 3; // conectar aqui el pulsador entre pin y GND
float calibrationFactor = 7.11;
volatile unsigned int pulseCount;
float flowRate;
float totalLitres;
unsigned long oldTime;
bool estado, estadoAnt = false;
float volumen = 0;
float volumenMaximo = 1; //CAMBIAR ESTO DEPENDIENDO LOS LITROS MÁXIMOS
bool flag = false;
void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void setup() {
// Initialize a serial connection for reporting values to the host
Serial.begin(9600);
// Set up the status LED line as an output
pinMode(electro_in1, OUTPUT);
pinMode(electro_in2, OUTPUT);
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
pinMode(sensorPin, INPUT);
pinMode(pulsadorPin, INPUT_PULLUP); // pulsador entre pin 3 y GND.
pulseCount = 0;
flowRate = 0.0;
totalLitres = 0.0;
oldTime = 0;
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
//Para el RTC
setSyncProvider(RTC.get);
Alarm.alarmRepeat(10, 28, 10, ReiniciarVolumen); // Evento diario, podriamos ponerla a las 00,00,01. ESTO ME GUSTARIA CAMBIAR
}
void loop() {
estado = digitalRead(pulsadorPin);
if (estado && estadoAnt) {
flag = true;
}
estadoAnt = estado;
if (volumen < volumenMaximo)
if ((millis() - oldTime) > 1000) { // Only process counters once per second
detachInterrupt(sensorInterrupt);
flowRate = (((1000.0) / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Add the millilitres passed in this second to the cumulative total
totalLitres += flowRate / 60;
volumen = totalLitres;
// unsigned int frac;
Serial.print ("Caudal: ");
Serial.print (flowRate,3);
Serial.print ("L/min\tVolumen: ");
Serial.print (volumen,3);
Serial.println (" L");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
oldTime = millis();
}
/* LE SAQUE ESTO, NO HACIA NADA
if (volumen >= volumenMaximo ){
flag = false;
}
*/
if (flag)
ControlValvula();
Alarm.delay(1000);
}
// de las alarmas!!!
void ReiniciarVolumen() {
flag = true;
}
void ControlValvula() {
// if (flag) { (CON ESTO NO ANDA, PORQUE SERA? MI HIPOTESIS ES QUE UNA VEZ QUE ARRANCA LA ELECTROVALVULA EL FLAG NO SE ACTUALIZA, ESTO ES MUY RARO)
if (volumen <= volumenMaximo ) {
digitalWrite(electro_in1, LOW);
digitalWrite(electro_in2, LOW);
//flag = false;
}
else {
digitalWrite(electro_in1, HIGH);
digitalWrite(electro_in2, HIGH);
}
}
void loop() {
estado = digitalRead(pulsadorPin);
if (estado && !estadoAnt) {
flag = true;
}
estadoAnt = estado;
if (volumen < volumenMaximo)
if ((millis() - oldTime) > 1000) { // Only process counters once per second
detachInterrupt(sensorInterrupt);
flowRate = (((1000.0) / (millis() - oldTime)) * pulseCount) / calibrationFactor;
// Add the millilitres passed in this second to the cumulative total
totalLitres += flowRate / 60;
volumen = totalLitres;
// unsigned int frac;
Serial.print ("Caudal: ");
Serial.print (flowRate,3);
Serial.print ("L/min\tVolumen: ");
Serial.print (volumen,3);
Serial.println (" L");
// Reset the pulse counter so we can start incrementing again
pulseCount = 0;
// Enable the interrupt again now that we've finished sending output
attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
oldTime = millis();
}
if (volumen >= volumenMaximo )
flag = false;
if (flag)
ControlValvula(LOW);
else
ControlValvula(HIGH);
Alarm.delay(1000);
}
// de las alarmas!!!
void ReiniciarVolumen() {
flag = true;
}
void ControlValvula(bool tmp) {
digitalWrite(electro_in1, tmp);
digitalWrite(electro_in2, tmp);
}
void loop() {
estado = digitalRead(pulsadorPin);
if (estado && estadoAnt) {
flag = true;
}
estadoAnt = estado;
y le puse esto
if (digitalRead(pulsadorPin)){ // Cuando el pulsador está activo...
estado = !estado; // Asigna el valor contrario (ON --> OFF --> ON --> OFF...)
}
if(estado){ // si Valor_pulsador es Verdadero --> 1 --> ON
flag = true; // Enciende el Led
}
else { // De lo contrario
flag = false; // Apaga el Led
}
me funciono ahi apagar y volver a encender, como si fuera un interruptor. esta bien no?
Si te funciona estará bien.
Si lo vas a usar de ese modo entonces no uses estado para luego cambiar flag sino hazlo directamente sobre flag
Lo que no me gusta es que
esta accción
if (digitalRead(pulsadorPin)){ // Cuando el pulsador está activo...
estado = !estado; // Asigna el valor contrario (ON --> OFF --> ON --> OFF...)
}
cambia estado cada vez que se completa el loop, o sea en un segundo cuantas veces puede cambiar? muchas.
En cambio esto
estado = digitalRead(pulsadorPin);
if (estado && !estadoAnt) {
flag = true;
}
estadoAnt = estado;
Lo hace solo de 0 1 y si quieres el contrario entonces simplemente agregas esto
estado = digitalRead(pulsadorPin);
if (estado && !estadoAnt) { // <= revisa porque estadoAnt debe ir con ! antes
flag = true;
}
if (!estado && estadoAnt) {
flag = true;
}
estadoAnt = estado;