1

I am writing a simple Conway's Game of Life implementation just to get to grips with the "Nokia 3310" LCD and I am having problems with boolean arrays. I am using an (unofficial) Arduino Pro Micro 5V/16MHz

Here's the code that is causing me trouble:

boolean buffer[84][48];

void setup(){  
  for(int i = 0; i < 84; i++){
    for(int j = 0; j < 48; j++){
      buffer[i][j] = true;
    }
  }
}

void loop(){}

When I upload this to the Arduino, it seemingly freezes up with the RX led on and its COM port stops working. If I want to upload any other sketch, I have to manually pull the RST pin LOW (since the Pro Micro doesn't have a reset button).

I've been playing around with the code and found out that the source of problems is this line:

buffer[i][j] = true;

It also doesn't matter if I use true or false.

I have tried debugging with Serial to the computer, but the Serial communication doesn't work at all, so I tried using an LED to find out where the problem is. I don't have any "regular" LEDs on me, so I had to try with an Adafruit NeoPixel. The outcome was quite interesting. When I comment out the problematic line, everything runs just fine, the led goes red for 500ms then it blinks white every time the problematic line would run and then it goes green and stays that way. With the problematic line in place, the LED won't do anything, even turn red, which I put much earlier in the code than the source of the problem.

Does anybody have any insights that might be useful? (Also, I really hope it is not some stupid typo, I swear I read it through about twenty times)

3

According to http://arduino.cc/en/pmwiki.php?n=Reference/BooleanVariables, "Each boolean variable occupies one byte of memory." Meaning you are trying to use 4032 Bytes of RAM with your array which I assume you do not have (whatever this unofficial Arduino is -- it's likely to be less than that: the ATmega328 of the Arduino Mini has 2 kB of SRAM, the ATmega32u4 of the Micro has 2.5 kB).

You could try with a quarter of the field size for a start and see if that makes your problems go away.

  • It's usually the ATmega32U4 in a Pro Mini I think. That still only has 2.5 KB SRAM though. – Peter Bloomfield Mar 2 '15 at 16:18
  • The Micro has an ATmega32U4 (I guess you mean that, google says it's the same for the Pro Micro), but the Mini has an ATmega328. (I only know Pro Mini, that's why I assumed it's more like that :) – fuenfundachtzig Mar 2 '15 at 16:20
  • Yep, that was it. The possibility crossed my mind, but I guess I forgot to check it. Just to clarify - the Pro Micro is functionally identical (AFAIK) to the Micro, but slightly smaller (12 0.1" pitch header pins on the Pro Micro and 17 on the Micro) and was designed by SparkFun instead of Adafruit. Also, by unofficial I meant from eBay :) – Sunbart Mar 3 '15 at 16:29
2

Well, if each boolean takes a full byte, as fuenfundachtzig says, then you might try some bitwise hacking to fit 8 bools per byte on your own. Maybe something like this:

unsigned int16 buffer[84][3];  //16 bits * 3 = 48 bits, per the original example

void init_buffer()
{
    for(int i = 0; i < 84; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            buffer[i][j] = 0xFFFF;  //all TRUE: each F is hexadecimal for 0b1111 in binary
        }
    }
}

bool get_buffer(unsigned int8 i, unsigned int8 j)
{
    unsigned int16 k = 0;
    while(j >= 16)
    {
        j -= 16;  //I can do this because i and j are passed by value and are therefore separate copies inside this function
        k++;
    }
    //now k is the array index and j is the bit position inside that element
    if(buffer[i][k] & (1 << j))  //(bitwise AND with 1 shifted left by j positions, so we only care about that bit)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
    //or, if your compiler supports it, you might replace the if/else with:
    return (buffer[i][k] & (1 << j));
}

As for the stylistic differences between my example and yours:

  • I like to completely specify my datatypes if I can. Don't rely on the compiler to do what you expect because it may have options to that effect that are set differently than you think.
  • I like to use brackets for everything, even single statements, and make them obvious. That way, there's no confusion later or additional bugs because a second statement was added to what used to be a bracketless single without adding the brackets.
    • The only exception to that is when I'm writing a series of almost-identical if's and I put both the if and the action on the same line, all aligned so that the subtle differences line up and become obvious.
  • I'll have to do something of the sorts. The good thing is, that the display I am working with takes 504 bytes to draw the full screen (84 columns of 6 bytes), so I will probably use bytes instead of uint16_t, but I will have to make sure bytes don't have any similar overhead. Regarding your stylistic advice, I haven't yet had any problem with using just int, but I will have to look into it to know, when it causes problems. Also, I do a similar thing with brackets, but I like to leave the opening bracket at the end of the line after the control structure. Cheers – Sunbart Mar 3 '15 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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