GY-63_MS5611/libraries/map2colour/README.md

289 lines
11 KiB
Markdown
Raw Normal View History

2021-12-04 15:32:57 -05:00
[![Arduino CI](https://github.com/RobTillaart/map2colour/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/map2colour/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/map2colour/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/map2colour/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/map2colour/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/map2colour/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/map2colour.svg?maxAge=3600)](https://github.com/RobTillaart/map2colour/releases)
# map2colour
2023-04-26 03:26:03 -04:00
Arduino library for mapping a float to a colour spectrum.
2021-12-04 15:32:57 -05:00
## Description
2023-04-26 03:26:03 -04:00
The map2colour library is used to map a float value to a colour in the RGB spectrum.
The float value can be the result of a calculation or read from a sensor,
e.g. temperature, humidity, light, distance, direction or pressure.
2021-12-04 15:32:57 -05:00
2023-04-26 03:26:03 -04:00
This function can be used to colour an element on a graphical display,
drive an RGB LED, or a LED string etc to indicate some sort of state visually.
The first releases used a fixed number of 7 floats values that describe the range being mapped.
With version 0.2.0 one can define the size as a parameter of the constructor.
There is no limit (except RAM) in theory, but in practice 16 or 32 entries is a lot.
A lookup array of float values is passed to the library with **begin()**.
These floats must be in **non-decreasing** order and are mapped default on the following colour array.
2021-12-04 15:32:57 -05:00
```cpp
2021-12-09 09:05:02 -05:00
uint32_t colours[] =
2021-12-04 15:32:57 -05:00
{
2023-04-26 03:26:03 -04:00
// M2C_BLACK M2C_RED M2C_YELLOW M2C_LIME M2C_AQUA M2C_BLUE M2C_WHITE
2021-12-04 15:32:57 -05:00
0x00000000, 0x00FF0000, 0x00FFFF00, 0x0000FF00, 0x0000FFFF, 0x000000FF, 0x00FFFFFF
}
```
2021-12-09 09:05:02 -05:00
New values will be linear interpolated between two points when needed.
2021-12-04 15:32:57 -05:00
2023-04-26 03:26:03 -04:00
Assume you initialize a float value array indicating temperature Celsius levels.
2021-12-04 15:32:57 -05:00
```cpp
2021-12-09 09:05:02 -05:00
float tempArray[] = { -20, -10, 5, 15, 30, 60, 125 };
2021-12-04 15:32:57 -05:00
```
2023-04-26 03:26:03 -04:00
A temperature of 0°C will be between the 2nd and 3rd value so it will be mapped
between the 2nd and 3rd element colour so between M2C_RED and M2C_YELLOW.
Similarly any temperature between 60°C and 125°C will be mapped between M2C_BLUE and M2C_WHITE.
**begin()** allows one to overrule the values and the colours array with arrays of your choice.
2021-12-09 09:05:02 -05:00
Adjusting the colour array allows one to use a "full spectrum" like the default or only
2023-04-26 03:26:03 -04:00
interpolate between two colours.
Note the library has several colours predefined in **m2c_colours.h** as constants to make the
colour table and therefore the code more readable.
If colours are missing please make a PullRequest (preferred) or file an issue.
2021-12-09 09:05:02 -05:00
2023-04-26 03:26:03 -04:00
**begin()** returns true if the array of values is in non-decreasing order, false otherwise.
2021-12-09 09:05:02 -05:00
If returned false the code might behave in unexpected ways.
2021-12-04 15:32:57 -05:00
2023-04-26 03:26:03 -04:00
Please note that the colourMap can have duplicate entries even side by side.
2021-12-04 15:32:57 -05:00
## Interface
2023-02-21 11:01:58 -05:00
```cpp
#include "map2colour.h"
```
#### Functions
2023-04-26 03:26:03 -04:00
- **map2colour(uint8_t size = 7)** constructor, default size 7 to be backwards compatible.
- **~map2colour()** destructor.
- **map2colourFast(uint8_t size = 7)** constructor, (larger code base, more RAM and faster)
- **~map2colourFast()** destructor.
- **uint8_t size()** returns the size of the arrays needed (== parameter of constructor).
- **bool begin(float \* values, uint32_t \* colourMap = NULL)** load the array with **size**
boundary values and the associated array of **size** colours packed in uint32_t **0x00RRGGBB**.
2021-12-09 09:05:02 -05:00
If the colour array is not given the last given (or the default) colour array is used.
**begin()** can be called multiple times to change the mapping.
2023-04-26 03:26:03 -04:00
The function returns false if the array of values is not in non-decreasing order.
2021-12-09 09:05:02 -05:00
- **uint32_t map2RGB(float value)** returns RGB colour packed in an uint32_t **0x00RRGGBB**.
2023-04-26 03:26:03 -04:00
If the value is out of range of the original values array, the value is always mapped upon the
first or last colour.
2023-02-21 11:01:58 -05:00
- **uint16_t map2_565(float value)** often used 16 bit colour format.
Currently a wrapper around **map2RGB**.
2021-12-09 09:05:02 -05:00
2023-04-26 03:26:03 -04:00
Note: the arrays passed to **begin()** should both have **size** elements!
2021-12-09 09:05:02 -05:00
2023-02-21 11:01:58 -05:00
The colour array can be filled with decimal or HEX values or predefined colours can be used.
See below.
2021-12-09 09:05:02 -05:00
## Predefined colours
2023-04-26 03:26:03 -04:00
Colours are represented as 32 bit .RGB values and have the pattern **0x00RRGGBB**.
In the file **m2c_colours.h** a number of colours are predefined.
2021-12-09 09:05:02 -05:00
2023-02-21 11:01:58 -05:00
| define | value | define | value |
|:--------------|:------------:|:-------------|:------------:|
| M2C_BLACK | 0x00000000 | M2C_GREEN | 0x00008000 |
| M2C_SILVER | 0x00C0C0C0 | M2C_LIME | 0x000FF000 |
| M2C_GRAY | 0x00808080 | M2C_OLIVE | 0x00808000 |
| M2C_WHITE | 0x00FFFFFF | M2C_YELLOW | 0x00FFFF00 |
| M2C_MAROON | 0x00800000 | M2C_NAVY | 0x00000080 |
| M2C_RED | 0x00FF0000 | M2C_BLUE | 0x000000FF |
| M2C_PURPLE | 0x00800080 | M2C_TEAL | 0x00008080 |
| M2C_FUCHSIA | 0x00FF00FF | M2C_AQUA | 0x0000FFFF |
2021-12-09 09:05:02 -05:00
2023-04-26 03:26:03 -04:00
Besides these colours, the file contains also GRAY-scale VALUES M2C_GRAY_0 .. M2C_GRAY_16.
2022-10-20 05:58:00 -04:00
More colour definitions can be found on the internet
e.g. https://www.w3.org/wiki/CSS/Properties/color/keywords
2021-12-04 15:32:57 -05:00
2023-04-26 03:26:03 -04:00
Note that only 3 bytes of 4 of the 32 bit colour patterns are used.
The 4th byte might be used in the future.
2021-12-04 15:32:57 -05:00
## Operation
See examples.
2021-12-09 09:05:02 -05:00
By changing the colour map one can get different effects.
2023-04-26 03:26:03 -04:00
The minimum to implement is an intensity effect going e.g. from black towards a colour at max intensity.
For this effect only two values are significant, however one must provide full size arrays.
```cpp
float values[7] = { -200, 200, 200, 200, 200, 200, 200, };
uint32_t colours[7] = { M2C_BLACK, M2C_RED, 0, 0, 0, 0, 0};
```
Note that the above colour scheme maps all colokrs above 200 to BLACK (0).
Another interesting colour scheme could be a symmetric one.
This could indicate 25 as an optimal value (GREEN).
```cpp
float values[5] = { -50, -25, 0, 25, 50, 75, 100};
uint32_t colours[5] = { M2C_BLACK, M2C_RED, M2C_YELLOW, M2C_GREEN, M2C_YELLOW, M2C_RED, M2C_BLACK};
```
More complex colour schemes are possible, up to **size** different colours.
2022-10-20 05:58:00 -04:00
2023-02-21 11:01:58 -05:00
2023-04-26 03:26:03 -04:00
#### Non-decreasing array
2022-10-20 05:58:00 -04:00
2023-04-26 03:26:03 -04:00
(experimental in 0.1.5)
2023-02-21 11:01:58 -05:00
If you create a non-decreasing array of values one can create a break in the colour gradient.
See example.
2022-10-20 05:58:00 -04:00
```cpp
2023-04-26 03:26:03 -04:00
float values[7] = { -200, -90, 0, 45, 45, 150, 180 };
2022-10-20 05:58:00 -04:00
uint32_t colours[7] = { M2C_BLUE, M2C_AQUA, M2C_LIME, M2C_YELLOW, M2C_RED, M2C_YELLOW, M2C_BLUE};
```
2023-04-26 03:26:03 -04:00
With **45** occurring twice in the values array above there would be no interpolation or colour gradient
between the **M2C_YELLOW** and **M2C_RED** effectively resulting in 2 continuous gradients.
2022-10-20 05:58:00 -04:00
2023-04-26 03:26:03 -04:00
A slightly less hard edge could be made by changing the second 45 to 46 or 47,
so there is a small area with a very steep gradient.
Note: Since 0.2.0 **begin()** will accept a non-decreasing value array and return true.
This was false in 0.1.5.
2021-12-09 09:05:02 -05:00
## Performance
2023-04-26 03:26:03 -04:00
Indicative performance figures measured with the performance example.
2021-12-09 09:05:02 -05:00
Performance depends on colours chosen, platform etc.
2023-02-21 11:01:58 -05:00
Note: time in microseconds
Note: UNO at 16 MHz, ESP32 at 240 MHz
2021-12-09 09:05:02 -05:00
2023-04-26 03:26:03 -04:00
2021-12-09 09:05:02 -05:00
#### version 0.1.2
2023-02-21 11:01:58 -05:00
| function call | time UNO | time ESP32 |
|:-------------------------|------------:|-------------:|
| begin(values) | 4 | 4 |
| begin(values, colours) | 12 | 4 |
| map2RGB(value) | 124 - 152 | 2 - 4 |
| map2_565(value) | 124 - 168 | 2 - 4 |
2021-12-09 09:05:02 -05:00
#### version 0.1.3
2023-02-21 11:01:58 -05:00
| function call | time UNO | time ESP32 |
|:-------------------------|------------:|-------------:|
| begin(values) | 4 | 4 |
| begin(values, colours) | 12 | 4 |
| map2RGB(value) | 64 - 132 | 2 - 3 |
| map2_565(value) | 68 - 140 | 2 - 3 |
2021-12-09 09:05:02 -05:00
#### version 0.1.4
2023-04-26 03:26:03 -04:00
map2colourFast.
2023-02-21 11:01:58 -05:00
| function call | time UNO | time ESP32 | notes |
|:-------------------------|------------:|-------------:|:------------------------|
| begin(values) | 284 | 15 | unexpected peak ESP32 |
| begin(values, colours) | 304 | 6 |
| map2RGB(value) | 40 - 104 | 1 - 2 |
| map2_565(value) | 44 - 112 | 1 - 2 |
2021-12-09 09:05:02 -05:00
#### optimization 0.1.4
One performance optimization (trade memory for speed) is replacing the float division
in map2RGB by a multiplication.
This optimization is implemented as a derived class **map2colourFast** in version 0.1.4.
2023-04-26 03:26:03 -04:00
This requires (size x 4) bytes RAM to hold the \[size] factors and some ~100 bytes
of PROGMEM for the calculation of the dividers in **begin()**.
2021-12-09 09:05:02 -05:00
The **map2RGB()** call is about 40 % faster compared to the original 0.1.2.
Although the **begin()** call is ~300 us longer, it only takes a dozen **map2RGB()** calls to break even.
Note: the gain for the ESP32 is less pronounced, but can still be interesting.
2021-12-04 15:32:57 -05:00
2023-04-26 03:26:03 -04:00
#### version 0.2.0
map2colourFast, slightly slower compared to 0.1.4.
Note that the larger the size the more time it takes to find the correct interval for the value.
| function call | time UNO | time ESP32 |
|:-------------------------|------------:|-------------:|
| begin(values) | 316 | 22 |
| begin(values, colours) | 332 | 7 |
| map2RGB(value) | 48 - 116 | 1 - 2 |
| map2_565(value) | 52 - 120 | 1 - 2 |
2021-12-04 15:32:57 -05:00
## Future
2023-02-21 11:01:58 -05:00
#### Must
2021-12-04 15:32:57 -05:00
- update documentation
2023-02-21 11:01:58 -05:00
#### Should
2022-10-20 05:58:00 -04:00
- look for optimizations.
- cache last value?
2023-04-26 03:26:03 -04:00
2023-02-21 11:01:58 -05:00
#### Could
2023-04-26 03:26:03 -04:00
- create a memory efficient version
- keep a pointer to the colour array.
- split RGB channels for every mapping.
- is this useful? only for smallest RAM devices.
- remove default array and break backwards compatibility.
2022-10-20 05:58:00 -04:00
2023-02-21 11:01:58 -05:00
#### Wont
2022-10-20 05:58:00 -04:00
- **uint32_t dumpColourMap()** ==> not needed
- PROGMEM for default array? ==> slower, AVR specific.
- move up the test for non-increase in **begin()** ==> fail fast.
- conflicts with begin of fast version.
2023-04-26 03:26:03 -04:00
- user responsibility.
- could a 4th (alpha) channel be enabled?
2023-02-21 11:01:58 -05:00
- not needed yet, would need new constants
- faster 16 bit 565 version?
- only on request as a separate class map2colour565.
- map2HSL() as extra colour space.
2023-04-26 03:26:03 -04:00
- not seen much HSL displays in "Arduino" world
- separate converter solves this.
- add **reset()** for default array?
- takes too much RAM.
- improve the constructor
- add **splitColorMap()**
- only done once so too little gain.
- map2RGB variant that gives a colour as the delta with the previous value.
- user can do that fairly easy => example
- add 3rd param size to **begin()** to allow smaller arrays?
- suppose you allocate size = 20 and want to use only 5 entries.
- create a new object.
- **bool adjustColour(uint8_t index, uint32_t RGB)**
- single colour adjustment
- returns false if index out of range.
- faster than calling **begin()**.
- divfactors need to be calculated again?
- see no real use case.
2021-12-09 09:05:02 -05:00