2D arrays in PSRAM

This post shows a minimal example sketch for storing a 2D array  in PSRAM memory of ESP32 WROVER modules. It’s mainly for my own reference, now that I’ve finally figured out how these notorious C++ pointers work*.

(An earlier post already showed a simple way to store 2D arrays in PSRAM, but that required some row/column book keeping).

The following sketch creates a 2D array named grid for storing float values in PSRAM. Then it fills all ‘cells’ with values of the form <column>.<row>. Finally, it prints the value of grid[123][234] (which should be 123.234, of course).


Storing, for example, uint16_t values instead of floats only requires replacement of all occurrences of float with uint16_t.

Note that you can store multiple 2D arrays (even of different types) this way. Just declare an additional pair of global pointers of the desired type and add a corresponding ‘create’ section for each array in setup().

Elements in the grid array from the above example can now simply be addressed like grid[x][y], just like in regular 2D arrays. This convenience comes at a price:

  • The presented method needs some extra memory for storing additional column pointers (the term sizeof(float *) * cols in the calculation formula of len).
  • My (and probably everybody’s) favorite ESP graphics library TFT_eSPI can push an entire buffer of pixel values to a TFT display (very fast!). However, that buffer needs to be referrenced to by a single pointer, whereas grid is declared as a double pointer. As far as I know, that means that you’ll have to push the grid array column by column, where grid[i] is a pointer to the column with (zero-offset) index i.

I’m now using the described method in sketches with many single-pixel read/write operations, or with multiple arrays stored in PSRAM. For ‘speedy’ TFT projects, I’ll keep stitching my rows and columns together for storage in a single 1D PSRAM array.


* Finding this piece of information about pointers was very helpful:  “… type is required to declare a pointer. This is the type of data that will live at the memory address it points to.” Before that, I presumed that pointers were supposed to be unsigned integers, long enough to hold any address they could point to.