Printing DS18B20 value to UTFT screen

Hi. I am using a DS18B20 temp sensor and having trouble trying to figure out the code to print the value to the screen. I found a code that allows you to exclude the need for the pullup resister and uses the one built into the chip.

#include <OneWire.h>
#include <DallasTemperature.h>

// This is an updated version of the Tester program that comes with the DallasTemp library
// It will drive a DS18x20 tempurature sensor plugged directly to the Arduino header pins 8,9, and 10.
// The flat side of the sensor should face into the center of the board.
// More info and a video here...
// http://wp.josh.com/2014/06/23/no-external-pull-up-needed-for-ds18b20-temp-sensor/#more-1892


// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 9
#define TEMPERATURE_PRECISION 9

// Uncomment this line if you are using the updated dallas_temp_library that 
// supports the busFail() method to diagnose bus problems
// #define BUSFAIL 

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

void setup(void)
{
  
  // This lines just make it so you can plug a DS18B20 directly into 
  // digitial pins 8-10. 
  
  digitalWrite( 8 , LOW );
  pinMode( 8  , OUTPUT );
  digitalWrite( 10 , LOW );  
  pinMode( 10 , OUTPUT );
  
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");
  
}


void loop(void)
{ 
  
  #ifdef BUSFAIL
  
    Serial.print(" Test:");
      
    if (sensors.reset()) {
      
      Serial.print("good");
      
    } else {
      
      if (sensors.busFail()) {
        
        Serial.print("fail");
        
      } else {
        
        Serial.print("empty");
        
      }
        
    }
    
  #endif 

  int numberOfDevices; // Number of temperature devices found

  DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address    
  
  // For testing purposes, reset the bus every loop so we can see if any devices appear or fall off
  sensors.begin();

  // Grab a count of devices on the wire
  numberOfDevices = sensors.getDeviceCount();

  Serial.print(" Parasite:"); 
  if (sensors.isParasitePowerMode()) Serial.print("ON ");
  else Serial.print("OFF ");
    
  Serial.print("Count:");
  Serial.print(numberOfDevices, DEC);
 // report parasite power requirements

  sensors.requestTemperatures(); // Send the command to get temperatures
  
  // Loop through each device, print out temperature data
  for(int i=0;i<numberOfDevices; i++)
  {
    // Search the wire for address
    if(sensors.getAddress(tempDeviceAddress, i))
	{
		// Output the device ID
		Serial.print(" #");
		Serial.print(i,DEC);
		Serial.print("=");


                float tempC = sensors.getTempC(tempDeviceAddress);

                Serial.print(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit

	} 
	//else ghost device! Check your power requirements and cabling
	
  }
  
 Serial.println("");
  
 delay(1000);
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

I have incorporated this into my very long sketch (5500 lines and too big to paste on here) but as a basic, how can I print this to my screen? The serial print works fine, just need it to screen. I want the temperature reading to replace the below line of code which was entered as a temporary measure to setup my spacings during design phase.

myGLCD.print("72.6",18,53);           // TEMPORARY VALUES

Any help appreciated. Thanks.

PS. I'd also like the ' ° ' added to the end of thats possible rather than just add a new 'myGLCD.print' part if you know what I mean?

Thanks

Look into dtostrf function to turn your temperature reading from float number to string for printing.

liudr:
Look into dtostrf function to turn your temperature reading from float number to string for printing.

I don't know why you would ever bother doing that when you can print to LCD in more or less the same way as you print to anything else.

Since you have a return Temp = 72.6, in place of the dummy

myGLCD.print("72.6",18,53);           // TEMPORARY VALUES

you might use

myGLCD.printNumF(Temp,18,53);

as is clearly outlined on p7 of the UTFT manual.

The only time I have ever seen a need to convert a float for output as a string is when some external software, as opposed to local hardware, demands it. The only example I am aware of that does is Bluetooth Graphics Terminal, where several floats are assembled as a single string.

Nick,

I didn't know the print function in that library has float but that doesn't mean a float string is almost useless. You just need more experience. That's all.

Thanks for your replies. With your suggestion Nick i'm getting the following error when entering this...

myGLCD.printNumF(DallasTemperature::toFahrenheit(tempC),18,53);
error: no matching function for call to 'UTFT::printNumF(float, int, int)'

I'm trying to play about with it now. :-/

I'm also having a play with the dtostrf function.

Hi,

If your sketch is too big, use REPLY rather than QUICK REPLY and it has an attachment facility, so you can post your sketch as an attachment.

Tom.... :slight_smile:

I can't get the dtostrf to work and can't fathom out the problem with the myGLCD.printNumF. no matter which way around I code it, I get some sort of error.

Hi Tom. Okie dokie... attached to this one. Please bare in mind that I only picked up an Arduino about 6 months ago so had to learn everything from scratch. With that said the coding might not be the most efficient way or even the proper way to do it, but so far, everything works.

Cheers,
Steve

Complete_build_v2.ino (213 KB)

Can you try a simple code that just does dtostrf and print on glcd? dtostrf is straight-forward. It formats a float number into a string. You specify the number of total characters and number of digits after decimal. Say you want 72.6118 to read "72.6" you do the following:

char buffer[5];
float temp=72.6118;
dtostrf(temp, buffer, 4,1);
glcd.print(buffer, x, y);

Hi liudr. thanks of your reply. I'm clearly not as experienced as you are. I did find a site that explained it all, and as a step by step I understand what it does, its just adding it to my code I am struggling with. I have tried placing different bits in different places but it just don't seem to work and I don't have the technical knowhow to trouble shoot it.

I will give it another go now and see what happens...

OK, so if I copy and paste your suggestion, obviously filling in the position that I want 'buffer' to appear, as follows...

char buffer[5];
        float temp=72.6118;
        dtostrf(temp, buffer, 4,1);
        glcd.print(buffer, 18, 53);

I get the following errors...

Complete_build_v2.ino: In function 'void menu2()':
Complete_build_v2.ino:457:34: error: invalid conversion from 'char*' to 'signed char' [-fpermissive]
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/Arduino.h:23:0,
                 from /Users/StevenCopping/Documents/Arduino/libraries/UTFT/UTFT.h:173,
                 from Complete_build_v2.ino:109:
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/stdlib.h:655:14: error:   initializing argument 2 of 'char* dtostrf(double, signed char, unsigned char, char*)' [-fpermissive]
 extern char *dtostrf(double __val, signed char __width,
              ^
Complete_build_v2.ino:457:34: error: invalid conversion from 'int' to 'char*' [-fpermissive]
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/Arduino.h:23:0,
                 from /Users/StevenCopping/Documents/Arduino/libraries/UTFT/UTFT.h:173,
                 from Complete_build_v2.ino:109:
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/stdlib.h:655:14: error:   initializing argument 4 of 'char* dtostrf(double, signed char, unsigned char, char*)' [-fpermissive]
 extern char *dtostrf(double __val, signed char __width,
              ^
Error compiling

So it doesn't even work on its own, and that is with defining the temp as 72.6118 and not even assigning it to the actual temperature value being produced by the sensor.

It appears that the library and code has a reading value of

tempC

for celsius and then some sort of sorcery that converts it to fahrenheit and the only part of code that I can see that does that is this

float tempC = sensors.getTempC(tempDeviceAddress);

I just can't fathom this out. I appreciate your help.

Stevelondon:
With your suggestion Nick i'm getting the following error when entering this...

myGLCD.printNumF(DallasTemperature::toFahrenheit(tempC),18,53);

Sorry, I was a bit too quick to point out what a stupid idea converting to strings would be, and the change from text to float is a bit more than I said, but it is explained in the manual nonetheless. I don't have my big screen going at the moment and have not used it for a year or so, but I believe the code should have read

myGLCD.printNumF(Temp, 2, 18,53);

The 18,53 are your stated coordinates, and the "2" denotes two fractional digits as routinely returned in the float from the DS18B20.

I hope we are not at cross purposes here. I am referring to the UTFT manual by Henning Karlsen. I think it comes from RinkyDink. The shape of your code suggests you are using this. Note also that I assume you are using small or big fonts. If you are using 7seg font, you need to break up the number into whole and frac, and make your own decimal point.(!)

An example is here but I'm not sure how helpful it would be and was a work in progress

http://homepages.ihug.com.au/~npyner/Arduino/UTFTgraph.ino

the output is here

http://homepages.ihug.com.au/~npyner/Arduino/Two Speed graph.jpg

Hi Nick. Thanks again for your time mate. I do appreciate it.

Yes I am using that UTFT library.

The trouble is the value name 'temp' in your example don't link to the library or code that I have and I'm having trouble finding the way to write it. It seems like it should be very simple like your example with a word like temp but its not.

In the code the use 'tempC' for the value in celsius and then theirs a long formula to convert it to fahrenheit...

float tempC = sensors.getTempC(tempDeviceAddress);

and then sends it to serial...

Serial.print(DallasTemperature::toFahrenheit(tempC));

But when I replace the 'temp' in your example, with either tempC or the long former above (which both work on their own to serial monitor, I get errors. Its really confusing me.

WOOOOHOOOO. Done it. I had to wiggle around with the placements to get it to work and done it. Thanks for your help peeps. :slight_smile:

Hi,
Can you tell us what you had to wiggle around to fix your problem, this will give some closure to this thread if anybody else has this problem.
Also go and edit the subject line to this thread and add [SOLVED]

Thanks Tom.... :slight_smile:

Stevelondon:
But when I replace the 'temp' in your example, with either tempC or the long former above (which both work on their own to serial monitor, I get errors. Its really confusing me.

OK, you've got it working, but now I'm the one who is confused. The "temp" was just a variable name like any other. If you put "tempC" , or any other of your floats in there, I believe it should have worked just fine - as is shown in the printNumF section of the manual. The float variable name therein is "num". Hopefully you just suffered some silly procedural glitch that only happens once. Note that I have never needed to use that optional stuff, just num,dec,x,y. This may be because of the range and nature of the essentially self-formatting returns from the DS18B20, and you may have to use the options with data from other sources. Note also that, in the example I linked to, I use tabs for x, which I'm not sure is such a good idea. Further (!), there is a string conversion tucked away in there, but it is for broadcast to a phone, and has nothing to do with this issue.

liudr:
Nick.....
You just need more experience. That's all.

Well, at least my experience actually extends to reading the manual. Perhaps at some other time, and place, you might draw on your extensive experience to expound upon why converting a float to a string for printing to LCD is actually useful, rather than a waste of programme space and computer time.

Will do Tom. I was away from my laptop (as I am now) when I updated this post but I'll do all that when I'm back on it tomorrow. Cheers.

Nick_Pyner:
Well, at least my experience actually extends to reading the manual. Perhaps at some other time, and place, you might draw on your extensive experience to expound upon why converting a float to a string for printing to LCD is actually useful, rather than a waste of programme space and computer time.

Of course. Besides having to serialize data between any two processors, such as arduino with sd card, to ethernet, wifi, or lcd, controlling the exact number of character and formatting is paramount for displaying correctly in a professional look. The print function in that lcd lib seems to lack any formatting control. If you count from 100 to 0 with lcd print, you will understand what I mean. Ive done formatted prints for over three decades and I still see careless new generation programmers that dont know how to make numbers print/format correctly, even to this date.

Righteo. Here we go.

So to solve this I used Nicks example code and had to put it in a few different places to find the right place. Now it might be obvious to experienced programmers, of which I am definitely not one of. The final placement for it was as below...

  #ifdef BUSFAIL
  
  Serial.print(" Test:");
    
  if (sensors.reset()) 
  {
    Serial.print("good");
  } 
  else 
  {
    if (sensors.busFail()) 
    {
      Serial.print("fail");  
    } 
    else 
    {  
      Serial.print("empty");   
    }     
  }
    
  #endif 
  int numberOfDevices; // Number of temperature devices found
  DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address    
  
  // For testing purposes, reset the bus every loop so we can see if any devices appear or fall off
  sensors.begin();

  // Grab a count of devices on the wire
  numberOfDevices = sensors.getDeviceCount();

  Serial.print(" Parasite:"); 
  if (sensors.isParasitePowerMode()) Serial.print("ON ");
  else Serial.print("OFF ");
    
  Serial.print("Count:");
  Serial.print(numberOfDevices, DEC);
 // report parasite power requirements

  sensors.requestTemperatures(); // Send the command to get temperatures
  
  // Loop through each device, print out temperature data
  for(int i=0;i<numberOfDevices; i++)
  {
    // Search the wire for address
    if(sensors.getAddress(tempDeviceAddress, i))
    {
      // Output the device ID
      Serial.print(" #");
      Serial.print(i,DEC);
      Serial.print("=");

      float tempC = sensors.getTempC(tempDeviceAddress);
      Serial.print(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit

      if (menu == 2)
      {
        if (DallasTemperature::toFahrenheit(tempC) < 83)           // If temp under 83...
        {    
          myGLCD.setColor(51, 204, 255);                           // Colour to BLUE
        }
        else if (DallasTemperature::toFahrenheit(tempC) > 86)      // If temp over 86...
        {
          myGLCD.setColor(255, 51, 0);                             // Colour to RED
        }
        else                                                      // Otherwise...
        {
          myGLCD.setColor(255, 255, 255);                         // Colour to WHITE
        }
        myGLCD.setFont(franklingothic_normal);
        //myGLCD.printNumF(tempC, 3, 50,50);                                   // Celcius
        myGLCD.print("`F",74,53);                                              // Tank temp
        myGLCD.printNumF(DallasTemperature::toFahrenheit(tempC), 1, 18,53);    // Farenheit 
        
      }
    }
        //else ghost device! Check your power requirements and cabling
  }

I also added some statements to give men either a blue for too cold or red for too hot and added used the 'franklingothic_normal' font as the ` symbol produces a degrees symbol. All seems to work fine now and really happy.

This is of course until I add the other two sensors to the same bus and then have to print each result in a different place. :-/ We'll see.