Go Down

Topic: Funcion booleana, como cambiar el estado? [Solucionado] Gracias! (Read 6092 times) previous topic - next topic

AlexLPD

Hola buenas, me he buscado un poc por ahi, pero parece ser que todos los ejemplos hablan de funciones
int, y bueno la cosa va a asi;

tengo esta subrutina;
Code: [Select]

boolean termostato(){
  analogRead(sondaTempRefrigeracion);
  tempVitrina= map(sondaTempRefrigeracion, 500, 4500, -40, 60); //revisar la hoja de datos de la sonda
    if(tempVitrina => inicioRefrigeracion){
      termostato = true;
      lcd.print ("Compresor ON");
      refrigeracionyventiladores();       }

    else if(tempVitrina <= finalRefrigeracion){
      termostato = false;
      lcd.print ("Compresor OF");
      soloventiladores(); }


Quiero lograr que la subritina lea una sonda de temperatura, mapee el valor de -40 a 60°C
que estaremos usando mas adelante.

En resumidas cuentas.... necesito saber como cambiar el estado de boolean termostato();
entre true y false


La ideas que tengo son;
1.- La subrutina evalua la temperatura actual de la vitrina y la comprara contra el limite inferior, si es mayor ... enciende la refrigeracion... esta evaluando la temperatura y una vez que alcanza el limite superior, empieza un delay (SIN DELAY) quiero que el cogido haga algo asi como;

Si tem == deseada
     contar 5 segundos
     entonces{ incia subrutina de paro de frio}
si temp => deseada
   contar 5 segundos
   entonces {inicia subrutina de frio}

La razon por la que no quiero usar delay, es por que voy a hacer mas funciones, y esto entorpeceria el programa.

Les dejo el pedacito de programa que llevo
ya que me ha señalado dos errores uno que esperaba un > antes de un pointer.
y otro que c++ prohibe comprar int contra boolean creo.

Code: [Select]

//LIBRERIAS
#include <LiquidCrystal.h>

//DECLARACION DE PINES
const byte sondaTempRefrigeracion = A0;
const byte sondaTempCongelacion   = A1; 
const byte solCompresor = 2;
const byte solEvaporador =3;
const byte compresor    = 4;
const byte ventiladores = 5;

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

//VARIABLES QUE PUEDEN SER ALTERADAS DURANTE EL PROGRAMA
int tempVitrina = 0;
int tempCongelador = 0;
int inicioRefrigeracion =0;
int finalRefrigeracion  =0;
int temCongelador = 0;


//FLAGS
boolean Encendido = false;


void setup(){
//INICIALIZACION
digitalWrite(solCompresor, LOW);
digitalWrite(solEvaporador, LOW);
digitalWrite(compresor, LOW);
digitalWrite(ventiladores, LOW);
}

void loop(){
 if (Encendido == true){

         boolean termostato();
           if(termostato == false){
               soloventiladores();}
           //else if(termostato == true){
             refrigeracionyventiladores();}
 
 else{
 lcd.print( "Vitrina Apagada");     
 }
 
 
 
}


boolean termostato(){
  analogRead(sondaTempRefrigeracion);
  tempVitrina= map(sondaTempRefrigeracion, 500, 4500, -40, 60); //revisar la hoja de datos de la sonda
    if(tempVitrina => inicioRefrigeracion){
      termostato = true;
      lcd.print ("Compresor ON");
      refrigeracionyventiladores();       }

    else if(tempVitrina <= finalRefrigeracion){
      termostato = false;
      lcd.print ("Compresor OF");
      soloventiladores(); }
   

}

void refrigeracionyventiladores(){
  digitalWrite(ventiladores, HIGH); 
//   delay(1500);
  digitalWrite(compresor, HIGH);
}
 
void soloventiladores(){
  digitalWrite(ventiladores, HIGH);
   //   delay(1500);
  digitalWrite(compresor, LOW);
}



Gracias por sus comentarios.
 :smiley-cool:
-Alex-

surbyte

#1
Dec 16, 2014, 04:17 am Last Edit: Dec 16, 2014, 04:18 am by surbyte
El primer error simple que tienes en termostado es este
analogRead(

devuelve un entero de modo que estas perdieron la información.
los valores que entrega estan entre 0 y 1023, jamás entre 500 y 4500, no se de donde sacas esos valores  a menos que viniesen expresados en milivolts y fueran 500 y 4500 mV.
supongo que 0 es -40 grados y 60 es el máximo de la sonda.

Code: [Select]

boolean termostato() {
  unsigned int valor =  analogRead(sondaTempRefrigeracion);
  tempVitrina= map(valor, 0, 1023, -40, 60); //revisar la hoja de datos de la sonda
    if(tempVitrina >= valor){  // se compara >= no a la inversa
      termostato = true;
      lcd.print ("Compresor ON");
      timeRyV = millis();
      refrigeracionyventiladores();       
    }else
    if (tempVitrina <= valor) {
       termostato = false;
       lcd.print ("Compresor OFF");
       timeSV = millis();
       soloventiladores();
   }
}


A ver si ahi se comporta mejor.

Code: [Select]

void refrigeracionyventiladores(){
   
  if (millis() - timeRyV < 1500) {
     digitalWrite(ventiladores, HIGH);
  } else digitalWrite(compresor, HIGH);
}
 
void soloventiladores(){
 
    if (millis() - timeSV < 1500) {
       digitalWrite(ventiladores, HIGH);
   } else digitalWrite(compresor, LOW);
}


No se si te interpreté bien sobre que debe hacer durante el delay. Hablas de 5 segundos, pero comentados habian delays de 1.5 seg.
En fin se ajusta o cambia facilmente.


AlexLPD

Efectivamente!

Pimero que nada gracias, @Surbyte...

Y efectivamente... estaba equivado en el analog read...  mañana me llega la sonda y podre conectarla para revisar bien, ya que va de -40 a 60°C o algo así, cosa facil en el calibrate.

Efectivamente el timer que pones era lo que tenia pensado!


AlexLPD

Vaya... tira los siguientes errores;

Code: [Select]

Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino: In function 'void loop()':
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino:39: warning: the address of 'boolean termostato()' will never be NULL
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino: In function 'boolean termostato()':
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino:56: warning: comparison between signed and unsigned integer expressions
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:57: error: assignment of function 'boolean termostato()'
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:57: error: cannot convert 'int' to 'boolean ()()' in assignment
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:59: error: 'timeRyV' was not declared in this scope
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino:63: warning: comparison between signed and unsigned integer expressions
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:64: error: assignment of function 'boolean termostato()'
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:64: error: cannot convert 'int' to 'boolean ()()' in assignment
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:66: error: 'timeSV' was not declared in this scope
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino:68: warning: no return statement in function returning non-void
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino: In function 'void refrigeracionyventiladores()':
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:75: error: 'timeRyV' was not declared in this scope
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable.ino: In function 'void soloventiladores()':
Termostato_digital_con_dos_zonas_de_frio_y_deshielo_programable:81: error: 'timeSV' was not declared in this scope



El codigo es;

Code: [Select]

//LIBRERIAS
#include <LiquidCrystal.h>

//DECLARACION DE PINES
const byte sondaTempRefrigeracion = A0;
const byte sondaTempCongelacion   = A1;  
const byte solCompresor = 2;
const byte solEvaporador =3;
const byte compresor    = 4;
const byte ventiladores = 5;


LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

//VARIABLES QUE PUEDEN SER ALTERADAS DURANTE EL PROGRAMA
int tempVitrina = 0;
int tempCongelador = 0;
int inicioRefrigeracion =0;
int finalRefrigeracion  =0;
int temCongelador = 0;


//FLAGS
boolean Encendido = false;


void setup(){
//INICIALIZACION
digitalWrite(solCompresor, LOW);
digitalWrite(solEvaporador, LOW);
digitalWrite(compresor, LOW);
digitalWrite(ventiladores, LOW);
}

void loop(){
 if (Encendido == true){

         boolean termostato();
           if(termostato == false){
               soloventiladores();}
           //else if(termostato == true){
             refrigeracionyventiladores();}
 
 else{
 lcd.print( "Vitrina Apagada");    
 }
  
  
  
}


boolean termostato(){
  unsigned int valor =  analogRead(sondaTempRefrigeracion);
  tempVitrina= map(valor, 0, 1023, -40, 60); //revisar la hoja de datos de la sonda
    if(tempVitrina >= valor){  // se compara >= no a la inversa
      termostato = true;
      lcd.print ("Compresor ON");
      timeRyV = millis();
      refrigeracionyventiladores();}
    
    else
    if (tempVitrina <= valor)      {
       termostato = false;
       lcd.print ("Compresor OFF");
       timeSV = millis();
       soloventiladores();         }
}

  



void refrigeracionyventiladores(){
  if (millis() - timeRyV < 1500){
      digitalWrite(ventiladores, HIGH);  
      digitalWrite(compresor, HIGH); }}
      
  
void soloventiladores(){
  if (millis() - timeSV < 1500){
  digitalWrite(ventiladores, HIGH);
   //   delay(1500);
  digitalWrite(compresor, LOW); }}



Lo de los timers es solo por que no se declararon en las variables globales, pero
me intriga que dice que no puede darle el valor de un int a un boolean... yo lo veo y lo veo y no encuentro tal cosa...

surbyte

Te lo corregí pero igualmente esta mal programado algo.
en el loop() consultas por termostato() que ahora si funcionará supongo.
Pero luego optas por enviar a las subrutiinas refrigeracionyventiladores() y soloventiladores pero dentro de termostato haces lo mismo.
decide, lo haces en un lado u otro pero no en ambos.
lo lógico es que termostato sea un termostato y tu loop haga el control.
O sea, retira de la subrutina termostato los llamados a esos dos controles

Code: [Select]
//LIBRERIAS
#include <LiquidCrystal.h>

//DECLARACION DE PINES
const byte sondaTempRefrigeracion = A0;
const byte sondaTempCongelacion   = A1;
const byte solCompresor = 2;
const byte solEvaporador = 3;
const byte compresor    = 4;
const byte ventiladores = 5;


LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

//VARIABLES QUE PUEDEN SER ALTERADAS DURANTE EL PROGRAMA
int tempVitrina = 0;
int tempCongelador = 0;
int inicioRefrigeracion = 0;
int finalRefrigeracion  = 0;
int temCongelador = 0;
unsigned int valor;
unsigned long timeRyV, timeSV;

//FLAGS
boolean Encendido = false;


void setup() {
  //INICIALIZACION
  digitalWrite(solCompresor, LOW);
  digitalWrite(solEvaporador, LOW);
  digitalWrite(compresor, LOW);
  digitalWrite(ventiladores, LOW);
}

void loop() {
  if (Encendido == true) {
    if (termostato() == false) {
      soloventiladores();
    }
    //else if(termostato == true){
    refrigeracionyventiladores();
  }
  else {
    lcd.print( "Vitrina Apagada");
  }
}


boolean termostato() {
 
  valor =  analogRead(sondaTempRefrigeracion);
  tempVitrina = map(valor, 0, 1023, -40, 60); //revisar la hoja de datos de la sonda
  if (tempVitrina >= valor) { // se compara >= no a la inversa
      // termostato = true;
      lcd.print ("Compresor ON");
      timeRyV = millis();
      refrigeracionyventiladores();
      return true;  // es el equivalente a que funcionara termostato = true que no puede hacerse de ese modo
  } else if (tempVitrina <= valor) {
           
            lcd.print ("Compresor OFF");
            timeSV = millis();
            soloventiladores();
            return false;
         }
}


void refrigeracionyventiladores() {

  if (millis() - timeRyV < 1500) {
    digitalWrite(ventiladores, HIGH);
  } else digitalWrite(compresor, HIGH);
}

void soloventiladores() {

  if (millis() - timeSV < 1500) {
    digitalWrite(ventiladores, HIGH);
  } else digitalWrite(compresor, LOW);
}

AlexLPD

 :smiley-eek-blue:
Efectivamente, tienes razon @Surbyte....

Una vez modificado me queda así...



Creo que se nos barrio a los dos, declarar la variable booleana que retorna la funcion  :smiley-lol:

Pero una vez haciendo los ajustes que me recomiendas;

Code: [Select]

//LIBRERIAS
#include <LiquidCrystal.h>

//DECLARACION DE PINES
const byte sondaTempRefrigeracion = A0;
const byte sondaTempCongelacion   = A1; 
const byte solCompresor = 2;
const byte solEvaporador =3;
const byte compresor    = 4;
const byte ventiladores = 5;
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

//VARIABLES QUE PUEDEN SER ALTERADAS DURANTE EL PROGRAMA
int tempVitrina = 0;
int tempCongelador = 0;
int enciendeRefrigeracion =0;
int apagaRefrigeracion  =0;
int temCongelador = 0;

//VARIABLES GLOBALES
unsigned int timeRyV = 0;
unsigned int timeSV = 0;

//FLAGS
boolean Encendido = false;
boolean Termo = false;

void setup(){
//INICIALIZACION
digitalWrite(solCompresor, LOW);
digitalWrite(solEvaporador, LOW);
digitalWrite(compresor, LOW);
digitalWrite(ventiladores, LOW);
}

void loop(){
 if (Encendido == true){
         
         lcd.print("Temp vitrina ");
         lcd.print("Temp Conge ");
         
         boolean termostato();
           
 
 else{
 lcd.setCursor (0,1);
 lcd.print( "Vitrina Apagada");}
}
}


boolean termostato(boolean Termo){
  unsigned int valor =  analogRead(sondaTempRefrigeracion);
 
  tempVitrina= map(valor, 0, 1023, -40, 60); //revisar la hoja de datos de la sonda
    if(tempVitrina >= enciendeRefrigeracion){  // se compara >= no a la inversa
      Termo = true;
      lcd.print ("Compresor ON");
      timeRyV = millis();
      refrigeracionyventiladores();}
   
    else
    if (tempVitrina <= apagaRefrigeracion)      {
       Termo = false;
       lcd.print ("Compresor OFF");
       timeSV = millis();
       soloventiladores();         }
}

 

void refrigeracionyventiladores(){
  if (millis() - timeRyV < 1500){
      digitalWrite(ventiladores, HIGH); 
      digitalWrite(compresor, HIGH); }}
     
 
void soloventiladores(){
  if (millis() - timeSV < 1500){
      digitalWrite(ventiladores, HIGH);
      digitalWrite(compresor, LOW); }}



Creo que por el momento para hacerlo mas legible dejare que el termostato encienda y apague la refrigeración, ya que aun me falta leer un encoder e imprimir texto como un menu en el LCD
La idea es poder usar el ecoder para seleccionar la temperatura de encendido y de paro... y debido a que este es mueble frio muy largo, quizas ponga unas 4 sondas de temperatura, y haga una subrutina que avise si alguna de las zonas esta fuera de su tempertarura (Potencial fallo en el sistema de refrigeracion)

Muchas Gracias!....

surbyte

#6
Dec 17, 2014, 01:58 pm Last Edit: Dec 17, 2014, 01:58 pm by surbyte
Un detalle que no vi en el post anterior o mejor dicho lo vi pero no lo documenté.
Mira esto

Code: [Select]
if (tempVitrina >= valor) { // se compara >= no a la inversa
   
Code: [Select]
} else if (tempVitrina <= valor) {

ves que en una tienes >= y en la otra <= asi no está bien.

Una debe incluir el igual y la otra no. Tu determina cual proceso es el que deba hacerlo.

AlexLPD

 :)  Tienes razon de nuevo @Surbyte

Lo modifico ya que arregle lo de los menus.

Gracias!!!!

Go Up