The amount of memory needed for my user interface is outrageous. Hence I decided to use flash memory. But after some successful readouts from program space, problems emerge.

Updated: I have some sort of initialisation files to collect all global arrays which go into flash like this: (intitialisation.cpp)


#include "initialisation.h" //which includes Arduino libraries and "globals.h"

const uint8_t gl_PsNMenuType[MAXMENUS] PROGMEM = { 0, 0, 0, 0, 0};  // this is, what I intend to read out later. 
const uint8_t gl_PsNMenuParent[MAXMENUS] PROGMEM = { MAXMENUS, 0, 0, 0, 0};  
const uint8_t gl_PsNMenuFixTexts[MAXMENUS][MAXFIXTEXTSPM] PROGMEM = {  
  { 20, 2, MFTS, MFTS, MFTS}, // 0
  {2, 9, 1, MFTS, MFTS}, // 1
  {2, 10, MFTS, MFTS}, //2
  {2, 11, MFTS}, //3
  {2, 12, MFTS} //4


Updated: while I propagate all global vars via another header (globals.h):

#ifndef GLOBALS
#define GLOBALS
#define SDTXT

#define MAXMENUS 80    

#include "initialisation.h"
extern const uint8_t gl_PsNMenuType[MAXMENUS];
extern const uint8_t gl_PsNMenuParent[MAXMENUS];  // referenz auf den übergeordneten MP
extern const uint8_t gl_PsNMenuFixTexts[MAXMENUS][MAXFIXTEXTSPM];  // Liste der festen Menütexte zu jedem MP

as one can see, I do not initialise my arrays fully, as I'm in a development phase, but the first bytes should be zeroed out correctly AFAIK.

But, when accessing my stored values later in a third file: (uimenu.cpp)

#include "uimenu.h" // which includes globals.h and initialisation.h

// somewhere in the code inside a function, with uint8_t mp=0:

The last line should print 0, as stated in initialisation, but it prints 12.

So, I think, I'm doing sth. substantially wrong here, but have no clue at the moment. I have several guesses:

  1. I should not use const with PROGMEM. I did this to be informed by the compiler, if I accidentally write to an array stored in flash.
  2. I made some mess with #includes, perhaps with order of occurrence. At the moment I try to sort the order out.
  3. There's something with having global variables or arrays defined and declared in a header and accessed in another source files function. But I cannot imagene, what.
  4. Updated: something wrong with my indices for my arrays? is uint8_t insufficient?

If you need more information or code, I'll edit my question accordingly. Thanks in advance! I appreciate any help. (all files were edited for brevity before posting them)

Update: I moved the definitions of the progmem arrays to the source file and all macro constants (#define) to globals.h. The outcome is: different numbers are printed, but they are wrong whatsoever. I poked elsewhere into the progmem array and got other wrong numbers.

  • Did you try declaring them as PROGMEM in your header so that other code units know how to use them? Oct 26, 2014 at 15:36
  • The correct way to use pgm_read_xxx is pgm_read_byte(gl_PsNMenuType + mp).
    – Gerben
    Oct 26, 2014 at 15:55
  • 2
    @Gerben: ... or pgm_read_byte(&gl_PsNMenuType[mp]) and mainly switch on warnings. This kind of error should be caught by gcc warnings.
    – TMa
    Oct 26, 2014 at 18:33
  • @IgnacioVazquez-Abrams I guess I brought some confusion into this matter by not posting my updates in a new section but changing the code. Actually the first thing I tried was to qefine and initialise it in header file. But I still have a extern declaration in "global.h" which is included by all other headers in my project. IMHO the declaration with extern should suffice for other code to make it linkable, shouldn't it? But I think I have to check gerben's comment as soon as I'm back at the hardware again.
    – Ariser
    Oct 27, 2014 at 14:07
  • @TMa: seems to work! I totally missed the necessity of referencing the array element. Thanks a lot. But I did not get any compiler warnings without the reference operator. Why isn't this call typesafe?
    – Ariser
    Oct 27, 2014 at 19:57

1 Answer 1


@TMa: seems to work! I totally missed the necessity of referencing the array element. Thanks a lot. But I did not get any compiler warnings without the reference operator. Why isn't this call type-safe?

The PROGMEM word is an attribute, not a type. It might be type-safe but not attribute-safe (if there is such a thing). See Data in Program Space


Putting constant data into program memory (PROGMEM)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.