Potenciometros analogicos - limites de temperatura [Solucionado]

Hola que tal, pues resulta que me salio un pequeño projecto... muy sencillo
se trata solamente de un termostato con una temperatura de inicio y una final.

Ademas tenemos un sensor de humedad y lo imprimimos todo en la LCD...

La idea basica era usar una libreria pero resulta que me cuesta mucho trabajo y no tengo de momento soporte, hablo de MENWIZ que es una maravilla, mas por desconocimiento no puedo hacer que trabaje como yo quiero.

Asi que me pregunte si puedo poner dos potenciomentros analogicos como limite inferior y superior respectivamente (tiene la ventaja que es mas sencillo para el usuario)

Idea general; la lcd imprime la temperatura en F y C ademas de la humedad.

Al mover un potenciometro la lcd cambia mostrado la nueva temperatura de incio o de final dependiendo de que potenciomentro se haya movido...

Ya tengo funcionando los sensores, ya imprimen la temperatura y humedad, solo me falta el ajuste, asi que si alguien me puede ayudar un poco se los agradeceria.

Intentaba hacer algo como;

leer_sensores// en relidad potenciomentros no lo he arreglado

si lectura actual =! anterior → Pantalla ajuste temp

si no pantalla_normal();

Por algun motivo(sospecho que no hay un debounce adecuado)
se imprime la pantalla de ajuste de temperatura.

Bueno, les dejo el codigo;

#include <Wire.h>
#include <OneWire.h>
#include <dht.h>                     //Libreria para DTH
#include <DallasTemperature.h>       //Libreria Ds1820
#include <LiquidCrystal_I2C.h>       //Libreria IC2 

dht DHT;                             //constructor del objeto 
#define DHT11_PIN 5                  // Pin sensor DTH

#define ONE_WIRE_BUS 2               //Pin Sensor temperatura
OneWire oneWire(ONE_WIRE_BUS);       //define un bus para comunicarse con cualquier sensor 
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature. 
DeviceAddress insideThermometer;     // arrays to hold device address

                                     //Constructor objeto LCD 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

//----------------------------------Variables Globlales ------------------------------------------//
int humedad = 0;                  //lectura del sensor de humedad
float tempC =   0;                //lectura del termomentro 
float tempF =   0;                //en farenheit 

float tempInicoSet = 0;           //variable para incial calefaccion 
float tempFinalSet = 0;           //variable para terminar calefaccion

byte AR_inc =0;                   //Analog read Incio 
byte AR_fin =0;                   //Analog read final 

float tempInicoAnt= 0; 
float tempFinalAnt= 0; 

////////////////////////////////////VOID SET UP///////////////////////////////////////////////////////
void setup(void)
{
  pinMode(A0, INPUT); 
  pinMode(A1, INPUT); 
  Serial.begin(9600);
  lcd.begin(16,2);
  //-----------------------------------SENSOR DS1820-------------------------------------------------//
  // locate devices on the bus
  sensors.begin();
  Serial.print(sensors.getDeviceCount(), DEC);
  //Linea para debug 
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  Serial.print("Device 0 Address: ");
  //Funcion para imprimir la direccion del dispositivo  --printAddress(insideThermometer);
  // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  sensors.setResolution(insideThermometer, 10);
  //--------------------------------SENSOR DTH-------------------------------------------------------//
  Serial.println("DHT TEST PROGRAM ");
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("     SANHER");
  lcd.setCursor(0,1);
  lcd.print("   INGENIEROS"); 
  delay(4000);
  lcd.clear(); 
  lcd.setCursor(0,0);
  lcd.print("   10/01/2015");
  delay(2000);
  lcd.clear();
}


void loop(void){ 
  lee_sensores();
  
  if(tempInicoSet =! tempInicoAnt){
     cambioTempIncio(); }
  
  if(tempFinalSet =! tempFinalAnt){
     cambioTempFinal(); }
     
  // READ DATA
  Serial.print("DHT11, \t");
 int chk = DHT.read11(DHT11_PIN);
  switch (chk)
  {
    case DHTLIB_OK:  
		Serial.print("OK,\t"); 
		break;
    case DHTLIB_ERROR_CHECKSUM: 
		Serial.print("Checksum error,\t"); 
		break;
    case DHTLIB_ERROR_TIMEOUT: 
		Serial.print("Time out error,\t"); 
		break;
    default: 
		Serial.print("Unknown error,\t"); 
		break;
  }
  //PRINT DATA   
  humedad = (DHT.humidity);
  Serial.print(humedad);
  
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  sensors.requestTemperatures(); // Send the command to get temperatures
  
  // It responds almost immediately. Let's print out the data
  printTemperature(insideThermometer); // Use a simple function to print out the data

  if (humedad < 40){
  alarma_humedad();}

//if (tempC < 25)
//  alarma_bajatemp();
  
   pantallaNormal();


Serial.print("Analog read 1 ="); Serial.println(AR_inc); 
Serial.print("Analog read 2 ="); Serial.println(AR_fin); 
Serial.print("  Temp Incio = ");   Serial.println(tempInicoSet); 
Serial.print("  Temp final = ");   Serial.println(tempFinalSet); 
Serial.println("----------------------"); 
}



//---------------------------FUNCIONES AUXILIARES ------------------------------------//

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  tempC = sensors.getTempC(deviceAddress);
  tempF = DallasTemperature::toFahrenheit(tempC); // Converts tempC to Fahrenheit
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.println(tempF); 
}


void pantallaNormal(){
  lcd.clear();
  lcd.setCursor(0,0);  
  lcd.print(tempC); 
  lcd.setCursor(0,1);
  lcd.print(tempF);
  lcd.setCursor(6,0); 
  lcd.print("C");
  lcd.setCursor(6,1);
  lcd.print("F"); 
  lcd.setCursor(9,0); 
  lcd.print("HUMEDAD");
  lcd.setCursor(11,1);  
  lcd.print(humedad); 
}

void lee_sensores(){
  AR_inc = analogRead(A0); 
  AR_fin = analogRead(A1);
 
  tempInicoSet = map(AR_inc,0, 254, 19, 51);   
  tempFinalSet = map(AR_fin,0, 254, 19, 51);     
}


void cambioTempIncio(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("  Temp Inic"); 
  lcd.setCursor(0,1); 
  lcd.print(tempInicoSet); 
  tempInicoSet = tempInicoAnt; 
}


void cambioTempFinal(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("  Temp Final"); 
  lcd.setCursor(0,1); 
  lcd.print(tempFinalSet); 
  tempFinalSet =tempFinalAnt; }


void alarma_humedad(){
   lcd. clear(); 
   lcd.setCursor(0,0);  
   lcd.print("      BAJA"); 
   lcd.setCursor(0,1);  
   lcd.print("    HUMEDAD"); 
   delay(3000); }

void alarma_bajatemp(){
   lcd. clear(); 
   lcd.setCursor(0,0);  
   lcd.print("      BAJA"); 
   lcd.setCursor(0,1);  
   lcd.print("  TEMPERATURA"); 
   delay(3000); }

Esta un poco sucio todavia, pero no lo he terminado espero se pueda entender...
Abajo esta la alarma por temperatura ... en lugar de un valor fijo... se contrastara contra el limite inferior que se lea del potenciometro..

Los potenciometros me dan una lectura analogica entre 0 y 256, es por eso que escogí ese rango en la funcion map...

Como puedo hacer un debounce adecuado?

Sera suficiente algo asi;
primera_lectura
delay(50);
segunda_lectura

if(primera_lectura =! segunda_lectura); ??????

Bueno... de ante mano... Gracias!!!!!

Saludos.
-Alex.

¿Un Industrial Engineer necesita ayuda para una cosa tan simple?

Solo soy un aficionado al Arduino, no me atrevo a orientarte para un trabajo profesional remunerado.

Jopapa

Si! Necesito una idea

Jeje en la carrera no llevaba un gramo de.electrónica... Y no no es remunerado un amigo tiene una incubadora de gallos q no le incuba mas....

Gracias @Jopapa

Supongo que para incubar un huevo se necesita una temperatura constante.
Si por ejemplo fuese 30ºC, yo pondría un solo potenciómetro. Con él determinas la temperatura que quieres y por software Arduino le dice al calefactor que conecte a <=29 y desconecte a >=31.
Mas simple.
El potenciómetro conectado a una entrada analógica que te dará un voltaje entre 0 y 1023. Esos valores los pasas a los valores de temperatura que quieras con la función MAP del Arduino y listo.

Jopapa
ww.jopapa.me

Yo soy la voz de la discorida respecto del menú Alex, dime que problema tuviste con MENWIZ ?
Por que Si funciona!

Mirando tu programa veo largos Serial.print(XXXXXXXXXXX)
aprende a usar esto que es mas facil y cómodo

Dos alternativas:

  1. defines un char str[24]; // la dimensión a gusto

reemplazo de

 lcd.print(tempC); 
  lcd.setCursor(0,1);
  lcd.print(tempF);
  lcd.setCursor(6,0); 
  lcd.print("C");
  lcd.setCursor(6,1);
  lcd.print("F"); 
  lcd.setCursor(9,0); 
  lcd.print("HUMEDAD");
  lcd.setCursor(11,1);  
  lcd.print(humedad);

luego usas

sprintf(str, "%d °C %d °F %d", tempC, tempF, humedad)
Serial.println(str);

puedes controlar el espaciado usando %4d entonces reserva 4 espacios para el entero y lo llena con lo que corresponda y el resto son espacios vacíos.

Alternativa dos.
Usas una librería muy simple que se llama printf.h y todo se simplifica en una operación, pero obvio, debes incluirla como

#define "printf.h" si esta en el directorio del sketch por ejemplo

y la usas directo y simplificando el Serial.println

 printf("%d °C %d °F %d\n", tempC, tempF, humedad);

el comando al final \n es el cambio de linea.

Luego te paso el link que ahora no encuentro.

Aporto algo a lo que sugiere jopapa que tiene toda la razón. Solo 1 potenciómetro alcanza.
Pero deberías considerar un control PID. Luego lo hablamos pero cuando se trata de mantener la temperatura hay que trabajar con PID.
Tu control es un P o sea Proporcinal. El otro suma Integral y Diferencial.

surbyte:
Yo soy la voz de la discorida respecto del menú Alex, dime que problema tuviste con MENWIZ ?
Por que Si funciona!

Hola !! @Surbyte, que gusto verte por aca... !!!!

Muchas gracias por la observación, en efecto de momento es algo sencillo y quiero usar dos potenciometros
para darle la felxibilidad al usuario que seleccione sus propias temperaturas o que las modifique a gusto... la verdad no se que tanta atención le pongan a esto.

Si definitivamente quiero aprender mas de PID tienen sus usos y seguramente mas pronto que nada se requerirán.

En cuento a la funcion para imprimir... te hare caso... esto del serial print, es muy cansado
hasta para un debug como el cogido que posteare a continuacion son varias cosas...

De MENWIZ ya me di una buena buscada y no encontre como solucionar el error, mira hasta hice varios post;

Descripcion del problema en español
En displays en ingles
En el sub menu de menwiz

Saludos de nuevo @Surbyte!!!!! Feliz año!

Jopapa:
Supongo que para incubar un huevo se necesita una temperatura constante.
Si por ejemplo fuese 30ºC, yo pondría un solo potenciómetro. Con él determinas la temperatura que quieres y por software Arduino le dice al calefactor que conecte a <=29 y desconecte a >=31.
Mas simple.
El potenciómetro conectado a una entrada analógica que te dará un voltaje entre 0 y 1023. Esos valores los pasas a los valores de temperatura que quieras con la función MAP del Arduino y listo.

Jopapa
ww.jopapa.me

Asi es! ... En efecto... solo que quiero establecer tambien el limite inferior en caso de que lo quieran mover dependiendo la variedad de gallo que vayan a criar o que se yo!

Gracias!

Bueno pues parece que el siguiente codigo funciona adecuadamente
ahora solo lo agregare al anterior !

Lo dejo por si alguien mas lo necesitara;

int pod_uno= 0; 
int pod_dos= 0; 

int pod_uno_pasado= 0; 
int pod_dos_pasado= 0; 
int diferencia1 = 0; 
int diferencia2 = 0; 
byte valor_debounce = 4; //cambiar para mejorar filtrado
float tem_inicio = 0; 
float tem_final = 0; 

void setup(){ 

  pinMode(A0, INPUT); 
  pinMode(A1, INPUT); 
  Serial.begin(9600);
}
  

void loop(){
  lee_pods(); 
  
  tem_inicio = map(pod_uno, 0, 1024, 19, 51);     
  tem_final  = map(pod_dos, 0, 1024, 19, 51); 

Serial.print("Analog Read     "); Serial.print(pod_uno); Serial.print("     "); Serial.println(pod_dos);  
Serial.print("Valores       "); Serial.print(tem_inicio); Serial.print("     "); Serial.println(tem_final); 
delay(100); 
}

void lee_pods(){
  pod_uno_pasado= analogRead(A0); 
  pod_dos_pasado= analogRead(A1); 
  delay(75); 
  pod_uno= analogRead(A0); 
  pod_dos= analogRead(A1); 
 
 diferencia1 = pod_uno-pod_uno_pasado; 
 diferencia2 = pod_dos-pod_dos_pasado; 
 
 if (diferencia1 > valor_debounce){
   Serial.println("cambio en el pod uno ");
   }
 if (diferencia2 > valor_debounce){
   Serial.println("cambio en el pod dos ");
   }
 
}

Si alguien tiene demasiados problemas de ruido, recomiendan poner un capacitor de 1uF entre el Analog pin y tierra, en caso de ruidos graves.

Por el momento a mi me funciona el puro codigo.
:sunglasses: :sunglasses: :sunglasses:

Tu código no tiene promediacion de las muestras. Esa es una técnica simple para limitar el ruido.
Luego hay una o dos rutinas muy eficaces que uso yo, una es de mediana y otra de un promedio pesado.
Armo algo y te lo paso.

surbyte:
Tu código no tiene promediacion de las muestras. Esa es una técnica simple para limitar el ruido.
Luego hay una o dos rutinas muy eficaces que uso yo, una es de mediana y otra de un promedio pesado.
Armo algo y te lo paso.

Vaya eso si no se me había ocurrido.... Suena muy interesante... Ya ando estudiando el prinf.

En algo aparte, soy el único al que el foro no le notifica de cambios en los post? A pesar de q ya lo defini así?.

Gracias!

Anda mal el tema de las notificaciones, varios se han quejado al respecto. yo entro y miro los mensajes actualizados o nuevos. Nunca espero respuestas por mi casilla de correo. De hecho elimniné las notificaciones, para que las quiero si sigo todos los avances del foro?