Potentiometer controls colour of my RGBs, but I want it to control brightness

this is my code for a traffic light system. I need to introduce a potentiometer that controls the brightness of the LEDs. However, when implenting code like

void loop() {
  int readButton = digitalRead(button);
  int potValue = analogRead(potPin); // Read the potentiometer value
  
  // Map the potentiometer value to the range 0-255
  int rgbValue = map(potValue, 0, 1023, 0, 255);
  int pedestrianValue = map(potValue, 0, 1023, 255, 0);
  
  // Set RGB and pedestrian lights based on potentiometer values
  setRgbColour(rgbValue, rgbValue);
  setPedestrianLights(pedestrianValue, 255 - pedestrianValue);

the code seems to adjust the colour of the RGB, but I need it to control the light intensity. How would I achieve this? Thanks

Post your complete code.

1 Like

can you see the google drive file?

//24948440
const int rgbRed = 3;
const int rgbGreen = 5;
const int pedestrianRed = 6;
const int pedestrianGreen = 7;
const int button = 8;
const int potPin = 0;

// 7 segment display pins
const int a = 13;
const int b = 12;
const int c = 11;
const int d = 10;
const int e = 9;
const int f = 2;
const int g = 4;

bool loopStarted = false;
bool wasButtonPressed = false;  // Flag to check if the button was pressed during the loop
bool loopComplete = false;      // Variable to track loop completion

unsigned long statusTime;
unsigned long currentTime = 0;
unsigned long lastBlink = 0;
unsigned long previousTime;
unsigned long lastDisplay = 0;
unsigned long buttonPressTime = 0;
unsigned long debounceDelay = 50;
unsigned long lastDebounceTime = 0;
int loopStep = 0;

String Status1 = "|TRAFFIC GREEN | PEDESTRIAN RED|";
String Status2 = "|TRAFFIC YELLOW | PEDESTRIAN RED|";
String Status3 = "|TRAFFIC RED | PEDESTRIAN RED|";
String Status4 = "|TRAFFIC RED | PEDESTRIAN GREEN|";
String Status5 = "|TRAFFIC RED | PEDESTRIAN RED FLASH|";

String currentStatus = "";


void setRgbColour(int rgbRedValue, int rgbGreenValue) {
  analogWrite(rgbRed, rgbRedValue);
  analogWrite(rgbGreen, rgbGreenValue);
}

void setPedestrianLights(int pedestrianRedValue, int pedestrianGreenValue) {
  analogWrite(pedestrianRed, pedestrianRedValue);
  analogWrite(pedestrianGreen, pedestrianGreenValue);
}

void waitForButtonPress() {
  while (digitalRead(button) == HIGH) {
    // Wait for the button to be pressed
  }
  while (digitalRead(button) == LOW) {
    // Wait for the button to be released
  }
}

void print9() {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  Serial.println("NINE");
}

void print8() {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  Serial.println("EIGHT");
}

void print7() {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
  Serial.println("SEVEN");
}

void print6() {
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  Serial.println("SIX");
}

void print5() {
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  Serial.println("FIVE");
}

void print4() {
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  Serial.println("FOUR");
}

void print3() {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
  Serial.println("THREE");
}

void print2() {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
  Serial.println("TWO");
}

void print1() {
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  Serial.println("ONE");
}

void print0() {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  Serial.println("ZERO");
}

void printBlank() {
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}



void setup() {
  pinMode(rgbRed, OUTPUT);
  pinMode(rgbGreen, OUTPUT);
  pinMode(pedestrianRed, OUTPUT);
  pinMode(pedestrianGreen, OUTPUT);
  pinMode(button, INPUT);
  pinMode(potPin, INPUT);
  Serial.begin(9600);

  setRgbColour(0, 255);         // RGB to green
  setPedestrianLights(255, 0);  // Pedestrian red
  currentStatus = Status1;      // Initialise currentStatus with the first status
  Serial.println("" + currentStatus);

  waitForButtonPress();  // Wait for the button press to start the loop

  statusTime = millis();

  printBlank();

  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
}




void loop() {

  int readButton = digitalRead(button);

  if (readButton == HIGH && !loopStarted) {
    Serial.println("|BUTTON HAS BEEN PRESSED|");
    buttonPressTime = millis();
    loopStarted = true;  // Start the loop when the button is pressed
    loopStep = 0;        // Reset loopStep to start from the beginning
  }

  unsigned long currentTime = millis();

  if (loopStarted) {

    unsigned long elapsedTime = currentTime - buttonPressTime;

    switch (loopStep) {

      case 0:  // Traffic Yellow, Pedestrian Red
        if (elapsedTime >= 3000) {
          Serial.println("" + Status2);
          setRgbColour(255, 255);
          setPedestrianLights(255, 0);
          loopStep++;
          previousTime = currentTime;
        }
        break;

      case 1:  // Traffic Red, Pedestrian Red
        if (currentTime - previousTime >= 5000) {
          Serial.println("" + Status3);
          setRgbColour(255, 0);
          setPedestrianLights(255, 0);
          loopStep++;
          previousTime = currentTime;
        }
        break;

      case 2:  // Traffic Red, Pedestrian Green
        if (currentTime - previousTime >= 5000) {
          Serial.println("" + Status4);
          setRgbColour(255, 0);
          setPedestrianLights(0, 255);
          int nestedLoopStep2 = 0;
          unsigned long nestedLoopStartTime2 = currentTime;
          loopStep++;
          print9();
          if (currentTime - nestedLoopStartTime2 >= 1000) {
            printBlank();
          }

          // Variables for the nested loop


          while (nestedLoopStep2 < 5) {
            if (currentTime - nestedLoopStartTime2 >= 1000) {
              switch (nestedLoopStep2) {
                case 0:
                  print8();
                  break;
                case 1:
                  print7();
                  break;
                case 2:
                  print6();
                  break;
                case 3:
                  print5();
                  break;
              }

              nestedLoopStep2++;                   // Increment the nested loop step
              nestedLoopStartTime2 = currentTime;  // Reset the nested loop timer
            }

            currentTime = millis();  // Update the current time
          }

          previousTime = currentTime;
        }
        break;


      case 3:  // Traffic Red, Pedestrian Flashing Red
        if (currentTime - previousTime <= 4000) {
          Serial.println("" + Status5);
          setRgbColour(255, 0);
          setPedestrianLights(255, 0);

          unsigned long startTime = currentTime;
          unsigned long blinkInterval = 111;  // Blink interval in milliseconds
          bool pedestrianRedState = HIGH;     // Initial state of the pedestrianRed LED

          // Variables for the nested loop
          int nestedLoopStep3 = 0;
          unsigned long nestedLoopStartTime3 = currentTime;

          while (currentTime - startTime <= 7000) {
            if (currentTime - lastBlink >= blinkInterval) {
              lastBlink = currentTime;
              pedestrianRedState = !pedestrianRedState;         // Toggle the pedestrianRed LED state
              digitalWrite(pedestrianRed, pedestrianRedState);  // Update the LED state
            }

            if (currentTime - nestedLoopStartTime3 >= 1000) {
              switch (nestedLoopStep3) {
                case 0:
                  print4();
                  break;
                case 1:
                  print3();
                  break;
                case 2:
                  print2();
                  break;
                case 3:
                  print1();
                  break;
                case 4:
                  print0();
                  break;
                case 5:
                  printBlank();
                  break;
              }

              if (currentTime - lastBlink >= blinkInterval) {
                lastBlink = currentTime;
                pedestrianRedState = !pedestrianRedState;         // Toggle the pedestrianRed LED state
                digitalWrite(pedestrianRed, pedestrianRedState);  // Update the LED state
              }
              lastBlink = currentTime;

              // Toggle the state of the pedestrianRed LED


              nestedLoopStep3++;                   // Increment the nested loop step
              nestedLoopStartTime3 = currentTime;  // Reset the nested loop timer
            }

            currentTime = millis();  // Update the current time
          }

          setPedestrianLights(255, 0);

          loopStep++;
          previousTime = currentTime;
        }
        break;


      case 4:  // Traffic Red, Pedestrian Red
        if (currentTime - previousTime >= 5000) {
          Serial.println("" + Status3);
          setRgbColour(255, 0);
          setPedestrianLights(255, 0);
          loopStep++;
          previousTime = currentTime;
        }
        break;

      case 5:  // Traffic Green, Pedestrian Red
        if (currentTime - previousTime >= 5000) {
          Serial.println("" + Status1);
          setRgbColour(0, 255);
          setPedestrianLights(255, 0);
          loopStep++;
          previousTime = currentTime;
        }
        break;

      case 6:  // End of sequence, Traffic Green Pedestrian Red
        if (currentTime - previousTime >= 1000) {
          Serial.println("" + Status1);
          setRgbColour(0, 255);
          setPedestrianLights(255, 0);
          loopStep = 0;
          loopComplete = true;
          loopStarted = false;  // Reset loop to start only when the button is pressed again
          previousTime = currentTime;
          resetLoop();
        }
        break;
    }
  }

  // Check if the button was pressed during the loop


  if (loopComplete) {
    resetLoop();
  }

  // Check if it's time to update the status
}



void statusUpdate() {
  // Print the current status to the serial monitor
  switch (loopStep) {
    case 0:
      Serial.println("" + Status1);
      break;
    case 1:
      Serial.println("" + Status2);
      break;
    case 2:
      Serial.println("" + Status3);
      break;
    case 3:
      Serial.println("" + Status4);
      break;
    case 4:
      Serial.println("" + Status5);
      break;
    case 5:
      Serial.println("" + Status3);
      break;
    case 6:
      Serial.println("" + Status1);
      break;
  }
}

void resetLoop() {
  loopStep = 0;
  loopComplete = false;
}

According to the full code you posted, this function will adjust the brightness, not the color:

Your code seems not able to adjust the color at all, because it seems to use a monochrome leds.

I'm not sure what you mean by monochrome LED, they are RGBs. I haven't wired up the circuit itself but have only simulated on tinkercad. In the simulation, the colour is modified and not the brightness

But you control your RGB led as three monochrome ones by separate wires for red, green and (perhaps) blue color?
So, your code changes exactly the brightness of each individual color in the RGB LED, thus changing the color.

It’s not entirely clear which exactly brightness you want to change in the traffic light - it only has two colors - red and green

well the RGBs have 4 legs each, one for ground and then one for red green and blue. And I want to be able to control the brightness of both RGBs as a whole, whatever colour state they are in I need them to be able to be dimmed

I am only using the red and green legs as blue is not needed to mix the colours red, green, and yellow

I am still not understand your code logic - why did you lit a green and red light simultaneously:

The code above turns on the both green and red leds with the same brightness, defined by pot value.
So your code is ready to change brightness already , you just used it incorrectly.

how could I correct it to control each leg individually?

To control the brightness of the red led by pot value you need to call the function this way:

for green light:

thank you, would I write this case per case in the state machine?

Don't know. In my opinion, this question has nothing to do with changing color and brightness.

You're not wrong there, thanks for the help

Are you using arduino UNO?

If yes, the pin 7 is not PWM pin, and no brightness adjust work in this pin.

" const int pedestrianGreen = 7;

" analogWrite(pedestrianGreen, pedestrianGreenValue); analogWrite not work for this pin.

To change the brightness of an RGB LED but maintain the color, you need to adjust all the PWM values accordingly. Most people do that by using the HSV (Hue, Saturation, Value) or HSL color wheels, which is transformed by code into individual RGB PWM values by a function, e.g.


typedef struct {
    double r;       // ∈ [0, 1]
    double g;       // ∈ [0, 1]
    double b;       // ∈ [0, 1]
} rgb;

typedef struct {
    double h;       // ∈ [0, 360]
    double s;       // ∈ [0, 1]
    double v;       // ∈ [0, 1]
} hsv;

rgb hsv2rgb(hsv HSV)
{
    rgb RGB;
    double H = HSV.h, S = HSV.s, V = HSV.v,
            P, Q, T,
            fract;

    (H == 360.)?(H = 0.):(H /= 60.);
    fract = H - floor(H);

    P = V*(1. - S);
    Q = V*(1. - S*fract);
    T = V*(1. - S*(1. - fract));

    if      (0. <= H && H < 1.)
        RGB = (rgb){.r = V, .g = T, .b = P};
    else if (1. <= H && H < 2.)
        RGB = (rgb){.r = Q, .g = V, .b = P};
    else if (2. <= H && H < 3.)
        RGB = (rgb){.r = P, .g = V, .b = T};
    else if (3. <= H && H < 4.)
        RGB = (rgb){.r = P, .g = Q, .b = V};
    else if (4. <= H && H < 5.)
        RGB = (rgb){.r = T, .g = P, .b = V};
    else if (5. <= H && H < 6.)
        RGB = (rgb){.r = V, .g = P, .b = Q};
    else
        RGB = (rgb){.r = 0., .g = 0., .b = 0.};

    return RGB;
}


//This page provides a function for conversion between color spaces, including RGB to HSL. 
// Must be translated to C/C++ for Arduino!

function RGBToHSL(r,g,b) {
  // Make r, g, and b fractions of 1
  r /= 255;
  g /= 255;
  b /= 255;

  // Find greatest and smallest channel values
  let cmin = Math.min(r,g,b),
      cmax = Math.max(r,g,b),
      delta = cmax - cmin,
      h = 0,
      s = 0,
      l = 0;

  // Calculate hue
  // No difference
  if (delta == 0)
    h = 0;
  // Red is max
  else if (cmax == r)
    h = ((g - b) / delta) % 6;
  // Green is max
  else if (cmax == g)
    h = (b - r) / delta + 2;
  // Blue is max
  else
    h = (r - g) / delta + 4;

  h = Math.round(h * 60);

  // Make negative hues positive behind 360°
  if (h < 0)
      h += 360;

  // Calculate lightness
  l = (cmax + cmin) / 2;

  // Calculate saturation
  s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));

  // Multiply l and s by 100
  s = +(s * 100).toFixed(1);
  l = +(l * 100).toFixed(1);

  return "hsl(" + h + "," + s + "%," + l + "%)";
}


void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

I’m a bit of a code noob so I’m a bit unsure of what to do with what you’ve provided. Can you perhaps give me some guidance on how this would fit into my current code? If not that’s fine I can try figure it out myself but I’m well and truly lost on how to do it at the moment I’ve been trying for 3 days and had limited success. Can you give me an example of how you’d related this to my code and my existing functions? thanks

First, you need to understand the definitions of the color wheels, linked in post #16. Using color wheels makes it much easier to control lighting.

Then, you will understand that you don't change R, G, and B to get what you want. Instead, you change the color (hue, H) and/or the brightness (value V or luminosity L) and the function calculates the new R, G and B values to use.

Saturation is not important at this stage and can be left at 1, but later you will understand how to use it to get "pink", for example.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.