Ограничен ли веб-сервер ESP32 HTTP определенным количеством изображений Base64?

Этот скетч отображает только около девяти изображений (когда их больше). Означает ли это, что ESP32 имеет ограниченное количество изображений Base64, которые могут быть отображены?

#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "ESP32"; 
const char* password = "12345678"; 

IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

WebServer server(80);

// Used for determining the selected pattern and HTML to display:
int pattern = 0;
int selectedPattern = 0;

String circleString = "<img src=\"data:image/png;base64,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\" alt=\"NAME\" style=\"width:100%\">\n";

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


  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);
  
  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
  
  server.begin();
  Serial.println("HTTP server started");
}
void loop()
{
  server.handleClient();

}

void handle_OnConnect() {

  server.send(200, "text/html", SendHTML(selectedPattern)); 
}



void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(int pattern)
{
    String ptr = "<!DOCTYPE html> <html>\n";
    // Instance of class String (not a pointer)
    
    ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
    // <meta> viewport element makes the web page responsive in any web browser
    // https://www.w3schools.com/css/css_rwd_viewport.asp


    ptr += "<style type=\"text/css\">\n";
    ptr +="</style>\n";
    
    ptr +="</head>\n";
    ptr +="<body>\n";
    

      /*  */
      ptr += "<div class=\"column\">\n"; // 1
        ptr += circleString;
      ptr += "</div>\n";
      
      ptr +="<a class=\"button\" href=\"/circle#1\">1</a>\n";

      ptr += "<div class=\"column\">\n"; // 2
        ptr += circleString;
      ptr += "</div>\n";

      ptr +="<a class=\"button\" href=\"/circle#1\">2</a>\n";

      ptr += "<div class=\"column\">\n"; // 3
        ptr += circleString;
      ptr += "</div>\n";
      
      ptr +="<a class=\"button\" href=\"/circle#1\">3</a>\n";

      ptr += "<div class=\"column\">\n"; // 4
        ptr += circleString;
      ptr += "</div>\n";

      ptr +="<a class=\"button\" href=\"/circle#1\">4</a>\n";

      ptr += "<div class=\"column\">\n"; // 5
        ptr += circleString;
      ptr += "</div>\n";

      ptr +="<a class=\"button\" href=\"/circle#1\">5</a>\n";

      ptr += "<div class=\"column\">\n"; // 6
        ptr += circleString;
      ptr += "</div>\n";
      
      ptr +="<a class=\"button\" href=\"/circle#1\">6</a>\n";

      ptr += "<div class=\"column\">\n"; // 7
        ptr += circleString;
      ptr += "</div>\n";

      ptr +="<a class=\"button\" href=\"/circle#1\">7</a>\n";

      ptr += "<div class=\"column\">\n"; // 8
        ptr += circleString;
      ptr += "</div>\n";
      
      ptr +="<a class=\"button\" href=\"/circle#1\">8</a>\n";

      ptr += "<div class=\"column\">\n"; // 9
        ptr += circleString;
      ptr += "</div>\n";
      
      ptr +="<a class=\"button\" href=\"/circle#1\">9</a>\n";




      ptr += "<div class=\"column\">\n"; // 10
        ptr += circleString;
      ptr += "</div>\n";

      ptr += "<div class=\"column\">\n"; // 11
        ptr += circleString;
      ptr += "</div>\n";

      ptr += "<div class=\"column\">\n"; // 12
        ptr += circleString;
      ptr += "</div>\n";

      ptr += "<div class=\"column\">\n"; // 13
        ptr += circleString;
      ptr += "</div>\n";

 
      
   
    ptr +="</body>\n";
    ptr +="</html>\n";

    return ptr;
      
}

Sketch использует 726230 байт (55%) памяти программы. Максимум - 1310720 байт. Глобальные переменные используют 39384 байта (12%) динамической памяти, оставляя 288296 байт для локальных переменных. Максимум - 327680 байт.

, 👍-1

Обсуждение

Вы включаете необработанные данные изображения несколько раз в возвращаемую строку. Это действительно может взорвать память. Почему бы вам просто не включить ссылку на изображение в html и не предоставить изображение отдельно?, @PMF

Потому что я не знаю, как это сделать. Кроме того, я не уверен, имеет ли это значение, но эта минимальная программа использует одно изображение, но фактическая программа использует все разные изображения., @adamaero

Мне тоже нужно будет прочитать документы. Вам нужно будет преобразовать изображение обратно в двоичный файл и обслуживать его напрямую. А затем сделайте что-то вроде"server.on ("/myimage.png", ServeImage(myimage.png))"., @PMF

вы проверили источник html в браузере? Я предполагаю, что это сокращено, потому что esp не может выделить больше памяти для большой строки, @Juraj


1 ответ


1

Вы создаете HTML - сайт, объединяя строки вручную в коде. Я знаю, что это делается во многих кодах по всему Интернету, но это действительно практично, только если вам нужно изменять содержимое сайта с каждым запросом. Обычно лучше использовать SPIFFS (или теперь LittleFS) для хранения файлов и позволить подходящей библиотеке веб-сервера обслуживать их как статические файлы. Кроме того, вы делаете швейцарский сыр из своей кучи памяти, когда вы так часто объединяете строковые переменные, и у вас может закончиться оперативная память.

Я не привык к LittleFS, поэтому я напишу этот ответ, используя SPIFFS. Но я уверен, что вы можете использовать LittleFS очень похожим образом. Я оставлю это вам, чтобы определить, как он вписывается в код для SPIFFS.

Взгляните на библиотеку ESPAsyncWebServer и ее простой пример сервера. Я использовал эту библиотеку для своих проектов. Попробуйте примеры, прочитайте документацию и получите представление о том, как работает эта библиотека.

Затем взгляните на документацию, где говорится "Обслуживание статических файлов". Я думаю, что вы хотите обслуживать свои статические файлы из каталога. Таким образом, библиотека будет искать запрошенные файлы в этом полном каталоге внутри SPIFFS. Внутри этого каталога у вас будет свой HTML-сайт (названный так index.html) и все изображения в виде двоичных данных в формате, который может прочитать веб-браузер (например, jpg, png, ...). На вашем HTML-сайте вы ссылаетесь на изображения с их путем. Поскольку в этом сценарии все они лежат в корневом каталоге, путь-это только имя файла (+ расширение файлов).

Когда веб-браузер запрашивает index.html из ESP библиотека будет обслуживать его из SPIFFS. Веб-браузер интерпретирует сайт и видит ссылки на изображения. Затем он пытается загрузить эти изображения, то есть отправляет запросы в ESP с указанием пути к изображениям. Библиотека будет искать эти файлы в SPIFFS, найдет их и передаст веб-браузеру, который затем отобразит их на веб-сайте.

Что-то вроде этого:

#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"

AsyncWebServer server(80);

void setup(){
  Serial.begin(115200);
  while(!SPIFFS.begin()){
    Serial.println("Could not mount SPIFFS");
    delay(500);
  }
  server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
  server.begin();
}

void loop(){
}

Примечание:

  • Я пропустил все, что связано с Wi-Fi. Вы должны добавить это сами.
  • Я не тестировал этот код, просто собрал его из одной из моих работающих больших программ.
  • Вам все равно нужно загрузить фактические файлы в ESP SPIFFS. Есть много руководств о том, как это сделать. Просто поместите ваши файлы в корневой каталог SPIFFS.
,

LittleFS vs SPIFFS docs находятся в https://github.com/esp8266/Arduino/blob/master/doc/filesystem.rst, @Dave X