 |
By: ChrisHale (offline) on Friday, September 03 2010 @ 08:00 AM PDT (Read 1919 times)
|
|
|
ChrisHale |
| ChrisHale |
|
Hey all,
I've been programming away on the Meggy for a few days now and I've run into something odd but understandable. I was making a 3 dimensional boolean array to store multiple single screen level data in. It was going to be something like...
PHP Formatted Code boolean Levels[36][8][8] =
{
{{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}}
, ... and so on ...
The trouble was is I think I'm hitting the upper limit for the allowed number of variables in my program. I'm currently 7.5k of the 32k of on board memory so I was wondering if anyone could explain this to me.
Right now its working with about 17 eight by eight arrays and another 50 variables but if I add another 4 or 5 grids to it the Meggy has trouble starting up.
Thanks!
|

Apprentice
Status: offline
Registered: 08/28/10 Posts: 9
California
|
|
|
|
|
 |
By: Windell (offline) on Saturday, September 04 2010 @ 01:50 AM PDT
|
|
|
Windell |
| Windell |
|
A few different issues here.
First, the "boolean" datatype is very inefficient. Each boolean is stored as an 8-bit char, and takes a full byte to store-- not a single bit. You'll do much better learning to use the bitwise operators-- then you can store the full 8x8 grid-- monochrome --in 8 bytes, not 64 bytes.
Next, you're trying to store 36 * 8 * 8 = 2304 bytes. The AVR chip (the ATmega328P) has 32 k of program space, but only 2 kb, 2048 bytes, of RAM. When you declare that array, you more than exceed the total available space on the chip. And, not all of the 2048 bytes is available to you. Some is taken up by the Arduino base libraries, and additional memory is used for the video buffer and other Meggy Jr library objects. Even so, there is usually enough space to do lots of interesting stuff, if you use the available space wisely.
So what can you do? The *big* trick is to store your static data objects in the program memory-- that 32 k that you know about. Then, only load in the parts that you need at any given time into memory. Also, *use* the Meggy's double-buffered video library-- there's already space allocated to store what's on the screen plus an off-screen buffer that you can use as scratch space to compose each image. Finally, switch to bitwise operations for your level data, so that it only takes about 36*8 = 288 bytes to store your full data array-- that's much easier to work with.
Windell H. Oskay
drwho(at)evilmadscientist.com
http://www.evilmadscientist.com/
|

Evil Scientist
 Status: offline
Registered: 06/15/06 Posts: 1932
Sunnyvale, CA
|
|
|
|
|
 |
By: ChrisHale (offline) on Saturday, September 04 2010 @ 05:29 PM PDT
|
|
|
ChrisHale |
| ChrisHale |
|
I suspected as much after talking with our tech artist at work. I just got a method working of storing half or 16 pixels inside of a single 'Long' variable and using the bitRead() function in the Arduino environment to retrieve the on/off state for each pixel.
PHP Formatted Code
void loop()
{
ClearSlate();
long picture[10] = {7060406, 6776431, 7194175, 16542934, 14540748, 15956118, 6519734, 16565862, 7039926, 7200454};
for (byte i = 0; i < 10; i++) {
ClearSlate();
drawTile( 10, 4, picture[i], Yellow );
DisplaySlate();
delay(1000);
}
}
void drawTile( byte initialOffset, byte tileWidth, long picture, byte color) {
byte startX = initialOffset % 8;
byte startY = initialOffset / 8;
byte number = 0;
for ( byte y = startY; y < 8; y++ ) {
for ( byte x = startX; x < (startX + tileWidth); x++) {
if ( bitRead(picture, number) ) {
DrawPx( x, y, color );
}
number++;
}
}
}
Is this sort of what you are describing and then just use the bitWise operators to apply any wanted changes to a variable? Two other questions is there an 8 byte variable I can use instead of a Long or is the best way to use two 4 byte variables like a Long? My last question, you mentioned using the program memory to store static data, how do I know when I'm using the RAM or the Program Memory and keep the seperate?
Thanks!
|

Apprentice
Status: offline
Registered: 08/28/10 Posts: 9
California
|
|
|
|
|
 |
By: Windell (offline) on Saturday, September 04 2010 @ 10:15 PM PDT
|
|
|
Windell |
| Windell |
|
You *can* use long variables, but it's generally a poor decision to do so unless it's absolutely necessary-- the reason is that the core processor uses 8-bit operations, and having to perform every operation 1/4 at a time introduces a huge amount of overhead. If at all possible, use a larger array of 8-bit integers instead-- that's much more efficient in terms of code size and speed. Using long longs is that much worse, of course.
Also, long variables are 32 bit, and long longs are 64 bit.
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html
The Arduino basic-logic functions, bitRead included, are typically very slow as well-- often 1/10 as fast as native C commands for the same operations. Use them with care, and with awareness that they're not particularly efficient.
> how do I know when I'm using the RAM or the Program Memory and keep the seperate?
If you just declare a variable, it always goes into RAM. You need to go out of your way to put arrays into program memory.
http://www.arduino.cc/en/Tutorial/Memory
http://www.arduino.cc/en/Reference/PROGMEM
Windell H. Oskay
drwho(at)evilmadscientist.com
http://www.evilmadscientist.com/
|

Evil Scientist
 Status: offline
Registered: 06/15/06 Posts: 1932
Sunnyvale, CA
|
|
|
|
|