1

Disclaimer: I just started using C++ and I'm a bit of a beginner. Keep that in mind as your answering.

So I recently bought my first Arduino. It's a customized one and it has an 8x8 display attached to it. To display something on the display, the company I bought it from recommends storing the instructions for the display in a two-dimensional byte array.

I now have a longer animation I want it to play, so I researched and found PROGMEM which lets me store much more data. So I write something along the lines of:

const byte frames[2][8] PROGMEM {
  {
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
    B10000100,
  },
  {
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
    B10010100,
  }
};

void setup() {
  arduino.begin();
}

void loop() {
  arduino.printImage(frames[0]);
  delay(1000);
  arduino.printImage(frames[1]);
  delay(1000);
}

After compiling, it throws a few errors at me:

warning: invalid conversion from 'const byte* {aka const unsigned char*}' to 'byte* {aka unsigned char*}' [-fpermissive]
   arduino.printImage(frames[0]);
                      ~~~~~~~~^

This did not worry me as much and I just ignored those. After uploading, however, the display just showed arbitrary patterns instead of the lines I told it to draw.

After I removed the PROGMEM, it worked flawlessly, however, the memory wasn't big enough to store the array (not the one I provided as an example).

I could think of two reasons:

  1. In the official documentation of PROGMEM, it states that you have to get the variables back into memory. However, none of the methods they provided worked for me.
  2. In a similar question on ASE, both answer and comments state that nested arrays aren't supported, but my knowledge of C++ isn't good enough to understand the answer.
2
  • @Juraj It's downloadable through the IDE. It's called Gamer.h.
    – gurkensaas
    Aug 7 at 20:10
  • @Juraj In the "Arrays of strings" it tells me to do something like this: strcpy_P(buffer, (char *)pgm_read_word(&(frames[1]))); arduino.printImage(buffer); However, it just tells me that 'buffer' was not declared in this scope
    – gurkensaas
    Aug 7 at 20:16
2

On the question you are referencing, the accepted answer suggests to modify the library. This could be the most efficient option. A less invasive solution, however, would be to copy the data from the flash memory to RAM, and use the printImage() function as is.

Obviously, copying everything to RAM defeats the purpose of PROGMEM. But you only need to copy one frame at a time, and only hold it in memory for little more than the duration of the call to printImage():

void printProgmemFrame(const byte flashFrame[8]) {
  byte ramFrame[8];
  memcpy_P(ramFrame, flashFrame, 8);
  arduino.printImage(ramFrame);
}

void loop() {
  printProgmemFrame(frames[0]);
  delay(1000);
  printProgmemFrame(frames[1]);
  delay(1000);
}
5
  • I tried your approach and it sadly still just displays arbitrary patterns. Do I need to do anything else except for inserting your printProgmemFrame-function and replacing the loop function?
    – gurkensaas
    Aug 7 at 20:30
  • @gurkensaas: In principle you need nothing else. I cannot test this, as I do not have the hardware. It works for me, however, with a mock of the arduino object. Aug 7 at 20:57
  • The code compiles fine, it uploads fine, but the problems of the arbitrary patterns stay the same.
    – gurkensaas
    Aug 7 at 20:59
  • I think you are returning ramFrame which is allocated on the stack when you call printProgmemFrame. Try again adding static to the variable declaration: static byte ramFrame[8]; Aug 7 at 21:17
  • @EugenioPace It generated another random pattern.
    – gurkensaas
    Aug 7 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.