I'm trying to find a circuit that can manually adjust the color of a RGB led strip with one potentiometer. Ideally it would be a dual potentiometer to control brightness as well as color. But not necessary. I understand I may need a microcontroller to do this, but I am too much of a novice to figure it out on my own.

  • 5
    \$\begingroup\$ You want the color to change through some arbitrary series of colors as you rotate the pot? You will almost definitely want to use programmable logic. A microcontroller is by far the easiest. As stated, this question is too broad to answer. \$\endgroup\$ – Dan Laks Jun 10 '16 at 0:53
  • \$\begingroup\$ Voting to reopen just so I can bounty this answer! \$\endgroup\$ – Passerby Jun 10 '16 at 19:00
  • \$\begingroup\$ When you say 'dual' do you mean two separate pots, one for brightness and one for color? \$\endgroup\$ – Bruce Abbott Jun 10 '16 at 21:29
  • \$\begingroup\$ The strip has 3 anode/3 kathode connections or just 1 anode or kathode connection and three of the other type? \$\endgroup\$ – le_top Jun 13 '16 at 10:10
  • \$\begingroup\$ While the PREMISE for this question ("SINGLE pot") is fatally flawed (or inadequately explained), nevertheless, the answers are an excellent exposition of the design considerations. \$\endgroup\$ – Richard Crowley Jun 13 '16 at 18:32

enter image description here

Figure 1. RGB mixing control signals.

To do what you require you will need to crossfade between red, green and blue.

  • At zero potentiometer setting red is fully on. Green and blue are off.
  • As you adjust the potentiometer over the first 1/6th the green fades up to 100%.
  • On the next 1/6th the red fades out until you only have green.
  • The pattern repeats for green to blue transition and finally for blue to red ending at the start point of full red.

Note that you can't get white light with this setup as you would require all lights on.

This would be a little complex to do with an analog circuit but easy enough with a micro. Assuming the micro analog in read or encoder counting from 0 to 100 and the analog outputs put out 0 to 100 the code would look something similar to the pseudo-code below

// RGB LED cross-fade control pseudo-code.
// Note 1/6th of 100 = 16.666.
if(Ain <= 16.6){                     // 0 to 60°
  R = 100;                           // Red on.
  G = Ain * 6;                       // Green fading up.
  B = 0;                             // Blue off.
if((Ain > 16.6) && (Ain <= 33.3){    // 60° to 120°
  R = 100 - (Ain - 16.6) * 6;        // Red fading down.
  G = 100;                           // Green on.
  B = 0;                             // Blue off.
if((Ain > 33.3) && (Ain <= 50){      // 120° to 180°
  R = 0;                             // Red off.
  G = 100;                           // Green on.
  B = (Ain - 33.3) * 6;              // Blue fading up.
if((Ain > 50) && (Ain <= 62.3){      // 180° to 240°
  R = 0;                             // Red off.
  G = 100 - (Ain - 50) * 6;          // Green fading down.
  B = 100;                           // Blue on.
if((Ain > 66.6) && (Ain <= 83.3){    // 240° to 300°
  R = (Ain - 66.6) * 6;              // Red fading up.
  G = 0;                             // Green off.
  B = 100;                           // Blue on.
if((Ain > 83.3) && (Ain <= 100){     // 300° to 360°
  R = 100;                           // Red on.
  G = 0;                             // Green off.
  B = 100 - (Ain - 86.6) * 6;        // Red fading down.

Ideally it would be a dual potentiometer to control brightness as well as color.

If you mean a 2-gang potentiometer (both on the same shaft) then you have a problem. If the brightness changes from min to max as you rotate the pot then you will have lamps off at the zero end and fully on at the 100% end getting brighter as you sweep through the spectrum. In our example above you would never have bright yellow.

Very simplified schematic


simulate this circuit – Schematic created using CircuitLab

Figure 2. A simplified schematic diagram of a micro controller for this system.

Improve your question and we can add more details to the answer.

Using a rotary encoder rather than a potentiometer

There are two problems with the potentiometer approach:

  • There are end-stops so when you reach the end of travel you can only go in reverse through the sequence you have just done.
  • It doesn't solve the brightness part of your question.

A good solution would be to use a rotary encoder with push switch.

enter image description here

Figure 3. A simple mechanical rotary encoder with push-to-make switch.

These work as a "quadrature encoder" giving out to pulse trains (as you rotate the knob) which are 90° out of phase. (90° = quarter of a turn, hence quadrature.)


simulate this circuit

Figure 4. 2-bit rotary encoder waveforms.

The program logic is very simple.

  • Track the current state of 'A'. If the state changes to 'high' then:
  • Look at input 'B'. If 'B' is low then count up. If 'B' is high then count down.
  • Add in some logic to roll the counter over as follows:

Pseudo code:

if (count > 100) count = 0;
if (count < 0) count = 100;  // or your value for maximum count.
// Choose a maximum count value to give the resolution / speed 
// you require on the encoder. If it's an even multiple of 6 all
// your code compares become integers and avoid the 16.667 multiples
// in the earlier pseudo-code. 

The encoder has a third contact that makes when the button is pressed. With this you can now do much more sophisticated control. E.g., rotating knob un-pressed changes colour as discussed above. Rotating knob while pressed changes brightness.


simulate this circuit

Figure 5. Encoder version schematic. Note that the micro's internal pull-up resistors would have to be enabled and some debounce logic required in the code to prevent spurious counts due to contact bounce.

enter image description here

Figure 6. Innards of the rotary encoder portion of an encoder / pushbutton. Source: an interesting disassembly article on Efton.sk.

Note the clever arrangement of the contacts in Figure 6. The rotor has three connected contacts 120° apart. One is always in contact with the common strip at the bottom of the photo. The other two will contact the "teeth" on the 'A' and 'B' segments in quadrature. Note the slightly wider black gap in the 12 o'clock position which offsets the patterns by the required 1/4 of a step.

Even brightness control

You don't need the plateaus particularly if you want an even brightness (100% red + 100% green will be bright compared to red and green separately). @IanBland.

enter image description here

Figure 7. Alternative cross-fade strategy for even brightness. Code would have to be modified to suit.

  • \$\begingroup\$ Nitpick: Your control signals diagram is not quite accurate. For example, you show no red in the violet. \$\endgroup\$ – dim Jun 10 '16 at 7:29
  • \$\begingroup\$ Good point. I went for a simple strategy rather than the full colour wheel and I've failed to include 120° of the wheel between red and blue. I'll stretch that spectrum so it runs blue to red and I'll do another with the full wheel. (Later.) Thanks. \$\endgroup\$ – Transistor Jun 10 '16 at 7:57
  • \$\begingroup\$ Magnificient diagram! +1 \$\endgroup\$ – dim Jun 10 '16 at 18:56
  • \$\begingroup\$ Voting to reopen just so I can bounty this answer! \$\endgroup\$ – Passerby Jun 10 '16 at 19:00
  • 2
    \$\begingroup\$ "_ I understand I may need a microcontroller to do this, but I am too much of a novice to figure it out on my own._" I figured it out for him with options and in colour! I agree that analog takes more head scratching and I started to doodle but realised that it got complicated very quickly and even when the voltages were sorted out you still have to generate the PWM. With a micro the hardware is ridiculously simple. I'd say there's enough in this project to keep the OP going for quite a while. Go on, throw me a vote! ;^) \$\endgroup\$ – Transistor Jun 10 '16 at 23:22

While I agree in every sentence of transistor's answer, and consider it the best answer you could make (and I couldn't upvote it enough), the comment "I agree that analog takes more head scratching and I started to doodle but realised that it got complicated very quickly ..." sounded like a challenge.

So here we go. Requiring only a quad-opamp chip and some passives ! Runs from a 7-32V supply (well, I think - maybe a few resistors needs to be adjusted). All three leds are driven with a current that looks like the "Alternative cross-fade strategy for even brightness" curve above (love those diagrams, really).

Well, I wouldn't explain in details how it works (I just give a few hints at the end), because I mostly used the "make up some values, simulate, adjust, simulate, add a diode, simulate, drink a beer, simulate, start again from scratch..." strategy, and didn't write a single formula, so I can't justify everything that is here (and it can certainly be improved). Morover, I totally agree with what has been said: this is not the way it should be done; using a MCU gives a lot more flexibility, accuracy, efficiency, and will make a smaller design.

But it's fun.

Here is the circuit:


simulate this circuit – Schematic created using CircuitLab

Here are the current curves (well, upside down), depending on the pot position (current has been set to 15mA per led, it can be adjusted by changing R5/R10/R24, but R5 and R10 must have the same value, or you'll need to change the ratio between R16/R17 as well):

current curves

A few hints on how it works, though.

  • The main difficulty has been to build the block with the OA1 opamp. But what it does is actually simple: it outputs a voltage that is the minimum between the input X and 2/3 * VCC - X. That directly gives the red LED current curve. Note that the feedback is not taken directly on the opamp output, but rather on a resistor put on the way of the current led flow to ground, so that the opamp drives current, not voltage (forget about the BAT54 put after that resistor, it is just here to fix some shifts due to the other diodes voltage drops).
  • for the green curve, we do the same thing, but we subtract 1/3 * VCC from the input voltage first (with OA4).
  • now, the blue curve is made from computing 1/3 * VCC - Vred - Vgreen (with OA5)

Neat, huh ?

Of course, for a whole led strip, the voltage will certainly need to be a lot higher, and power consumption will start to be a problem. But this circuit could be used to drive higher power current sources with better efficiency (unfortunately, OP did not give enough information to build this part - well, this question had been originally closed for a reason).

  • 1
    \$\begingroup\$ This is why I love EE StackExchange! \$\endgroup\$ – bigjosh Jun 15 '16 at 3:19
  • \$\begingroup\$ "sounded like a challenge" - That's what I thought too. Your attempt is much more efficient with opamp usage than the one I've been working on. Really cool! \$\endgroup\$ – bhillam Jun 20 '16 at 3:33
  • \$\begingroup\$ @bhillam that was my target: no more than 4 or I don't post. \$\endgroup\$ – dim Jun 20 '16 at 5:05

The analog solution

I earlier proposed a digital solution to this problem with some pseudo-code. It's elegant in that it only requires a pot and a micro with analog in and PWM out. @dim worked out an analog version which simulated for him but by his own admission he is doing some funky stuff with the diodes and it's a bit tricky to figure out what's going on. @IanBland's "A microcontroller is a thorougly boring way to do it" left me concerned for Ian's boredom.

Further analysis of the problem led me to conclude that if I was able to generate the modified pot curves shown in Figure 1b that I could sum them to generate the control curves of Figure 1c.

enter image description here

Figure 1. (a) The full spectrum and the RGB intensities required. (b) Three basic modified potentiometer curves required. (c) The PWM control curves.

A web search for opamp min-max circuits led me to a fascinating AD8036 Voltage Feedback Clamp Amp from Analog Devices. This device, when used in non-inverting mode can clamp the input voltage between an upper and lower limit.

enter image description here

Figure 2. Clamp-amp block diagram. (See page 16 of the datasheet.) \$ +V_{IN} \$ is applied to A1's non-inverting input until \$ +V_{IN} > V_H \$ at which point S1 applies \$ V_H \$ to A1. Similarly when \$ +V_{IN} < V_L \$ S1 applies \$ V_L \$ to A1.

There are a few limitations to the device - particularly the supply voltages and 6.3 V max \$ \Delta \$V between \$V_H\$ and \$V_L\$ - but we can work around those.


simulate this circuit – Schematic created using CircuitLab

Figure 3. (Almost) complete control curve generator circuit. Missing components are decoupling capacitors for all chips and the AD8036 \$V_H\$ and \$V_L\$ pins.

How it works.

  • R1 generates a 0 to 6 V signal depending on pot position. This is buffered by OA1. Note that OA1 needs a V++ > 6 V + headroom. +9 V is probably the minimum here. OA2, 3 and 4 are shown powered from +5 V but can be powered from the same V+ as OA1.
  • U1 is wired as a unity gain non-inverting summing amplifier. The 0 - 6 V signal from the pot will be averaged by R3 and 4 to give a 0 - 3 V signal into the non-inverting amplifier. With \$ V_H = 1V\$ and \$ V_L = 0 V \$ the output will increase from 0 to 1 V between 0 and 120° of the pot rotation.
  • U2 is similarly wired but with a -2 V bias on the input giving a -1 to +2 V input over the pot span. At 120° the output voltage will start to rise above 0 V and will be clamped at 1 V at 240°.
  • U3, with a -4 V bias, will rise from 0 to 1 V between 240° and 360° on the pot.
  • OA2, 3 and 4 sum the A, B and C signals to give the D, E and F curves specified in Figure 1c.


All that remains is to generate the PWM signals. The LTC6992-1 (which shows up in many of Andy Aka's posts) is ideal for this.

enter image description here

Figure 4. LTC6992-1 pinout and waveforms.

As can be seen, the configuration is simplicity itself. The choice of 0 to 1 V control in Figures 1 and 3 was determined by the MOD input of this chip. One chip is required for each of the red, green and blue channels.


R7 and R10 are loading the potential divider circuit which probably should be buffered for the -2 and -4 V.

I haven't built or tested this circuit. I only did the exercise for the design challenge and present it here as it may be of interest to others - in particular the clamp-amp chips.

  • \$\begingroup\$ Seriously, you're killing me... All right, +1. I want to clarify something, though: my design wasn't totally obtained by chance, and it should work for anyone, not just my simulator. \$\endgroup\$ – dim Jun 26 '16 at 19:47
  • \$\begingroup\$ Sorry, dim! What I wrote doesn't say what I intended. I'll fix that. I enjoyed the challenge as much as you did, I suspect. Thanks for egging me on. \$\endgroup\$ – Transistor Jun 26 '16 at 20:06
  • \$\begingroup\$ Of course I enjoyed it too. And don't feel obligated to fix anything in your post, it was probably just my ego talking... \$\endgroup\$ – dim Jun 26 '16 at 20:09

We are having a fundamental disconnect when you say that you want to control TWO INDEPENDENT variables (color hue and brightness) "with one potentiometer." Does that mean that red will never show because it correlates with zero brightness? A clarification would go a long ways toward helping us understand the question.

Suggestions for dual-concentric pots (which are actually TWO pots and two knobs with concentric shafts may or may not meet your requirement for "one potentiometer." And suggestions for rotary shaft encoders (with a push function) could be use to shift the action of the pot between color hue and brightness.

Another possibility would be a joy-stick which has two axes (X and Y) that could be mapped to color and brightness.

  • \$\begingroup\$ I think everyone is hung up on the dual pot thing. It can easily be solved by using a pot with a switch or pushbutton, or using an external button or switch to change the mode the pot controls. \$\endgroup\$ – Passerby Jun 13 '16 at 18:06
  • 1
    \$\begingroup\$ Using a traditional (position-dependent) pot for a "switchable" function (color hue vs. brightness) doesn't work very well as there is no way to "normalize" the control value when switching between functions. That is why a rotary encoder is typically used. So that it can "start" at whatever the current value is, and allow the user to adjust up or down as desired without worrying about hitting the physical end-stop before reaching the logical end of the range. \$\endgroup\$ – Richard Crowley Jun 13 '16 at 18:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.