Data in progmem - not working - why?

Hi all,

I made a little bitmap image that I want to send to a VFD display. The image is 128 x 64 pixels, therefore 8192 / 8 or 1024 bytes.

Of course, I want to put it into PROGMEM, and that's where my problem is.

Here's the code:

#include <avr/pgmspace.h>

void loop(void) { ; }

uint8_t PROGMEM image[] = {
        0xf8,0x7f,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7d,0xfe,0x7d,0xed,
        0xfc,0x83,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0xfd,0xf3,0xd9,
        0xfc,0x04,0xff,0xff,0x80,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0xfd,0xb5,0x7c,
        0xfc,0x80,0x1f,0xfe,0x00,0x41,0x00,0x00,0x20,0x00,0x00,0x00,0x1f,0xfb,0xe7,0xed,
        0xfe,0x02,0x57,0xf4,0x93,0x0e,0x20,0x00,0x00,0x00,0x00,0x00,0x1f,0xfb,0xef,0x7c,

///////-----snip -- left out a big chunk in the middle for brevity

        0x59,0xa0,0x05,0xff,0x8a,0x00,0x10,0x00,0x00,0x49,0x25,0x86,0xc0,0xab,0x60,0x0f,
        0x46,0x58,0x0b,0xff,0xd8,0x00,0x81,0x20,0x03,0x6f,0xda,0x68,0x72,0x54,0x88,0x0f,
        0x69,0x60,0x3b,0xce,0xc0,0x00,0x08,0x00,0x35,0xba,0x29,0x23,0x09,0x96,0xfc,0x07,
        0x16,0xa0,0x5a,0x50,0x72,0x00,0x20,0x80,0x96,0xcd,0xd5,0x94,0xaf,0xd2,0x4c,0x07,
        0xd1,0xa0,0xb2,0x90,0xc0,0x00,0x00,0x02,0x75,0xb6,0x96,0x52,0x4f,0xed,0x9e,0x93,
        0x2d,0x60,0x79,0x01,0x00,0x00,0x00,0x15,0x9b,0xda,0xd9,0x48,0x9f,0xf9,0x5c,0xf3,
        0x93,0xb0,0x00,0x80,0x00,0x00,0x09,0xaa,0x6e,0xed,0x2d,0x25,0x7f,0xbe,0x42,0xf7
};

void setup(void)
{
        char buffer[8];
        const char *mask = "0x%02X, ";

        Serial.begin(115200);

        uint8_t data;
        uint16_t x;

        for (x = 0; x < 1024; x++) {
                data = pgm_read_byte(image[x]);
                sprintf(buffer, mask, data);
                Serial.print(buffer);
                if (((x+1) % 16) == 0) {
                        Serial.print("\r\n");
                }
        }

}

Now, of course, I would expect the first few lines to look like this:

0xF8, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xFE, 0x7D, 0xED,
0xFC, 0x83, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xFD, 0xF3, 0xD9,

... but it comes out like this:

0x0C, 0xDD, 0xDD, 0xDD, 0x00, 0x05, 0xDD, 0x0C, 0x0C, 0x0C, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,

Anyone have an idea what I'm doing wrong???

Thanks!

-- Roger

Instead of this construct, which I haven't seen before:

data = pgm_read_byte(image[x]);

…what happens if you try this:

data = pgm_read_byte(image + x);

-br

Or this...

data = pgm_read_byte( & image[x] );

Both your example and Billroy's example work. Which tells me that "image" is a POINTER........

Thanks and karma++ for both.

-- Roger

Which tells me that "image" is a POINTER.

No. image is an array. There are strong similarities between arrays and pointers, but there are (subtle) differences, too.

PaulS:

Which tells me that "image" is a POINTER.

No. image is an array. There are strong similarities between arrays and pointers, but there are (subtle) differences, too.

Funny thing is, if I put the data in a "regular" array (i.e. const char *image = "0x00, 0xff.....":wink: I can access individual bytes with "image[x]" syntax. But if it's in progmem, then "image" acts like a pointer (i.e. "image + 0" is the first element, as well as "&image[0]").

I've been programming in C and C++ for years, so the occasional "odd" things I have to do for AVR programming sometimes throws me a curve.

Anyway, I've got it all working and I see what's going on, so it's another problem solved and another byte or two of new data to store in my brain! :slight_smile:

Thanks!

-- Roger

and another uint8_t or two of new data to store in my brain!

I fixed that for you... 8)