Go Down

Topic: Controlling multiple RGB LED strips with potentiometers, I'm no good at coding (Read 609 times) previous topic - next topic

yeahwhateverman

Hello, after several hair-pulling hours of trying to find a solution online, I am pulling out the white flag and asking you guys for some help!

I am building a play kitchen for my kids, and I am completely stumped with how to control the lighting. I've purchased some 12v commmon-cathode RGB LED strips that I intend to use for the pretend cooktop. There are 4x 1/2 meter strips that I am using, 1 for each mock-burner. Each is controlled by a potentiometer that is read by an arduino mega (for the number of pwm pins). I wrote a sketch that I thought (hoped rather) would work beautifully. However, the result has proven to be quite the opposite.

I'll start by explaining what the code is supposed to do:

1. The main loop simply checks the potentiometer outputs to the board (analog pins 0 - 3 on the Mega), and determines if the led strip associated with each pot should be "on" or "off" by referencing a minimum value. If the value read is below the minimum value, it then determines if the light was previously "on" or not. If not, then the code should prevent the lights from turning on (which would be the case if the loop were to call the "TurnOff" method, otherwise it should turn the light strip off by decreasing the brightness to 0.

2. I wrote a seperate method to handle the task of turning the light strip on, this just gradually increases the brightness of the red to max (255), and then the green to some smaller value in order to achieve an orange color.

3. A second method I created is in charge of turning the light strip off, by doing the opposite of the "TurnOn" method.

4. The last method I made just sets the rgb pins for the led strip to output 0, essentially preventing them from turning on (in a situation where the light was previously not on, so that it doesn't call the "TurnOff" method when the light strip should be off (below the minimum value)).

There are also small "indicator" lights (just through-hole leds) that should come on whenever the led strip is on, and off when the strip is off (this is how the main loop determines if the led strip was previously on or off when checking if the pot value is below the minimum value).

Now, as previously mentioned: how it is meant to work, and how it is actually working are very different. As it is, the indicator lights are permanently on, the strips never turn off, and instead of orange, I am getting a bright green. I am assuming that this is the result of my sketch (I am not going to pretend like I'm a good coder, I have very little experience with any kind of programming and only a small portion of that experience is with the arduino). For the physical circuit, I am fairly certain that everything is connected as it should be (I have far more experience creating electronic circuits than writing code). I am using logic-level N-channel mosfets to isolate the 12v supply from the arduino board, there are 3 for each led strip (one for each color). I have completely re-wired the circuit about half a dozen times (just to make sure everything is wired correctly) and there has been no change.

So now I will offer up my arduino sketch for dissection, please let me know if you spot where I am going wrong with this (probably several places). I have heavily commented the sketch to try and offer up a clear dialog of what the code is supposed to be doing. Thanks everyone who made it this far, any and all help, criticism, and advice is greatly appreciated!

Code: [Select]
// initialize 3 arrays for the inputs and outputs:
int inputArray[4] {
  A0, A1, A2, A3 // these pins are the potentiometer pins that are connected to the arduino
};

int rgbArray[4][3] = {
  {2, 3, 4}, // rgb pins for led strip 1
  {5, 6, 7}, // rgb pins for led strip 2
  {8, 9, 10}, // rgb pins for led strip 3
  {11, 12, 13} // rgb pins for led strip 4
};

int ledIndicatorArray[4] {
  50, 51, 52, 53 // pins for the led indicator lights
};

// initialize global variables used throughout the sketch:
int brightness = 0;
int rBright = 0;
int gBright = 0;
int bBright = 0;
int fadeSpeed = 10;

void setup() {
  // this loops through the 3 arrays defined above and sets the pinmode for each
  for (int i = 0; i < 4; i++) {
    // loop through the multidimensional array for the rgb pins:
    for (int j = 0; j < 3; j++) {
      pinMode(rgbArray[i][j], OUTPUT);
    }
    pinMode(ledIndicatorArray[i], OUTPUT);
    pinMode(inputArray[i], INPUT);
  }
  Serial.begin(9600); // begin serial transmission @ 9600b
}

// main code simply checks each potentiometer value being input to the arduino board:
void loop() {

  // loop through the potentiometers to check if any are on:
  for (int i = 0; i < 4; i++) {
    int ledIndicator = ledIndicatorArray[i]; // select the appropriate indicator light for the potentiometer being checked
    int knob = inputArray[i]; // set the pin to check potentiometer
    int redPin = rgbArray[i][0]; // set the red color pin
    int greenPin = rgbArray[i][1]; // set the green color pin
    int knobPosition = analogRead(knob); // store the value from potentiometer in "knobPosition" variable

    knobPosition = map(knobPosition, 0, 1023, 0, 255); // map the potentiometer position to a value that can be output on PWM pin
   
    // this condition will turn off the led strip and appropriate indicator light if the potentiometer is below a specific threshold (10 in this case):
    if (knobPosition < 10) {
      // this condition checks if the potentiometer was "on" prior to falling below the minimum threshold:
      if (ledIndicator = HIGH) {

        TurnOff(ledIndicator, redPin, greenPin); // if the potentiometer was "on", turn it off
       
      }
      // this condition indicates that the potentiometer was NOT previously "on" and loops through the rgb pins and appropriate indicator lights to prevent them from turning on:
      else {
       
        for (int j = 0; j < 3; j++) {
          int pinNumber = 0;
          int rgbPin = rgbArray[i][pinNumber];
         
          PreventOn(ledIndicator, rgbPin);
         
          pinNumber +=1;       
        }           
      }   
    }
    // this condition will turn the led strip on, along with the appropriate indicator light:
    else {
     
      TurnOn(ledIndicator, redPin, greenPin);
     
    }
  }
}

// this method is called when the main code reads a potentiometer value above the minimum threshold:
void TurnOn(int indicator, int red, int green) {
 
  digitalWrite(indicator, HIGH); // turn on the appropriate indicator light
  // gradually increase the brightness of the red leds:
  for (int c = 0; c < 256; c++) {
    analogWrite(red, rBright);
    rBright +=1;
    delay(fadeSpeed);
  }
  //gradually increase the brightness of the green leds:
  for (int c = 0; c < 31; c++) {
    analogWrite(green, gBright);
    gBright +=1;
    delay(fadeSpeed);
  }
}

//this method is called when the main code reads a potentiometer value below the minimum threshold and the potentiometer was previously "on":
void TurnOff(int indicator, int red, int green) {

  digitalWrite(indicator, LOW); // turn off the appropriate indicator light

  brightness = 30;
  for (int c = 0; c < 31; c++) {
    analogWrite(green, brightness);
    brightness -=1;
    delay(fadeSpeed);
  }

  brightness = 255;
  for (int c = 0; c < 256; c++) {
    analogWrite(red, brightness); // turn off the brightness to the color pin that was passed into this method
    brightness -=1;
    delay(fadeSpeed);
  }
}

// this method is called when the main code reads a potentiometer value below the minimum threshold and the potentiometer was NOT previously "on":
void PreventOn(int indicator, int rgb) {

  digitalWrite(indicator, LOW);
  analogWrite(rgb, 0);
 
}

dougp

Your problem may lie in this for() loop.

Code: [Select]

        for (int j = 0; j < 3; j++) {
          int pinNumber = 0;
          int rgbPin = rgbArray[i][pinNumber];
         
          PreventOn(ledIndicator, rgbPin);
         
          pinNumber +=1;       
        }           



Each time through the loop the  pinNumber  is reset to zero.  Try initializing  pinNumber  outside the loop or using  j  in its place.

.02
I don't trust atoms.  They make up everything.

No private consultations undertaken!

yeahwhateverman

Your problem may lie in this for() loop.

Code: [Select]

        for (int j = 0; j < 3; j++) {
          int pinNumber = 0;
          int rgbPin = rgbArray[i][pinNumber];
         
          PreventOn(ledIndicator, rgbPin);
         
          pinNumber +=1;       
        }           



Each time through the loop the  pinNumber  is reset to zero.  Try initializing  pinNumber  outside the loop or using  j  in its place.

.02
Thank you so much for pointing this out, I'm not sure how I missed that. I fixed this and re-uploaded the sketch, but unfortunately I am still getting some really strange behavior. That said, some of the led strips now turn off, just not in the desired manner. I may have to abandon the breadboards and do some soldering with some protoboard to ensure that all of the connections are being properly maintained. Thanks again for pointing out my mistake!

yeahwhateverman

Well, after staying up most of the night and spending a few hour this morning trying to get this to work, I have finally succeeded. I completely re-wrote the code and made several changes, mainly abandoning the idea of mixing colors, so I am now only using the red terminal of the led strip, the green and blue will go unused (for now).

For anyone interested, here is a summary of the sketch as well as the code itself. I hope this helps someone trying to accomplish a similar task.

A summary of what the sketch does:

1- read the first potentiometer
2- a) if the value read is below minimum, check if the paired indicator light is on
        i) if paired indicator light is on, turn off the led strip and paired indicator light
       ii) if paired indicator light is off, keep the led strip and paired indicator light off
    b) if the value read is above minimum, check if the paired indicator light is on
        i) if paired indicator light is on, keep the led strip and paired indicator light on
       ii) if paired indicator light is off, turn the led strip and paired indicator light on
3- loop...

The sketch itself:

Code: [Select]
int potentiometers[4] {
  0, 1, 2, 3
};

int indicatorLights[4] {
  50, 51, 52, 53
};

int colorTerminals[4] {
  2, 5, 8, 11
};

int selectedPot = 0;
int potVal = 0;
int selectedIndicator = 0;
int indicatorState = 0;
int selectedColorTerminal = 0;
int brightness = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  for (int i =0; i < 4; i++) {
    pinMode(indicatorLights[i], OUTPUT);
    pinMode(colorTerminals[i], OUTPUT);
  }
}

void readPots() {
  for (int i = 0; i < 4; i++) {
    selectedPot = potentiometers[i];
    selectedIndicator = indicatorLights[i];
    selectedColorTerminal = colorTerminals[i];
    indicatorState = digitalRead(selectedIndicator);
    potVal = map(analogRead(selectedPot), 0, 1023, 0, 255);
//    Serial.print("Selected Pot: ");
//    Serial.print(selectedPot);
//    Serial.print('\n');
//    Serial.print("Selected Indicator: ");
//    Serial.print(selectedIndicator);
//    Serial.print('\n');
//    Serial.print("Selected Color Terminal: ");
//    Serial.print(selectedColorTerminal);
//    Serial.print('\n');
//    Serial.print("Indicator State: ");
//    Serial.print(indicatorState);
//    Serial.print('\n');
//    Serial.print("Pot Value: ");
//    Serial.print(potVal);
//    Serial.print('\n');
//    Serial.print('\n');
    if (potVal < 20) {
      if ( indicatorState == HIGH ) {
        TurnOff(selectedIndicator, selectedColorTerminal);
      }
      if ( indicatorState == LOW ) {
        RemainOff(selectedIndicator, selectedColorTerminal);
      }
    }
    if (potVal > 20) {
      if ( indicatorState == HIGH ) {
        RemainOn(selectedIndicator, selectedColorTerminal);
      }
      if ( indicatorState == LOW ) {
        TurnOn(selectedIndicator, selectedColorTerminal);
      }
    }
  }
}

void TurnOff (int indicator, int colorTerminal) {
  digitalWrite(indicator, LOW);
  brightness = 255;
  for (int j = 0; j < 256; j++) {
    analogWrite(colorTerminal, brightness);
    brightness -=1;
    delay(10);
  }
}

void RemainOff (int indicator, int colorTerminal) {
  brightness = 0;
  digitalWrite(indicator, LOW);
  analogWrite(colorTerminal, brightness);
}

void RemainOn (int indicator, int colorTerminal) {
  brightness = 255;
  digitalWrite(indicator, HIGH);
  analogWrite(colorTerminal, brightness);
}

void TurnOn (int indicator, int colorTerminal) {
  digitalWrite(indicator, HIGH);
  brightness = 0;
  for (int j = 0; j < 256; j++) {
    analogWrite(colorTerminal, brightness);
    brightness +=1;
    delay(10);
  }
}

void loop() {
  readPots();
}

Go Up