Need help optimizing code to display bitmaps on an e-ink display.

Hello all, so I'm working on a project that seems I'll need help with to actually get it all to fit on the arduino, even when I'm using the crossroads 1284 mini.

End goal is to have a menu where you can select a few (three or four total) different configs which will display images in different orders, either automated or manually when you press a button (I may just do it manually to save trouble with it being finicky), however with even one of the configs it's already using up 53% of the program storage space.

There must be a more efficient way to do what I'm thinking but I know very little about c programming when it comes down to it.

This is the code so far which I have set up to test the concept out and verify that the e-ink display was working.

void setup(void)  //save-on-foods config
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("setup");
  display.init(115200); // enable diagnostic output on Serial
  display.setTextColor(GxEPD_BLACK);
  display.setFont(&FreeMonoBold9pt7b);
  display.fillScreen(GxEPD_WHITE);
  display.update();
  delay(500);
  Serial.println("setup done");
  display.drawExampleBitmap(programmode, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex4, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex0, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex5, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex7, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hexf, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex9, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex8, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hexb, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(hex1, sizeof(endprog));
  delay(1000);
  display.drawExampleBitmap(saveandreset, sizeof(endprog));
  delay(1000);
  display.fillScreen(GxEPD_WHITE);
  display.update();

}

Now, I'm guessing there's some fancy way to other commands to basically pre-set the order for these, instead of doing it line by line like I am above, but I'm not sure what that is. I mean, at least I hope there is, if not I might have to look into a mini raspberry pi or something, though that would add some complication, and also require spending even more on this.

Start by making sizeof(endprog); a variable or even a constant rather than calculating it for each line.

Use the F() macro wherever possible for constant text to save memory

  Serial.println(F("setup"));

UKHeliBob:
Start by making sizeof(endprog); a variable or even a constant rather than calculating it for each line.

Use the F() macro wherever possible for constant text to save memory

  Serial.println(F("setup"));

Hmm, so I think I caught on to what you mean, I think that the sizeof(endprog) part was only useful if you were changing overall image size, or if you were using the sketch but didn’t have a set display size, and that allowed it to adjust based on whatever you selected as an option for the e ink library. The image/display size is “4736”, and I replaced that part on each line and it still functions, and it does use up slightly less space, it was 69,822 and is now 69,714.

Not really a big difference but I suppose any bit is good. I am also very tired so could have totally missed something.

  Serial.begin(115200);
  Serial.println("setup");
  display.init(115200); // enable diagnostic output on Serial
  display.setTextColor(GxEPD_BLACK);
  display.setFont(&FreeMonoBold9pt7b);
  display.fillScreen(GxEPD_WHITE);
  display.update();
  delay(500);
  Serial.println("setup done");
  display.drawExampleBitmap(programmode, 4736);
  delay(1000);
  display.drawExampleBitmap(hex4, 4736);
  delay(1000);
  display.drawExampleBitmap(hex0, 4736);
  delay(1000);
  display.drawExampleBitmap(hex5, 4736);
  delay(1000);
  display.drawExampleBitmap(hex7, 4736);
  delay(1000);
  display.drawExampleBitmap(hexf, 4736);
  delay(1000);
  display.drawExampleBitmap(hex9, 4736);
  delay(1000);
  display.drawExampleBitmap(hex8, 4736);
  delay(1000);
  display.drawExampleBitmap(hexb, 4736);
  delay(1000);
  display.drawExampleBitmap(hex1, 4736);
  delay(1000);
  display.drawExampleBitmap(saveandreset, 4736);
  delay(1000);
  display.fillScreen(GxEPD_WHITE);
  display.update();

I added in a second void routine and copy-pasted the bitmap display stuff into that, and interestingly it only took the usage up to 61%, I was expecting the usage to jump up to somewhere like 80 or 90. If each one of those sections only uses 8% memory then I might actually be totally fine here.

Still, if there's some other way to tune this better I'm all ears.

  display.drawExampleBitmap(hex4, 4736);

My advice would be to not use "magic" numbers in the code as they make maintaining it more difficult. Personally I would declare a suitably named const variable with the value to be used then use the variable in the function calls.

I am also very tired so could have totally missed something.

Did you try using the F() macro for static text ?

How about the rest of the program ?
Are all of the variables of appropriate types for the values held ?

You could tidy up the code by writing a function that called the drawExampleBitmap() function and pass it a bitmap name, which is what I assume the first parameter is. It may not make the program smaller but would possibly make it easier to understand and maintain.

Incidentally, although I am not familiar with the library, from its name I would expect there to be a need to call the display.update(); function each time the display is changed in order to update what is displayed. If so then this too could be called from within your function to avoid code duplication.

Do you actually have a full working program ?

Fonts are huge. Make sure you don’t end up with fonts in your sketch that you’re not using.
Which display library are you using?

Right now this basically is the whole program, I just got the 1284 boards in today and wanted to verify it worked and see how much extra space I had compared to the pro mini. The example code I posted above is also the only text printing and that’s just left over and going to be removed since I won’t be watching a serial output, but I will be sure ti use that F macro for the menu system.

Once I have some free time after work today I’ll work on making a menu system to navigate with the little joystick thing I have, once that’s done the rest should be really quick to come together.

The library I’m using is GxEPD to actually use the e-ink display and is fairly large, good point about the fonts though, I am only using one of them from the adafruit library however.

There’s also another file which has the code for the bitmaps, however that can’t really be changed but here’s the full program to give some context as to the library that’s included.

This is all in the very early stages as I had to wait for these boards since the pro mini didn’t have enough memory even for this, I’ve spent a lot more time on the design of an enclosure for it so far but that needs tweaking, and waiting on other parts.

#include <GxEPD.h>
#include <GxGDEH029A1/GxGDEH029A1.cpp>      // 2.9" b/w

#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>

// FreeFonts from Adafruit_GFX
#include <Fonts/FreeMonoBold9pt7b.h>

#include <GxGDEH029A1/customimages.h>


GxIO_Class io(SPI, /*CS=*/ SS, /*DC=*/ 8, /*RST=*/ 9); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io /*RST=9*/ /*BUSY=7*/); // default selection of (9), 7

void setup(void)  //save-on-foods config
{
  Serial.begin(115200);
  Serial.println("setup");
  display.init(115200); // enable diagnostic output on Serial
  display.setTextColor(GxEPD_BLACK);
  display.setFont(&FreeMonoBold9pt7b);
  display.fillScreen(GxEPD_WHITE);
  display.update();
  delay(500);
  Serial.println("setup done");
  display.drawExampleBitmap(programmode, 4736);
  delay(1000);
  display.drawExampleBitmap(hex4, 4736);
  delay(1000);
  display.drawExampleBitmap(hex0, 4736);
  delay(1000);
  display.drawExampleBitmap(hex5, 4736);
  delay(1000);
  display.drawExampleBitmap(hex7, 4736);
  delay(1000);
  display.drawExampleBitmap(hexf, 4736);
  delay(1000);
  display.drawExampleBitmap(hex9, 4736);
  delay(1000);
  display.drawExampleBitmap(hex8, 4736);
  delay(1000);
  display.drawExampleBitmap(hexb, 4736);
  delay(1000);
  display.drawExampleBitmap(hex1, 4736);
  delay(1000);
  display.drawExampleBitmap(saveandreset, 4736);
  delay(1000);
  display.fillScreen(GxEPD_WHITE);
  display.update();

}

void loop()
{
=
}

void programsaveon()
{

}