dtfrost at convert floats to chars. Stops Arduino

Hi to all!

I always have this luck to escalate from problems :disappointed_relieved:

Im doing a thermostat for start and stop a resistor. After a very frustrating attempt to do so by two pots and analog read.

I switch to a menu code... MENWIZ... make the menu set the variables all good to go, but then the code uses a normal screen to display sensors and stuff like in a char type...

1.-Problem; convert float number to a string or chart.[SOLVED... SORT OF]
After investigate, the c++ is capable to do so by using itoa, but for space reasons this was left
behind the arduino compiler.

So I search the web and I found a perfect function to do this; dtostrf...
Thanks to Nick Gammon on this post
So I implement on the sketch and works !

I tested using; //Code snip

dtostrf(tempC, 10, 2, stempC);                        // Pass the float value to char 
Serial.print("String C"); Serial.println( stempC); //prints on serial 
dtostrf(tempF, 10, 2, stempF); 
Serial.print("String F"); Serial.println (stempF); 
Serial.println("---------------------------------");   //space bar.

PROBLEM TO SOLVE;

The arduino stops after some iteration, I count 36.

After the problem strikes me... I seek to search a litte bit more and found the way to save on flash
static comments or strings like so;

dtostrf(tempC, 10, 2, stempC); 
Serial.print(F("String C")); Serial.println( stempC); 
dtostrf(tempF, 10, 2, stempF); 
Serial.print(F("String F")); Serial.println (stempF); 
Serial.print("freeMemory()=");Serial.println(freeMemory());

I was thinking, it might solve the problem but dont...

After that point Im kind of lost... I don't have an specific problem to deal width... just symptoms and I would thank you for some hints on this.

THINGS ALREADY DO;
1.- Install memoryfree library to see if there was any free memory... it marks 516 steady.

2.- Try to uncomment the static screen to see if the chars was overloading it.

3.- Clean the chars by mychar[0] = 0; At the begining of the loop to see if there was a rollover problem.

4.- Uninstall all libraries dont requiered for the program to work (include memoryfree);

5.- Try to count the numbers of iterations on each reaset by adding a variable like so;

global variable byte myVariable = 0; 
     void loop(){
myVariable = myVariable++
//myVariable++
//myVariable +1
Serial.print("My Variable") Serial.println(myVariable);

In all cases above the serial output was 1.
So I cant count precisely the iterations.

ALTERNATIVES TO SOLUTION

1.- Some sort of menu implementation to up and down two float values.
I already seek phi-menu, M2klib but there are too big for this.

2.- Find a problem on the sketch and fix it.
And this is were I ask for help to delimitate the problem since I dont know what else to do!!!!

I leave the complete code here:

//=====================================LIBRERIAS==================================================//
#include <MemoryFree.h>
#include <OneWire.h>
#include <dht.h>                     //Libreria para DTH
#include <DallasTemperature.h>       //Libreria Ds1820


#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>       //Libreria IC2 
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>

//=====================================COSNTRUCTORES =============================================//
// DEFINE ARDUINO PINS FOR THE NAVIGATION BUTTONS
#define UP_BUTTON_PIN       9
#define DOWN_BUTTON_PIN     10
#define LEFT_BUTTON_PIN     7 
#define RIGHT_BUTTON_PIN    8
#define CONFIRM_BUTTON_PIN  12
#define ESCAPE_BUTTON_PIN   11

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

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

//=====================================GLOBAL VARIABLES==============================================//
float ti = 19.00;
float tf = 25.00;

const byte led =13;              //led to chek if the heating element has staring 
const byte rele = 4;             //pin to start or stop heating element
int humidity =  0;               //read the humidity sensor 
float tempC =   0;              //read the sensor temperature  
float tempF =   0;              //farenheit 

char stempC [10];              //Char to hold the temperature on C 
char stempF [10];              //Char to hold the temperature on F 
int iteracion = 0; 
//=====================================VOID SET UP ==================================================//
void setup(void)
{
Serial.begin(9600);

  pinMode(A0, INPUT); 
  pinMode(A1, INPUT); 
  pinMode(led, OUTPUT);

//-----------------------------------MENWIZ MENU-------------------------------------------------//
  _menu *r,*s1,*s2;
  _var *v; 
  int  mem;
  
// inizialize the menu object (16 colums x 2 rows)
  menu.begin(&lcd,16,2);
//create the menu tree
 r=menu.addMenu(MW_ROOT,NULL,F("MENU"));             //create a root menu at first (required)
   s1=menu.addMenu(MW_SUBMENU,r,F("AJUSTE TEMPER"));
      
      s2=menu.addMenu(MW_VAR,s1,F("TEMP INCIO"));             //add a terminal node (that is "variable"); 
      s2->addVar(MW_AUTO_FLOAT,&ti,20.00,50.00,0.5);      //create a variable of type "float number"... 
      
      s2=menu.addMenu(MW_VAR,s1,F("TEMP FINAL"));             //add a terminal node (that is "variable"); 
      s2->addVar(MW_AUTO_FLOAT,&tf,20.00,50.00,0.5);      //create a variable of type "float number"... 

  menu.addUsrScreen(msc,10000);

  menu.navButtons(UP_BUTTON_PIN,DOWN_BUTTON_PIN,ESCAPE_BUTTON_PIN,CONFIRM_BUTTON_PIN);

//-----------------------------------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);

}


//=====================================VOID LOOP ==================================================//
void loop(void){ 
  iteracion = iteracion+1;

  menu.draw(); 
 
  limpia_char(); 
  
 if (tempC < tf){          //Chek if the temperature is below the off heating element
  digitalWrite(rele, LOW);  
  digitalWrite( led, ON);
 }
  
 if (tempC > ti){
   digitalWrite(rele, HIGH);  //chek if the temperature is above the start temperature 
   digitalWrite (led, OFF);    
 }

   sensors.requestTemperatures(); // Comando para obtener temperatura
   // It responds almost immediately. Let's print out the data
   printTemperature(insideThermometer); // Use a simple function to print out the data

dtostrf(tempC, 10, 2, stempC); 
Serial.print(F("String C")); Serial.println( stempC); 
dtostrf(tempF, 10, 2, stempF); 
Serial.print(F("String F")); Serial.println (stempF); 
Serial.print(F("freeMemory()="));Serial.println(freeMemory());
Serial.print(F("Numero de iteracion = ")); Serial.println(iteracion); 
Serial.println(F("---------------------------------"));
}



void msc(){
static  char buf[7];
  strcat(menu.sbuf, stempC); strcat(menu.sbuf,"C/n");  //1st lcd line
  strcat(menu.sbuf, stempF); strcat(menu.sbuf,"F/n"); //2nd lcd line
  menu.drawUsrScreen(menu.sbuf);
  }
 
 
// 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(F("Temp C: "));
 Serial.print(tempC);
 Serial.print(F(" Temp F: "));
 Serial.println(tempF); 
}
  
void limpia_char(){
  stempC[10] = 0 ;
  stempF[10] = 0 ;
  }

Have some words on Spanish but I believe is quite understandable, if is not, my apologies.

Thank you very much for you help.

-Alex. :astonished:

1.-Problem; convert float number to a string or chart.[SOLVED... SORT OF]
After investigate, the c++ is capable to do so by using itoa, but for space reasons this was left
behind the arduino compiler.

It does seem strange that you think that itoa() (integer to ascii) would be even remotely relevant for converting a float to a string.

The itoa() function IS supported on the Arduino.

The arduino stops after some iteration, I count 36.

Snippets be damned. Post ALL of your code.

I don't have an specific problem to deal width

You don't?

2.- Try to uncomment the static screen to see if the chars was overloading it.

Once more, in English please. This makes no sense.

So I cant count precisely the iterations.

Not using nonsense code that hasn't a snowball's chance in hell of compiling, anyway.

char stempC [10];              //Char to hold the temperature on C 
char stempF [10];              //Char to hold the temperature on F

With room for 9 characters and a terminating NULL, why are you telling dtostrf() to write 10 characters and a NULL to the array? That's a crash waiting to happen. Which does happen.

Hi @PaulS. Thans for the time to write, Im uptdating the hole thing.
The hole code it is at the bottom of the original post. I will copy and paste it again, or try to upload complete with libraries (The forum has been doing some strange things).

Hi @Delta_G, you have nail the problem, I wasn't clear enough on my firs post (Didint do on purpose, take me the hole afternoon to scrap some things).

Why I need to convert a float in a char?
The float numbers on this post are used as start and stop for a heating element.
The subyacent problem; Im using a menu called MENWIZ, for creating a menu capable of set the variables on the site, with out the need of a reprogramming the arduino.

This menu manager has a built it function;
Once the user left the interaction with the buttons, the menu counts an amount of time and then
change the "Menu Mode" for a "User Screen" or a "Splash Screen" in witch is possible (And desirable in mi application to print the actual temperature of the sensor.

The problem; This "splash screen" only use strings.
Now I have delimitated some more the problem, I hope you can help me out a litte bit here!

Itoa
The itoa() function IS supported on the Arduino., yes and according I was reading it don have the complete capabilites of the c++ "original" for size on the compiler.

Clean a char
Lef this aside, I expend the afternoon trying to solve this, and the investigation yields me on the same observation that you do, I change the function for this;

void clean_char(){
  stempC[0] = '\0' ; //this will become all bits on the char to a know empty space 
  stempF[0] = '\0' ;
  }

After that more research suggested, a better way to do this like so;

void clean_char(){
memset(stempC, '\0', 11); //This will clear all the bites on the char. 
memset(stempF, '\0', 11); 
  }

The Real Problem
Well at this point the clean_char subroutine its doing its job properly. Still the problems persist.
After many attemps for debuging the code, the "crashing" fuction is this;

/*void msc(){
  static  char buf[7];
  strcat(menu.sbuf, "prueba"); strcat(menu.sbuf,"C/n");  //1st lcd line
  strcat(menu.sbuf, "prueba"); strcat(menu.sbuf,"F/n"); //2nd lcd line
  menu.drawUsrScreen(menu.sbuf);
  }
 */

At this point I want to make some clarifications before posting the hole code;
Yes... the cleaning char was wrong, but wasnt the issue
Yes the dtostrf converts satisfactory the float number to a char and is possible to print it using serial.

My latter approach to solve this problem is;
Using sprinf to "print all the need data on a char for each LCD line"
Using the same functions above mentioned to print the result on the LCD display.

I made a quick example on this, and after complete Im sure I need some
Help with sprintf

I chek This link an some others but I cant make the fuction does as intended..

//Example to prove the assembly off two char arrays holding information 
//for each LCD display line

float tempC = 19;
float humidity = 5; 
int iteraction = 0; 
  
char stempC[10];
char shumidity[10];

char superior_line[17]; 
char inferior_line[17];  


void setup(){
Serial.begin(9600); 
Serial.println(F("The program Has Started"));   
}


void loop(){
  iteraction = iteraction + 1;
  clearChar(); 
  
  tempC = tempC+0.1 ; 
  humidity = humidity+0.1 ;

  Serial.println(F("------------Direct Values-----------------"));
  Serial.print(F("Iteraction  = "));Serial.println(iteraction); 
  Serial.print(F("Temperature = "));Serial.println(tempC);  
  Serial.print(F("Humidity    = "));Serial.println(humidity);  
  
  dtostrf(tempC, 6, 2, stempC);
  dtostrf(humidity, 4, 2, shumidity);

  sprintf(superior_line,"%s C   HUMIDITY",stempC); 
  sprintf(inferior_line,"%s%s", shumidity, " %"  ); 
  
  Serial.println(superior_line); 
  Serial.println(inferior_line); 
  
  
  delay(500); 
}

void clearChar(){
  memset(superior_line, '\0', 16); 
  memset(inferior_line, '\0', 16); 
}

Im aiming for something like;
char superior_line = " 23 C HUMIDITY"
char infeior_line = "100F 40"

Know... I will post the entire code. As well the libraries Im using.
The ds1820 works properly and the dth11 to.

I hope I have provide enough information to you to help me out.

Im not lazy, just a beginner with a very good luck to find real odd problems.
And if you provide me with some tips or tutorials on this specifics task, I will read them and try to implement the code by my self.

-Alex-

Ok the entire code is here;

Also the non standard libraries
The forum dont let me upload it. I will leave the links in here;

Dallas temperature

Menwiz 1.02

//The crashing function is also included as it is know

An example of the MENWIZ menu manager that compiles and function included on the library itself

//MENWIZ ESAMPLE
#include <Wire.h>
//INSERT ALL THE FOLLOWING 5 INCLUDES AFTER INCLUDING WIRE LIB 
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>    // to be included only if defined EEPROM_SUPPORT

// DEFINE ARDUINO PINS FOR THE NAVIGATION BUTTONS
#define UP_BUTTON_PIN       9
#define DOWN_BUTTON_PIN     10
#define LEFT_BUTTON_PIN     7 
#define RIGHT_BUTTON_PIN    8
#define CONFIRM_BUTTON_PIN  12
#define ESCAPE_BUTTON_PIN   11

//Create global object menu and lcd
menwiz menu;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity

//instantiate global variables to bind to menu
int      tp=0;
float    f=26.0;
boolean  bb=0;
byte     b=50;

void setup(){
  _menu *r,*s1,*s2;
  _var *v; 
  int  mem;

  Serial.begin(19200);  
  
  // have a look on memory before menu creation
  Serial.println(sizeof(menwiz));
  mem=menu.freeRam();
  
  // inizialize the menu object (20 colums x 4 rows)
  menu.begin(&lcd,20,4);
  //menu.setBehaviour(MW_MENU_INDEX,false);    

  //create the menu tree
  r=menu.addMenu(MW_ROOT,NULL,F("MAIN MENU"));              //create a root menu at first (required)
    s1=menu.addMenu(MW_SUBMENU,r,F("MEASURE SUBMENU"));     //add a child (submenu) node to the root menu
    //s1->setBehaviour(MW_MENU_COLLAPSED,true);          
    
      s2=menu.addMenu(MW_VAR,s1,F("list"));            //add a terminal node (that is "variable"); 
          s2->addVar(MW_LIST,&tp);                          //create a variable of type "option list".. 
          s2->addItem(MW_LIST,F("option 1"));               //add option to the OPTION LIST
          s2->addItem(MW_LIST,F("option 2"));               //add option to the OPTION LIST
          s2->addItem(MW_LIST,F("option 3"));               //add option to the OPTION LIST
          s2->addItem(MW_LIST,F("option 4"));               //add option to the OPTION LIST
          s2->addItem(MW_LIST,F("option 5"));               //add option to the OPTION LIST
//          s2->setBehaviour(MW_SCROLL_HORIZONTAL,true);    
//          s2->setBehaviour(MW_LIST_2COLUMNS,true);          
//          s2->setBehaviour(MW_LIST_3COLUMNS,true);          

      s2=menu.addMenu(MW_VAR,s1,F("float var"));       //add a terminal node (that is "variable"); 
          s2->addVar(MW_AUTO_FLOAT,&f,11.00,100.00,0.5); //create a variable of type "float number"... 
                                                         //...associated to the terminal node and bind it to the app variable "f" of type float
      s2=menu.addMenu(MW_VAR,s1,F("byte var"));        //add a terminal node (that is "variable"); 
          s2->addVar(MW_AUTO_BYTE,&b,25,254,10);         //create a variable of type "byte"...
                                                         //...associated to the terminal node and bind it to the app variable "b" of typr byte
      s2=menu.addMenu(MW_VAR,s1,F("boolean var"));     //add a terminal node (that is "variable"); 
          s2->addVar(MW_BOOLEAN,&bb);                    //create a variable of type "boolean" 
                                                         //...associated to the terminal node and bind it to the app variable "bb" of type boolean
    s1=menu.addMenu(MW_VAR,r,F("WRITE TO SERIAL"));             //add a terminal node (that is "variable") create an "action" associated to the terminal node... 
      s1->addVar(MW_ACTION,act);                         //the act function as default will be called when enter button is pushed
//      s1->setBehaviour(MW_ACTION_CONFIRM,false);         //...if you don't need action confirmation

    s1=menu.addMenu(MW_VAR,r,F("SAVE TO EPROM"));           //add a terminal node (that is "variable") create an "action" associated to the terminal node... 
      s1->addVar(MW_ACTION,savevar);                     //the act function as default will be called when enter button is pushed

    s1=menu.addMenu(MW_VAR,r,F("LOAD FROM EEPROM"));        //add a terminal node (that is "variable") create an "action" associated to the terminal node... 
      s1->addVar(MW_ACTION,loadvar);                     //the act function as default will be called when enter button is pushed

  //declare navigation buttons (required)
  menu.navButtons(UP_BUTTON_PIN,DOWN_BUTTON_PIN,ESCAPE_BUTTON_PIN,CONFIRM_BUTTON_PIN);

  //(optional)create a user define screen callback to activate after 10 secs (10.000 millis) since last button push 
  menu.addUsrScreen(msc,10000);

  //(optional) create a splash screen (duration 5.000 millis)with some usefull infos the character \n marks end of LCD line 
  //(tip): use preallocated internal menu.sbuf buffer to save memory space!
//  sprintf(menu.sbuf,"MENWIZ TEST V %s\n.Free mem. :%d\n.Used mem  :%d\n.Lap secs  :%d",menu.getVer(),menu.freeRam(),mem-menu.freeRam(),5);
//  menu.addSplash((char *) menu.sbuf, 5000);
  }

void loop(){
  menu.draw(); 
  //PUT APPLICATION CODE HERE (if any)
  }

// user defined callbacks
// WARNING avoid sprintf usage: it requires > 1.5 kbytes of memory! 
void msc(){
  static  char buf[7];
  strcpy(menu.sbuf,"User screen"); //1st lcd line
  strcat(menu.sbuf,"\nUptime (s): ");strcat(menu.sbuf,itoa((int)(millis()/1000),buf,10));//2nd lcd line
  strcat(menu.sbuf,"\nFree mem  : ");strcat(menu.sbuf,itoa((int)menu.freeRam(),buf,10));//3rd lcd line
  strcat(menu.sbuf,"\n"); //4th lcd line (empty)
  menu.drawUsrScreen(menu.sbuf);
  }
  
void act(){
  Serial.println("FIRED ACTION!");
 }
 
void savevar(){
  menu.writeEeprom();
  }
  
void loadvar(){
  menu.readEeprom();
  }

thermostat_menwiz_original_code.ino (5.54 KB)

MENWIZ_1_0_2.zip (695 KB)

thermostat_menwiz_original_code.ino (5.54 KB)

  sprintf(superior_line,"%s C   HUMIDITY",stempC);

The string in stempC is 6 characters. The literal string " C HUMIDITY" is 13 characters. 6 + 13 + 1 (for the terminating NULL) is greater than 17. Once again, you are shitting on memory you don't own. Stop doing that, and your program will stop doing strange things.

strcat() can only work on textual data that already has a null ('\0') at the end of the text. Otherwise, the function will march through memory looking for a null and then append to it. That rarely works. That could be well past the memory that you've allocated to the array. Also, you are trying to stuff 16 characters into an array that is allocated 7 characters. See if this helps:

void msc(){
   static  char buf[17];   // Needs to be larger

   strcpy(menu.sbuf, "prueba");  //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf,"C/n"); 
   strcat(menu.sbuf, "prueba");  //2nd lcd line
   strcat(menu.sbuf,"F/n"); 
   menu.drawUsrScreen(menu.sbuf);
  }

econjack:
strcat() can only work on textual data that already has a null ('\0')

Thaths a very usfull information!

I will try the above example And comebakc ti post ir!

@PaulS, @econjak

First of all thank you for the comebacks.

Paul, I make the buffer larger as you indicates me...
I try [21], [30] and even [40] with the corresponding clean char function.

The program keeps stopping.

After I search a litte bit more information I came across another huge thing...

Apparently;

void msc(){
  static  char buf[20];   // Needs to be larger
   strcpy(menu.sbuf, "prueba");  //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf,"C/n");                                   ←THIS YIELDS AN ERROR. 
   strcat(menu.sbuf, "prueba");  //2nd lcd line  
   strcat(menu.sbuf,"F/n"); 
   menu.drawUsrScreen(menu.sbuf);
  }
void msc(){
  static  char buf[20];   // Needs to be larger
   strcpy(menu.sbuf, "prueba");  //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf,"C\n");                                   ←THIS WORKS CORRECTLY 
   strcat(menu.sbuf, "prueba");  //2nd lcd line  
   strcat(menu.sbuf,"F\n"); 
   menu.drawUsrScreen(menu.sbuf);
  }

Apparently it is very important the side of the diagonal. Any how... The code works and the splash screen appears on the LCD as intended.
The only thing to do know is to search the correct way to assembly the string lines.

-Alex.

So... I remake the code...

And apparently It just will print one line of the LCD..

void msc(){
   static  char buf[5];   // Needs to be larger
   strcpy(menu.sbuf, inf_line);  //2nd lcd line  
   strcat(menu.sbuf,"\n"); 
   strcpy(menu.sbuf, sup_line);  //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf,"\n");                                   


   menu.drawUsrScreen(menu.sbuf);
  }

This will print

23.25 C ---First line display
---Secod line display

void msc(){
   static  char buf[5];   // Needs to be larger
   strcpy(menu.sbuf, sup_line);  //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf,"\n");                                   
   strcpy(menu.sbuf, inf_line);  //2nd lcd line  
   strcat(menu.sbuf,"\n"); 


   menu.drawUsrScreen(menu.sbuf);
  }

While this print
---First line display
76.20 F ---Secod line display

I already tray to make the buffer larger but dont makes any difference.

Also try to add;
strcat(menu.sbuf,"\n");
strcat(menu.sbuf,"\n");

At the end of the lines to see what happens ... the lines don't move from there.

My bad...I didn't notice the backslash was "leaning" the wrong way. Note this is true for all escape sequences (e.g., '\r', '\n', '\t', etc.)

@econojack @PaulS @Delta_G

Thanks a lot for your commentaries.

The problem has been solved.

The function stays as;

void msc(){
   static  char buf[7];   // Needs to be larger
   strcpy(menu.sbuf, sup_line); strcat(menu.sbuf,"\n");       //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf, inf_line); strcat(menu.sbuf,"\n");
       
   menu.drawUsrScreen(menu.sbuf);
  }

I will upload a video with the menu working.

The entire code. Is here;

//=====================================LIBRERIAS==================================================//
#include <OneWire.h>
#include <dht.h>                     //Libreria para DTH
#include <DallasTemperature.h>       //Libreria Ds1820

#include <Wire.h>
#include <LiquidCrystal_I2C.h>       //Libreria IC2 
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>

//=====================================COSNTRUCTORES =============================================//
// DEFINE ARDUINO PINS FOR THE NAVIGATION BUTTONS
#define UP_BUTTON_PIN       9
#define DOWN_BUTTON_PIN     10
#define LEFT_BUTTON_PIN     7 
#define RIGHT_BUTTON_PIN    8
#define CONFIRM_BUTTON_PIN  12
#define ESCAPE_BUTTON_PIN   11

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

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


//=====================================GLOBAL VARIABLES==============================================//
float ti = 19.00;
float tf = 25.00;

const byte led =13;              //led to chek if the heating element has staring 
const byte rele = 4;             //pin to start or stop heating element
int humidity =  0;               //read the humidity sensor 
float tempC =   0;              //read the sensor temperature  
float tempF =   0;              //farenheit 

char stempC [11];              //Char to hold the temperature on C 
char stempF [11];              //Char to hold the temperature on F 
byte iteracion = 0;

char inf_line[20];             //char to hold the first lcd line 
char sup_line[20];             //char to hold the second lcd line
//=====================================VOID SET UP ==================================================//
void setup(void)
{
Serial.begin(9600);

  pinMode(A0, INPUT); 
  pinMode(A1, INPUT); 
  pinMode(led, OUTPUT);
  Serial.println(F("Programa iniciando"));
//-----------------------------------MENWIZ MENU-------------------------------------------------//
  _menu *r,*s1,*s2;
  _var *v; 
  int  mem;
  
// inizialize the menu object (16 colums x 2 rows)
  menu.begin(&lcd,16,2);
//create the menu tree
 r=menu.addMenu(MW_ROOT,NULL,F("MENU"));             //create a root menu at first (required)
   s1=menu.addMenu(MW_SUBMENU,r,F("AJUSTE TEMPER"));
      
      s2=menu.addMenu(MW_VAR,s1,F("TEMP INCIO"));             //add a terminal node (that is "variable"); 
      s2->addVar(MW_AUTO_FLOAT,&ti,20.00,50.00,0.5);      //create a variable of type "float number"... 
      
      s2=menu.addMenu(MW_VAR,s1,F("TEMP FINAL"));             //add a terminal node (that is "variable"); 
      s2->addVar(MW_AUTO_FLOAT,&tf,20.00,50.00,0.5);      //create a variable of type "float number"... 

  menu.addUsrScreen(msc,10000);

  menu.navButtons(UP_BUTTON_PIN,DOWN_BUTTON_PIN,ESCAPE_BUTTON_PIN,CONFIRM_BUTTON_PIN);

//-----------------------------------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);

}


//=====================================VOID LOOP ==================================================//
void loop(void){ 
  menu.draw(); 
 
  limpia_char(); 
  
  clean_lcd_char();
  
 if (tempC < tf){          //Chek if the temperature is below the off heating element
  digitalWrite(rele, LOW);  
  digitalWrite( led, ON);
 }
  
 if (tempC > ti){
   digitalWrite(rele, HIGH);  //chek if the temperature is above the start temperature 
   digitalWrite (led, OFF);    
 }

   sensors.requestTemperatures(); // Comando para obtener temperatura
   // It responds almost immediately. Let's print out the data
   printTemperature(insideThermometer); // Use a simple function to print out the data

dtostrf(tempC, 5, 2, stempC); 
Serial.print(F("String C")); Serial.println( stempC); 
dtostrf(tempF, 5, 2, stempF); 
Serial.print(F("String F")); Serial.println (stempF); 
Serial.print(F("Numero de iteracion = ")); Serial.println(++iteracion); 
Serial.println(F("---------------------------------"));

sprintf(sup_line,"%s C HUMEDAD", stempC); 
sprintf(inf_line,"%s F   %i   ", stempF, humidity); 

}



// user defined callbacks
// WARNING avoid sprintf usage: it requires > 1.5 kbytes of memory! 
void msc(){
   static  char buf[7];   // Needs to be larger
   strcpy(menu.sbuf, sup_line); strcat(menu.sbuf,"\n");       //1st lcd line...note this is a copy, not a concat.
   strcat(menu.sbuf, inf_line); strcat(menu.sbuf,"\n");
       
   menu.drawUsrScreen(menu.sbuf);
  }
   
  
  
  

// 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(F("Temp C: "));
 Serial.print(tempC);
 Serial.print(F(" Temp F: "));
 Serial.println(tempF); 
}
  
void limpia_char(){
memset(stempC, '\0', 10); 
memset(stempF, '\0', 10); 

  }
  
void clean_lcd_char(){
memset(inf_line, '\0', 19); 
memset(sup_line, '\0', 19); 

  }

Thanks Again!!!!

Hi to all... As I say earlier on the post.

Here is the video

Of the thing working...

Of course I already working on the next generation.

I hope can contribute with some else..

Thanks to all for your contribution!

-Alex.