What does PROGMEM mean?

I see it a lot with defining image arrays. What does it mean?

Also what does const unsigned char mean?

PROGMEM means the data is stored in program memory (ROM) and not RAM.

const unsigned char means “This is a character (generally an 8 bit value) that can only hold numbers that are unsigned (eg, it cannot be negative) and this one is const, which means you cannot change it like a normal variable”

A const unsigned char will be a 1 byte value in RAM.

Images are best stored in PROGMEM as they tend to be big, and you have a small amount of RAM, so you don’t want to fill it with your images.

So if i never add progmem it would place the image in ram by default?
what if my image is greater than 1 byte?

Yes, if you don’t add PROGMEM it will be stored in RAM.
Remember: The Arduboy has 32 KB ROM and 2,5 KB RAM - where 1KB is reserved for the screenbuffer so you only have 1,5 KB left.

Of course you can have images bigger than one byte.

1 Like

So Bergasms said a const unsigned char will be 1 byte maximum. Does this mean I need to change this definition to some other variable type if I exceed 1 byte? How would I know if my image exceeds 1 byte

Ah you probably misunderstood that.
A char variable by definition can only hold 1 Byte.

If you want to store an image you will need to make an array of multiple chars. That’s where the [] brackets come into play.


unsigned char const myImage[] PROGMEM = whatever...

so effectively each item in the array (each pixel) can be maximum 1 byte but the entire variable can a maximum of 32kb (size of rom)

for example an image is usually

Nope, that is also incorrect.

A single char can actually represent 1x8 pixels, because a byte is 8 bits. On the arduboy, you have a black and white screen, so a bit being a 1 means an on pixel, and a 0 means off pixel.

So for example, the char 0xAB is equivalent to 10101011, which is 8 pixels, on,off,on,off,on,off,on,on

An 8x8 sprite can be represented by 8 chars (8 bytes). So for example.

 PROGMEM const char sprite [] = {0xFF, 0x81,0x91,0xA5,0xA1,0x95,0x81,0xFF};    

represents an 8x8 sprite that looks a bit like a smiley face, and consumes 8 bytes of progmem.

Ohh!! I get it now. And those a drawn vertically i’ve read

Yep. I always keep this excellent image made by @emutyworks around for whenever I have to deal with sprites manually:

There’s plenty of image file to progmem array tools around though.

And about an hour ago I wrote a command line batch-processing one in C# in case my internet ever goes down.

Someone should make a forum post tallying them all or something.

1 Like

Ardu-imconvert - A desktop image converter for Arduboy this is probably the best


I went ahead and made that forum post I was debating. Added Zeduck’s converter to it as well.

Let’s say that I want to make a sprite that is 16 px high and 8 px wide… how will arduboy know to stack the 8x8 blocks vertically as opposed to horizontally like normal




You need the width to know that.

1 Like

It’s just a different calculation.

In a 16x8 image the memory gets read all the way along, no interruptions.

[b0, …, b7] [b8, …, 15]

In an 8x16 image, when it gets to the 8th byte it moves the drawing position 8 pixels down and 8 pixels left and continues drawing as normal.

[b0, …, b7]
[b8, …, 15]

In a 16x16 image, it does both.

[b0, …, b7] [b8, …, 15]
[b16, …, b23] [b24, …, b31]

So it’s all just a matter of calculating the right place to write the bytes.

So the width x height specified in the drawBitmap() function determines how they are placed

Yeah, width and height determine how the data is interpreted.

Try it yourself. Get an 8x16 image, try drawing it with
arduboy.drawBitmap(0,0, image, 8, 16, WHITE) and then try drawing it with arduboy.drawBitmap(0,0, image, 16, 8, WHITE) and see how it behaves differently. Then do the same with a 16x8.

It would have been completely possible to have the progmem arrays represent the image the ‘normal’ way around and convert it to match the screen as the game is running, but that would waste procesing time (and code space because the code would almost certainly be longer) so it makes more sense to force people to store their sprites in the format that matches the screen.

1 Like