从OpenWeatherMap获取数据后,ESP8266在正常运行一段时间后会重置 [英] ESP8266 resets after some time of normal running while getting data from OpenWeatherMap

查看:120
本文介绍了从OpenWeatherMap获取数据后,ESP8266在正常运行一段时间后会重置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,很抱歉,如果没有解释清楚;这是我第一次寻求有关堆栈溢出的帮助.我有一个连接到DHT11温度/湿度传感器的ESP8266和一个ILI9341 TFT-LCD屏幕,用于显示从NTP服务器和OpenWeatherMap接收到的数据.我注意到经过一段时间的正常运行后,由于我认为内存不足(由OpenWeatherMap引起),它只是重置了.我尝试检查它重置时给出的错误,这与ESP8266的紧急"模式有关,尽管我从未设法得到它吐出的内容的副本.

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.

下面是供您检查的代码,以防万一Json部件出了问题,我相信这是罪魁祸首,因为我刚接触ArduinoJson库,尽管我早已明白了它.

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}

推荐答案

首先,根据有效负载发送回去,您确实为 DynamicJsonBuffer json_buf(3584)分配了很多资源从您使用的API中来看, json_buf 仅需要少于800个字节,因此 DynamicJsonBuffer json_buf(800)绰绰有余.您可以使用 ArduinoJson Assistant 通过将json有效负载复制并粘贴到输入中来计算所需的缓冲区大小页面上的框.

First of all, you do over-allocated quite a bit for the DynamicJsonBuffer json_buf(3584), according to the payload send back from the API you used, the json_buf would only need less than 800 bytes, so DynamicJsonBuffer json_buf(800) would be more than sufficient. You can use ArduinoJson Assistant to calculate the buffer size required by copying and pasting the json payload into the input box on the page.

但是,超大型ArduinoJson缓冲区不是您面临的堆碎片的根源.String类导致堆碎片的问题之一来自String串联,这就是您的情况所发生的情况.字符串连接使Arduino用户可以像在JavaScript或Pyhton中那样将两个字符串放在一起,字符串temp ="Temperature =" +字符串(温度)+摄氏" .但是,即使您只想要最后一个,此语句也会生成5个堆分配(而不是4个).

Over-size ArduinoJson buffer however is not the cultprit for the heap fragmentation that you are facing. One of the problem that String class caused heap fragmentation come from String concatenation, and this is what happen to your case. String concatenation gives Arduino users the capability of put two strings together like in JavaScript or Pyhton, String temp = "Temperature=" + String(temperature)+" Celsius". However, this statement along generates 5 heap allocations (not 4) even though you only want the final one.

在您的代码中,声明一个全局变量 result ,然后在函数中进行String串联.

In your code, you declare a global variable result and you are doing String concatenation in your function.

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 循环的每次迭代中.这就是为什么即使某些堆分配在功能结束时仍可以释放的原因,也没有必要将其重用(想像一块带有很多孔的奶酪).

When you do concatenation, the original allocation for your global variable result may no longer have enough space for the concatenated variable, so it create a temporary heap and do the concatenation, and then eventually put the result back to a newly allocated memory for result on the heap, leaving a hole at the heap for the original result variable. What make this worst is that this is happening for each iteration of the while loop. This is why even some of the heap allocations get free-up at the end of function, it does not necessary will be re-usable (think of a piece of cheese with a lot of holes on it).

顺便说一句,您的代码:

BTW, your code:

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

从未真正释放内存分配.这是另一个常见的误解.

never really free up the memory allocation. This is another common misunderstanding.

话虽如此,如果您知道发生了什么事以及如何使用它,String类并不总是邪恶的.解决您的问题的快速方法之一(因为我没有时间为您优化代码)是在函数内部局部使用它,而不对 String结果使用全局变量; .通过删除全局变量 result 并在 getWeatherData()函数中声明为丢弃"局部变量,我进行了快速测试,从而稳定了可用的堆内存并不再导致崩溃.当您在函数中使用String类时,它不会在整个堆空间中留下空洞,而是会在函数末尾释放空间.

Having said that, String class is not always the evil if you know what's going on and how to use it. One of the quick fix for your problem (as I don't have time to optimise the code for you) is to use it locally within the function and do not use the global variable for the String result;. I did a quick test, by removing the global variable result and declare as a "throw-away" local variable within the getWeatherData() function, the free heap memory stabilised and no longer caused crash. When you use String class within a function, it does not leave a hole in the overall heap space, but get free up at the end of the function.

// 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类

为获得更好的解决方案,请不要在while循环中使用String串联.这是不使用String类的版本,为消除不必要的全局变量(还有一些重构某些重复代码)做了很多清理工作.

Long term fix - Don't use String class

For a better fix, do not use String concatenation within the while loop. Here is the version without using String class, and quite a bit clean up for eliminating the unnecessary global variables (also some re-factoring some of the repetitive codes).

#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
 }

您可以详细了解" The Evils的详细信息".我希望我的示例将帮助您学习有关如何管理内存的知识,并避免使用String类.

You can learn more about "The Evils of Arduino Strings" in more details. I hope my example will help you to learn something on how to manage the memory and avoid of using String class.

这篇关于从OpenWeatherMap获取数据后,ESP8266在正常运行一段时间后会重置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆