Pages: [1]   Go Down
Author Topic: PROGMEM: storing and retrieving unsigned long data  (Read 1083 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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.
Logged

North Queensland, Australia
Online Online
Edison Member
*
Karma: 65
Posts: 2110
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: October 16, 2012, 08:11:13 am by pYro_65 » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

My reading code: (simplified
Code:
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;
    }
  }
}

Logged

Ontario
Offline Offline
God Member
*****
Karma: 24
Posts: 862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

France
Offline Offline
God Member
*****
Karma: 34
Posts: 987
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Shouldn't you be using pgm_read_dword_far instead?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Ontario
Offline Offline
God Member
*****
Karma: 24
Posts: 862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: