RGB LEDstrip Code problem. See any errors?

Hello everyone

I’m Bas, New on the forrum. I’m building a light suit for my self. And i have problems with writing the code for it. For so far i have the code ready, but there is a little problem with it. I will post the code below.

The code works as follows; When you turn a rotary encoder the color will shift, when you push the encoder shaft a switch will be made setting the color to white, when pushed again the color from the encoder will be set. The RGB LEDstrip is driven by 3 Mosfets.

The thing i don’t know when i want to add a rainbow function( the fade piece in the code) it doesn’t look at the encoder any more but just starts with the rainbow function. the thing i want to do is to is push a button once The rainbow function starts, push the button again and the rainbow function stops and goes back to the encoder.

Could you help me with this code. Every thing that i try won’t work.

Thank you

#define FADESPEED 10
int redPin = 3;
int greenPin = 5;
int bluePin = 6;
int aPin = 4;
int bPin = 7;
int buttonPin = 2;
int mixPin = 8;
boolean isOn = true;
int color = 0;

long colors[48]= {
  0xFF2000, 0xFF4000, 0xFF6000, 0xFF8000, 0xFFA000, 0xFFC000, 0xFFE000, 0xFFFF00, 
  0xE0FF00, 0xC0FF00, 0xA0FF00, 0x80FF00, 0x60FF00, 0x40FF00, 0x20FF00, 0x00FF00,
  0x00FF20, 0x00FF40, 0x00FF60, 0x00FF80, 0x00FFA0, 0x00FFC0, 0x00FFE0, 0x00FFFF,
  0x00E0FF, 0x00C0FF, 0x00A0FF, 0x0080FF, 0x0060FF, 0x0040FF, 0x0020FF, 0x0000FF,
  0x2000FF, 0x4000FF, 0x6000FF, 0x8000FF, 0xA000FF, 0xC000FF, 0xE000FF, 0xFF00FF,
  0xFF00E0, 0xFF00C0, 0xFF00A0, 0xFF0080, 0xFF0060, 0xFF0040, 0xFF0020, 0xFF0000
};

void setup()
{
  pinMode(aPin, INPUT);
  pinMode(bPin, INPUT);
  pinMode(buttonPin, INPUT);
  pinMode(mixPin, INPUT);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop()
{
  if (digitalRead(buttonPin))
  {
    isOn = ! isOn;
    delay(200);    // de-bounce
  }
  if (isOn)
  {
    int change = getEncoderTurn();
    color = color + change;
    if (color < 0)
    {
      color = 47; 
    }
    else if (color > 47)
    {
      color = 0;
    }
    setColor(colors[color]);
  }
  else
  {
   setColor(0); 
  }
  delay(1);

if (digitalRead(mixPin))
  {
    isOn = ! isOn;
    delay(200);    // de-bounce
  }
  if (isOn)
  {
   int r, g, b;
    // fade from blue to violet
    for (r = 0; r < 256; r++) {
    analogWrite(redPin, r);
    delay(FADESPEED);
    }
    // fade from violet to red
    for (b = 255; b > 0; b--) {
    analogWrite(bluePin, b);
    delay(FADESPEED);
    }
    // fade from red to yellow
    for (g = 0; g < 256; g++) {
    analogWrite(greenPin, g);
    delay(FADESPEED);
    }
    // fade from yellow to green
    for (r = 255; r > 0; r--) {
    analogWrite(redPin, r);
    delay(FADESPEED);
    }
    // fade from green to teal
    for (b = 0; b < 256; b++) {
    analogWrite(bluePin, b);
    delay(FADESPEED);
    }
    // fade from teal to blue
    for (g = 255; g > 0; g--) {
    analogWrite(greenPin, g);
    delay(FADESPEED);
    }
  }
}

int getEncoderTurn()
{
  // return -1, 0, or +1
  static int oldA = LOW;
  static int oldB = LOW;
  int result = 0;
  int newA = digitalRead(aPin);
  int newB = digitalRead(bPin);
  if (newA != oldA || newB != oldB)
  {
    // something has changed
    if (oldA == LOW && newA == HIGH)
    {
      result = -(oldB * 2 - 1);
    }
  }
  oldA = newA;
  oldB = newB;
  return result;
} 

void setColor(long rgb)
{
  int red = rgb >> 16;
  int green = (rgb >> 8) & 0xFF;
  int blue = rgb & 0xFF; 
  analogWrite(redPin, 255 - red);
  analogWrite(greenPin, 255 - green);
  analogWrite(bluePin, 255 - blue);
}

Your code have lots of for-loops with delay(FADESPEED); in it.

In µC programming the loop() function should not only run once to perform its whole task. At least, if you wish it to behave interactively, and react on buttons while "the show goes on".

A nice loop() has not more than eventually a little delay(10) for debouncing, but else just looks at the time ( millis() ) and checks what to do ( if at all ). Usually loop finishes immediately, just to restart.

The BlinkWithoutDelay Sample is very simplistic, but shows the principle.

Instead of all the for( ; ; ) loops, a static or global counter and another variable, telling which step of your Rainbow Show is currently on, would turn one loop() into thousands of small steps.

SO what i understand is to make the rainbow piece in another loop and when i push the button i will call that piece of loop?

Could you give me a example of how i can do that. ?

Thanks in advance

I imagine something like this ( just a single little delay(FADESPEED) in each loop ) ...

...
enum RAINBOW {BLUEVIOLET=0, VIOLETRED,REDYELLOW, YELLOWGREEN, GREENTEAL, TEALBLUE} state;
...
void loop()
{
  // ... ( Handle buttons and encoder )   
  if (isOn)
  {
  // for each state of rainbow, do one step ( 0 .. 255 )
   static byte step;
   switch (state)
   {
      case BLUEVIOLET:
        // fade from blue to violet
        analogWrite(redPin, step++);
        delay(FADESPEED);
        if (step == 0)   state = VIOLETRED;
        break;
      case VIOLETRED:
        // fade from blue to violet
        analogWrite(bluePin, 255 - step++);
        delay(FADESPEED); 
        if (step == 0)   state = REDYELLOW;
        break;
    //  .... other 4 cases similar
    }
 }
}

Thank you very much!! I will take a silent moment and work on the program

Than you for the example

hello,

I have made the changes in the program. Code below:

int redPin = 3;
int greenPin = 5;
int bluePin = 6;
int aPin = 2;
int bPin = 4;
int buttonPin = 7;
int mixPin = 13;
boolean isOn = true;
int color = 0;
#define FADESPEED 10
enum RAINBOW {BLUEVIOLET=0, VIOLETRED,REDYELLOW, YELLOWGREEN, GREENTEAL, TEALBLUE} state;

long colors[49]= {
  0xFF2000, 0xFF4000, 0xFF6000, 0xFF8000, 0xFFA000, 0xFFC000, 0xFFE000, 0xFFFF00, 
  0xE0FF00, 0xC0FF00, 0xA0FF00, 0x80FF00, 0x60FF00, 0x40FF00, 0x20FF00, 0x00FF00,
  0x00FF20, 0x00FF40, 0x00FF60, 0x00FF80, 0x00FFA0, 0x00FFC0, 0x00FFE0, 0x00FFFF,
  0x00E0FF, 0x00C0FF, 0x00A0FF, 0x0080FF, 0x0060FF, 0x0040FF, 0x0020FF, 0x0000FF,
  0x2000FF, 0x4000FF, 0x6000FF, 0x8000FF, 0xA000FF, 0xC000FF, 0xE000FF, 0xFF00FF,
  0xFF00E0, 0xFF00C0, 0xFF00A0, 0xFF0080, 0xFF0060, 0xFF0040, 0xFF0020, 0xFF0000,
};

void setup()
{
  pinMode(aPin, INPUT);
  pinMode(bPin, INPUT);
  pinMode(mixPin, INPUT);
  pinMode(buttonPin, INPUT);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop()
{
  if (digitalRead(buttonPin))
  {
    isOn = ! isOn;
    delay(200);    // de-bounce
  }
  if (isOn)
  {
    int change = getEncoderTurn();
    color = color + change;
    if (color < 0)
    {
      color = 47; 
    }
    else if (color > 47)
    {
      color = 0;
    }
    setColor(colors[color]);
  }
  else
  {
   setColor(0); 
  }
  delay(1);
{
  if (digitalRead(mixPin))// ... ( Handle buttons and encoder ) 
{  
  isOn = ! isOn;
    delay(200);    // de-bounce
}
  if (isOn)
{
  int change = getEncoderTurn();
  // for each state of rainbow, do one step ( 0 .. 255 )
   static byte step;
   switch (state)
   {
      case BLUEVIOLET:
        // fade from blue to violet
        analogWrite(redPin, 255 - step++);
        delay(FADESPEED);
        if (step == 0)   state = VIOLETRED;
        break;
      case VIOLETRED:
        // fade from violet to red
        analogWrite(bluePin, 255 - step++);
        delay(FADESPEED); 
        if (step == 0)   state = REDYELLOW;
        break;
    case REDYELLOW:
        // fade from blue to violet
        analogWrite(greenPin, 255 - step++);
        delay(FADESPEED);
        if (step == 0)   state = YELLOWGREEN;
        break;
      case YELLOWGREEN:
        // fade from blue to violet
        analogWrite(redPin, 255 - step++);
        delay(FADESPEED); 
        if (step == 0)   state = GREENTEAL;
        break;        
       case GREENTEAL:
        // fade from blue to violet
        analogWrite(bluePin, 255 - step++);
        delay(FADESPEED);
        if (step == 0)   state = TEALBLUE;
        break;
      case TEALBLUE:
        // fade from blue to violet
        analogWrite(greenPin, 255 - step++);
        delay(FADESPEED); 
        if (step == 0)   state = BLUEVIOLET;
        break;
    }
 }
}
}

int getEncoderTurn()
{
  // return -1, 0, or +1
  static int oldA = LOW;
  static int oldB = LOW;
  int result = 0;
  int newA = digitalRead(aPin);
  int newB = digitalRead(bPin);
  if (newA != oldA || newB != oldB)
  {
    // something has changed
    if (oldA == LOW && newA == HIGH)
    {
      result = -(oldB * 2 - 1);
    }
  }
  oldA = newA;
  oldB = newB;
  return result;
} 

void setColor(long rgb)
{
  int red = rgb >> 16;
  int green = (rgb >> 8) & 0xFF;
  int blue = rgb & 0xFF; 
  analogWrite(redPin, 255 - red);
  analogWrite(greenPin, 255 - green);
  analogWrite(bluePin, 255 - blue);
}

Still the rainbow effect is not fading very wel. It is not good. And it still starts and can not get the encoder turns

    delay(200);    // de-bounce

Get real. Even the crappiest mechanical switch does not bounce that long.

    int change = getEncoderTurn();

What value are you getting? Why don't you know?

Why are mixPin's state AND buttonPin's state affecting isOn? Only one of them should.

  if (isOn)
{
  int change = getEncoderTurn();
  // for each state of rainbow, do one step ( 0 .. 255 )

Why are you reading the encoder again?

Why are you STILL using delay()?