-1

I am running a Mega 2560 processor board.

I have a large "unsigned char" database currently stored in a 2 dimensional array in SRAM. I have plenty of room in program memory and need to move the database to PROGMEM. It appears that the rules around how to use PROGMEM have changed and the documentation does not reflect the change. I have found a way to store the array in PROGMEM and can access the data statically (ARRAY[0,1]). If I try to access the array dynamically, (ARRAY[var1,var2]), I get junk.

Since I have seen some questions what I mean by "static" and "Dynamic" I gladly add the following examples:

//Array initialization

const static unsigned char __attribute__ ((progmem)) Image_1d_Array[234]={
  0x00, 0x0e, 0xf8, 0xff, 0xdf, 0x03, 0xc0, 0x1d, 0x60, 0x1f, 0x60, 0x00, 0x03,
   0xdb, 0x01, 0x00, 0x08, 0xe3, 0x07, 0x00, 0x0e, 0x00, 0x1e, 0x30, 0x00, 0x00,
   0x00, 0x0e, 0xf0, 0x07, 0xfc, 0x01, 0xc0, 0x39, 0x00, 0x1f, 0xe0, 0x00, 0x03};


void setup:  
  int i;
  char myChar;

//  Static read.  This will give me the correct values  
  Serial.print("Image= "); Serial.println(Image_1d_Array[0],HEX);
  Serial.print("Image= "); Serial.println(Image_1d_Array[1],HEX);
  Serial.print("Image= "); Serial.println(Image_1d_Array[2],HEX);
  Serial.print("Image= "); Serial.println(Image_1d_Array[3],HEX);
  Serial.println("");

//  Dynamic read.  This will give me the junk values  
  for(i = 0; i <=11; i++){
     Serial.print("AImage= ");
     myChar = pgm_read_byte_near(&Image_1d_Array + i);
     Serial.println(myChar,HEX);
    }

I can't even get a single dimensional array to work dynamically.

Does anybody understand the new rules to access the array?? The following data structures from the Arduino reference manual are no longer supported

prog_char - a signed char (1 byte) -127 to 128
prog_uchar - an unsigned char (1 byte) 0 to 255
prog_int16_t - a signed int (2 bytes) -32,767 to 32,768
prog_uint16_t - an unsigned int (2 bytes) 0 to 65,535
prog_int32_t - a signed long (4 bytes) -2,147,483,648 to * 2,147,483,647.
prog_uint32_t - an unsigned long (4 bytes) 0 to 4,294,967,295
  • 1
    Please edit your question and explain what you mean by the phrases “access the data statically” and “access the data dynamically”. You might need to add a Minimal, Complete, and Verifiable example of code so people don't have to waste time guessing what you did or what you meant. § AFAIK, “the rules around how to use PROGMEM have changed” is false. – James Waldby - jwpat7 May 20 '17 at 0:25
  • 1
    I tested on an UNO and it works fine if you remove the &. – Johnny Mopp May 20 '17 at 12:25
  • Accept Edgar Bonnet's answer to close your question. – user31481 Nov 20 '17 at 16:21
1

You wrote:

myChar = pgm_read_byte_near(&Image_1d_Array + i);

Here &Image_1d_Array is the address of the array. Its type is “pointer to an array of 234 unsigned chars”. When you add i to this pointer, per the rules of pointer arithmetic, you are actually adding to the address i times the size of the array.

What you actually mean by &Image_1d_Array is “the address of the first element of the array”, which can be written &Image_1d_Array[0]. Or you could rely on the usual “decay to pointer” semantics, and simply write Image_1d_Array, as suggested in Johnny Mopp's comment.

Now you should have noticed that both Image_1d_Array and &Image_1d_Array behave as pointers to the same memory address, only they have different types. See the C FAQ and references therein for more on this distinction.

Note that the usual way of doing what you want is:

myChar = pgm_read_byte_near(&Image_1d_Array[i]);
  • Thanks for the info, I thought the "i" in "(&Image_1_Array+i)" was adding an offset of "i" to the Array not "i * Array size". Big difference!! – Ken Kloster May 23 '17 at 13:52
  • @KenKloster: As a general rule, (size_t)(&foo + i) always means (size_t)&foo + i * sizeof foo. Note that size_t is just an integer type large enough to hold a pointer. – Edgar Bonet May 23 '17 at 15:31

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.