Hi! I kept working on this program, and with help from other people. I basically combined two programs. The thing is that the program freezes, or at least the LCD (it's a 16x1 but I command it like a 16x2), as you can see in the picture. After 1-2 hours of operation on the LCD I see hieroglyphs, as I usually say. The time should be displayed for 50s, and the weather for 10s. The mainboard is an ESP32.
I put about 4 messages at certain key moments, those messages appear on the Serial Monitor, but I don't understand what is happening with the LCD.
I also tested the programs separately for two days, no problem. One is for displaying clock + day (NTP clock), and the other is for displaying local weather + city using a private API.
What do you think would be the problem? In the part where I did the 50s-10s division?
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
#include "time.h"
#include "sntp.h"
#include <LiquidCrystal_I2C.h>
//0x3F or 0x27
LiquidCrystal_I2C lcd(0x27, 16, 2); //LCD Object
const char* ssid = "@@@@@";
const char* password = "@@@@@";
const char* ntpServer1 = "pool.ntp.org";
const char* ntpServer2 = "time.nist.gov";
const long gmtOffset_sec = 7200;
const int daylightOffset_sec = 3600;
char *daynames[7] = {
"Duminica",
" Luni",
" Marti",
"Miercuri",
" Joi",
" Vineri",
" Sambata"
}; // put them in this order as tm struct 0 = Sunday
//*****************************************************************************************************
byte degree[8] = {
0B00111,
0B00101,
0B00111,
0B00000,
0B00000,
0B00000,
0B00000,
0B00000
}; // create degree sign
// Set your own API here
String openWeatherMapApiKey = "@@@@@@";
// Set your country code and city name here
String city = "Sibiu";
String countryCode = "RO";
// THE DEFAULT TIMER IS SET TO 10 SECONDS FOR TESTING PURPOSES
// For a final application, check the API call limits per hour/minute to avoid getting blocked/banned
unsigned long lastTime = 0;
// Timer set to 1 hr in ms
unsigned long timerDelay = 5220000;
// set boolean firsttime
bool firstTime = true;
String jsonBuffer;
JSONVar myObject = JSONVar();
//*****************************************************************************************************
int counter1 = 0;
int counter2 = 0;
unsigned long startTime = 0;
unsigned long startTime2 = 0;
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("No time available (yet)");
return;
}
//lcd.print(&timeinfo, "%A%H:%M:%S"); // e.g Tuesday 10:30:05
//lcd.print(&timeinfo, "%d %B %Y"); //e.g November 22 2022
//Display Time
lcd.setCursor(0, 0);
lcd.print(&timeinfo, "%H:%M:%S"); // 10:30:05
// Display Day
char *day_string = daynames[timeinfo.tm_wday];
char buff[64] = "";
snprintf(buff, 64, "Day: %s", day_string);
Serial.println(buff);
lcd.setCursor(0, 1);
lcd.print(day_string);
Serial.println("Message 1");
} // printLocalTime
// Callback function (get's called when time adjusts via NTP)
void timeavailable(struct timeval *t)
{
Serial.println("Got time adjustment from NTP!");
printLocalTime();
}
void setup()
{
Serial.begin(115200);
// Setup LCD with backlight and initialize
lcd.init();
lcd.backlight();
lcd.createChar(0, degree);
// set notification call-back function
sntp_set_time_sync_notification_cb( timeavailable );
/**
NTP server address could be aquired via DHCP,
NOTE: This call should be made BEFORE esp32 aquires IP address via DHCP,
otherwise SNTP option 42 would be rejected by default.
NOTE: configTime() function call if made AFTER DHCP-client run
will OVERRIDE aquired NTP server address
*/
sntp_servermode_dhcp(1); // (optional)
/**
This will set configured ntp servers and constant TimeZone/daylightOffset
should be OK if your time zone does not need to adjust daylightOffset twice a year,
in such a case time adjustment won't be handled automagicaly.
*/
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
lcd.clear();
lcd.print("Connecting to ");
lcd.setCursor(0, 1);
lcd.print(ssid);
delay(1000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
lcd.clear();
lcd.print("CONNECTED");
delay(2000);
lcd.clear();
} // setup
void loop()
{
unsigned long currentTime = millis();
if (currentTime - startTime >= 1000)
{
counter1++;
counter2++;
startTime = currentTime;
}
// display local time for 50s
if (counter1 < 50)
{
printLocalTime();
Serial.println("Message 2");
}
else if (counter1 == 50)
{
counter2 = 0;
lcd.setCursor(0, 0);
lcd.print(" ");
}
// display local weather for 10s
else if (counter2 < 10)
{
lcd.setCursor(0, 0);
lcd.print(myObject["main"]["temp"]);
lcd.write((byte)0);
lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("in ");
lcd.print(city);
Serial.println("Message 3");
}
else if (counter2 == 10)
{
counter1 = 0;
}
if (((millis() - lastTime) > timerDelay) || firstTime)
{
// Check WiFi connection status
if (WiFi.status() == WL_CONNECTED)
{
String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&units=metric&APPID=" + openWeatherMapApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());
Serial.println(jsonBuffer);
myObject = JSON.parse(jsonBuffer);
// JSON.typeof(jsonVar) can be used to get the type of the var
if (JSON.typeof(myObject) == "undefined")
{
Serial.println("Parsing input failed!");
return;
}
Serial.println("Message 4");
// Dump to serial
Serial.print("JSON object = ");
Serial.println(myObject);
Serial.print("Temperature: ");
Serial.println(myObject["main"]["temp"]);
Serial.print("Pressure: ");
Serial.println(myObject["main"]["pressure"]);
Serial.print("Humidity: ");
Serial.println(myObject["main"]["humidity"]);
Serial.print("Wind Speed: ");
Serial.println(myObject["wind"]["speed"]);
}
else
{
Serial.println("WiFi Disconnected");
}
// Reset timer
lastTime = millis();
// disable firsttime
firstTime = false;
}
} // loop
String httpGETRequest(const char *serverName)
{
WiFiClient client;
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "{}";
if (httpResponseCode > 0)
{
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
}
else
{
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
return payload;
}