# Color temperature

**URL:** <https://forum.arduino.cc/t/color-temperature/1297136>\
**Category:** Sensors\
**Created:** [August 31, 2024, 2:13pm UTC](https://forum.arduino.cc/t/color-temperature/1297136 "2024-08-31T14:13:01Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![janvol2](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol2/32/1099001_2.png) [@janvol2](https://forum.arduino.cc/u/janvol2)\
**Post date:** [August 31, 2024, 2:13pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/1 "2024-08-31T14:13:01Z")

</div>

Does anyone have experience with retreiving or deducing cct from the rgb sensor from the nano ble sense?  
or have an idea on how best to approach this?

thanks, Jan

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [August 31, 2024, 2:36pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/2 "2024-08-31T14:36:45Z")

</div>

What have you tried? How do you plan to calibrate the sensor?

There is lots of useful and easily found information on the web, for example [Map Colors of a CIE Plot and Color Temperature Using an RGB Color Sensor | Analog Devices](https://www.analog.com/en/resources/technical-articles/map-colors-of-a-cie-plot-and-color-temperature-using-an-rgb-color-sensor.html)

---

<div class="post-metadata">

**Author:** ![janvol2](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol2/32/1099001_2.png) [@janvol2](https://forum.arduino.cc/u/janvol2)\
**Post date:** [August 31, 2024, 3:19pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/3 "2024-08-31T15:19:37Z")

</div>

It is more about differenences than about actual values, so calibration is not that important, as long as a deviation is fairly constant over the range.  
I am hoping there is already some code available somewhere..

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [August 31, 2024, 3:24pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/4 "2024-08-31T15:24:29Z")

</div>

The sensor returns values for R, B and G, and it is trivial to compute differences from two sets of measurements.

To get started, look for example code to read the sensor.

---

<div class="post-metadata">

**Author:** ![janvol2](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol2/32/1099001_2.png) [@janvol2](https://forum.arduino.cc/u/janvol2)\
**Post date:** [September 1, 2024, 8:19am UTC](https://forum.arduino.cc/t/color-temperature/1297136/5 "2024-09-01T08:19:05Z")

</div>

Ok, I will start with that, tnx.

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 10, 2024, 8:21pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/6 "2024-10-10T20:21:33Z")

</div>

I did that and noticed that r, g, b, and c have maximum values of 4097, when defined as int.  
In the library I do not see any min or max values for the output. From the datasheet of the  
APDS-9960 I get the impression that the output per channel is 2 byte (65535).  
Does anyone know if I can read higher values than 4097 and if so, how?

btw I had some problems logging in, but I am janvol2

---

<div class="post-metadata">

**Author:** ![rsmls](https://avatars.discourse-cdn.com/v4/letter/r/5daacb/32.png) [@rsmls](https://forum.arduino.cc/u/rsmls)\
**Post date:** [October 10, 2024, 9:51pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/7 "2024-10-10T21:51:29Z")

</div>

> [@janvol](#):
>
> r, g, b, and c have maximum values of 4097

> [@janvol](#):
>
> the output per channel is 2 byte (65535)

The ambiguity may be down to which settings are used on the sensor. IDK what library you use and what defaults it in turn uses; you'd have to look into this. See the datasheet, page 20, bottom table. As you can see, the integration time affects the full scale range, according to the formula: CountMAX = 1025 x CYCLES

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 11, 2024, 12:57pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/8 "2024-10-11T12:57:09Z")

</div>

The library is Arduino\_APDS9960.h  
The code I use is from the library examples: ColorSensor.ino  
the board is Arduino nano 33 BLE sense

I do not see anything I can influence the CYCLES with.  
Do I miss something?

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [October 11, 2024, 3:38pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/9 "2024-10-11T15:38:29Z")

</div>

> [@janvol](#):
>
> Does anyone know if I can read higher values than 4097 and if so, how?

Why should that matter?

If you can read R, G, B values from the sensor, you can estimate the color temperature by fitting them to the color temperature curve.

[This possibly useful example](https://andi-siess.de/rgb-to-color-temperature/) uses a Python program to fit 8-bit RGB values and modify an image to illustrate the effect.

---

<div class="post-metadata">

**Author:** ![rsmls](https://avatars.discourse-cdn.com/v4/letter/r/5daacb/32.png) [@rsmls](https://forum.arduino.cc/u/rsmls)\
**Post date:** [October 11, 2024, 4:59pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/10 "2024-10-11T16:59:54Z")

</div>

> [@janvol](#):
>
> Do I miss something?

> <https://github.com/arduino-libraries/Arduino_APDS9960/blob/master/src/Arduino_APDS9960.cpp>

Lines 59-60:

```arduino
  // set ADC integration time to 10 ms
  if (!setATIME(256 - (10 / 2.78))) return false;

```

It's hard-coded. You could modify this, or create a new function that allows you to set the atime/integration time and call that after begin(). The fact that you're using a library doesn't mean you're limited to what it offers. In this case, the library is limited in its functionality as you can see.

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 11, 2024, 8:29pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/11 "2024-10-11T20:29:37Z")

</div>

Thanks. That's true. But I want also lux values and since outside lux values can differ between 0 and 100.000 it would be nice to have a higher resolution.

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [October 11, 2024, 8:33pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/12 "2024-10-11T20:33:45Z")

</div>

The integration time in the library was probably selected for sunlight illumination, about 100K lux.

For more control over the sensor you need to add options to the library, or choose another.

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 11, 2024, 8:36pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/13 "2024-10-11T20:36:30Z")

</div>

thanks for the example!

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 11, 2024, 8:48pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/14 "2024-10-11T20:48:29Z")

</div>

I see, more or less. But I don't consider myself qualified to change the library as a copy.  
If you could help me, great. if not, I will see how far I get with the existing 4097.

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 17, 2024, 1:54pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/15 "2024-10-17T13:54:43Z")

</div>

Progress is made and I can now measure the Kelvin value of a lightsource.  
I have a question on Ambient light measurement now..:  
I use a light source Dali dt8 controlled, When I swipe from 2700K to 6500K and measure the output in Lux with a standard meter, it stays practically the same of the whole range.  
When I look at the ALS output of the ble sense, it is 35% higher at 6500K than at 2700K.  
What is the explanation for that fact?

---

<div class="post-metadata">

**Author:** ![rsmls](https://avatars.discourse-cdn.com/v4/letter/r/5daacb/32.png) [@rsmls](https://forum.arduino.cc/u/rsmls)\
**Post date:** [October 17, 2024, 3:48pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/16 "2024-10-17T15:48:51Z")

</div>

> [@janvol](#):
>
> What is the explanation for that fact?

Things get complicated, fast.

There's a couple of things that make this tricky.  
First, color temperature is very simply put the blue/red ratio of a light source. This becomes relevant later on.

Second, lux is a measure that's weighted for the sensitivity of the human eye. This means that green light registers high on the lux scale, while the same amount or irradation (in w/m2) in longer (red) or shorter (blue) wavelengths will produce a lower lux value. The weighting is done (AFAIK) according to the human photopic response, which is like this:  
 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/b/9/7/b9743b56f5f9bc6c3af4ce875cdc85ae3666d4de.png)  
Note a high sensitivity for green, which drops off on both sides. The explanation is in the sensitivity of our rods & cones, and likely is not the clean bell curve shown above, but this is what we end up using in practice.

Third, a color sensor like the AMS etc. also has its own, unique spectral sensitivity. Here it is for the sensor you're using:  
 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/a/7/3/a73e8e8f2c7e7d9802ab5ad008330bef1f716970.png)  
From here: [https://cdn.sparkfun.com/assets/learn\_tutorials/3/2/1/Avago-APDS-9960-datasheet.pdf](https://cdn.sparkfun.com/assets/learn_tutorials/3/2/1/Avago-APDS-9960-datasheet.pdf)

Fourth, your controllable light source has again its unique spectral output. I assume this is a LED-based light source, and these basically consist of blue LEDs with a phosphor that converts some of the blue light into longer wavelengths. Warm white LEDs have a lower output of blue, while cool white LEDs have a higher output, like this:  
 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/6/b/a/6ba4e697febea311025e3de3347d6b0ede642d30.jpeg)

Now, if you shift the color balance of the light source, what really happens is that the mixing ratio of cool and warm white LEDs is being changed. Effectively, this increases or decreases the blue peak you see in the image above. After all, changing the height of the blue peak automatically changes the balance between blue and red, and that's what (roughly speaking) defines color temperature.

If you now relate this to the spectral sensitivity of your light sensor as well as the photopic curve (which is relevant for a lux measurement), you'll recognize that, to put it bluntly, it's pretty much a crapshoot what readings you're going to get.

You could calibrate your light sensor (using the code you write and by reading the color channels separately) to the light source you're using so that it more closely matches the readings you get with your lux meter. However, if you use a different light source (e.g. sunlight, which doesn't have the characteristic valley around 500nm/cyan that white LED tends to have), you may find that the readings are different once again. You're essentially running into a variant of metamerism.

Like I said, things can get complicated when it comes to color. I'd suggest to decide how deep you need to dive into this in order to solve the practical problem you're facing; trying to get to the bottom of it will take years of study (and you'll end up with several PhD's only to realize you still haven't figured it all out!) Try not to overshoot the mark; satisfice instead of optimize.

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 21, 2024, 3:28pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/17 "2024-10-21T15:28:24Z")

</div>

Thanks very much.  
I took your exp;lanation and warnings at heart and proceeded making the code to work in practice and it did. Since the judgement is in what you see happening, that is what I used as reference. It worked.

The major difficulty i encounter now is the fact that at low light levels, the 256 bit pwm will not do the job, when mixing colors. I read some things about fast pwm and mbed os, but I do not know how to proceed.  
So far I know how to work with the arduino IDE and how to make use of the language reference guide.  
I don't mind learning, but on what should I best focus for this?

---

<div class="post-metadata">

**Author:** ![anon94801460](https://avatars.discourse-cdn.com/v4/letter/a/278dde/32.png) [@anon94801460](https://forum.arduino.cc/u/anon94801460)\
**Post date:** [October 21, 2024, 3:36pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/18 "2024-10-21T15:36:58Z")

</div>

> [@janvol](#):
>
> 256 bit pwm will not do the job

What is the job, and what is the problem?

---

<div class="post-metadata">

**Author:** ![janvol](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/janvol/32/1099504_2.png) [@janvol](https://forum.arduino.cc/u/janvol)\
**Post date:** [October 21, 2024, 4:37pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/19 "2024-10-21T16:37:17Z")

</div>

sorry, I mean 8bit, of course.. if you have low duty cycles, you can not mix colors properly, be it rgb or cw/ww.

---

<div class="post-metadata">

**Author:** ![rsmls](https://avatars.discourse-cdn.com/v4/letter/r/5daacb/32.png) [@rsmls](https://forum.arduino.cc/u/rsmls)\
**Post date:** [October 21, 2024, 4:55pm UTC](https://forum.arduino.cc/t/color-temperature/1297136/20 "2024-10-21T16:55:03Z")

</div>

> [@janvol](#):
>
> if you have low duty cycles, you can not mix colors properly, be it rgb or cw/ww.

Depends. You'd have to answer this first:

> [@anon94801460](#):
>
> What is the job, and what is the problem?

I.e. for what purpose are you mixing colors, and what's going wrong when doing so, involving low duty cycles? At what point does the problem occur, i.e. below which duty cycle? What phenomenon/problem are you running into when doing so? What PWM frequency are you using and what hardware and sketch are you using to PWM what kind of light source (please provide schematic)?

[Next page](https://forum.arduino.cc/t/color-temperature/1297136.md?page=2)
