This one is a total mystery to me. I have a strip of WS2812 around my Xmas tree and have programmed 10 different patterns into it. I have a "showcase" mode which cycles through all 10 patterns. Well, it is supposed to but it crashes after 1 cycle through them all. I had it working but I decided to change some things around and now it has been acting very strangely.
I don't actually have it connected to the lights at the moment (I am at work) so I am running a whole bunch of Serial.print()s to see where in the sketch it is and at what point it crashes.
When I change around various things such as my Serial.print()s, adding in extra variables it changes the way it crashes. So far I have seen (on my serial monitor):
It stopping printing anything with no garbage and no further output to serial.
It printing a "null" character and stopping with no further output to serial.
It printing a funny ? within a diamond then resetting.
Typically the point at which it crashes is when currentPattern is either 0 or 1 on the second cycle of the "showcase". This seems to be independent of the variable showcaseTime, although when I set that to 1000 it made it through 2 whole cycles of patterns before crashing. I have tried it at 2000, 3000 and 5000 and they all crash shortly after completing 1 cycle.
Actually there are cases where it doesn't even complete 1 cycle. I just uncommented all my Serial.println(freeRam()) lines and it crashed on pattern 6. I will put the code in its current state below.
I don't think I am running out of RAM because every time I call freeRam() it gives me the same value. I feel as though I am somehow corrupting memory somewhere somehow but I just can't figure it out.
Also for anyone wondering how I get around the fact of using WS2812 with fastLED and an IR remote, I just put up with unresponsiveness of the remote and the fact I have to press a button several times to get a response.
Here is the start of my code. Since people don't like downloading ino files (I never do either) and also complain when the full code isn't posted, I have to split it into 3 posts.
#include <Arduino.h>
#include <FastLED.h>
#include "IRremote.h"
//function definitions
void checkRemoteControl();
void setInitialCondition();
void updatePattern();
void greenRed();
void whiteBlack();
void waveFade();
void waveConstant();
void rainbowFlow();
void fillRainbow();
void fillSingleColour();
void fullRainbow();
void singleSpiral();
void rainbowSpiral();
void translateIR();
void resetFillTime();
void resetForModeChange();
void updateRandom();
void updateTime(bool upPressed);
int freeRam();
const int NUM_LEDS = 123;
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
const int GREEN_LED = 3;
const int RED_LED = 4;
bool onOff = true;
byte currentPattern = 0;
unsigned long patternLastUpdate;
unsigned long lastIRcodeTime;
unsigned long IRcodeDelay = 50;
bool canReceiveIRcode = true;
unsigned long patternUpdateTime[] = {1000, 1000, 100, 100, 100, 10, 10, 100, 100, 100};
bool greenOrRed = false;
byte brightnessLevels[] = {0,31,63,95,127,159,191,223,255};
byte systemBrightnessIndex = 5;
byte waveStartIndex = 0;
byte waveColour = 0;
byte rainbowHues[NUM_LEDS];
byte fillIndex = 0;
byte fillTo = NUM_LEDS + 1;
byte fillStartColour = 0;
bool fillReset = true;
byte fullRainbowIndex = 0;
bool spiralDirection = true;
byte spiralIndex = 0;
unsigned long spiralChangeDirectionTime = 0;
unsigned long spiralLastChange;
byte singleSpiralColour = 0;
byte rainbowSpiralColour = 0;
bool randomMode = true;
bool showcaseMode = true;
unsigned long showcaseTime = 2000;
unsigned long randomModeTime = showcaseTime;
unsigned long randomModeLastUpdate;
//IR remote stuff
int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
void setup()
{
//serial only for debug
Serial.begin(9600);
delay(1000);
Serial.println("start");
delay(1000);
FastLED.addLeds<LED_TYPE, 2, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.clear();
FastLED.show();
for(byte i = 0; i < NUM_LEDS; i++)
{
rainbowHues[i] = map(i,0,NUM_LEDS - 1,0,255);
}
irrecv.enableIRIn(); // Start the receiver
pinMode(RED_LED,OUTPUT);
pinMode(GREEN_LED,OUTPUT);
delay(3000);
patternLastUpdate = millis();
spiralLastChange = millis();
randomModeLastUpdate = millis();
lastIRcodeTime = millis();
}
void loop()
{
checkRemoteControl();
updateRandom();
updatePattern();
}
void checkRemoteControl()
{
if(millis() - lastIRcodeTime >= IRcodeDelay)
{
canReceiveIRcode = true;
digitalWrite(GREEN_LED,LOW);
digitalWrite(RED_LED,LOW);
}
//if a change in mode has been detected, clear led data
if (irrecv.decode(&results) && canReceiveIRcode) // have we received an IR signal?
{
translateIR();
irrecv.resume(); // receive the next value
}
}
void updatePattern()
{
if(onOff)
{
switch (currentPattern)
{
case 0:
greenRed();
break;
case 1:
whiteBlack();
break;
case 2:
waveFade();
break;
case 3:
waveConstant();
break;
case 4:
rainbowFlow();
break;
case 5:
fillRainbow();
break;
case 6:
fillSingleColour();
break;
case 7:
fullRainbow();
break;
case 8:
singleSpiral();
break;
case 9:
rainbowSpiral();
break;
}
}
}
//switches alternating LEDs between green and red. how christmassy
void greenRed()
{
Serial.print("0");
if(millis() - patternLastUpdate >= patternUpdateTime[currentPattern])
{
Serial.println("in");
Serial.println(millis());
Serial.println(freeRam());
patternLastUpdate = millis();
greenOrRed = !greenOrRed;
for(byte i = 0; i < NUM_LEDS; i++)
{
if(i%2 == greenOrRed)
{
leds[i] = CHSV(HUE_RED,255,brightnessLevels[systemBrightnessIndex]);
}
else
{
leds[i] = CHSV(HUE_GREEN,255,brightnessLevels[systemBrightnessIndex]);
}
}
FastLED.show();
}
}
void whiteBlack()
{
Serial.print("1");
if(millis() - patternLastUpdate >= patternUpdateTime[currentPattern])
{
Serial.println("in");
Serial.println(millis());
Serial.println(freeRam());
patternLastUpdate = millis();
greenOrRed = !greenOrRed;
FastLED.clearData();
for(byte i = 0; i < NUM_LEDS/2; i++)
{
leds[i*2+greenOrRed] = CRGB::White;
leds[i*2+greenOrRed] %= brightnessLevels[systemBrightnessIndex];
}
FastLED.show();
}
}
void waveFade()
{
Serial.print("2");
if(millis() - patternLastUpdate >= patternUpdateTime[currentPattern])
{
Serial.println("in");
Serial.println(millis());
Serial.println(freeRam());
patternLastUpdate = millis();
byte pattern[] = {9,9,9,4,3,2,1,0,1,2,3,4,9,9,9};
byte j = waveStartIndex;
byte b; //brightness
//give a boost to the brightness since not many LEDs are on at once
byte s = 0;
if(systemBrightnessIndex != 0)
{
s = systemBrightnessIndex + 2;
}
if(s > 8)
{
s = 8;
}
for(byte i = 0; i < NUM_LEDS; i++)
{
b = s - pattern[j];
if(b >= 9)
{
b = 0;
}
leds[i] = CHSV(waveColour,255,brightnessLevels[b]);
j++;
if(j == 15)
{
j = 0;
}
}
waveColour++;
if(waveStartIndex != 0)
{
waveStartIndex--;
}
else
{
waveStartIndex = 14;
}
FastLED.show();
}
}
void waveConstant()
{
Serial.print("3");
if(millis() - patternLastUpdate >= patternUpdateTime[currentPattern])
{
Serial.println("in");
Serial.println(millis());
Serial.println(freeRam());
patternLastUpdate = millis();
byte pattern[] = {9,9,9,4,3,2,1,0,1,2,3,4,9,9,9};
byte j = waveStartIndex;
byte b; //brightness
//give a boost to the brightness since not many LEDs are on at once
byte s = 0;
if(systemBrightnessIndex != 0)
{
s = systemBrightnessIndex + 2;
}
if(s > 8)
{
s = 8;
}
for(byte i = 0; i < NUM_LEDS; i++)
{
b = s - pattern[j];
if(b >= 9)
{
b = 0;
}
leds[i] = CHSV(map(i,0,NUM_LEDS-1,0,255),255,brightnessLevels[b]);
j++;
if(j == 15)
{
j = 0;
}
}
if(waveStartIndex != 0)
{
waveStartIndex--;
}
else
{
waveStartIndex = 14;
}
FastLED.show();
}
}