Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP Calls stop after a while #11

Open
balsimpson opened this issue Feb 7, 2017 · 3 comments
Open

HTTP Calls stop after a while #11

balsimpson opened this issue Feb 7, 2017 · 3 comments

Comments

@balsimpson
Copy link

Hi

Thanks a lot for this library. Am a complete noob, but I was trying to get your planespotter demo working. After I started on it I realized I have a different LED panel than yours and I couldn't get ahead. I then somehow got the LED panel working and designed some simple screens to display the data and all works. Except that after about twenty minutes, it stops working.

Is there some memory heap I need to take care of? Any help would be greatly appreicated.

I have the AdbsExchangeClient.cpp and AdbsExchangeClient.h files in the same sketch folder which I have not done any major modification to.

My main code is:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <JsonListener.h>
#include <ESP8266mDNS.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>

// ST7735
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>

#define TFT_CS     16
#define TFT_RST    4 
#define TFT_DC     5

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

#include "TimeClient.h"
#include "AdsbExchangeClient.h"

/**************
   Required Libraries:
   - Weather Station by Daniel Eichhorn
   - WifiManager by tzapu
   - ESP8266 OLED Driver by Daniel Eichhorn, Fabrice Weinberg
   - Json Streaming Parser by Daniel Eichhorn
*/
/***************************
   Begin Settings
 **************************/
// Please read http://blog.squix.org/weatherstation-getting-code-adapting-it
// for setup instructions

// Setup
const int UPDATE_INTERVAL_SECS_LONG = 15; // Update every 15 seconds if no airplanes around
const int UPDATE_INTERVAL_SECS_SHORT = 10; // Update every 3 seconds if there are airplanes

int currentUpdateInterval = UPDATE_INTERVAL_SECS_LONG;
long lastUpdate = 0;

// Check http://www.virtualradarserver.co.uk/Documentation/Formats/AircraftList.aspx
// to craft this query to your needs
const String QUERY_STRING = "lat=1.3012244&lng=103.8603969&fDstL=0&fDstU=100&fAltL=0&fAltL=1500&fAltU=20000";

const int UTC_OFFSET = 2;

const float pi = 3.141;

// save data points for display
int visibleCrafts;
int prevVisible;
String from;
String to;
String aircraft;
String altitude;
String opcode;
int highScore;
int transition = 1;

/***************************
   End Settings
 **************************/

TimeClient timeClient(UTC_OFFSET);

AdsbExchangeClient adsbClient;

// flag changed in the ticker function every 10 minutes
bool readyForUpdate = false;

//declaring prototypes
void configModeCallback (WiFiManager *myWiFiManager);


void setup() {
  Serial.begin(115200);

  //ST7735
  tft.initR(INITR_144GREENTAB);   // initialize a ST7735S chip, black tab
  Serial.println("Initialized");

  uint16_t time = millis();
  tft.fillScreen(ST7735_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST7735_RED);
  testdrawtext("PLANE", ST7735_WHITE, 10, 50, 2);
  testdrawtext("SPOTTER", ST7735_WHITE, 10, 70, 2);  
  delay(2000);

  WiFiManager wifiManager;
  
//  wifiManager.resetSettings(); // Uncomment for testing wifi manager
  wifiManager.setAPCallback(configModeCallback);

  //or use this for auto generated name ESP + ChipID
  wifiManager.autoConnect();

  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    testdrawtext("WIFI CONNECTING..", ST7735_WHITE, 20, 30, 2);
    delay(1000);
    counter++;
  }
    
  //  Serial.println("Hostname: " + hostname);
  tft.fillScreen(ST7735_BLACK);
}

void loop() {
  
  // If there are airplanes query often
  if (adsbClient.getNumberOfVisibleAircrafts() == 0) {
    currentUpdateInterval = UPDATE_INTERVAL_SECS_LONG;
  } else {
    currentUpdateInterval = UPDATE_INTERVAL_SECS_SHORT;
  }

 // switch between screens
![img_1174](https://cloud.githubusercontent.com/assets/16057289/22691329/ee940bc8-ed5f-11e6-9190-34399fc60aaa.JPG)
![img_1173 1](https://cloud.githubusercontent.com/assets/16057289/22691330/ee94982c-ed5f-11e6-9126-c3a08bf87fda.JPG)

 
  if (lastUpdate < millis() - currentUpdateInterval && transition == 1) {
    listAll();
  } else if (transition == 2) {
    visible();
  }

  updateData();
}

void visible() {

  tft.fillScreen(ST7735_BLACK);
  tft.fillRect(0, 0, tft.width(), 80, ST7735_WHITE);
  if (visibleCrafts <= 9) {
    tft.setCursor(tft.width() / 2 - 10, 30);
  } else {
    tft.setCursor(tft.width() / 2 - 25, 30);
  }

  if (visibleCrafts < 4) {
    tft.setTextColor(ST7735_BLACK);
  } else {
    tft.setTextColor(ST7735_RED);
  }

  tft.setTextSize(5);
  tft.print(visibleCrafts);

  if (visibleCrafts > highScore) {
    highScore = visibleCrafts;
    testdrawtext("RECORD", ST7735_RED, 70, 20, 1);
  }
  
  testdrawtext("AIRCRAFTS", ST7735_WHITE, 10, 90, 2);
  testdrawtext("CURRENTLY OVERHEAD", ST7735_WHITE, 10, 110, 1);
  
}

void listAll() {

  if (adsbClient.isAircraftVisible()) {
    tft.setTextWrap(true);

    testdrawtext("FROM", ST7735_WHITE, 10, 5, 1);
    tft.fillRect(0, 15, tft.width(), 20, ST7735_WHITE);
    tft.setTextColor(ST7735_BLACK);
    tft.setCursor(10, 22);
    tft.print(from);

    tft.fillRect(0, 35, tft.width(), 20, ST7735_BLACK);
    testdrawtext("TO", ST7735_WHITE, 10, 40, 1);
    tft.fillRect(0, 50, tft.width(), 20, ST7735_WHITE);
    tft.setCursor(10, 56);
    tft.setTextColor(ST7735_BLACK);
    tft.print(to);

    tft.setTextColor(ST7735_WHITE);
    tft.setCursor(10, 80);
    tft.fillRect(0, 70, tft.width(), 26, ST7735_BLACK);
    tft.print(aircraft);

    tft.fillRect(60, 96, tft.width(), 108, ST7735_YELLOW);
    testdrawtext("ALTITUDE", ST7735_BLACK, 70, 99, 1);

    tft.fillRect(0, 96, 60, 108, ST7735_RED);
    tft.setCursor(10, 105);
    tft.setTextSize(2);
    tft.setTextColor(ST7735_WHITE);
    tft.print(opcode);

    tft.setTextSize(2);
    tft.setCursor(70, 110);
    tft.setTextColor(ST7735_BLACK);
    tft.print(altitude);
  }
  
}

//ST7735
void testdrawtext(char *text, uint16_t color, uint16_t x, uint16_t y, uint16_t s) {
  tft.setCursor(x, y);
  tft.setTextColor(color);
  tft.setTextSize(s);
  tft.setTextWrap(true);
  tft.print(text);
}

void updateData() {
  readyForUpdate = false;
  adsbClient.updateVisibleAircraft(QUERY_STRING);
  lastUpdate = millis();
  visibleCrafts = adsbClient.getNumberOfVisibleAircrafts();
  if (visibleCrafts != prevVisible) {
    transition = 2;
    prevVisible = visibleCrafts;
  } else {
    transition = 1;
  }
  from = String(adsbClient.getFrom());
  to = String(adsbClient.getTo());
  opcode = String(adsbClient.getOperatorCode());
  altitude = String(adsbClient.getAltitude());
  aircraft = String(adsbClient.getAircraftType());
  delay(5000);
}

void configModeCallback (WiFiManager *myWiFiManager) {
  Serial.println("Entered config mode");
  Serial.println(WiFi.softAPIP());
  //if you used auto generated SSID, print it
  Serial.println(myWiFiManager->getConfigPortalSSID());
}

void checkReadyForUpdate() {
  // Only do light work in ticker callback
  if (lastUpdate < millis() - currentUpdateInterval * 1000) {
    readyForUpdate = true;
  }
}

screenshot1

screenshot2

@Ierlandfan
Copy link

I am running into the same problem as you, it seems to be related to the amount of data to be parsed. Somewhere between the 25 and 30 elements and it stops working (Freezes) or wdt kicks in.

@mataide
Copy link

mataide commented Nov 22, 2017

You need to cast parser.reset(); otherwise it will crash the heap.

Ex:

void loop() {
  parser.setListener(&listener);

    char json[] = "{\"macro\": [{\"codeRaw\": [\"3450\",\"1700\",\" 450\",\"450\",\" 450\",\"1250\",\" 450\",\"400\",\" 450\",\"400\"],\"codeValue\": null,\"kind\": \"IR\",\"bits\": 32,\"repeatValue\": false,\"codeType\": -1},{\"kind\": \"DELAY\",\"time\": 1},{\"codeRaw\": [\"350\",\"600\",\" 350\",\"600\",\"300\"],\"codeValue\": null,\"kind\": \"IR\",\"bits\": 32,\"repeatValue\": false,\"codeType\": -1}";
    for (int i = 0; i < sizeof(json); i++) {
      parser.parse(json[i]); 
    } 
    parser.reset();
  Serial.print(json[0]);
  delay(1000); 
}

@Gerry33
Copy link

Gerry33 commented Nov 28, 2017

-- Edit -- Solved:
To whom it may help:

  • For reading data from an external HTTP source, use HTTPClient, not WebClient.
  • make Json parser and HTTPclient part of your class.
  • parser.reset() before each usage as suggested above.
  • Do not use HTTPclient .reuse(true);
  • make loop() as short as possible : e.g. separate retrieving data from displaying it in different loop()- runthroughs .

Then no problems with heap, no problems with WIFI disconnect().

Same problem here.
startDocument() is called, endDocument() fails after some time.

I did not observe heap problems. I logged ESP.getHeap() ... and it is not decreasing.
The src of the parser only used the stack.

In the above example, the parser is defined local on stack and IMHO a reset() is not needed. Only
if the parser object would be somehow permanent and reused between usage.

I made such a test with the parser being a member of a class and using reset() between each parsings and it did not help. Sooner or later the endDocument() is not called and the ESP is stalled.

I'm running out of ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants