Concatenate PROGMEM strings

Pelleren
Posts: 2
Joined: Thu Mar 17, 2022 2:46 am

Concatenate PROGMEM strings

Postby Pelleren » Thu Mar 17, 2022 3:00 am

Hi,

I'm building a simple web interface to a simple ESP32 application to learn about the ESP32 WROOM processer.

I have 3 html pages and I would like the same logo to be present on every page. The logo is represented in the html img tag shown below in the code, and the image itself is rather big (memory).

Is there a way to store the image in PROGMEM only once, instead of repeating the same html img tag in all pages?

In the example below I would imagine I would need 3 PROGMEM and piece them together something like FIRST_PART_HTML+IMG+LAST_PART_HTML in the handleData function?

Thank you in advance.

  1. #include <ESPAsyncWebServer.h>
  2.  
  3. const char data_html[] PROGMEM = R"=====(
  4. <!DOCTYPE html>
  5. <html>
  6.    ... additional html ...
  7. <body>
  8.    <img src="data:image/png;base64,iVBORw0KGgoA  .... .... .... .... ">
  9.    ... additional html ...
  10. </body>
  11. </html>
  12. )=====";
  13.  
  14.  
  15. void handleData(AsyncWebServerRequest *request) {
  16.   request->send_P(200, "text/html", data_html);
  17. }
  18.  
  19.  
  20. server.on("/data", handleData);

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Concatenate PROGMEM strings

Postby ESP_Sprite » Thu Mar 17, 2022 6:46 am

Why not have the image as a separate URL, rather than baked into all pages?

lbernstone
Posts: 826
Joined: Mon Jul 22, 2019 3:20 pm

Re: Concatenate PROGMEM strings

Postby lbernstone » Thu Mar 17, 2022 7:13 pm

PROGMEM is the same thing as a const char* in esp32. That is, it is a constant pointer mapped directly to the flash, so it does not reside in active memory. As such, there is no way to embed one const into another- you can't have a pointer pointing to another pointer like that. You can make a String (or std::string) that concats or replaces a value in a const char* template, and then after http delivery, that String variable is deallocated, so you are only using the heap space for a short time. If you are doing a lot of this, you can get a esp32 with 4MB of psram for about 30 cents more.
I think what you are really looking for is a way to embed binaries into your firmware. The easiest way to do that is with the command line utility `xxd -i`. This will convert the binary into the hex array that C wants for a variable. Redirect it into a header (.h) file, include it in your sketch, and edit it to make the array a constant. You can then make an href to it in your html, and deliver it via a separate URL using the send_P function. You can even gzip it before xxd. That way it is stored and delivered compressed, and the end client will extract it. This is extremely useful for javascript- you can get a minimized and compressed jquery down to 30KB in your firmware.
An example is worth 1000 words, so you can see how I converted an app that was using a script from the internet to use an embedded file at https://github.com/lbernstone/rrdtool_E ... 3368714827 .

Pelleren
Posts: 2
Joined: Thu Mar 17, 2022 2:46 am

Re: Concatenate PROGMEM strings

Postby Pelleren » Thu Mar 24, 2022 2:34 am

@lbernstone I had a look at your example, and it's a bit involved for my current experiments - but I will definitely look into it some more, as it looks like an good way to manage involved web pages.

The simpler way using an additional handler to "simulate" the image placed at an URL is good for my current purposes (ESP_Sprite).

What is the actual difference between the 2 methods? By creating a handler to serve the image - the image itself can be placed in PROGMEM, and that is how I understand the method of lbernstone?

Thank you both very much for the input.

lbernstone
Posts: 826
Joined: Mon Jul 22, 2019 3:20 pm

Re: Concatenate PROGMEM strings

Postby lbernstone » Thu Mar 24, 2022 11:31 pm

Well, I'd say the basic advantages to having an external reference is that
a) This is the way things are normally done, so anybody looking at your code will immediately understand that href rather than having a huge chunk of embedded binary data.
b) If you have someone else providing you with the graphics, they can just give you an updated file (like a png). You then convert it into binary, and replace the existing file in your code one time, one place. You can even put a handy remark in there with instructions how to do so in case you "get hit by a bus".

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 79 guests