Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

printing whole numbers

jessey72

New Member
Hi Everyone,
I'm working on a project where I'm displaying a temperature reading from a DS18B20 to my 4x20 LCD. I coppied a sample code
for Arduino Nano for the DS18B20 online from here: https://randomnerdtutorials.com/guide-for-ds18b20-temperature-sensor-with-arduino/
that displays the temp using the serial monitor and that part works good but when I display the temperature to my LCD it's
trying to display a decimal point and 2 extra numbers to another line of my LCD that has text in it so it's flasning over the first
3 charcaters of that text line.

I kinda remember I had that problem years ago with a ds1820 when I first got into arduino and on a forum I asked how to display just whole numbers and now I can't remember the the code snipet that solved my problem.

Dose anyone here know a solution?

Any help will be greatly appreciated.

Thanks...
 
The basic algorithm is repeated division by descending powers of 10 to get the quotient digit and the remainder. You print the quotient digit and the remainder becomes the dividend for the next division by a smaller power of 10. When the remainder is less than 10 you have the final digit.
 
Thanks Papabravo,
I didn't quite understand your concept of dividing by 10 or where to place it into the serial code
that I copied and pasted to form basis of my program.
However I did find this post while searching the arduino.cc forum tonight:
I changed the float var to an int varaiable of both the tempF and tenpC in the serial
code and now it prints whole numbers to both my LCD and in the serial monitor and there's
no more conflicts of my lcd flickering between text and the decimal with two numbers which
was a little annoying to say the least!
I would still be interested to learn how what you suggested by /10 would work and
where in the serial code I would implement that change to get rid of the decimal
point to print only whole numbers?
Thanks
jessey
 
If you used printf or sprintf, you could format the number to be however you want - however, if it's running over to the following line, then it sounds like you're printing it at the wrong position on the display anyway.
 
The problem is it was printing like you said, over some text in the next line because it was a too big of a number when it was printing a decimal followed two more numbers. It's fine now that it's printing whole numbers without a decimal.
 
In a typical program you will want to use the temperature you have just read in some other functions like turning on relays etc.
To this end we save our read temperature to another float , you can then Print it and specify how many decimal places you want eg 1, 2 or 0 for none,

float tempSaved = sensors1.getTempCByIndex(0);
Serial.print("temp is ");
Serial.println (tempSaved , 0);


if (tempSaved > 20) ..etc
 
printf() and its formatting, attached.

Regards, Dana.
 

Attachments

  • printf (2).pdf
    81.5 KB · Views: 175
  • Printf.pdf
    1.9 MB · Views: 294
Thanks Papabravo,
I didn't quite understand your concept of dividing by 10 or where to place it into the serial code
that I copied and pasted to form basis of my program.
However I did find this post while searching the arduino.cc forum tonight:
I changed the float var to an int varaiable of both the tempF and tenpC in the serial
code and now it prints whole numbers to both my LCD and in the serial monitor and there's
no more conflicts of my lcd flickering between text and the decimal with two numbers which
was a little annoying to say the least!
I would still be interested to learn how what you suggested by /10 would work and
where in the serial code I would implement that change to get rid of the decimal
point to print only whole numbers?
Thanks
jessey
Go back and reread my post a bit more carefully. The phrase you blew past without understanding was "repeated division by descending powers of 10 ". For example, if you are starting with a 16-bit unsigned integer that you wish to convert to a decimal string, the largest power of 10 that you need is 10,000. The sequence of divisors is 10,000, then 1,000, then 100, then 10 and finally 1. In the last step you don't have to do anything since you know the result of dividing by 1 and you have the remainder as well.

As to where you wan't to do this, only you can answer that since we don't have access to your code.
 
Can someone tell me why casting to integer isn't viable? What have I missed?

Mike.
The variable is a floating point, casting it to integer would lose the fractional part.

You could simply multiply by 100, and then physically add the decimal point in the right place when you print it.

But why not just use printf or sprintf which is there for this exact situation, and deals with it perfectly, including leading and trailing zeros as required.
 
I thought that's what the OP wanted to do? As he said "Print whole numbers" I.E without decimal part. As I said, "What have I missed?"

Mike.
It was what the OP wanted but some people want the OPs to ask different questions than they really ask.
 
This is the code I wrote to make a thermometer with DS18B20, Arduino UNO and LCD. Hope it helps.

#include <LiquidCrystal.h>
#include <OneWire.h>

int DS18S20_Pin = 7; //DS18S20 Signal pin on digital 7

//Temperature chip i/o
OneWire ds(DS18S20_Pin); // on digital pin 7
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(void) {
Serial.begin(9600);
lcd.begin(16, 2); // set up the LCD's number of columns and rows:



}

void loop(void) {
float temperature = getTemp();
if(temperature==-1000)
{
lcd.clear();
lcd.print("Error");
}
else{
lcd.clear();
lcd.print("**Temperature**");
float farenhiet=temperature+33.8;
Serial.println(temperature);
lcd.setCursor(0,1);
lcd.print(temperature);//Show the temperature in LCD
lcd.print((char)223);// command for printing ° sign in LCD Ref: lcd.print("C");// C for Celcius
lcd.setCursor(9,1);
lcd.print(farenhiet);//Show the temperature in LCD
lcd.print((char)223);// command for printing ° sign in LCD Ref: lcd.print("F");// C for Celcius

delay(50); //just here to slow down the output so it is easier to read
}
}


float getTemp(){
//returns the temperature from one DS18S20 in DEG Celsius

byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;

}

if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;

}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;

}

ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end

byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad


for (int i = 0; i < 9; i++) { // we need 9 bytes
data = ds.read();
}

ds.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;

return TemperatureSum;

}
 
Last edited:
C to F:

Divide by nine; multiply by five. Then add 32
First, I think you mean,
Multiply by 9, divide by 5, add 32
100°C x 9 = 900
900 / 5 = 180
180 + 32 = 212°F

Or, I try to avoid division on an 8-bit chip

100°C x 18 = 1800
1800 + 320 = 2120 (then illuminate the appropriate decimal) for 212.0°F
 

Latest threads

New Articles From Microcontroller Tips

Back
Top