Skip to content

Commit

Permalink
optimize (#6)
Browse files Browse the repository at this point in the history
- major improvement **BGR()**
- minor improvement **CMYK()**
- extend timing example.
- update readme.md
- update GitHub actions
- update license 2023
  • Loading branch information
RobTillaart committed Jan 30, 2023
1 parent 3f24835 commit 4409939
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 39 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.1.6] - 2022-11-14
- major improvement **BGR()**
- minor improvement **CMYK()**
- extend timing example.
- update readme.md
- update GitHub actions
- update license 2023


## [0.1.5] - 2022-11-14
- Add RP2040 support to build-CI.
- Add CHANGELOG.md
Expand All @@ -14,7 +23,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- fix bug in **BGR()**
- fix unit test BGR-bug


## [0.1.4] - 2021-12-20
- update library.json
- update license
Expand Down
21 changes: 12 additions & 9 deletions Kelvin2RGB.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
//
// FILE: Kelvin2RGB.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.5
// VERSION: 0.1.6
// DATE: 2018-01-31
// PURPOSE: Arduino library for converting temperature to RGB values
// URL: https://github.com/RobTillaart/Kelvin2RGB
//
// HISTORY: see changelog.md


#include "Kelvin2RGB.h"
Expand Down Expand Up @@ -169,11 +167,11 @@ uint32_t Kelvin2RGB::RGB()
uint16_t Kelvin2RGB::RGB565()
{
uint16_t val = 0;
val = uint8_t(_red * 32);
val = uint8_t(_red * 32);
val <<= 6;
val |= uint8_t(_green * 64);
val <<= 5;
val |= uint8_t(_blue * 32);
val |= uint8_t(_blue * 32);
return val;
}

Expand All @@ -183,18 +181,23 @@ uint32_t Kelvin2RGB::CMYK()
float k = _red;
if (k < _green) k = _green;
if (k < _blue) k = _blue;

float t1 = k;
k = 1 - k;
uint32_t c = 255 * (1 - _red - k) / (1 - k);
uint32_t m = 255 * (1 - _green - k) / (1 - k);
uint32_t y = 255 * (1 - _blue - k) / (1 - k);
float t2 = 255.0 / (1 - k);

uint32_t c = (t1 - _red ) * t2;
uint32_t m = (t1 - _green) * t2;
uint32_t y = (t1 - _blue ) * t2;

return (c << 24) + (m << 16) + (y << 8) + (k * 255);
}


uint32_t Kelvin2RGB::BGR()
{
return round(255 * _blue) * 65536UL + round(255 * _green) * 256UL + round(255 * _red);
return uint8_t(255 * _blue + 0.5) * 65536UL + uint8_t(255 * _green + 0.5) * 256UL + uint8_t(255 * _red + 0.5);
// return round(255 * 65536UL * _blue) + round(255 * 256UL * _green) + round(255 * _red);
}


Expand Down
7 changes: 3 additions & 4 deletions Kelvin2RGB.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
//
// FILE: Kelvin2RGB.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.5
// VERSION: 0.1.6
// DATE: 2018-01-31
// PURPOSE: Arduino library for converting temperature to RGB values
// URL: https://github.com/RobTillaart/Kelvin2RGB
//


#define KELVIN2RGB_LIB_VERSION (F("0.1.5"))
#define KELVIN2RGB_LIB_VERSION (F("0.1.6"))

#include "Arduino.h"

Expand Down Expand Up @@ -97,5 +96,5 @@ class Kelvin2RGB
};


// -- END OF FILE --
// -- END OF FILE --

51 changes: 29 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ Arduino library for converting temperature and brightness to RGB values.

## Credentials

This library is based upon an article of Tanner Helland
and a related story by Neil Bartlett
http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
http://www.zombieprototypes.com/?p=210
https://en.wikipedia.org/wiki/Color_temperature#Categorizing_different_lighting
This library is based upon an article of Tanner Helland and a related story by Neil Bartlett

- http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
- http://www.zombieprototypes.com/?p=210
- https://en.wikipedia.org/wiki/Color_temperature#Categorizing_different_lighting

There are more approximation formulas, some claim to be better,
however these are not investigated. On request these can be added.
Expand All @@ -26,14 +26,14 @@ however these are not investigated. On request these can be added.
## Description

The library converts a temperature in Kelvin and a brightness (0..100%)
to 3 numbers red, green and blue.
to three numbers **red**, **green** and **blue**.
These numbers are weights can be used to correct a colour image for virtual white temperature.

There are 2 convert functions where the **convert_NB()** is claimed to be
There are two convert functions where the **convert_NB()** is claimed to be
the more accurate one.

With the numbers R,G,B calculated one can convert images so they will look
more like taken with candle light, sunrise or sunset etc.
With the numbers **red**, **green** and **blue** calculated one can convert images
so they will look more like taken with candle light, sunrise or sunset etc.


**pseudo code**
Expand All @@ -51,16 +51,20 @@ for each pixel in image
}
```

The numbers can also be used to reduce the blue channel so it has less effect
The numbers can also be used to reduce the blue channel so it has less effect
on "getting sleepy".

The library uses floats for the R,G and B weights to keep values as accurate as possible.
Especially with images with more than 8 bits per channel this is preferred.
That said it is also possible to use this on a 565 image or to adjust color lookup tables.
That said it is also possible to use this on a 565 image or to adjust colour lookup tables.


## Interface

```cpp
#include "Kelvin2RGB.h"
```

The interface is straightforward:

- **Kelvin2RGB()** constructor
Expand All @@ -85,8 +89,7 @@ red, green, blue should be in 0 .. 1.0 range. brightness should be in 0..100%, D
returns a 24 bit RGB value,
- **uint32_t RGB()** returns a 24 bit RGB value, 0 .. 16777215
more efficient than 3 floats for communication.
- **uint16_t RGB565()** returns a 16 bit RGB value,
5 bits for red, 6 for green and 5 for blue.
- **uint16_t RGB565()** returns a 16 bit RGB value, 5 bits for red, 6 for green and 5 for blue.
- **uint32_t BGR()** returns a 24 bit BGR value, 0 .. 16777215
- **uint32_t CMYK()** returns a 32 bit = 4 byte CMYK value,

Expand All @@ -98,21 +101,25 @@ See examples

## Future

#### must
- add examples
- CMYK()
- BGR()
#### Must

#### Should

#### should
- define constants like candleLight as parameter.
- investigate other formulas.
- investigate timing and performance
- investigate usability for RGB led strip.
- investigate **RGB_10_12_10()**

#### could
#### Could

- separate brightness per colour channel to mimic "artificial illumination" (0.2.0 ?)
- remove begin() ?
- example Led-strip()
- add examples
- ledstrip
- CMYK()
- BGR()

#### Wont

- investigate **RGB_10_12_10()**
- nowhere used (not found)

57 changes: 56 additions & 1 deletion examples/Kelvin2RGB_timing/Kelvin2RGB_timing.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ void loop()
void test_timing()
{
Serial.println(__FUNCTION__);
Serial.print("KELVIN2RGB_LIB_VERSION: ");
Serial.println(KELVIN2RGB_LIB_VERSION);
Serial.println();
delay(100);

// volatile to minimize optimization
volatile float bright = 100.0;
Expand Down Expand Up @@ -62,8 +65,60 @@ void test_timing()
Serial.println(duration2 * 0.001);
Serial.print("ratio:\t");
Serial.println(1.0 * duration1 / duration2, 4);
Serial.println();
delay(100);

volatile uint32_t RGB;
start = micros();
for (int i = 0; i < 1000; i++)
{
RGB = KRGB.RGB();
}
stop = micros();
Serial.print("RGB:\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(RGB);
delay(100);

volatile uint32_t CMYK;
start = micros();
for (int i = 0; i < 1000; i++)
{
CMYK = KRGB.CMYK();
}
stop = micros();
Serial.print("CMYK:\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(CMYK);
delay(100);

volatile uint32_t BGR;
start = micros();
for (int i = 0; i < 1000; i++)
{
BGR = KRGB.BGR();
}
stop = micros();
Serial.print("BGR:\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(BGR);
delay(100);

volatile uint16_t RGB565;
start = micros();
for (int i = 0; i < 1000; i++)
{
RGB565 = KRGB.RGB565();
}
stop = micros();
Serial.print("RGB565:\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(RGB565);
}


// -- END OF FILE --

18 changes: 18 additions & 0 deletions examples/Kelvin2RGB_timing/performance_0.1.5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
IDE 1.8.19
UNO

Kelvin2RGB_timing.ino

test_timing
KELVIN2RGB_LIB_VERSION: 0.1.5

TH: 514.05
NB: 557.81
ratio: 0.9216

RGB: 760
CMYK: 936
BGR: 44540
RGB565: 552

done...
19 changes: 19 additions & 0 deletions examples/Kelvin2RGB_timing/performance_0.1.6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
IDE 1.8.19
UNO

Kelvin2RGB_timing.ino

test_timing
KELVIN2RGB_LIB_VERSION: 0.1.6

TH: 514.05
NB: 557.81
ratio: 0.9216

RGB: 760 16775934
CMYK: 888 327680
BGR: 816 16710399
RGB565: 544 2015

done...

2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/Kelvin2RGB.git"
},
"version": "0.1.5",
"version": "0.1.6",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Kelvin2RGB
version=0.1.5
version=0.1.6
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for converting temperature to RGB values
Expand Down

0 comments on commit 4409939

Please sign in to comment.