2

I'm attempting to drive 300 TM1803 RGB LEDs from an Arduino Uno using the FastLED library. My code works fine for 100 LEDs, but when I go to 150, the arrays that store LED values and my sensor data get corrupted, causing the LEDs to flash colors randomly every few seconds. From what I've read these are exactly the symptoms of running out of RAM, leading to something overwriting the RAM that contains my arrays.

However, with 150 LEDs, the MemoryFree library says I'm only using 920 bytes of RAM, no matter where in my code I measure, and the IDE says 880. Does anybody know what's going on? Is there something using 1100 bytes of RAM for a very short amount of time, so that I can't measure it?

My code:

#include "FastLED.h"
#include <MemoryFree.h>

const byte ledsPin = 3;
const byte sensorPin = A1;

const int numLeds = 300;
const int ledTime = 1000;

const int sensorMin = 0;
const int sensorMax = 512;

const CRGB correction = CRGB(80,255,70); // Cool white
//const CRGB correction = CRGB(160,255,20); // Warm white
const byte hOffset = 170; // baseline hue value
const int8_t hDirection = -1; // 1 or -1, direction of rainbow
const byte s = 255; // saturation (colorfulness)
const byte v = 255; // value (brightness)

const unsigned int arrayLength = numLeds+1;
byte hues[arrayLength];

CRGB leds[numLeds];
byte h = 0; // hue (color)

unsigned long sensorSum;
unsigned int loopCounter;
unsigned int arrayCounterLed;
unsigned int updatesPerLed;
char sp = ' ';
int arrayCounter;

unsigned long time;
unsigned long timeNextLed;
unsigned long timeLeft;
unsigned long time1;
byte route;

void setup() {
  FastLED.addLeds<TM1803, ledsPin, RBG>(leds, numLeds).setCorrection(correction);
  FastLED.setDither(0);
  pinMode(ledsPin, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  delay(10);
  time=millis();
  sensorSum += analogRead(sensorPin);
  loopCounter++;
  if(time >= timeNextLed) {
    timeNextLed = (time/ledTime+1)*ledTime;
    arrayCounter = (arrayCounter +1) % (arrayLength);
    hues[arrayCounter] = (constrain(map(hDirection*sensorSum/loopCounter, sensorMin, sensorMax, 0, 239), 0, 239)+hOffset)%256;
    updatesPerLed = loopCounter;
    loopCounter=0;
    sensorSum = 0;
  }
  for(int led = 0; led < numLeds; led++) {
    time1=micros();
    arrayCounterLed = pseudoMod(arrayCounter - led -1, arrayLength);
    timeLeft = timeNextLed-time;
    byte dist = abs(hues[arrayCounterLed]-hues[(arrayCounterLed+1)%(arrayLength)]);
    if(abs(hues[arrayCounterLed]-hues[(arrayCounterLed+1)%(arrayLength)])<=128) { // if it doesn't cross through 0
      h = (hues[arrayCounterLed]*timeLeft + hues[(arrayCounterLed+1)%(arrayLength)]*(ledTime-timeLeft))/ledTime;
    }
    else if(hues[arrayCounterLed] > hues[(arrayCounterLed+1)%(arrayLength)]) { // if it crosses through 0 forwards
      h = ((hues[arrayCounterLed]*timeLeft + (hues[(arrayCounterLed+1)%(arrayLength)]+256)*(ledTime-timeLeft))/ledTime)%256; // Causing flashing on red pixels?
    }
    else { // if it crosses through 0 backwards
      h = (((hues[arrayCounterLed]+256)*timeLeft + hues[(arrayCounterLed+1)%(arrayLength)]*(ledTime-timeLeft))/ledTime)%256;
    }
    time1 = micros() - time1;
    if(led == 0) {
      Serial.print(dist);
      Serial.print(sp);
      Serial.print(route);
      Serial.print(sp);
      Serial.print(timeLeft);
      Serial.print(sp);
      Serial.print(hues[arrayCounterLed]);
      Serial.print(sp);
      Serial.print(hues[(arrayCounterLed+1)%(arrayLength)]);
      Serial.print(sp);
      Serial.print(hues[arrayCounterLed]*timeLeft);
      Serial.print(sp);
      Serial.print(hues[(arrayCounterLed+1)%(arrayLength)]*(ledTime-timeLeft));
      Serial.print(sp);
      Serial.println(h);
    }
    leds[led] = CHSV(h, s, v);
  }
  FastLED.show();
  Serial.print(updatesPerLed);
  Serial.print(time1);
  Serial.println();
}

int pseudoMod(int a, int b) {
  if(a<0) {
    return a+b;
  } 
  else {
    return a;
  }
}
  • You're running out of memory. An uno has enough memory to drive ~140 RGB LEDs. Each LED needs 6 bytes. (i.e. Red 0-255, Green 0-255, and blue 0-255. So to define one LED's color takes 6 bytes (i.e. #000000 thru #FFFFFF) – Tyson Feb 21 '15 at 1:49
  • 3
    Wouldn't it be three bytes per LED? – ahalekelly Feb 21 '15 at 2:30
  • Memfree does not lie. Either not measuring in depest place. Is it possible the object if led is being copied, just temporarily. Doubling used space. Also that chip does not have clock. Any stuttering can cause to string could latch. turn off interrupts. And or show code. – mpflaga Feb 21 '15 at 2:36
  • PLease post your code here, otherwise it is difficult to find out what in your program could potentially use more memory than you think, even for a short amount of time. – jfpoilpret Feb 21 '15 at 6:54
  • Alright, added my code. I did some testing to see exactly how many leds it can handle, which is 126. It seems too close to 128 to be coincidence, particularly considering the array to hold my sensor data has numLeds+1 indexes. – ahalekelly Feb 21 '15 at 23:36
4

I found it! I was returning an int8_t variable from my mod function, causing me to not be able to iterate over more than 126 LEDs. Now this little Arduino Uno is maxing out it's RAM at 409 LEDs!

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.