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;
}
}