Controlling > 344 LEDs at once with fastspi

Hello, I’m having an issue controlling more than 344 LEDS modules with LPD-6803 drivers. I’ve been using the fastspi led library to accomplish this (http://code.google.com/p/fastspi/) for a bit but now that I’ve added a few more modules and gone over 344 the code appears to halt. At 344 everything works as intended but any number over this causes none of the commands to be sent out of the arduino.

The code I’m using to test this is as follows:

#include <FastSPI_LED.h>

#define NUM_LEDS 345
unsigned short Display[NUM_LEDS];  

void setup() {
  
  memset(Display, 0, sizeof(unsigned int)*NUM_LEDS);
  
  FastSPI_LED.setLeds(NUM_LEDS);
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803);
  FastSPI_LED.setCPUPercentage(70); 
  FastSPI_LED.init();
  FastSPI_LED.start();

  show();
}

void show()
{
  // copy data from display into the rgb library's output - we need to expand it back out since 
  // the rgb library expects values from 0-255 (because it's more generically focused).
  unsigned char *pData = FastSPI_LED.getRGBData();
  for(int i=0; i < NUM_LEDS; i++) { 
    int r = (Display[i] & 0x1F) * 8;
    int g = ((Display[i] >> 10) & 0x1F) * 8;
    int b = ((Display[i] >> 5) & 0x1F) * 8;
    
    *pData++ = r;
    *pData++ = g;
    *pData++ = b;
  }
  FastSPI_LED.show();
}

// Create a 15 bit color value from R,G,B
unsigned int Color(byte r, byte g, byte b)
{
  //Take the lowest 5 bits of each value and append them end to end
  return( ((unsigned int)g & 0x1F )<<10 | ((unsigned int)b & 0x1F)<<5 | (unsigned int)r & 0x1F);
}

//Input a value 0 to 127 to get a color value.
//The colours are a transition r - g -b - back to r
unsigned int Wheel(byte WheelPos)
{
  byte r,g,b;
  switch(WheelPos >> 5)
  {
    case 0:
      r=31- WheelPos % 32;   //Red down
      g=WheelPos % 32;      // Green up
      b=0;                  //blue off
      break; 
    case 1:
      g=31- WheelPos % 32;  //green down
      b=WheelPos % 32;      //blue up
      r=0;                  //red off
      break; 
    case 2:
      b=31- WheelPos % 32;  //blue down 
      r=WheelPos % 32;      //red up
      g=0;                  //green off
      break; 
  }
  return(Color(r,g,b));
}

void loop() {

  for(byte r=0; r <= 96 ; r++)
  {
    for(int j=0; j < NUM_LEDS; j++)
    {
      Display[j] = Wheel(r);
    }

    show();
    delay(100);
  }

  
}

It seems that even just declaring the initial array to be > 344 causes the arduino to stop working. Is there something obvious I’m doing wrong? Or is someone more familiar with the fastspi library and know why it would break at 345?

Thanks! :slight_smile:

edit I’m trying to debug the situation. Is there a good way to get error output from the arduino to see if there are any runtime errors?

Which Arduino are you using? Perhaps you are running out of SRAM.

I believe you are correct! At 345 LEDs that makes for 3*345=1035 bytes of memory that is needed just for the display array (1 byte for each color channel per led). I've been using the ATmega328 on the arduino Duemilanove which has 2kB of SRAM I believe. I'm going to try the code out on a Mega in a few days to test out this theory (8kB of SRAM).

My only worry is that the malloc command is failing because it's being called for > 1024 bytes. This seems like it could be true since the code breaks exactly at LED 344. Does anyone know what the limits on the arduino malloc are? I will need > 1024 bytes allocated and I'm not sure how feasible it is to split the memory up.

unsigned [glow]short [/glow]Display[NUM_LEDS];  

void setup() {
  
  memset(Display, 0, sizeof(unsigned [glow]int[/glow])*NUM_LEDS);

The memset arguments need to match the amount of space actually being written to.

At 345 LEDs that makes for 3*345=1035 bytes of memory that is needed just for the display array (1 byte for each color channel per led).

Where did the 3* come from. I don't see that you are allocating 1035 bytes.

Opps, small typo there with the short/int. The malloc occurs in the fastspi library I am using in FastSPI_LED.h:

  // set the number of rgb leds 
  void setLeds(int nLeds) { m_nLeds = nLeds * 3; m_nCounter = 0; m_nDirty = 0; m_pData = (unsigned char*)malloc(m_nLeds); memset(m_pData,0,m_nLeds); m_pDataEnd = m_pData + m_nLeds; }

It seems that forcing that malloc to be 1024 allows the arduino to work but LEDs past 344 are not addressed.

If the 1024 was really a magic number, I'd expect issues to occur when the number of LEDs exceeded 341 (3*341 = 1023).

It looks, given the fact that the library allocates 1035 bytes for 345 LEDs and the Display array that needs another 345 bytes, for a total of 1,380 bytes just for the two arrays, not counting stack space, etc., like you are running out of memory.

If not, you could re-write the library to use three smaller arrays (one per color) instead of one big array.