Weird program behavior when using too many PSTR/PROGMEM definitions

Hello all,

I recently learned about using the PSTR() macro and variables stored in PROGMEM to contain large strings, so as to minimize their impact on RAM. This helped me solve some problems I was having running out of RAM. But now I have a new problem: if I define too many strings in PSTR, the application crashes like it did before.

The full application (including the two libraries I'm using, MatrixDisplay and Ethercard) can be found here: GitHub - bklang/tankersign: Jill's personal LED sign, handcrafted by master artisans

A few notes on the application:

  • This application is running on an Arduino Uno and has an ENC28J60 network card, as well as 4 Sure Electronics DE-DP13111 32x8 LED matrices. The goal is to receive network packets containing short bits of text and display them on the LED display.

  • I'm using the globally defined "messages" variable as the placeholder to write text that will be scrolled out to the LED display

  • I've commented out a lot of functionality to debug, so the only thing it's actually doing right now is showing the amount of free memory on the display, unless a network request comes in, in which case it shows a messages to that effect.

The problem is this: when I add one more 22-character string with a PSTR(), or even if I pad any of the existing strings with just 22 more bytes (eg. "AAAAAAAAAAAAAAAAAAAAAA"), the application crashes and tends to behave like it has run out of memory.

With the extra strings commented out, the display shows me my free memory. Regardless of the number or length of PSTR() log strings, my display reports 204 bytes of RAM free, so I don't think I'm running out of RAM.

The Arduino IDE shows:
The sketch is using 15,158 bytes (46%) of program space. The maximum is 32,256 bytes.
Global variables are using 1,473 byte (71%) of dynamic memory, leaving 575 bytes free for local variables. The maximum is 2,048 bytes.

This makes me think I've got more than enough program space available for more PSTR() uses. So why does adding length to these strings cause my program to fail? Any hints on troubleshooting?

204 bytes RAM free ? that's scary.

The display library uses malloc(), that means it allocates memory, but also that memory could have the "kaboom" scenario :

Those two libraries require a lot of memory. You better use another Arduino board. For example the Arduino Mega 2560 (that is the same family of microcontrollers as the Arduino Uno) or a newer 3.3V board.
And replace the ENC28J60 with a W5200 or W5500.

Thanks Koepel! The suggestion to use the hardware-offload TCP/IP stack alone was a big help.

You also wrote that only 204 bytes free was scary. What's a less scary number? I actually was down into the low double-digits before I started moving strings to PSTR() :frowning:

When using ethernet and displays, I rather have half the ram available when using an Arduino Uno.
Perhaps the library was developed for a Arduino Mega 2560 board or for a ARM M0+ processor.
The trouble seems to be that malloc() in the display library, but I don't know how much is allocated. So I don't know.

Your led display :

I think that the best you can do is to upgrade to an Arduino Mega 2560 board.

Do you really need 700 bytes buffer for the EtherCard library ? Perhaps you can lower it, and be careful how much is transmitted.
Please don't use the 'String' object. Many Arduino users suggest to not use String objects at all with an Arduino Uno.
I mean this one: "static const String charLookup PROGMEM...."
Make that a normal character array please, and change the drawChar() function to use a normal character array.

I did not find String objects in the libraries. If you can remove them all, that will save memory.