Page 1 of 1

### Clock & Temp on 16x2 Display

Posted: Thu Jun 23, 2016 7:43 am
Hi guys. I've got a code somewhat working to display the time on the top line and the day/date and the temp on the second.
2 things, something's not correct as the temp is flashing every second or so, which in turn somehow effects the seconds on the time on the top row, that change every 2 or 3 seconds, but keeps up time. Also, is there any way to make the temp printout just the degrees with no decimal places

Im using a Arduino Mega with the Freetronics Display Shiels mounted on it. I have a DS18B20 and an RTC on a Breadboard with Jumpers
Here's my code

Code: Select all

``````// Libraries
#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );
#include <DallasTemperature.h> //will find addresses of sensors automatically
const char degree = 223;   //This will give us the degree symbol after the temp

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return( (val/16*10) + (val%16) );
}
// Data wire from DS18B20 to Arduino Digital PIn 31
#define ONE_WIRE_BUS 31

// Setup oneWire instance to communicate with devices
OneWire oneWire(ONE_WIRE_BUS);

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

int n = 1;

void setup()
{

Wire.begin();
lcd.begin(16, 2);
// set the initial time here:
// DS3232 seconds, minutes, hours, day, date, month, year
//setDS3232time(0, 32, 17, 3, 21, 6, 16);
}
void setDS3232time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
// sets time and date data to DS3232
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.write(0); // set DS3232 register pointer to 00h
Wire.endTransmission();
// request seven bytes of data from DS3232 starting from register 00h
}
void displayTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from DS3232
readDS3232time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
&year);
// send the data to the LCD shield
lcd.clear();
lcd.setCursor(4,0);
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10)
{
lcd.print("0");
}
lcd.print(minute, DEC);
lcd.print(":");
if (second<10)
{
lcd.print("0");
}
lcd.print(second, DEC);
lcd.setCursor(0,1);
switch(dayOfWeek)
{
case 1:
lcd.print("Sun");
break;
case 2:
lcd.print("Mon");
break;
case 3:
lcd.print("Tue");
break;
case 4:
lcd.print("Wed");
break;
case 5:
lcd.print("Thu");
break;
case 6:
lcd.print("Fri");
break;
case 7:
lcd.print("Sat");
break;
}
lcd.print(" ");
lcd.print(dayOfMonth, DEC);
lcd.print("/");
lcd.print(month, DEC);
lcd.print("/");
lcd.print(year, DEC);

sensors.begin();
}
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
sensors.requestTemperatures(); // Get temps
lcd.setCursor ( 12, 1 ); //Print Room temp on bottom line
lcd.print(sensors.getTempCByIndex(0)); //Use this if you want C
//lcd.print(sensors.getTempCByIndex(0)* 9/5 * .54); //convert to F

}
void loop()
{
displayTime(); // display the real-time clock time on the LCD,
delay(1000); // every second
delay (1000);//reads temp every .5 second
}

``````
Thanks
Chris

### Re: Clock & Temp on 16x2 Display

Posted: Fri Jun 24, 2016 4:03 am
Hi Chris,

Sorry to hear it's not quite working yet. At the moment the code updates the time, then waits one second, then updates the temperature, then waits one second before updating the time again. You can try updating both at the same time.

Change this part:

Code: Select all

``````void loop()
{
displayTime(); // display the real-time clock time on the LCD,
delay(1000); // every second
delay (1000);//reads temp every .5 second
}
``````
To something like this:

Code: Select all

``````void loop()
{
displayTime();
delay (1000);
}
``````
Chris wrote:Also, is there any way to make the temp printout just the degrees with no decimal places
You can, by making the temperature into an "int" (integer whole number) instead of a "float" (floating point number.) Try changing this line:

Code: Select all

``````    lcd.print(sensors.getTempCByIndex(0)); //Use this if you want C
``````
To this:

Code: Select all

``````    lcd.print( (int) sensors.getTempCByIndex(0)); //Use this if you want C
``````
Regards,

Angus

### Re: Clock & Temp on 16x2 Display

Posted: Fri Jun 24, 2016 9:24 am
Thanks for the reply Angus. Unfortunately the time is still updating every 2 seconds and the temp is flashing every 1 or so. But the temp whole number worked ok.

Chris

### Re: Clock & Temp on 16x2 Display

Posted: Mon Jun 27, 2016 12:28 am
You can try removing the "lcd.clear()" line (which will erase the entire display each time it redraws), although you might find you need to print some extra spaces ' ' so it doesn't leave "cruft" at the end of the line when it draws the new time over the old time.

At the same time, you could also try reducing the 'delay' in the main loop to less than the current one second (1000ms), because all of the other updating probably takes some time as well. Maybe try 250 or 500, or even try removing it entirely.

### Re: Clock & Temp on 16x2 Display

Posted: Mon Sep 25, 2017 4:15 pm
I realize that this is an old thread, and I really don't have much experience with Arduino programming, however, I did spend some time patching together various example code blocks to do what the OP was attempting to achieve with the 16x02 LCD display.

In my situation, the display used is a 40x02 display, addressed via an I2C bus which passes through a DS3231 RTC module. Temp is derived from a Maxim Integrated DS18B20 sensor that I had laying about--only for the higher precision of the temp readout.

With patching-together several bits of example code to get this to do what I wanted it to do, and fiddling with it to solve problems that I encountered, there is--admittedly--a lot of dross in the code below (It's downright ugly right now!) that can be adjusted and / or cleaned-up; however, the essential problems that I see discussed in this thread have been solved. I only provide this in an attempt to aid anyone who might be wandering the same path as the OP.

My apologies for the condition of the contribution, but I really am more of a hardware guy, getting back into programming as a means to an end, the last experience with which I had back in the mid-1980's. I'll get around to actually cleaning it up later.

Code: Select all

``````#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS   2

LiquidCrystal_I2C lcd(0x27, 40, 2);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

char    weekDay[9];

float   tempC,
tempF;

int     Wkday;

byte bcdToDec(byte val)  {
return( (val/16*10) + (val%16) );
}

void setup()  {
lcd.begin(40,2);
lcd.backlight();
sensors.begin();
setSyncProvider(RTC.get);
checkTimeSetStatus();
}

void checkTimeSetStatus()  {
if (timeStatus()!= timeSet)  {
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print("Unable to sync with the RTC.");
delay(4000);
lcd.clear();
delay(1000);
} else {
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print("RTC has set the system time.");
delay(1000);
lcd.clear();
}
}

void ClockDisplay()  {
lcd.setCursor ( 0, 0 );
lcd.print("   ");
lcd.print(year());
printMoDy(month());
printMoDy(day());
lcd.print("    ");
printHour(hour());
printDigits(minute());
printDigits(second());
lcd.print(" ");
printDoW();
}

void printHour(int digits)  {
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}

void printDigits(int digits)  {
lcd.print(":");
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}

void printMoDy(int digits)  {
lcd.print(".");
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}

void printDoW()  {
Wkday = (weekday());
switch (Wkday) {
case 1:
strcpy(weekDay, " SUNDAY  ");
break;
case 2:
strcpy(weekDay, " MONDAY  ");
break;
case 3:
strcpy(weekDay, " TUESDAY ");
break;
case 4:
strcpy(weekDay, "WEDNESDAY");
break;
case 5:
strcpy(weekDay, "THURSDAY ");
break;
case 6:
strcpy(weekDay, " FRIDAY  ");
break;
case 7:
strcpy(weekDay, "SATURDAY ");
break;
}
lcd.print("   ");
lcd.print(weekDay);
}

void TempDisplay()  {
sensors.requestTemperatures();
tempC = (sensors.getTempCByIndex(0));
tempF = ((tempC * 1.8) + 32.0);
lcd.setCursor ( 0, 1 );
lcd.print("           T = ");
lcd.print(tempC);
lcd.print("C  ");
lcd.print(tempF);
lcd.print("F  ");
}

void loop()  {
if (timeStatus() == timeSet) {
ClockDisplay();
TempDisplay();
} else {
lcd.clear();
delay(1000);
lcd.setCursor ( 0, 0 );
lcd.print("The Time has not been set.");
lcd.setCursor ( 0, 1 );
delay(1000);
lcd.clear();
}
}
``````
All-in-all, this will be either a helpful first post, here, for me, or a terrible mistake. LOL

Best Regards

######## EDITED ########

Should you wish to only print-out the integer portion of the temp, simply declare an integer variable, local to the "TempDisplay" function, and assign the float temp value to the integer variable and substitute the integer temp variable in the output statement. The decimal fraction of the float will be dropped in the assignment to the integer.