adafruit / Adafruit_IO_Arduino

Arduino library to access Adafruit IO from WiFi, cellular, and ethernet modules.
Other
208 stars 108 forks source link

Max feed count per sketch #146

Open OilSlick opened 3 years ago

OilSlick commented 3 years ago

Configure 20+ AdafruitIO_Feeds. I'm not sure if there is any correlation between the number of feeds configured for sub vs pub vs pub/sub.

The number of feeds that produces the exception seems relatively constant for me at 20+. However, the reason I found the issue was general, inconsistent lock-ups (that may be completely unrelated).

The sketch I am using to reproduce the error is below. The only information in config.h is my WiFi and AIO authentication information.

#include "config.h"                     // Needed for Adafruit IO
#include "AdafruitIO_WiFi.h"

#if defined(USE_AIRLIFT) || defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) ||         \
    defined(ADAFRUIT_PYPORTAL)
// Configure the pins used for the ESP32 connection
#if !defined(SPIWIFI_SS) // if the wifi definition isnt in the board variant
// Don't change the names of these #define's! they match the variant ones
#define SPIWIFI SPI
#define SPIWIFI_SS 10  // Chip select pin
#define SPIWIFI_ACK 9  // a.k.a BUSY or READY pin
#define ESP32_RESETN 6 // Reset pin
#define ESP32_GPIO0 -1 // Not connected
#endif
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS, SPIWIFI_SS,
                   SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI);
#else
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);
#endif

//For Adafruit IO
AdafruitIO_Time *seconds = io.time(AIO_TIME_SECONDS);
AdafruitIO_Feed *nightmodeButtonFeed = io.feed("alarm.nightmode");
AdafruitIO_Feed *debugButtonFeed = io.feed("alarm.debug-button");

//AdafruitIO_Feed *currentTempFeed = io.feed("air-particulate-sensor.currenttemp");
//AdafruitIO_Feed *currentHumiFeed = io.feed("air-particulate-sensor.currenthumi");
//AdafruitIO_Feed *currentSmokeFeed = io.feed("air-particulate-sensor.currentsmoke");
//AdafruitIO_Feed *pm25CurrentFeed = io.feed("air-particulate-sensor.currentpm25");
AdafruitIO_Feed *pm10CurrentFeed = io.feed("air-particulate-sensor.currentpm10");
AdafruitIO_Feed *pm25AQIFeed = io.feed("air-particulate-sensor.aqipm25");

AdafruitIO_Feed *pm10AQIFeed = io.feed("air-particulate-sensor.aqipm10");

//AdafruitIO_Feed *light = io.feed("light");
//AdafruitIO_Feed *counter = io.feed("counter");
AdafruitIO_Feed *pm25nowCastFeed = io.feed("air-particulate-sensor.nowcastpm25");
AdafruitIO_Feed *pm10nowCastFeed = io.feed("air-particulate-sensor.nowcastpm10");

AdafruitIO_Feed *NH3Feed = io.feed("kencana-air-sensor.nh3");
AdafruitIO_Feed *COFeed = io.feed("kencana-air-sensor.co");
AdafruitIO_Feed *NO2Feed = io.feed("kencana-air-sensor.no2");
AdafruitIO_Feed *NO2ppbvFeed = io.feed("kencana-air-sensor.no2-ppbv");
AdafruitIO_Feed *NO2HourlyAvgFeed = io.feed("kencana-air-sensor.no2-hrly-avg");
AdafruitIO_Feed *NO2HourlyMinFeed = io.feed("kencana-air-sensor.no2-hrly-min");
AdafruitIO_Feed *NO2HourlyMaxFeed = io.feed("kencana-air-sensor.no2-hrly-max");

AdafruitIO_Feed *C3H8Feed = io.feed("kencana-air-sensor.c3h8");
AdafruitIO_Feed *C4H10Feed = io.feed("kencana-air-sensor.c4h10");
AdafruitIO_Feed *CH4Feed = io.feed("kencana-air-sensor.ch4");
AdafruitIO_Feed *H2Feed = io.feed("kencana-air-sensor.h2");
AdafruitIO_Feed *C2H5OHFeed = io.feed("kencana-air-sensor.c2h5oh");

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

  io.connect();

  //subscribe to AIO feeds from which we want input
  //iso->onMessage(handleISO);
  seconds->onMessage(handleSecs);
  nightmodeButtonFeed->onMessage(handlenightmodeButtonFeed);
  debugButtonFeed->onMessage(handledebugButtonFeed);

  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
}

void loop() {
  io.run();
  // put your main code here, to run repeatedly:
}
void handlenightmodeButtonFeed(AdafruitIO_Data *data) 
{
}
void handledebugButtonFeed(AdafruitIO_Data *data) 
{
}
void handlepingButtonFeed(AdafruitIO_Data *data) 
{
}
void handleSecs(char *data, uint16_t len) 
{
  Serial.println(data);
}

The exception that I get from the ESP8266 is below:

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads PC: 0x40220f96: br_ssl_hs_client_run at src/ssl/ssl_hs_client.c line 1871 EXCVADDR: 0x00000e94

Decoding stack results 0x402208e1: br_ssl_hs_client_run at src/ssl/ssl_hs_client.c line 1528 0x4021ef90: jump_handshake at src/ssl/ssl_engine.c line 1081 0x4021f475: br_ssl_engine_recvrec_ack at src/ssl/ssl_engine.c line 1206 0x40204ee2: BearSSL::WiFiClientSecure::_run_until(unsigned int, bool) at /Users/mwright/Library/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp line 540 0x402023ec: Adafruit_MQTT_Client::connectServer() at /Users/mwright/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp line 34 0x40205091: BearSSL::WiFiClientSecure::available() at /Users/mwright/Library/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp line 386 0x402044f2: BearSSL::WiFiClientSecure::connected() at /Users/mwright/Library/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp line 260 0x40203120: ESP8266WiFiSTAClass::status() at /Users/mwright/Library/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 634 0x40208e48: Adafruit_MQTT_Client::connected() at /Users/mwright/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp line 48 0x40201524: AdafruitIO::mqttStatus(bool) at /Users/mwright/Documents/Arduino/libraries/Adafruit_IO_Arduino/src/AdafruitIO.cpp line 437 0x402015bf: AdafruitIO::status() at /Users/mwright/Documents/Arduino/libraries/Adafruit_IO_Arduino/src/AdafruitIO.cpp line 368 0x402010bd: setup() at /Users/mwright/Documents/Arduino/web_gateway/web_gateway.ino line 67 0x40207158: loop_wrapper() at /Users/mwright/Library/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/cores/esp8266/core_esp8266_main.cpp line 194

Thank you in advance for your help!

brentru commented 3 years ago

@OilSlick I was able to reproduce this on my end. It seems like declaring < 20 feeds does not cause this issue. Also the ESP32 does not have this issue, if you have one.

This looks to be an issue within the ESP8266's board package's SSL module, BearSSL. It looks like an allocation failure occurs within BearSSL (similar to https://github.com/esp8266/Arduino/issues/5815) when you allocate over 19 feeds on the ESP8266.

It also looks similar to this issue: https://github.com/esp8266/Arduino/issues/7801 which I am now following.

OilSlick commented 3 years ago

Thank you for the update.