Potentiometer LED Control

Hello all,

I need a little help with my program. I found this code online, modified it a bit, and tried it out using an RGB LED and a single potentiometer (because I only have one on hand):

const int redPin = 9;
const int greenPin = 10;
const int bluePin = 11;

const int redPot = 2;
const int bluePot = 1;
const int greenPot = 3;

int currentRed;
int currentGreen;
int currentBlue;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop(){
  currentRed = map(analogRead(redPot), 0, 1024, 0, 255);
  currentGreen = map(analogRead(greenPot), 0, 1024, 0, 255);
  currentBlue = map(analogRead(bluePot), 0, 1024, 0, 255);
  
  analogWrite(redPin, currentRed);
  analogWrite(greenPin, currentGreen);
  analogWrite(bluePin, currentBlue);
}

My circuit is:
Common Cathode RGB LED - red anode connected to 220ohm resistor on pin 9, and cathode on +5v.
25ohm potentiometer connected to +5v & GND, with output to analog pin 2.

The problem is that the LED never turns off. It goes from kinda dim when the pot is on the low end, and really bright when the pot is on the high end. I'd like to be able to go from completely off --> fully bright.

Here's a video explaining the situation:

If you have any questions or I wasn't clear, let me know. All help is appreciated!

What is connected to A1 and A3 (bluePot, greenPot). If they are unconnected, connect them to ground. The floating analog inputs are undefined and can be anywhere between 0 and 1023. A 25 ohm pot is really low value for what you are doing. 1K to 10K or more would be better as the 25 ohm is pulling 200 milliAmps.

groundfungus:
What is connected to A1 and A3 (bluePot, greenPot). If they are unconnected, connect them to ground. The floating analog inputs are undefined and can be anywhere between 0 and 1023. A 25 ohm pot is really low value for what you are doing. 1 to 10K or more would be better as the 25 ohm is pulling 200 milliAmps.

They weren't connected to anything but I just connected them to ground and got the same result. So you think trying a 10k pot would make it work?

I don't think the size of pot is the problem, its just that you are using a lot of power unnecessarily with the 25 ohm pot. Insert a serial print into your code to see what numbers you are actually getting from the pot. It may not give the full range 0 - 1023.

groundfungus:
I don't think the size of pot is the problem, its just that you are using a lot of power unnecessarily with the 25 ohm pot. Insert a serial print into your code to see what numbers you are actually getting from the pot. It may not give the full range 0 - 1023.

Hmm.. it's showing values from about 75 to 945. And the mapped values showing are from about 20 to 245. Strange. How could I fix that?

The quick way to "fix" it in code would be to change your map command to read

currentRed = map(analogRead(redPot), 75, 945, 0, 255);

The proper way to get it right would be to find a pot that will allow you full range of input values. I usually get good result out of 5K pots but that's mostly because i use them a lot at work so they are easily accessible.

Goofballtech:
The quick way to "fix" it in code would be to change your map command to read

currentRed = map(analogRead(redPot), 75, 945, 0, 255);

The proper way to get it right would be to find a pot that will allow you full range of input values. I usually get good result out of 5K pots but that's mostly because i use them a lot at work so they are easily accessible.

I tried that already but it didn't work very well. I got some strange results, like the LED flashing unexpectedly as I moved the potentiometer.

I also tried using an if statement, like if currentRed is less than 25, cut power. That didn't work like I wanted it to either, but I'm not sure I was doing it right.

You may have a noisy pot? perhaps an average over a few samples could smooth it out for you? Worth a try in any case....

 for (int i=1; i<=50 ; i++){ //take 50 readings from Analog Input pin
 trueValue = analogRead(potIn);
 totalValue += trueValue;
 }

ledBrightness = totalValue/50; //get average of 50 readings pulled in from loop

Goofballtech:
You may have a noisy pot? perhaps an average over a few samples could smooth it out for you? Worth a try in any case....

 for (int i=1; i<=50 ; i++){ //take 50 readings from Analog Input pin

trueValue = analogRead(potIn);
totalValue += trueValue;
}

ledBrightness = totalValue/50; //get average of 50 readings pulled in from loop

I'd try that but I don't think I even wrote my original if/else statement correctly. I'll try a different pot and see what happens.

Thanks!

Would be easier for someone to comment on your if/else statement if it was actually in the post for us to look at...

Just throwing that out there. For whatever its worth.

Goofballtech:
Would be easier for someone to comment on your if/else statement if it was actually in the post for us to look at...

Just throwing that out there. For whatever its worth.

Good idea, here's what I have:

const int redPin = 9;
const int greenPin = 10;
const int bluePin = 11;

const int redPot = 2;
const int bluePot = 1;
const int greenPot = 3;

int currentRed;
int currentGreen;
int currentBlue;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  Serial.begin(9600);
}

void loop(){
 
   currentRed = map(analogRead(redPot), 0, 1024, 0, 255);
   currentGreen = map(analogRead(greenPot), 0, 1024, 0, 255);
   currentBlue = map(analogRead(bluePot), 0, 1024, 0, 255);
    
   analogWrite(redPin, 255 - currentRed);
   analogWrite(greenPin, 255 - currentGreen);
   analogWrite(bluePin, 255 - currentBlue);
  
   Serial.println(currentRed, DEC);
   
   if(currentRed < 25) {
     analogWrite(redPin, 0);
   }
   else (currentRed > 25) {
   }
  
}

The "else" part is confusing me. Truly, if currentRed > 25, I want it to go back here:

   currentRed = map(analogRead(redPot), 0, 1024, 0, 255);
   currentGreen = map(analogRead(greenPot), 0, 1024, 0, 255);
   currentBlue = map(analogRead(bluePot), 0, 1024, 0, 255);
    
   analogWrite(redPin, 255 - currentRed);
   analogWrite(greenPin, 255 - currentGreen);
   analogWrite(bluePin, 255 - currentBlue);

But i don't know exactly how to make that happen.

adambowker98:
Good idea, here's what I have:

const int redPin = 9;

const int greenPin = 10;
const int bluePin = 11;

const int redPot = 2;
const int bluePot = 1;
const int greenPot = 3;

int currentRed;
int currentGreen;
int currentBlue;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  Serial.begin(9600);
}

void loop(){

currentRed = map(analogRead(redPot), 0, 1024, 0, 255);
  currentGreen = map(analogRead(greenPot), 0, 1024, 0, 255);
  currentBlue = map(analogRead(bluePot), 0, 1024, 0, 255);
   
  analogWrite(redPin, 255 - currentRed);
  analogWrite(greenPin, 255 - currentGreen);
  analogWrite(bluePin, 255 - currentBlue);
 
  Serial.println(currentRed, DEC);
 
  if(currentRed < 25) {
    analogWrite(redPin, 0);
  }
 
}




The "else" part is confusing me. Truly, if currentRed > 25, I want it to go back here:

But i don't know exactly how to make that happen.

well your in luck. If this is all of your code then you don't have a choice in that matter. As you likely know the loop() runs over and over in your code. If we were to assign letters in the alphabet to your code then your "map" functions are step A and the "if" statement are step Z.

So with or without the "else" you will be rolling back to your A after the last function has executed unless you insert code to make it stop for some specific reason.