me-no-dev / ESPAsyncWebServer

Async Web Server for ESP8266 and ESP32
3.77k stars 1.22k forks source link

ESP-01 reboots with websockets and WifiClientSecure #1115

Closed vatsake closed 2 years ago

vatsake commented 2 years ago

For some reason if there is no handler for a path, and if the user navigates to it. The ESP-01 crashes (WDT reset). Also cannot connect to the websocket, also crashes.

#include <TimeLib.h>                             // https://github.com/PaulStoffregen/Time   

#include <WiFiUdp.h>                             // https://www.arduino.cc/en/Reference/WiFiUDPConstructor
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266HTTPClient.h>
#include <ESPAsyncWebServer.h>                   // https://github.com/me-no-dev/ESPAsyncWebServer
#include <ESPAsyncTCP.h>

#define ARDUINOJSON_DECODE_UNICODE 1
#define ARDUINOJSON_USE_LONG_LONG 1
#include <ArduinoJson.h>

extern "C" {
#include "user_interface.h"
}

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

typedef struct {
  time_t date;
  float price;
} stock;
stock electricityPrices[24];

unsigned int UdpPort = 8888;                     // local port to listen for UDP packets
static const char ntpServerName[] = "1.ee.pool.ntp.org";
const int timeZone = 2; 
const int NTP_PACKET_SIZE = 48;                  //TIME NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE];              //TIME buffer to hold incoming & outgoing packets
WiFiUDP Udp;

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

 WiFi.begin(); //SSID, PASSWORD

 while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print("."); }
 server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/plain", "Howdy partner!");
 });
 server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){ //Without these lines, it will crash everytime you navigate somewhere
    request->send(200, "image/png", "x");
});
 ws.onEvent(NULL);
 server.addHandler(&ws);
 server.begin();

 setSyncProvider(getNtpTime);

  WiFiClientSecure httpClient;
  httpClient.setInsecure();

  HTTPClient http;
  http.setReuse(true);
  http.useHTTP10(true);

    char link[110];
    sprintf(
      link,
      "https://dashboard.elering.ee/api/nps/price?start=%i-%02d-%02dT15%%3A00%%3A00.000Z&end=%i-%02d-%02dT15%%3A59%%3A59.999Z",
      year(now() - 86400),
      month(now() - 86400),
      day(now() - 86400),
      year(now()),
      month(now()),
      day(now())
    );
  http.begin(httpClient, link);

  int x;
  if (x = http.GET() == 200) {
    DynamicJsonDocument doc(7000);
    deserializeJson(doc, http.getStream());
    JsonArray data_ee_item = doc["data"]["ee"].as<JsonArray>();
    for (int i = 0; i < data_ee_item.size(); i++) {
      int TiMe = data_ee_item[i]["timestamp"].as<time_t>() + (3600 * timeZone);
      electricityPrices[i].date = TiMe;
      electricityPrices[i].price = data_ee_item[i]["price"];
    }
  } else Serial.println(x);
  http.end();
}

void loop() {
  ws.cleanupClients();
}

time_t getNtpTime()
{
  IPAddress ntpServerIP; // NTP server's ip address
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  WiFi.hostByName(ntpServerName, ntpServerIP);
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;
  Udp.beginPacket(ntpServerIP, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  return 0; // return 0 if unable to get the time
}

It probably has something to do with memory?

vatsake commented 2 years ago

Sorry, I'm officially mentally re....