Problem reading PROGMEM data dynamically [SOLVED]

I have a problem reading int arrays from progmem. I am storing nested int arrays. When I hardcode which sub array to read from progmem into my in-memory array all works fine. When I try to load it dynamically it fails and something random is placed in my in-memory array.

This is the code:

#include <avr/pgmspace.h>

const int START_CHAR_VALUE = 97;
int char_0[] PROGMEM = { 221, 124 };
int char_1[] PROGMEM = { 252, 70 };
int char_2[] PROGMEM = { 205, 70 };
int char_3[] PROGMEM = { 252, 70 };
int char_4[] PROGMEM = { 223, 72 };
const int CURR_CHAR_ARRAY_SIZE = 2;
int curr_char[CURR_CHAR_ARRAY_SIZE];
PROGMEM const int* chars[] = {char_0, char_1, char_2, char_3, char_4};


void setup() {
  Serial.begin(9600);
}

void load(int charVal) {
    memcpy_P(curr_char, chars[charVal], CURR_CHAR_ARRAY_SIZE * 2);
}

void loop() {

  memcpy_P(curr_char, chars[3], CURR_CHAR_ARRAY_SIZE * 2);
  Serial.println(curr_char[0]);
  // Correctly prints 252

  load(3);
  Serial.println(curr_char[0]);
  // Prints something else

  delay(2000);
}

The first printout correctly prints the expected value. The other one prints something else.

Any suggestions on what I am doing wrong?

Any suggestions on what I am doing wrong?

Nothing obvious to me, but I do have some questions.

None of the values anywhere in your code need int storage space. So, why are the arrays using ints, rather than bytes?

Ignoring any datatype questions at the moment, I really would like to advice you Mikal Hart's Flash library (Flash | Arduiniana) which can be found in the playground - but somehow the link to it is offline at the moment.

Back to your problem: your chars array is located in flash, but you do not read from flash when you think you access it. So either remove PROGMEM from the line or use something like the following to read the pointer array member from flash:

void load(int charVal) {
    memcpy_P(curr_char, (prog_void*)pgm_read_word(&chars[charVal]), CURR_CHAR_ARRAY_SIZE * 2);
}

And how about using #defines. They are the proper way in C/C++

const int CURR_CHAR_ARRAY_SIZE = 2;
#define CURR_CHAR_ARRAY_SIZE 2

The define is as good as your 'constant' but it does not need SRAM and the compiler has a chance to optimize.

Marek080:
And how about using #defines. They are the proper way in C/C++

const int CURR_CHAR_ARRAY_SIZE = 2;

#define CURR_CHAR_ARRAY_SIZE 2




The define is as good as your 'constant' but it does not need SRAM and the compiler has a chance to optimize.

There's a recent thread about this. The compiler will optimize the const int too.

Marek080: Your tip did the trick! Thank you very much. The array is now read as it should be. I obviously failed getting a proper source pointer. I'll check the flash lib when the page is back up.

PaulS: The example program is heavily simplified and I can now see it is misleading. I actually do need to use flash storage. What I am trying to store is a font. I am storing the coordinates for the outline of 94 characters where each character takes 40-140 ints to represent. I'm building a plotter and want to be able to draw text. I will try to shrink and translate the coordinates so they fit as bytes though.