Electronic – arduino – Memory management problems with ATTiny85

arduinoattinyccompiler

The setup is as follows:
I have a little program to drive single color 8×8 led matrix using 595 shift registers that are supplied with data by ATTiny85 through USI as SPI Master. I upload program to ATTiny85 using Arduino Uno. Program is compiled and uploaded using Visualmicro plugin for VS2010 or Arduino IDE (both with the same results). Compiled program is 2970 bytes long (36.3% of chip's memory)

The issues are:

  1. The Array Problem: I cannot declare array that is longer then 296 bytes.
    I have array that holds binary representation of a font to display characters on LED matrices. The desired size for this array is 760 bytes. It is declared as follows:

    byte font[] =
    {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( )
        0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, // Char 033 (!)
        ...
        0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, // Char 125 (})
        0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Char 126 (~)
    }// 760 bytes total
    

    If I refer to first element of the array in the code, I receive 648th element [first byte of fonts character 113 (q)]. Whole array is messed up. Blocks of 8 bytes or more (n*8bytes) of the arrays content are mixed up with each other and with completely unrelated areas of memory.
    If I try to display any text on on the matrices I see completely different characters or some mess (I think what I actually see is the very program running in the memory – it's cool but useless). If I cut the array down to 296 bytes everything works fine.

  2. The Pointer Problem– to work around problem #1 I split the array into 3 smaller arrays(296 bytes max). I declared pointer to point to proper font array depending on character to "render". I cannot point this pointer to any array inside the "if" block

    char c1='a';  //character to display
    byte font1[]={...};  //binary font representation split in to 3 arrays
    byte font2[]={...};  
    byte font3[]={...};
    byte  ascii_offset1= 32,ascii_offset2= 69,ascii_offset3= 106;  //offset for each array
    byte * font_ptr1=font1; //This works fine. 
    font_ptr1=font3;        //This also worked fine in tests. 
    
    if(c1>=ascii_offset3)  
    {   
        font_ptr1=font3;  //This DOESN'T work at all
        c1-=ascii_offset3
    }
    else ...
    

In fact I think that line, commented as not working, is actually hanging up the ATTiny. I see nothing on matrices, except for few LEDs constantly lighten up.

In case of issue #1 I suspect that compiler or linker messes something up. But #2 is total mystery to me. I thought that maybe it's stack overflow, but according to documentation stack size is limited only by SRAM size, witch is plenty and additionally I don't allocate any memory dynamically.

Best Answer

Follow the steps in this post to check your RAM usage:

Checking memory footprint in Arduino

My guess is that you have gone over as the RAM size of the ATTiny85 is 512 bytes. In your sketch, font will be stored in RAM. You want to store it in the FLASH program memory. Follow these instructions to do so:

http://www.arduino.cc/en/Reference/PROGMEM