I'm a real newbie to Arduino so please be patient with me!
My first project is using an Uno, a DS3231 RTC and a 20x4 LCD
After a few hours I finally got the code to work; my clock project displays date, time and temperature!
I thought it would be nice to add UTC time as well and I used t.hour-2 to display UTC time.
This works great, the only trouble is at midnight the time displays the hour as -1 and at 01h00 as -2
How can I display the correct time?
lcd.setCursor(0,2); //Go to third line of the LCD Screen
lcd.print("UTC Time ");
lcd.setCursor(11,2); //Start text at column 11 on third line
There is a difference between local time and UTC time. What you are trying to display is local time. That is NOT done by just subtracting 2 hours from the UTC time's hour value.
You need to look at the hour value. If it is 2 or more, subtract 2. If it less than 2, add 22 AND subtract one from the day value. Of course, that will get tricky on the last day of the month, especially on the last day of the year.
Better would be to google time zone offset, and find the Arduino code to deal with time zones. By getting the time as a time_t object, instead of a bunch of discrete values, you can easily subtract 2 hours, and then convert the time_t to a bunch of discrete values. And, therein lies a hint as to how the time zone code works.
PaulS:
There is a difference between local time and UTC time. What you are trying to display is local time. That is NOT done by just subtracting 2 hours from the UTC time's hour value.
You need to look at the hour value. If it is 2 or more, subtract 2. If it less than 2, add 22 AND subtract one from the day value. Of course, that will get tricky on the last day of the month, especially on the last day of the year.
Thank you Paul,
I want to display both times, local and UTC. UTC time is minus 2 hours from local time
I am displaying Local time on line 2 and UTC time on line 3 of my display, both showing okay.
The problem only occurs at midnight, UTC then displays -2 as the hour instead of 00 (12pm) and -1 instead of 01 (1am)
I understand UTC time is displaying what I can told it to display, I.E. local time minus 2 ( 0-2 at midnight and 1-2 at 1am).
How do I change my code to correct this error?
As you are new here, I will explain about posting code.
When you post code, please use code tags. Code tags make your code look
like this
when you post it.
To get code tags, click on the </> symbol in the row of icons at the top of the message input box. (The </> symbol is at the beginning of the row.)
Also, when you post code, please post your complete sketch. I noticed that the code you posted did not have this
void setup()
nor this
void loop()
therefore it could not have been a complete sketch.
Please post your complete sketch, using code tags, and then we will be able to give you better help.
#include <Wire.h>
#include <ds3231.h>
#define BUFF_MAX 128
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;
void setup()
{
Wire.begin();
DS3231_init(DS3231_INTCN);
memset(recv, 0, BUFF_MAX);
//***LCD Setup***
lcd.begin (20,4); // initialize the lcd
// setTheTime("301810101092017"); // ssmmhhWDDMMYYYY set time once in the given format
}
void loop()
{
char tempF[6];
float temperature;
char buff[BUFF_MAX];
unsigned long now = millis();
struct ts t;
// show time once in a while
if (now - prev > interval){
DS3231_get(&t); //Get time
temperature = DS3231_get_treg(); //Get temperature
dtostrf(temperature, 5, 1, tempF);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(t.mday);
printMonth(t.mon);
lcd.print(t.year);
lcd.setCursor(0,1); //Go to second line of the LCD Screen
lcd.print("Local Time ");
lcd.print(t.hour);
lcd.print(":");
if(t.min<10)
{
lcd.print("0");
}
lcd.print(t.min);
lcd.print(":");
if(t.sec<10)
{
lcd.print("0");
}
lcd.print(t.sec);
lcd.print(' ');
lcd.setCursor(0,2); //Go to third line of the LCD Screen
lcd.print("UTC Time ");
lcd.setCursor(11,2); //Start text at column 11 on third line
lcd.print(t.hour-2);
lcd.print(":");
if(t.min<10)
{
lcd.print("0");
}
lcd.print(t.min);
lcd.print(":");
if(t.sec<10)
{
lcd.print("0");
}
lcd.print(t.sec);
lcd.print(' ');
lcd.setCursor(0,3); //Go to fourth line of the LCD Screen
lcd.print("Temperature");
lcd.setCursor(12,3); //Go to column 12 on fourth line of the LCD Screen
lcd.print(tempF);
lcd.print(char(223));
lcd.print("C ");
prev = now;
}
}
void setTheTime(char *cmd)
{
struct ts t;
// ssmmhhWDDMMYYYY set time
t.sec = inp2toi(cmd, 0);
t.min = inp2toi(cmd, 2);
t.hour = inp2toi(cmd, 4);
t.wday = inp2toi(cmd, 6);
t.mday = inp2toi(cmd, 7);
t.mon = inp2toi(cmd, 9);
t.year = inp2toi(cmd, 11) * 100 + inp2toi(cmd, 13);
DS3231_set(t);
Serial.println("OK");
}
void printMonth(int month)
{
switch(month)
{
case 1: lcd.print(" January ");break;
case 2: lcd.print(" February ");break;
case 3: lcd.print(" March ");break;
case 4: lcd.print(" April ");break;
case 5: lcd.print(" May ");break;
case 6: lcd.print(" June ");break;
case 7: lcd.print(" July ");break;
case 8: lcd.print(" August ");break;
case 9: lcd.print(" September ");break;
case 10: lcd.print(" October ");break;
case 11: lcd.print(" November ");break;
case 12: lcd.print(" December ");break;
default: lcd.print(" Error ");break;
}
}
char tempF[6];
float temperature;
char buff[BUFF_MAX];
unsigned long now = millis();
struct ts t;
please insert this (see my comments, in the lines with the // marks):
// declare some variables for our timekeeping calculations:
// an int can hold whole numbers (integers) from -32768 to 32767
// which, for what we are doing, is more than enough
int localHour, utcHour;
The reason you insert that is to make this next part work.
This line in your code
DS3231_get(&t); //Get time
is where your Arduino checks the DS3231 to find out what time it is.
Once it knows the time, then we can perform some calculations, thus:
// get the local hour
localHour = t.hour;
// subtract 2 hours from the local hour to get the UTC hour
utcHour = localHour - 2;
// does this give us a negative result? let's check:
if (utcHour < 0)
{
// a negative number for the hour is unacceptable
// so, if it's negative, we add 24 to make it positive
utcHour += 24;
}
Then the variable utcHour will have the value we want it to have so we can do things like this:
// to print the UTC hour on the display:
lcd.print(utcHour);
If you are not familiar with variables and how to use them, perhaps the other people in this forum could recommend a tutorial or guide for you.
You can get the day, month, year, hour, minute, and second values from the RTC. You can use them, and the TimeLib library to create a time_t object. You can subtract 2 hours from the time_t object. You can then convert the time_t object back to day, month, year, hour, minute, and second values, and the date WILL reflect the fact that you subtracted 2 hours.