Page 1 of 1

ESP32 with libraries: sketch size too big.

Posted: Tue Jul 02, 2024 10:13 am
by dburgt98
Dear ESP community,

I have ran into an issue with the memory used by the ESP32 libraries that I included in my sketch for the WEMOS LOLIN32 board.

I made an application inspired by the examples for WiFiClientConnect, BasicHTTPClient and Scan (BLE).
The task for the application is to scan for BLE advertisements and then upload the results via a HTTP request over Wifi.
Currently I have included three libraries ("HTTPClient", "WiFi.h" and "BLEDevice.h") in my application.

When I compile this code via the Arduino IDE, it produces the error that the sketch is too big for the board (see image below).
It has the size of 1762301 bytes, which is approx. 1.7MB.
It says this is 134% of the available program storage.
In my opinion, the size of the sketch seems a bit large for this application.

Is there any way that I can reduce the size of the libraries / compiled binary file, while remaining the same functionality?
Furthermore, the board description states that the WEMOS LOLIN32 has 4MB flash memory.
How come that I cannot compile a 1.7MB sketch to this board?

Any assistance or tips in this regard are highly appreciated.

Best regards, Dirk



Debugging soo far
When I remove all code related to the BLEDevice library, the memory reduces from 134% to 76% (-58%).
When I remove all code related to the WiFi library, the memory reduces from 77% to 45% (-32%).
When I remove all code related to the HTTPClient library, the memory reduces from 46% to 20% (-26%).

All the three libraries seem to be the culprit. But BLEDevice uses most memory by far (58%).
However, I cannot just exclude this library because the BLE functionality is important to my application.

Note that I might need a bit of a buffer left below the 100%, because in future I want to add the EEPROM library as well for saving some device settings.


Image
Image

Code: Select all

#include <HTTPClient.h>
#include <BLEDevice.h>
#include <WiFi.h>

#define NR_FILTERS 1
#define FIRMWARE_VERSION "1.0"
#define HOST "CONFIDENTIAL"
#define PASSKEY ""

// Dynamic settings
static int SCAN_TIME = 60; // in seconds
static int NR_HTTP_REQUEST_RETRIES = 3;
static int WIFI_CONNECT_TIMEOUT = 10000; // milliseconds
static char *SSID = "CONFIDENTIAL";
static char *PASSWORD = "CONFIDENTIAL";

static const char* filters[NR_FILTERS] = {"dc:2c:6e"};
static BLEScan* _pBLEScan = NULL;
static char mac[] = "D8:BC:38:FA:A4:56";

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks 
{
    void onResult(BLEAdvertisedDevice advertisedDevice) {
        String address = advertisedDevice.getAddress().toString();
        int rssi = advertisedDevice.getRSSI();
        for (int i = 0; i < NR_FILTERS; i++) {
            if (!address.startsWith(filters[i])) {
                continue;
            }
            Serial.printf("Advertised Device: %s, rssi: %d \n", 
                address.c_str(), rssi);
            // to do: save detected device
        }
    }
};


bool WifiConnect(int timeout) 
{
  uint32_t msBegin = millis();
  Serial.println();
  Serial.println("******************************************************");
  Serial.print("Connecting to ");
  Serial.print(SSID);

  WiFi.begin(SSID, PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
    if (millis() - msBegin > timeout) {
      Serial.println("Failed to connect to Wifi within timeout");
      WiFi.disconnect(true);
      return false;
    }
  }
  Serial.println();
  Serial.print("WiFi connected, ");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  return true;
}


void WifiDisconnect()
{
    WiFi.disconnect(true);
}


bool sendRequest(char* payload, char* responseBuffer,
    uint16_t responseBufferSize)
{
    HTTPClient http;
    http.begin(HOST);
    http.addHeader("Content-Type", "application/json");

    int httpResponseCode = http.POST(payload);

    if (httpResponseCode > 0) {
      const char* httpResponse = http.getString().c_str();
      int length = strlen(httpResponse);
      if (length > responseBufferSize) {
        Serial.println("HTTP response buffer is too small!");
        http.end();
        return false;
      }
      strcpy(responseBuffer, (char*) httpResponse);
      return true;
    } else {
      Serial.print("Error on sending POST request: ");
      Serial.println(httpResponseCode);
      Serial.println(http.errorToString(httpResponseCode).c_str());
      http.end();
      return false;
    }
}

static String encode_http_payload(char* mac)
{
    String detectionsStr = "[";
    int resultCount = 0;
    for (int i = 0; i < resultCount; i++) {
      // to do: add detected BLE devices to payload
    }
    detectionsStr += "]";

    String payload = "{\"gateway_id\":\"" + String(mac) + "\",\"version\":" + FIRMWARE_VERSION + ",\"password\":\"" + PASSKEY + "\",\"detections\":" + detectionsStr + "}";
    
    return payload;
}


void setup() 
{
  Serial.begin(115200);
  BLEDevice::init("Gateway");
  _pBLEScan = BLEDevice::getScan();
  _pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), 
      true);
  //active scan uses more power, but get results faster
  _pBLEScan->setActiveScan(true);
  _pBLEScan->setInterval(100);
  _pBLEScan->setWindow(99);  // less or equal setInterval value
  Serial.println("Initialized GWLite");
}


void loop() 
{
    Serial.println("Starting scan....");
  
    BLEScanResults *foundDevices = _pBLEScan->start(SCAN_TIME, false);
    _pBLEScan->clearResults();

    Serial.println("Scan done!");

    String payload = encode_http_payload(mac);
    
    Serial.println(payload);

    if (!WifiConnect(WIFI_CONNECT_TIMEOUT))
    {
      return;
    }

    char response[500];
    bool success = false;
    for (int i = 0; i < NR_HTTP_REQUEST_RETRIES; i++)
    {
      success = sendRequest((char*)payload.c_str(), response, 
        sizeof(response));
      if (success) break;
    }
    if (success)
    {
      Serial.print("Recieved response: ");
      Serial.println(response);
    }

    // Disconnect WiFi to make radio hardware available for BLE
    WifiDisconnect();
}