First of all, sorry if anything isn't well explained; this is my first time asking for help on Stack Overflow. I have an ESP8266 connected to a DHT11 temp/humidity sensor and an ILI9341 TFT-LCD screen to display the data I receive from the NTP server and OpenWeatherMap. I noticed that after a while of normal running it just resets due to what I believe is a shortage of memory (caused by OpenWeatherMap). I tried inspecting the error it gives when it resets and it has something to do with a "Panic" mode of the ESP8266's, although I never managed to get a copy of what it spits out.
I'm asking this question because I'm planning to add a weather forecast section, but when I tried to add the piece of code needed to get the forecast data, it just crashed right off the bat everytime it turned on.
Down here is the code for you to inspect, in case anything is wrong with the Json part, which I believe is the culprit for this, as I'm new to working with the ArduinoJson library, although I got my head around it.
#include <DHT.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ILI9341esp.h>
#include <ESP8266WiFi.h>
#include <time.h>
#include <Adafruit_GFX.h>
#include <ArduinoJson.h>
#define TFT_MISO D6
//#define TFT_LED 3.3V (change to IO pin if you want the screen to be toggled on/off)
#define TFT_SCK D5
#define TFT_MOSI D7
#define TFT_DC D2
#define TFT_RESET D3
#define TFT_CS D8
#define DHTPIN D1
#define DHTTYPE DHT11
#define WIFI_SSID "MY_SSID"
#define WIFI_PASS "MY_PASS"
#define TX_LED D0
WiFiClient client;
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
DHT dht(DHTPIN, DHTTYPE);
int wifitries = 0;
int timezone = 2 * 3600; //when time changes change this from 2 to 1
int dst = 0;
float t = 0.0;
float h = 0.0;
const long interval = 15000;
int elapsed_t = 0;
String APIKEY = "someapikey";
String CityID = "somecityid";
char servername[] = "api.openweathermap.org";
String result;
String weatherDescription = "";
String weatherDesc;
String weatherID;
int Temperature;
int Humidity;
char* tem = " ";
char* hum = " ";
char* temp = " ";
char* humi = " ";
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(TX_LED, OUTPUT);
digitalWrite(TX_LED, HIGH);
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(115200);
tft.begin();
configTime(timezone, dst, "pool.ntp.org", "it.pool.ntp.org");
dht.begin();
WiFi.disconnect();
delay (3000);
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.println();
Serial.println ("Connecting to TP-LINK_DD1E61");
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Connecting to ");
tft.println("TP-LINK_DD1E61");
while ((!(WiFi.status() == WL_CONNECTED))) {
Serial.print(".");
wifitries++;
tft.setTextSize(1);
tft.print(".");
delay(300);
}
if (wifitries = 15) {
wifitries = 0;
WiFi.disconnect();
delay (3000);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while ((!(WiFi.status() == WL_CONNECTED))) {
Serial.print(".");
wifitries++;
tft.setTextSize(1);
tft.print(".");
delay(300);
}
}
if (WiFi.status() == WL_CONNECTED) {
tft.setTextSize(2);
tft.println();
tft.println("Connected to ");
tft.println("TP-LINK_DD1E61");
delay(500);
tft.fillScreen(ILI9341_BLACK);
}
while (!time(nullptr)) {
Serial.print("*");
delay(300);
}
tft.drawLine(0, 18, 320, 18, ILI9341_WHITE);
tft.setTextSize(2);
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setCursor(0, 135);
tft.print("TEMPO");
tft.setCursor(20, 25);
tft.println("TEMPERATURA");
tft.println();
tft.println();
tft.setCursor(215, 25);
tft.println("UMIDITA'");
tft.setTextSize(1);
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setCursor(0, 52);
tft.print("INTERNO");
tft.setCursor(0, 87);
tft.print("ESTERNO");
delay(1000);
DHT_read();
getWeatherData();
displayConditions(Temperature, Humidity, weatherDescription);
}
void DHT_read() {
float newT = dht.readTemperature();
if (isnan(newT)) {
Serial.println("Failed to read from DHT sensor!");
tft.setTextSize(2);
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setCursor(109, 43);
tft.print("!");
}
else {
int t = newT;
if (t >= 10) {
char* temp = " ";
sprintf(temp, "%02d", t);
}
else {
char* temp = " ";
sprintf(temp, "%01d", t);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(79, 43);
tft.print("0");
}
Serial.print("Temperature: ");
Serial.print(temp);
Serial.println();
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(67, 43);
tft.print(temp);
tft.setCursor(92, 40);
tft.setTextSize(1);
tft.print("o");
tft.setCursor(99, 43);
tft.setTextSize(2);
tft.print("C");
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(109, 43);
tft.print("!");
}
float newH = dht.readHumidity();
if (isnan(newH)) {
Serial.println("Failed to read from DHT sensor!");
tft.setTextSize(2);
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setCursor(287, 43);
tft.print("!");
}
else {
int h = newH;
if (h >= 10 && h <= 99) {
char* humi = " ";
sprintf(humi, "%02d", h);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(261, 43);
tft.print("0");
}
else if (h = 100) {
char* humi = " ";
sprintf(humi, "%03d", h);
}
else {
char* humi = " ";
sprintf(humi, "%01d", h);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(261, 43);
tft.print("0");
}
Serial.print("Humidity: ");
Serial.print(humi);
Serial.println();
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(237, 43);
tft.print(humi);
tft.setCursor(277, 43);
tft.print("%");
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(287, 43);
tft.print("!");
}
}
void screen() {
time_t now = time(nullptr);
struct tm* p_tm = localtime(&now);
char* day = " ";
sprintf(day, "%02d", p_tm->tm_mday);
tft.setCursor(192, 0);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print(day);
tft.setCursor(217, 0);
tft.print("/");
char* month = " ";
sprintf(month, "%02d", p_tm->tm_mon + 1);
tft.setCursor(231, 0);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print(month);
tft.setCursor(256, 0);
tft.print("/");
char* year = " ";
sprintf(year, "%04d", p_tm->tm_year + 1900);
tft.setCursor(268, 0);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print(year);
char* hour = " ";
sprintf(hour, "%02d", p_tm->tm_hour);
tft.setCursor(0, 0);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print(hour);
tft.setCursor(22, 0);
tft.print(":");
char* minute = " ";
sprintf(minute, "%02d", p_tm->tm_min);
tft.setCursor(34, 0);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print(hour);
}
void getWeatherData() {
if (client.connect(servername, 80))
{ //starts client connection, checks for connection
client.println("GET /data/2.5/weather?id=" + CityID + "&units=metric&APPID=" + APIKEY + "&lang=it");
client.println("Host: api.openweathermap.org");
client.println("User-Agent: ArduinoWiFi/1.1");
client.println("Connection: close");
client.println();
}
else {
Serial.println("connection failed"); //error message if no client connect
Serial.println();
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setCursor(0, 220);
tft.print("CONNESSIONE FALLITA");
}
while (client.connected() && !client.available())
delay(1); //waits for data
while (client.connected() || client.available())
{ //connected or data available
char c = client.read(); //gets byte from ethernet buffer
result = result + c;
}
client.stop(); //stop client
result.replace('[', ' ');
result.replace(']', ' ');
Serial.print(result);
Serial.println();
char jsonArray [result.length() + 1];
result.toCharArray(jsonArray, sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
DynamicJsonBuffer json_buf(3584); //was 4096
JsonObject &root = json_buf.parseObject(jsonArray); //
if (!root.success())
{
Serial.println("parseObject() failed");
tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
tft.setCursor(109, 78);
tft.print("!");
tft.setCursor(287, 78);
tft.print("!");
}
else {
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(109, 78);
tft.print("!");
tft.setCursor(287, 78);
tft.print("!");
}
float temperature = root["main"]["temp"];
float humidity = root["main"]["humidity"];
String weather = root["weather"]["main"];
String description = root["weather"]["description"];
String id = root["weather"]["id"];
weatherDescription = description;
Temperature = temperature;
Humidity = humidity;
weatherID = id;
result = ""; //to clean memory and keep it from running out of space
}
void displayConditions(int Temperature, int Humidity, String weatherDescription) {
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
if (Temperature >= 10) {
char* tem = " ";
sprintf(tem, "%02d", Temperature);
}
else {
char* tem = " ";
sprintf(tem, "%01d", Temperature);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(79, 78);
tft.print("0");
}
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(67, 78);
tft.print(tem);
tft.setCursor(92, 75);
tft.setTextSize(1);
tft.print("o");
tft.setCursor(99, 78);
tft.setTextSize(2);
tft.print("C");
if (Humidity >= 10 && Humidity <= 99) {
char* hum = " ";
sprintf(hum, "%02d", Humidity);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(261, 78);
tft.print("0");
}
else if (Humidity = 100) {
char* hum = " ";
sprintf(hum, "%03d", Humidity);
}
else {
char* hum = " ";
sprintf(hum, "%01d", Humidity);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(261, 78);
tft.print("0");
}
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(237, 78);
tft.print(hum);
tft.setCursor(277, 78);
tft.print("%");
if (weatherDesc != weatherDescription) {
weatherDesc = weatherDescription;
tft.fillRect(0, 150, 320, 240, ILI9341_BLACK);
tft.setCursor(0, 150);
tft.print(weatherDescription);
}
else {
tft.setCursor(0, 150);
tft.print(weatherDescription);
}
}
void loop() {
screen();
if (millis() > elapsed_t + interval) {
elapsed_t = millis();
getWeatherData();
DHT_read();
displayConditions(Temperature, Humidity, weatherDescription);
Serial.print("Free heap: ");
Serial.print(ESP.getFreeHeap());
Serial.println();
}
if (ESP.getFreeHeap() < 1000) {
ESP.reset();
}
}
EDIT This is the payload I get from running the code:
{"coord":{"lon":longitude,"lat":latitude},
"weather": {"id":800,"main":"Clear","description":"cielo sereno","icon":"01d"} ,"base":"stations",
"main":{"temp":16.56,"feels_like":13.87,"temp_min":13.33,"temp_max":20,"pressure":1022,"humidity":38},
"visibility":10000,
"wind":{"speed":1.5,"deg":80},
"clouds":{"all":0},"dt":1586590775,
"sys":{"type":1,"id":6776,"country":"IT","sunrise":1586579815,"sunset":1586627707},
"timezone":7200,"id":city_id,"name":"city_name","cod":city_code}