Using RGB LED's and a potentiometer to control colour based on Kelvin scale

Hi there everyone!

I have just entered the world of arduino and have picked up an arduino uno and a neopixel ring. I have no experience programming and very little with electronics (sorry!). I'm a Product Design Engineer doing my masters project at the moment and need to do a proof of concept for a product I'm designing. I pick things up quickly and am always looking to expand my knowledge.

What I'm trying to do - Basically what I'm looking to do is have an end product where I can control the colour of a neopixel ring with a slider (potentiometer) in the kelvin scale (1000k to 6000K say)

I have basically no coding experience though and just wanted to ask if this code potentially already exists somewhere and I could just use it? I can't imagine this would be very easy to code as the kelvin scale would effectively have to converted to individual RGB values? I know that if I have to code this completely myself I will never get where I need to get and so I'm really just looking for any pointers as to how I would do it? (or if it already exists somewhere)

any help would be greatly appreciated!

Thank you in advance


Well one way to map RGB values to a linear range (1000-6000) would be to make the values into type word 0xRRGGBB or in 565 format and scale it based on the range.

You could probably use the map() function for this like I did here.

void setup()

void loop()
  Serial.println(map(analogRead(A0),0,1023,0x0000,0xFFFF),HEX); // map 0-1023 to 565 color format

This code here does the reverse of what you want, but you could reverse engineer it.

void setup(){
Serial.print(ConvertRGB(255,255,13), HEX);

void loop() {

uint16_t ConvertRGB( byte R, byte G, byte B)
  return ( ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | (B >> 3) );

what you call the "Kelvin scale" is a relationship between the apparent colour spectrum of a light source, compared to the spectrum of a hot black box radiator.

There is no particular reason why you can't simulate that with leds, but it is not simple. You have to deal with the fact that light from led's contains a limited set of wavelengths rather than a complete spectrum.

Thanks for the replies. I'm completely new to coding so don't really understand what the coding you posted does. Does it convert RGB values to hexadecimal values? giving you more range than the 255? I think the 255 options will be suffice for the range I am looking for. When I said I wanted to control the colour from 1000 - 6000 I meant in terms of the Kelvin scale. Essentially I am trying to re-create this:

Accuracy at this stage is not hugely important as I plan to measure the actual wavelength of the light being emitted so I can check whether it is actually producing what it should be. But the ideal would be to basically produce this scale and use a slider to control RGB LED's (a neopixel ring). I know that these LED's will not be perfect, and I have read that red seems to be more dominant, but if I can create this scale, then I can alter it afterwards to make it more accurate. My problem at the moment is that I can't code (and am a total n00b when it comes to arduinos) which means I have no starting point. I plan to work my way through tutorials to get the basics but I feel that this will not particular help me when it comes to recreating the kelvin scale for colour control.

I plan to measure the actual wavelength of the light being emitted so I can check whether it is actually producing what it should be.

The wavelengths of the light you receive will have three peaks at the wavelengths (pretty much fixed) of the three LEDs, which will appear to your eye to be similar to the wavelength of the light that would be emitted by a body at whatever temperature you choose, but the ratios of intensities of those three peaks will vary.

You said you were using a slider, "potentiometer", so to get the value of that pot, you need to use the analogRead() function which returns a range from 0 - 1023. Your RGB LEDs, use 3 sets of bytes, (255, 255, 255) to determine their color. What I gave you use the 565 format, basically RGB(255,255,255) = 565(0xFFFF). Incrementing 0xFFFF is easier than using IF/ELSE statements to increment 255,255,255.

I did try using 0x00FFFFFF, in the map function, but I didn't get the proper results I was looking for.

oh right ok, I'm with you! Sorry bit slow over here obviously. That makes a lot more sense. So rather then having to define the scale in terms of single values for r, g and b I can instead determine it all in one value in hex?

I will look into the map function as it is going way over my head. But basically I can use it to define a starting point and an end point for my scale? Instead of having to say define each increment of the kelvin scale individually?

Sorry for my lack of knowledge (I can imagine how frustrating it must be for you)

And AWOL I understand what you are saying, basically that because it essentially a red, green and blue light mixed at different brightnesses there will always be three separate wavelengths, just with varying peaks. So although to the eye it will look like it is creating different colour temperatures, technically it won't be? If white light is just a mixture of coloured light though at different wavelengths, in terms of photography will this have any impact do you think? Like for example, currently light sources used for photography and film are "daylight balanced" and then you use filters to change the colour temperature. My thinking was that these filters could potentially be made redundant if RGB LED's can be used to recreate the kelvin scale (tested to ensure it is reliable). Sorry if I'm way off here, you don't know if you don't ask/try

Hi guys,

I just spotted this thread... I was wondering if anything had been concluded? I too am looking to change the colour values of some neopixels based on kelvin colour temperature.

I'd love to know if you found anything.


I plan to measure the actual wavelength of the light being emitted

Waste of time. There are three wavelengths, these are fixed. It's merely the comparative brightness of each of these that fools our eyes into thinking it's another wavelength. If you actually attempt to measure it, though, it then becomes apparent that it's not a pure single frequency.