ESP8266 сбрасывается после некоторого времени нормальной работы при получении данных из OpenWeatherMap - PullRequest
0 голосов
/ 10 апреля 2020

Прежде всего, извините, если что-то не очень хорошо объяснено; я впервые обращаюсь за помощью по переполнению стека. У меня есть ESP8266, подключенный к датчику температуры / влажности DHT11, и TFT-LCD экран ILI9341 для отображения данных, которые я получаю от NTP-сервера и OpenWeatherMap. Я заметил, что после некоторого времени нормальной работы он просто сбрасывается из-за того, что я считаю нехваткой памяти (вызванной OpenWeatherMap). Я попытался проверить ошибку, которая выдается, когда он сбрасывается, и это как-то связано с режимом «Pani c» ESP8266, хотя мне так и не удалось получить копию того, что он выплевывает.

I Я задаю этот вопрос, потому что я планирую добавить раздел прогноза погоды, но когда я попытался добавить фрагмент кода, необходимый для получения данных прогноза, он просто зависал сразу после включения.

Ниже приведен код, который вы можете проверить на случай, если что-то не так с частью Json, и я считаю, что виновником этого является то, что я новичок в работе с библиотекой Arduino Json, хотя я обдумал это.

#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();
  }
}

РЕДАКТИРОВАТЬ Это полезная нагрузка, которую я получаю при запуске кода:

        {"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}

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Прежде всего, вы слишком много перераспределяете для DynamicJsonBuffer json_buf(3584), в соответствии с полезной нагрузкой, отправленной обратно из используемого вами API, json_buf потребуется всего менее 800 байтов, поэтому DynamicJsonBuffer json_buf(800) будет быть более чем достаточно. Вы можете использовать Arduino Json Assistant для расчета размера буфера, необходимого для копирования и вставки полезной нагрузки json в поле ввода на странице.

Превышение размера Arduino Json буфер, однако, не является культом для фрагментации кучи, с которой вы сталкиваетесь. Одна из проблем, связанных с тем, что класс String вызвал фрагментацию кучи, связана с конкатенацией строк, и именно это происходит в вашем случае. Конкатенация строк дает пользователям Arduino возможность соединить две строки, как в JavaScript или Pyhton, String temp = "Temperature=" + String(temperature)+" Celsius". Однако этот оператор генерирует 5 выделений кучи (не 4), даже если вы хотите только последнее.

В своем коде вы объявляете глобальную переменную result и выполняете конкатенацию строк в своей функции.

String result;

// later in your function

void getWeatherData() {

  // at part of your function

  while (client.connected() || client.available())
  { //connected or data available
    char c = client.read();                //gets byte from ethernet buffer
    result = result + c;
  }

  // at end of your function  

  result = "";  //to clean memory and keep it from running out of space
}

Когда вы делаете конкатенацию, исходное выделение для вашей глобальной переменной result может больше не иметь достаточно места для конкатенированной переменной, поэтому он создает временную кучу и выполняет конкатенацию, а затем в конечном итоге помещает результат возвращается во вновь выделенную память для result в куче, оставляя дыру в куче для исходной переменной result. Хуже всего то, что это происходит для каждой итерации while l oop. Вот почему даже некоторые из выделений кучи освобождаются в конце функции, и нет необходимости в их повторном использовании (например, кусок сыра с множеством отверстий на нем).

Кстати, ваш код:

result = "";  //to clean memory and keep it from running out of space

никогда не освобождает выделение памяти. Это еще одно распространенное недоразумение.

Краткосрочное исправление - используйте String локально

Сказав это, класс String не всегда является злом, если вы знаете, что происходит и как его использовать. Одним из быстрых решений вашей проблемы (поскольку у меня нет времени на оптимизацию кода для вас) является использование его локально в функции и не использование глобальной переменной для String result;. Я провел быструю проверку, удалив глобальную переменную result и объявив ее как «выбрасываемую» локальную переменную внутри функции getWeatherData(), объем свободной динамической памяти стабилизировался и больше не вызывал cra sh. Когда вы используете класс String внутри функции, он не оставляет дыры в общем пространстве кучи, но освобождается в конце функции.

// String result; //comment the global variable out

void getWeatherData() {

  String result;    //declare it as a local variable

  while (client.connected() || client.available())
  { //connected or data available
    char c = client.read();           //gets byte from ethernet buffer
    result = result + c;
  }

  //result = "";  //this is not necessary and does not free up heap
}

Долгосрочное исправление - не используйте String класс

Для лучшего исправления не используйте конкатенацию строк в течение времени l oop. Вот версия без использования класса String, и немного очищена для устранения ненужных глобальных переменных (также некоторые перефакторинг некоторых повторяющихся кодов).

#include <Arduino.h>
#include <DHT.h>
#include <ESP8266WiFi.h>
#include <time.h>
#include <ArduinoJson.h>
#include <Adafruit_Sensor.h>
// #include <Adafruit_ILI9341esp.h>
// #include <Adafruit_GFX.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 "wifi-ssid"
#define WIFI_PASS "wifi-password"
#define TX_LED D0

WiFiClient client;
// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
DHT dht(DHTPIN, DHTTYPE);

int timezone = 2 * 3600; //when time changes change this from 2 to 1
int dst = 0;

const unsigned long interval = 15000;
unsigned long elapsed_t = 0;

const char APIKEY[] = "open-weather-api-key";  //replace with actual api-key
const char CityID[] = "cityID";  //replace with actual city ID
char servername[] = "api.openweathermap.org";

void displayConditions(int Temperature, int Humidity, char *weatherDescription) {
  // tft.setTextSize(2);
  // tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);

  char tem[3] = {0};
  if (Temperature >= 10) {
    sprintf(tem, "%02d", Temperature);
  }
  else {
    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");

  char hum[4] = {0};
  if (Humidity >= 10 && Humidity <= 99) {
    sprintf(hum, "%02d", Humidity);
    // tft.setTextColor(ILI9341_BLACK);
    // tft.setTextSize(2);
    // tft.setCursor(261, 78);
    // tft.print("0");
  }
  else if (Humidity == 100) {
    sprintf(hum, "%03d", Humidity);
  }
  else {
    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("%");

  static char weatherDesc[10];
  if (strcmp(weatherDesc, weatherDescription) != 0) {
    strcpy(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 DHT_read() {

  float newT = dht.readTemperature();
  float newH = dht.readTemperature();
  if (isnan(newT) || isnan(newH)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    // tft.setTextSize(2);
    // tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
    // tft.setCursor(109, 43);
    // tft.print("!");
    // tft.setCursor(287, 43);
    // tft.print("!");
    return;
  }
  char condition[] = "";
  displayConditions((int)newT, (int)newH, condition);
}

void screen() {
  char timeNow[20];
  time_t now = time(nullptr);
  struct tm* p_tm = localtime(&now);

  strftime(timeNow, 20, "%H:%M  %d:%m:%Y", p_tm);
  Serial.println(timeNow);
  // tft.setCursor(0, 0);
  // tft.setTextSize(2);
  // tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
  // tft.print(timeNow);
}

void getWeatherData() {

  if (client.connect(servername, 80))
  { //starts client connection, checks for connection
    char buff[110];
    char getString[] = "GET /data/2.5/weather?id=%s&units=metric&APPID=%s&lang=it";
    sprintf(buff, getString, CityID, APIKEY);
    client.println(buff);
    client.println(F("Host: api.openweathermap.org"));
    client.println(F("User-Agent: ArduinoWiFi/1.1"));
    client.println(F("Connection: close"));
    client.println();
  }
  else {
    Serial.println(F("connection failed"));        //error message if no client connect
    Serial.println();
    // tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
    // tft.setCursor(0, 220);
    // tft.print(F("CONNESSIONE FALLITA"));
    return;
  }

  while (client.connected() && !client.available())
    delay(1);                                          //waits for data

  char result[800];
  int i = 0;
  while (client.connected() || client.available())
  { //connected or data available
    result[i++] = (char)client.read();
  }

  client.stop();                                      //stop client
  result[strlen(result) + 1] = '\0';
  Serial.println(result);

  DynamicJsonBuffer json_buf(800); //was 4096
  JsonObject &root = json_buf.parseObject(result); //

  if (!root.success())
  {
    Serial.println(F("parseObject() failed"));
    // tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
    // tft.setCursor(109, 78);
    // tft.print("!");
    // tft.setCursor(287, 78);
    // tft.print("!");
    return;
  }

  // tft.setTextColor(ILI9341_BLACK);
  // tft.setCursor(109, 78);
  // tft.print("!");
  // tft.setCursor(287, 78);
  // tft.print("!");

  char weatherDescription[10] = {0};
  strcpy(weatherDescription, (const char*)root["weather"][0]["main"]);
  weatherDescription[strlen(weatherDescription) + 1] = '\0';

  int temperature = (int)root["main"]["temp"];
  int humidity = (int)root["main"]["humidity"];
  int weatherID = root["weather"][0]["id"];    //this was not used anywhere in the program

  displayConditions(temperature, humidity, weatherDescription);
}



void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(TX_LED, OUTPUT);
  digitalWrite(TX_LED, HIGH);
  digitalWrite(LED_BUILTIN, HIGH);

  Serial.begin(115200);
  // tft.begin();
  // dht.begin();

  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.println (F("Connecting to TP-LINK_DD1E61"));

  // tft.setRotation(3);
  // tft.fillScreen(ILI9341_BLACK);
  // tft.setTextSize(2);
  // tft.println(F("Connecting to "));
  // tft.println(F("TP-LINK_DD1E61"));
  while (WiFi.status() != WL_CONNECTED) {
   Serial.print(".");
   // tft.setTextSize(1);
   // tft.print(".");
   delay(300);
  }

  // query the ntp should be only after the establish of wifi connection
  configTime(timezone, dst, "pool.ntp.org", "it.pool.ntp.org");
  while (!time(nullptr)) {
   Serial.print("*");
   delay(300);
  }

  Serial.println(F("Connceted"));
  // tft.setTextSize(2);
  // tft.println();
  // tft.println(F("Connected to "));
  // tft.println(F("TP-LINK_DD1E61"));
  // delay(500);
  // tft.fillScreen(ILI9341_BLACK);

  // 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(F("TEMPERATURA"));
  // tft.println();
  // tft.println();
  // tft.setCursor(215, 25);
  // tft.println(F("UMIDITA'"));
  // tft.setTextSize(1);
  // tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
  // tft.setCursor(0, 52);
  // tft.print(F("INTERNO"));
  // tft.setCursor(0, 87);
  // tft.print(F("ESTERNO"));

}

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();
  }
  delay(1000);  // only update the time once per second
 }

Вы можете узнать больше о " Зло Arduino Strings"более подробно. Я надеюсь, что мой пример поможет вам узнать кое-что о том, как управлять памятью и избегать использования класса String.

0 голосов
/ 10 апреля 2020

Вы правы с частью Json, но перед этим несколько советов:

  • Никогда не публикуйте свои логины / API-ключи / пароли - я удалил их из кода
  • заменить

    if (millis ()> elapsed_t + interval) {

на (делает то же самое, но безопасно при опрокидывании)

if (millis() - elapsed_t > interval) {

Теперь t oArduino Json - эта библиотека для вас "раздутая", попробуйте вручную разобрать строку - если вы публикуете реальную строку, я могу показать вам, как это сделать. И избавьтесь от класса String

  String APIKEY = "someapikey";
  String CityID = "somecityid";
  char servername[] = "api.openweathermap.org"; // GOOD example of how to avoid String class
  String result;
  String weatherDescription = "";
  String weatherDesc;
  String weatherID;

Класс String разрушает кучу и обычно приводит к тому, что esp8266 / esp32 превращается в sh через некоторое время. Бесплатная проверка кучи не помогает - кучи достаточно, но она разбита так долго, что строки не могут быть обработаны правильно. На микроконтроллерах нет сборки мусора для решения этой проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...