Go Down

Topic: PROGMEM: storing and retrieving unsigned long data (Read 1 time) previous topic - next topic

I am making a game on the Arduino with large maps stored in unsigned long datatype in two dimensional arrays.
I have tried to use the PROGMEM code to store and retrieve the map data; I cannot find out how to retrieve it but I was able to store it.
I really do not understand this PROGMEM code, but here is what I have so far:

Code: [Select]

#include <avr/pgmspace.h>
PROGMEM const prog_uint32_t MAPGreen[][97] = { //the maps in the game
{
  0b11111111111111111111111111111111, 0b11111111111111111111111111111111,
  0b10000000000000000000000000000000, 0b00000000000111111111111111111111,
  0b10000000000000000000000000000000, 0b00000000000110000000000000000011,
  0b10000000000000000000000000000000, 0b00000000000110000000000000000011,
  0b10000000000000000000000000000000, 0b00000000000110000000011101110011
},
  {0b10000000000000000000000000000000, 0b00000000000110000000011101110011,
  0b10000000000000000000000000000000, 0b00000000000110000000010101010011,
  0b10000000000000000000000000000000, 0b00000000000000000000000000000011,
  0b10000000000000000000000000000000, 0b00000000000110000000000000000011,
  0b10000000000000000000000000000000, 0b00000000000110000000010101010011,
},
};


note: there is a total of 97 numbers in each string in the full code, I just decided to spare you of the massive amount of binary data

What I do with this data is check every bit of every line with another value, so if it is possible to set it up to where that is possible, that would be great. If I have to add a step or two to be able to do it, that is fine too.

pYro_65

#1
Oct 16, 2012, 03:09 pm Last Edit: Oct 16, 2012, 03:11 pm by pYro_65 Reason: 1
Here is a link to all the PROGMEM functionality

http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

http://tom-itx.dyndns.org:81/~webpage/abcminiuser/articles/progmem_basics_index.php

the macros like pgm_read_byte are what you need.

I tried using pgm_read_dword to read my MAPGreen string, but it does not seem to work

My reading code: (simplified
Code: [Select]

for(int x = 0; x < 20; x++){
  for(int y = 0; y < 20; y++){
    if((bitRead(pgm_read_dword(MAPGreen[y]), x) == 1){
      locationX = x;
      locationY = y;
    }
  }
}


gardner

MAPGreen[][97] is two dimensional and I'm not sure why your example is specifying only one dimension.  Anyhow, lets say you want MAPGreen[5][7], then you might do:

Code: [Select]
uint32_t cell_val = pgm_read_dword(&(MAPGreen[5][7]));
if (bitRead(cell_val, x)) {
   // la la la
}


You can combine the expressions, of course.  I just split them out for clarity.


My bad, I really only had 1 map so far so I just took away the second dimension for testing. Turns out I was missing a "&" in pgm_read_dword(&(MAPGreen[5][7])), I added it, and now it works! Thanks guys!

guix

Shouldn't you be using pgm_read_dword_far instead?

I tried using far, but the compiler does not recognize it, using near is working fine though.

gardner


Shouldn't you be using pgm_read_dword_far instead?


The linker migrates progmem constants to the lower part of address space.  If the aggregate of progmem constants is larger than 64K, then it would be necessary to use _far to address the ones past that mark.  With the O/Ps "uint32_t MAPGreen[][97]" a bit more than 160 elements will fit.  It might make sense to have a line or two of code to assert that sizeof(MAPGreen) < 64K, just in case.

Go Up