I'm trying to build a state machine for a project I'm working on and I can't get the sketch to work properly. My problem is, for example, if I'm in 'mode-1 Red' and push the 2nd button to go into 'mode-2 theater-chase', mode-1 is still active in the background and 'bleeding' through into mode-2 wherever a pixel is "off/black". So I guess I'm trying to find a way to shut off mode-1 when going into mode-2. The closest I've gotten to a solution is to purposely turn off the other mode (you can see what I'm talking about in the commented-out lines in the sketch), but that's preventing button1 from working again when I do want to use it.
I'm open to all suggestions.
#include <Adafruit_NeoPixel.h>
#include <WS2812.h>
const int button1 = 2;
const int button2 = 3;
const int button1Led = A4;
const int button2Led = A5;
int mode1;
int mode2;
int mode;
const int ledPin = 6;
const int numLeds = 74;
//Solid Colors
const int cOFF = 0;
const int RED = 1;
const int BLUE = 2;
const int GREEN = 3;
//Patterns
const int pOFF = 1;
const int THEATER_CHASE1 = 2;
const int THEATER_CHASE2 = 3;
const int THEATER_CHASE3 = 4;
int currentColor = cOFF;// the current state we're in at any given time. We want to start in "off", so we set the variable to sOff when we declare it.
int nextColor = RED; // we need to have somewhere to go when we leave sOff, so let's pick red
int currentPattern = pOFF;
int nextPattern = THEATER_CHASE1;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(74, 6, NEO_GRB + NEO_KHZ800);
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
strip.begin();
strip.show();
Serial.begin(9600);
}
void loop()
{
mode1 = digitalRead(button1);
mode2 = digitalRead(button2);
if (mode1 == HIGH) {
mode = 1;
}
switch(currentColor)
{
case cOFF:
Serial.println("off");
if (digitalRead(button1) == HIGH){
currentColor = cOFF;
}
else if (digitalRead(button1) == LOW) {
currentColor = nextColor;
}
break;
case RED:
Serial.println("RED");
if (digitalRead(button1) == HIGH) {
Red();
currentColor = RED;
nextColor = BLUE;
}
else if (digitalRead(button1) == LOW){
currentColor = nextColor;
}
break;
case BLUE:
Serial.println("blue");
if (digitalRead(button1) == HIGH) {
Blue();
currentColor = BLUE;
nextColor = GREEN;
}
else if (digitalRead(button1) == LOW){
currentColor = nextColor;
}
break;
case GREEN:
Serial.println("green");
if (digitalRead(button1) == HIGH){
Green();
currentColor = GREEN;
nextColor = RED;
}
else if (digitalRead(button1) == LOW){
currentColor = nextColor;
}
break;
default: // the default case, which is an error for us
Serial.println("ERROR: default state");
currentColor = cOFF;
nextColor = cOFF;
break;
}
/******************************************/
if (mode2 == HIGH) { mode = 2; }
switch(currentPattern)
{
case pOFF:
Serial.println("off");
if (digitalRead(button2) == HIGH) {
currentPattern = pOFF;
nextPattern = THEATER_CHASE1;
}
else if (digitalRead(button2) == LOW){
currentPattern = nextPattern;
}
break;
case THEATER_CHASE1:
Serial.println("theater chase1");
if (digitalRead(button2) == HIGH){
TheaterChase1(50);
currentPattern = THEATER_CHASE1;
nextPattern = THEATER_CHASE2;
// currentColor = cOFF;
}
else if (digitalRead(button2) == LOW){
currentPattern = nextPattern;
}
break;
case THEATER_CHASE2:
Serial.println("theater chase2");
if (digitalRead(button2) == HIGH){
TheaterChase2(50);
currentPattern = THEATER_CHASE2;
nextPattern = THEATER_CHASE3;
// currentColor = cOFF;
}
else if (digitalRead(button2) == LOW) {
currentPattern = nextPattern;
}
break;
case THEATER_CHASE3:
Serial.println("theater chase3");
if (digitalRead(button2) == HIGH){
TheaterChase3(50);
currentPattern = THEATER_CHASE3;
nextPattern = THEATER_CHASE1;
// currentColor = cOFF;
}
else if (digitalRead(button2) == LOW){
currentPattern = nextPattern;
}
break;
default: // the default case, which is an error for us
Serial.println("ERROR: default state");
// currentColor = pOFF;
nextColor = pOFF;
break;
}
if (mode == 1)
{
digitalWrite(button1Led, LOW);
digitalWrite(button2Led, HIGH);
}
if (mode == 2)
{
digitalWrite(button2Led, LOW);
digitalWrite(button1Led, HIGH);
}
Serial.println(mode);
}
/*******************************************************************/
void Red(){
for(uint32_t i = 0; i<numLeds; i++)
{
strip.setPixelColor(i, 0xff0000);
strip.show();
}
}
void Blue(){
for(uint32_t i = 0; i<numLeds; i++)
{
strip.setPixelColor(i, 0x0000ff);
strip.show();
}
}
void Green(){
for(uint32_t i = 0; i<numLeds; i++)
{
strip.setPixelColor(i, 0x008000);
strip.show();
}
}
/***************************************************************/
void TheaterChase1( int SpeedDelay) {
for (int j=0; j<1; j++) { //do 1 cycle of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < numLeds; i=i+3) {
strip.setPixelColor(i+q, 0, 100, 0 ); //turn every third pixel on
}
strip.show();
delay(SpeedDelay);
for (int i=0; i < numLeds; i=i+3) {
strip.setPixelColor(i+q, 0,0,100); //turn every third pixel off
}
}
}
strip.show();
}
void TheaterChase2( int SpeedDelay) {
for (int j=0; j<1; j++) { //do 1 cycle of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < numLeds; i=i+3) {
strip.setPixelColor(i+q, 100, 0, 0 ); //red. turn every third pixel on
}
strip.show();
delay(SpeedDelay);
for (int i=0; i < numLeds; i=i+3) {
strip.setPixelColor(i+q,100,100,100); //white. turn every third pixel off
}
}
}
strip.show();
}
void TheaterChase3( int SpeedDelay) {
for (int j=0; j<1; j++) { //do 1 cycle of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < numLeds; i=i+3) {
strip.setPixelColor(i+q, 0xff8c00); //orange turn every third pixel on
}
strip.show();
delay(SpeedDelay);
for (int i=0; i < numLeds; i=i+3) {
strip.setPixelColor(i+q,0x4B0082); //green. turn every third pixel off
}
}
}
strip.show();
}

