I've got some working code with a definition that looks like this:
const unsigned char DynTextPositions[10][4][4] = {
...
};
Which is defined / referenced via a header:
#include <avr/pgmspace.h>
#ifndef DYNTEXTPOS_H
#define DYNTEXTPOS_H
extern const unsigned char DynTextPositions[10][4][4];
#endif
This data is being fed into a rendering function which draws lines based on the given positions. The data is read as follows:
float deltas[4][4];
// ...
deltas[n][k] = float(DynTextPositions[c+1][n][k] - DynTextPositions[c][n][k]) / 32.0;
As-is, this works just fine, as long as I've got my other scenes commented out. When I uncomment them, the combined data size seems to overflow the data segment. This is expected, because there's a fair bit of data, so I'm trying to move the DynTextPositions
data into PROGMEM
.
I've got PROGMEM
working with some bitmaps, but it doesn't seem to work here. An example definition for a working bitmap is as follows:
PROGMEM const unsigned char ArduinoLogo[] = { ... };
However, as soon as I apply the PROGMEM
attribute to DynTextPositions
the rendering code seems to freak out - the positions appear to be all off-screen and completely wrong.
The only thing I can think of is that, for some reason, the data is either being considered signed rather than unsigned, or is getting corrupted along the way. Either that or the nested array is somehow being treated as a set of pointers.
Any idea why this might be?
1 Answer 1
Including <avr/pgmspace.h>
and using the PROGMEM
qualifier macro are only two of the steps required in order to get this to work. Since the data will no longer be available via the data bus you will need to use the various pgm_read_*()
macros or *_P*()
functions defined in avr/pgmspace.h
. These work by using the appropriate assembly code instructions to access data stored in program space, i.e. flash, on the MCU.
Under GCC 4.7 or higher when writing C code, the __flash
named address space is available. Variables declared within this namespace do not require any additional steps to access them. Note that the Arduino IDE compiles as C++, and hence does not make this (or any of the others) available.
PROGMEM
. With__flash
sure, but that isn't usable from C++.pgm_read_byte(&DynTextPositions[c,l,k])
but still seem to be getting garbage values. Am I missing something?