Potentiometer to adjust 4 LED's up and down in wave-like pattern

So I set up 4 LED's on my breadboard and a pot to adjust them up and down. But I wanted to add a wave effect to it. Here's what I've come up with so far. It does actually work to some extent anyway. On the upstroke it works pretty decent but don't know why it doesn't work nearly as well on the downstroke if even at all. I don't think I've seen it work correctly on my real setup. And its definitely not a perfect system in general. A bit laggy, buggy, more delays that I would like. I'm curious to see what you guys think. Outright problems with the code or just possible improvements? Thanks.

One other thing guys. Is it just me or is the LED mechanism on wokwi flawed? Any program I open with LED's even if its not mine they always appear to blow out as soon as turned on no matter what and then they always oscillate on and off. Also can't you rotate the overall position potentiometer? Like all other components that I've messed with have an editor to either rotate it or flip it, stuff like that but I see nothing for the pot. Are these just minor shortcomings that come with a free app?

do you just want the LEDs come in sequence as the pot is turned up and turn off in reverse sequence when the pot is turned back?

don't know what you mean by wave-like

  • what's the purpose of the while loop in loop()
  • what's the intent of chageValues(), to in/decrease the pwm of the LEDs in sequence over a 250 msec period
  • why updateValues() and outputLED() after seting the LED value in changeValues()

not sure what you want the LEDs to do

seems that you want the intensity of the LEDs to be increase in stepd but with a delay between each LED

seems that it doesn't take much change in pwm to go from off to near full brightness: 255 off, 200 bright for LED wired between 5V and the pin

well yes but not just from 0 to full. I mean its pwm so... I was actually going to expand on exactly what I had in mind for "wave-like" but I don't think it really matters. Because ya the current implement is slightly different than what I had in mind but you can only go so deep with 4 LED's so I think the current mechanism is just fine which is basically a gradual increment from previous value to new value starting left to right with each iteration. I mean maybe I can do a for loop for each led individually starting left moving right. Idk that might look good.
But the main thing is that I think my code is flawed somewhere. The downward action doesn't seam to be working like the upward does. They're just dimming simultaneously and I don't understand why.

yes that is true. i figure the delays make it more noticable not too quick. also the open for loop is to give the user time to adjust the knob before it jumps straight into the "wave" function. Redundancy in functions I'll take a look at that

ok

don't understand the other code

  • while loop involving millis()
  • checks for a change in the pot value
  • changeValues() and updateLED()

why not repeatedly do what changeValues() seems to do but using the current pot value -- changing the max intensity of the LED from low to high

this would allow a new pot value to take effect immediately. Or you can measure the pot before calling changeValues() and using that value until changeValues() completes

changeValues() only updates every LED at once the where the pot value is currently at rather than adding any kind of gradual effect. So the while loop inside the main loop only starts when it sees a small change in pot value. it will then loop only for these conditions. (time < 100ms AND potValue - prevpotValue > 5). So only if the pot is changing and time is under 100ms. at least thats the idea

why? to delay calls to the rest of the code while the pot is being changed?

the visual effect might be more noticiable if each LED is gradually increased in intensity determined by the pot before doing same for the next LED

so one LED turns on at a time

Well to answer your question why. Its because I figure if it goes straight to the "Wave" function, the value will be too small to see any kind of effect. Maybe wrong idk I'll try without that. But as to your suggestion about how to do the effect. I don't necessarily disagree. I was already thinking about trying that

But even still. Why is up working but down is not?

I gotta start learning arrays so I should easily be able to do that effect with a nested for loop right

This was a mistake. I meant updateValues() does this ^

Not you, it is weak point for reasons.

It seems they could do better. For indicators they are fine, but for any LED effects or colours you'll be better off testing IRL.

They don't even go full on to full off in any convincing way.

a7

1 Like

Hello forum members

Here is the unpacked sketch by user mattyp77

// DEFINE ALL PINS TO COMPONENTS
// LED PINS + BRIGHTNESSES
const int LED_YELLOW_PIN = 5; int YELLOW_BRIGHTNESS = 0;
const int LED_BLUE_PIN = 6; int BLUE_BRIGHTNESS = 0;
const int LED_GREEN_PIN = 9; int GREEN_BRIGHTNESS = 0;
const int LED_RED_PIN = 10; int RED_BRIGHTNESS = 0;
// POT_PIN
#define potValue analogRead(POT_PIN)
const int POT_PIN = A0;  
// LED brightness
int POT_INPUT_VALUE = 0;
int POT_INPUT_PREV_VALUE = 0;
int LED_BRIGHTNESS = 0;     
int time = 0;
void setup() {
  // ESTABLISH PIN MODES 
  pinMode(LED_YELLOW_PIN, OUTPUT);
  pinMode(LED_BLUE_PIN, OUTPUT);   
  pinMode(LED_GREEN_PIN, OUTPUT);  
  pinMode(LED_RED_PIN, OUTPUT);  
  // CREATE TIME-STAMP
  time = millis();
  // READ POTENTIOMETER. MAP IT TO PMW VALUE AND SAVE TO VARIABLE 
  POT_INPUT_VALUE = potValue;
  POT_INPUT_PREV_VALUE = potValue;
  // ENABLE SERIAL MONITOR FOR DEBUGGING
  Serial.begin(9600);         
}
// ------ PRINT VALUES TO SCREEN --------
void displayValues() {
  Serial.print("Sensor: ");
  Serial.println(POT_INPUT_VALUE);
  Serial.print("PWM Output: ");
  Serial.println(LED_BRIGHTNESS);
}
// -------- OUTPUT TO LED'S --------
void outputLED() {
  analogWrite(LED_YELLOW_PIN, YELLOW_BRIGHTNESS);
  analogWrite(LED_RED_PIN, RED_BRIGHTNESS);
  analogWrite(LED_GREEN_PIN, GREEN_BRIGHTNESS);
  analogWrite(LED_BLUE_PIN, BLUE_BRIGHTNESS);
}
// -------- UPDATE EACH INDIVIDUAL LED'S BRIGHTNESS BASED ON THE POT WHILE MAKING WAVE PATTERN --------
void updateValues() {
  LED_BRIGHTNESS = map(POT_INPUT_VALUE, 0, 1023, 0, 255);
  YELLOW_BRIGHTNESS = LED_BRIGHTNESS;
  RED_BRIGHTNESS = LED_BRIGHTNESS;
  GREEN_BRIGHTNESS = LED_BRIGHTNESS;
  BLUE_BRIGHTNESS = LED_BRIGHTNESS;
}
//  ------------------- POT VALUE HAS CHANGED. UPDATE LED'S GRADUALLY IN WAVY PATTERN ----------------
  void changingValues() {
    // LED'S GRADUATE UP
    if (potValue > POT_INPUT_PREV_VALUE){
      Serial.println("ADJUST +");                                                               // DEBUGGING
      // STARTING WITH THE RED LED, GRADUALLY ADJUST EACH LED BRIGTHNESS IN A WAVE-LIKE PATTERN (LEFT TO RIGHT)
      for(int i = LED_BRIGHTNESS; i <= map(potValue, 0, 1023, 0, 255); i+= 6){
        Serial.print("PWM: ");                                                              // DEBUGGING
        Serial.println(i);                                                                  // DEBUGGING
        delay(50);
        analogWrite(LED_RED_PIN, i);
        delay(50);
        analogWrite(LED_GREEN_PIN, i);
        delay(50);
        analogWrite(LED_BLUE_PIN, i);
        delay(50);
        analogWrite(LED_YELLOW_PIN, i);
        delay(50);
      }
    }
    else if (potValue < POT_INPUT_PREV_VALUE){
      Serial.println("ADJUST -");                                                                     // DEBUGGING
      // STARTING WITH THE YELLOW LED, GRADUALLY ADJUST EACH LED BRIGTHNESS IN A WAVE-LIKE PATTERN (RIGHT TO LEFT)
      for(int i = LED_BRIGHTNESS; i >= map(potValue, 0, 1023, 0, 255); i-= 6){
        Serial.print("PWM: ");                                                                    // DEBUGGING
        Serial.println(i);                                                                        // DEBUGGING
        delay(50);
        analogWrite(LED_YELLOW_PIN, i);
        delay(50);
        analogWrite(LED_BLUE_PIN, i);
        delay(50);
        analogWrite(LED_GREEN_PIN, i);
        delay(50);
        analogWrite(LED_RED_PIN, i);
        delay(50);
      }
    }
    Serial.println("--function end--");                                            // DEBUGGING
    LED_BRIGHTNESS = map(potValue, 0, 1023, 0, 255);
    outputLED();
  }
// ===================================================================================================
// =======================================  MAIN LOOP  ===============================================
void loop() {
  time = millis();                                                // TIME STAMP FOR ALLOWING USER ADJUSTMENT TIME
  delay(10);
  // CHECK FOR POT CHANGES WITHIN TIME LIMIT TO ALLOW USER TIME TO ADJUST FURTHER
  while(abs(potValue - POT_INPUT_VALUE) > 5 && millis() - time < 100){
    Serial.print("---- Start Loop Time: ");                                           // DEBUGGING
    Serial.println(millis());
    Serial.print("Current Value: ");
    Serial.println(potValue);
    Serial.print("Prev Value ");
    Serial.println(POT_INPUT_VALUE);
  }
  Serial.println("--OUT--- ");                                        // DEBUGGING
  Serial.print("Time: ");                                             // DEBUGGING
  Serial.println(millis());                                           // DEBUGGING
  // IF VALUE DIFFERENCE IS LARGE ENOUGH GO TO changingValues()
  if(abs(potValue - POT_INPUT_VALUE) > 12){
    // POT_INPUT_VALUE = potValue;                                   // UPDATE POT INPUT VARIABLE
    changingValues();                                                // CALL FUNCTION THAT GRADUATES LED CHANGING IN WAVY PATTERN
  }
  // UPDATE POT VALUE
  POT_INPUT_VALUE = potValue;                                        // UPDATE POT INPUT VARIABLE
  //displayValues();                                                  // DEBUGGING
  updateValues();
  outputLED();
}

i see both ADJUST + and ADJUST - and only when there's a pot change.

guessing you're not seeing the effect you want

looks like the code is intended to gradually change the LED brightness from the previous setting to the current and changing pot level ... but only when the code in loop() sees a change in the pot level

i don't see much of a change in brightness except near the end of the PWM level

    238,    238      0
    259,    238     21
 loop: delta > 12
changingValues
ADJUST +
PWM: 59
--function end--
    259,    259      0
    259,    259      0
    259,    259      0
    259,    259      0
    259,    259      0
    259,    259      0
    235,    259    -23
 loop: delta > 12
changingValues
ADJUST -
PWM: 64
PWM: 58
--function end--

So I've improved on it a lot. There definitely were some redundancies that I removed and it's working pretty well now. It is still a little buggy at times. I think part of it might be this cheap pot I'm using. In fact I've read up that its not even really considered a pot but rather a permanent solder in trimmer.

// DEFINE ALL PINS TO COMPONENTS
// LED PINS + BRIGHTNESSES
const int LED_YELLOW_PIN = 5; int YELLOW_BRIGHTNESS = 0;
const int LED_BLUE_PIN = 6; int BLUE_BRIGHTNESS = 0;
const int LED_GREEN_PIN = 9; int GREEN_BRIGHTNESS = 0;
const int LED_RED_PIN = 10; int RED_BRIGHTNESS = 0;
// POT_PIN
#define potValue analogRead(POT_PIN)                // ABSOLUTE CURRENT POT VALUE READ
const int POT_PIN = A0;  
// LED brightnes
#define mappedPot map(potValue, 0, 1023, 0, 255)    // DEFINE LED BRIGHTNESS BASED ON ABSOLUTE CURRENT POT VALUE
int POT_INPUT_VALUE = 0;
int POT_INPUT_PREV_VALUE = 0;
int LED_BRIGHTNESS = 0;     
int time = 0;
 
void setup() {
  // ESTABLISH PIN MODES 
  pinMode(LED_YELLOW_PIN, OUTPUT);
  pinMode(LED_BLUE_PIN, OUTPUT);   
  pinMode(LED_GREEN_PIN, OUTPUT);  
  pinMode(LED_RED_PIN, OUTPUT);  
  // CREATE TIME-STAMP
  time = millis();
  // READ POTENTIOMETER. MAP IT TO PMW VALUE AND SAVE TO VARIABLE 
  POT_INPUT_VALUE = potValue;
  POT_INPUT_PREV_VALUE = potValue;
  // ENABLE SERIAL MONITOR FOR DEBUGGING
  Serial.begin(9600);         
}

// ------ PRINT VALUES TO SCREEN --------
void displayValues() {
  Serial.print("Sensor: ");
  Serial.println(POT_INPUT_VALUE);
  Serial.print("PWM Output: ");
  Serial.println(LED_BRIGHTNESS);
}

// -------- OUTPUT TO LED'S --------
void outputLED() {
  analogWrite(LED_YELLOW_PIN, LED_BRIGHTNESS);
  analogWrite(LED_RED_PIN, LED_BRIGHTNESS);
  analogWrite(LED_GREEN_PIN, LED_BRIGHTNESS);
  analogWrite(LED_BLUE_PIN, LED_BRIGHTNESS);
}

//  ------------------- POT VALUE HAS CHANGED. UPDATE LED'S GRADUALLY ONE BY ONE ----------------
  void gradualChange() {
    // LED'S GRADUATE UP
    if (potValue > POT_INPUT_PREV_VALUE){
      Serial.println("ADJUST +");  

      // FOR LOOP 1 - 4 (LEFT TO RIGHT) LED BRIGHTNESS GRADUALLY INCREASES
      for (int L = 0; L <= 3; L++){
        for(int B = LED_BRIGHTNESS; B <= mappedPot; B+=8){
          if (L == 0){                                    //  : OUTPUTS RED LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_RED_PIN, B);
          }
          else if (L == 1){                               // 1 : OUTPUTS GREEN LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_GREEN_PIN, B);
          }
          else if (L == 2){                               // 2 : OUTPUTS BLUE LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_BLUE_PIN, B);
          }
          else if (L == 3){                               // 3 : OUTPUTS YELLOW LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_YELLOW_PIN, B);
          }
          Serial.println(B);                              // DEBUGGING
          delay(10);
        }
      }
      // ======================================== OLD CODE ===============================================
      // STARTING WITH THE RED LED, GRADUALLY ADJUST EACH LED BRIGTHNESS IN A WAVE-LIKE PATTERN (LEFT TO RIGHT)
      // for(int i = LED_BRIGHTNESS; i <= mappedPot; i+= 6){
      //   // Serial.print("PWM: ");                                                              // DEBUGGING
      //   // Serial.println(i);                                                                  // DEBUGGING
      //   delay(20);
      //   analogWrite(LED_RED_PIN, i);
      //   delay(20);
      //   analogWrite(LED_GREEN_PIN, i);
      //   delay(20);
      //   analogWrite(LED_BLUE_PIN, i);
      //   delay(20);
      //   analogWrite(LED_YELLOW_PIN, i);
      //   delay(20);
      // }
    }

    else{ // if (potValue < POT_INPUT_PREV_VALUE){
      Serial.println("ADJUST -"); 

      // FOR LOOP 3 - 0 (RIGHT TO LEFT) LED BRIGHTNESS GRADUALLY DECREASES
      for (int L = 3; L >= 0; L--){
        for(int B = LED_BRIGHTNESS; B >= mappedPot; B--){
          if (L == 0){                                    //  : OUTPUTS RED LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_RED_PIN, B);
          }
          else if (L == 1){                              // 1 : OUTPUTS GREEN LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_GREEN_PIN, B);
          }
          else if (L == 2){                              // 2 : OUTPUTS BLUE LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_BLUE_PIN, B);
          }
          else if (L == 3){                              // 3 : OUTPUTS YELLOW LED ONLY TO CURRENT BRIGHTNESS VALUE
            analogWrite(LED_YELLOW_PIN, B);
          }
          Serial.println(B);                             // DEBUGGING
          delay(10);
        }
      }
      // ======================================== OLD CODE ===============================================
      // STARTING WITH THE YELLOW LED, GRADUALLY ADJUST EACH LED BRIGTHNESS IN A WAVE-LIKE PATTERN (RIGHT TO LEFT)
      // for(int i = LED_BRIGHTNESS; i >= mappedPot; i-= 6){
      //   Serial.print("PWM: ");                                                                    // DEBUGGING
      //   Serial.println(i);                                                                        // DEBUGGING
      //   delay(20);
      //   analogWrite(LED_YELLOW_PIN, i);
      //   delay(20);
      //   analogWrite(LED_BLUE_PIN, i);
      //   delay(20);
      //   analogWrite(LED_GREEN_PIN, i);
      //   delay(20);
      //   analogWrite(LED_RED_PIN, i);
      //   delay(20);
      // }
    }

    Serial.println("--function end--");                                            // DEBUGGING
    LED_BRIGHTNESS = mappedPot;
  }
 
// ===================================================================================================
// =======================================  MAIN LOOP  ===============================================

void loop() {
  time = millis();                                                // TIME STAMP FOR ALLOWING USER ADJUSTMENT TIME

  // CHECK FOR POT CHANGES WITHIN TIME LIMIT TO ALLOW USER TIME TO ADJUST FURTHER
  while(abs(potValue - POT_INPUT_VALUE) > 5 && millis() - time < 100){
    Serial.print("---- Start Loop Time: ");                                           // DEBUGGING
    Serial.println(millis());
    Serial.print("Current Value: ");
    Serial.println(potValue);
    Serial.print("Prev Value ");
    Serial.println(POT_INPUT_VALUE);
  }
  Serial.println("--OUT--- ");                                        // DEBUGGING
  Serial.print("Time: ");                                             // DEBUGGING
  Serial.println(millis());                                           // DEBUGGING


  // IF VALUE DIFFERENCE IS LARGE ENOUGH GO TO changingValues()
  if(abs(potValue - POT_INPUT_VALUE) > 12){
    gradualChange();                                                // CALL FUNCTION THAT GRADUATES LED CHANGING IN WAVY PATTERN
  }

  // UPDATE POT VALUE
  POT_INPUT_VALUE = potValue;                                        // UPDATE POT INPUT VARIABLE

  //displayValues();                                                  // DEBUGGING
  LED_BRIGHTNESS = mappedPot;           // UPDATE LED BRIGHTNESS VALUES TO CURRENT POT VALUE
  outputLED();
}

Hi, @mattyp77

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Knowing how your hardware is connected will help.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia: