I apologize for my ignorance but I'm very new to programming. I have tried searching every example I can find but nothing is working. I would like for the time output from the gps to be the local timezone of EST (-5) but everything I try continues to give me UTC. Here is my code.
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <TinyGPSPlus.h>
byte last_second, Second, Minute, Hour, Day, Month;
int Year;
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Initialize the OLED display with address 0x3C
TinyGPSPlus gps; //defines the gps object
void setup() {
Serial.begin(9600); // This starts the global serial interface. This is what is used for the majority of the functions.
Serial3.begin(9600); // This starts the GPS on the pin. Anything to do with pin will be referenced as Serial3
lcd.init();
}
void loop() {
while (Serial3.available() > 0)
gps.encode(Serial3.read());
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("Latitude: ");
lcd.print(gps.location.lat());
lcd.setCursor(1, 1);
lcd.print("Longitude: ");
lcd.print(gps.location.lng());
lcd.setCursor(1, 2);
lcd.print("Time: ");
byte Minute = gps.time.minute();
byte Second = gps.time.second();
byte Hour = gps.time.hour();
byte Day = gps.date.day();
byte Month = gps.date.month();
byte Year = gps.date.year();
setTime(Hour, Minute, Second, Day, Month, Year);
adjustTime(-5);
lcd.setCursor(1, 3);
lcd.print("Date: ");
lcd.print(gps.date.month());
lcd.print("/");
lcd.print(gps.date.day());
lcd.print("/");
lcd.print(gps.date.year());
Serial.println("# of Satellites " + gps.satellites.value());
Serial.println(gps.satellites.value());
Serial.println(gps.location.lat());
Serial.println(Hour);
}
For testing, I'm just sending the hour to the serial monitor. Once it is correct, I will update the lcd output.
What is it giving you for the year? You are trying to fit the year into a byte. A byte can only go from 0 to 255. We are in the year 2024. I don't see how the number 2024 can fit into a byte.
Why are you declaring variables with these names at the top, like this
and then again declaring variables with these names here?
Do you want Year to be an int or a byte?
I would remove the word byte from those lines.
Try:
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <TinyGPSPlus.h>
byte last_second, Second, Minute, Hour, Day, Month;
int Year;
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Initialize the OLED display with address 0x3C
TinyGPSPlus gps; //defines the gps object
void setup() {
Serial.begin(9600); // This starts the global serial interface. This is what is used for the majority of the functions.
Serial3.begin(9600); // This starts the GPS on the pin. Anything to do with pin will be referenced as Serial3
lcd.init();
}
void loop() {
while (Serial3.available() > 0)
gps.encode(Serial3.read());
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("Latitude: ");
lcd.print(gps.location.lat());
lcd.setCursor(1, 1);
lcd.print("Longitude: ");
lcd.print(gps.location.lng());
lcd.setCursor(1, 2);
lcd.print("Time: ");
Minute = gps.time.minute();
Second = gps.time.second();
Hour = gps.time.hour();
Day = gps.date.day();
Month = gps.date.month();
Year = gps.date.year();
setTime(Hour, Minute, Second, Day, Month, Year);
adjustTime(-18000);
lcd.setCursor(1, 3);
lcd.print("Date: ");
lcd.print(gps.date.month());
lcd.print("/");
lcd.print(gps.date.day());
lcd.print("/");
lcd.print(gps.date.year());
Serial.println("# of Satellites " + gps.satellites.value());
Serial.println(gps.satellites.value());
Serial.println(gps.location.lat());
Serial.println(hour());
}
What does this get you? If this doesn't work, I have another approach you could use.
I went back and look at everything again. If I print gps.data.year I get 2024. Serial.println(year()); will give me 2024. If I print Year, it gives 232 as that is defined as an integer. That could just be removed.
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <TinyGPSPlus.h>
byte last_second, Second, Minute, Hour, Day, Month;
int Year;
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Initialize the OLED display with address 0x3C
TinyGPSPlus gps; //defines the gps object
void setup() {
Serial.begin(9600); // This starts the global serial interface. This is what is used for the majority of the functions.
Serial3.begin(9600); // This starts the GPS on the pin. Anything to do with pin will be referenced as Serial3
lcd.init();
}
void loop() {
while (Serial3.available() > 0)
gps.encode(Serial3.read());
lcd.backlight();
lcd.setCursor(1, 0);
lcd.print("Latitude: ");
lcd.print(gps.location.lat());
lcd.setCursor(1, 1);
lcd.print("Longitude: ");
lcd.print(gps.location.lng());
Minute = gps.time.minute();
Second = gps.time.second();
Hour = gps.time.hour();
Day = gps.date.day();
Month = gps.date.month();
Year = gps.date.year();
// adjust for local time zone: UTC minus 5 hours
// to avoid negative numbers in the calculation,
// we do it by adding 19 hours and subtracting one day
Hour += 19;
Day--;
// twenty-four hours make one day
if (Hour >= 24) {
Hour -= 24;
Day++;
}
// change "zeroth" day of month to last day of previous month
if (Day == 0) {
Month--;
if (Month == 0) {
Month = 12;
Year--;
}
if ((Month == 4) || (Month == 11) || (Month == 9) || (Month == 6)) {
Day = 30;
}
else if (Month == 2) {
if ((Year % 4) == 0) {
// this will fail in the year 2100
Day = 29;
}
else {
Day = 28;
}
}
else {
Day = 31;
}
}
setTime(Hour, Minute, Second, Day, Month, Year);
lcd.setCursor(1, 2);
lcd.print("Time: ");
lcd.print(Hour);
lcd.print(":");
if (Minute < 10) {
lcd.print("0");
}
lcd.print(Minute);
lcd.print(":");
if (Second < 10) {
lcd.print("0");
}
lcd.print(Second);
lcd.setCursor(1, 3);
lcd.print("Date: ");
lcd.print(Month);
lcd.print("/");
lcd.print(Day);
lcd.print("/");
lcd.print(Year);
Serial.println("# of Satellites " + gps.satellites.value());
Serial.println(gps.satellites.value());
Serial.println(gps.location.lat());
Serial.println(hour());
}
I just did the conversion "the long way". I wanted to subtract 5 hours, but subtracting 5 could possibly result in a negative number (what if UTC hours were less than 5 when we did it?), so instead I added 19 hours, which would give the same time of day as subtracting 5 hours. Then I needed to take care of what happens if the hours end up being a number that is 24 or greater. Then the rest of the code is just to get the date right: think of what happens if adding or subtracting hours gets us into a different day.