{"id":20989943,"url":"https://github.com/robtillaart/map2colour","last_synced_at":"2025-10-16T06:01:44.865Z","repository":{"id":45540731,"uuid":"434941269","full_name":"RobTillaart/map2colour","owner":"RobTillaart","description":"Arduino library for mapping a float to RGB colour spectrum","archived":false,"fork":false,"pushed_at":"2024-04-13T09:16:32.000Z","size":49,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-06T18:19:02.358Z","etag":null,"topics":["arduino","color","colour","map","rgb","value"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2021-12-04T15:42:15.000Z","updated_at":"2024-03-11T17:16:02.000Z","dependencies_parsed_at":"2023-11-06T14:29:49.818Z","dependency_job_id":"0cf85d97-6066-443f-99de-0f629538d574","html_url":"https://github.com/RobTillaart/map2colour","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2Fmap2colour","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2Fmap2colour/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2Fmap2colour/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2Fmap2colour/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/map2colour/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225305828,"owners_count":17453463,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","color","colour","map","rgb","value"],"created_at":"2024-11-19T06:26:48.161Z","updated_at":"2025-10-16T06:01:44.858Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":[],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/map2colour/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/map2colour/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/map2colour/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/map2colour/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/map2colour/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/map2colour.svg)](https://github.com/RobTillaart/map2colour/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/map2colour/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/map2colour.svg?maxAge=3600)](https://github.com/RobTillaart/map2colour/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/map2colour.svg)](https://registry.platformio.org/libraries/robtillaart/map2colour)\n\n\n# map2colour\n\nArduino library for mapping a float to a colour spectrum.\n\n\n## Description\n\nThe map2colour library is used to map a float value to a colour in the RGB spectrum.\nThe float value can be the result of a calculation or read from a sensor, \ne.g. temperature, humidity, light, distance, direction or pressure. \n\nThis function can be used to colour an element on a graphical display,\ndrive an RGB LED, or a LED string etc to indicate some sort of state visually.\n\nThe first releases used a fixed number of 7 floats values that describe the range being mapped.\nWith version 0.2.0 one can define the size as a parameter of the constructor.\nThere is no limit (except RAM) in theory, but in practice 16 or 32 entries is a lot.\n\nA lookup array of float values is passed to the library with **begin()**.\nThese floats must be in **non-decreasing** order and are mapped default on the following colour array.\n\n```cpp\nuint32_t colours[] =\n{\n  // M2C_BLACK  M2C_RED   M2C_YELLOW   M2C_LIME   M2C_AQUA    M2C_BLUE    M2C_WHITE\n  0x00000000, 0x00FF0000, 0x00FFFF00, 0x0000FF00, 0x0000FFFF, 0x000000FF, 0x00FFFFFF\n}\n```\n\nNew values will be linear interpolated between two points when needed.\n\nAssume you initialize a float value array indicating temperature Celsius levels.\n\n```cpp\nfloat tempArray[] = { -20, -10, 5, 15, 30, 60, 125 };\n```\n\nA temperature of 0°C will be between the 2nd and 3rd value so it will be mapped \nbetween the 2nd and 3rd element colour so between M2C_RED and M2C_YELLOW.\nSimilarly any temperature between 60°C and 125°C will be mapped between M2C_BLUE and M2C_WHITE.\n\n**begin()** allows one to overrule the values and the colours array with arrays of your choice.\nAdjusting the colour array allows one to use a \"full spectrum\" like the default or only \ninterpolate between two colours. \nNote the library has several colours predefined in **m2c_colours.h** as constants to make the \ncolour table and therefore the code more readable. \nIf colours are missing please make a PullRequest (preferred) or file an issue.\n\n**begin()** returns true if the array of values is in non-decreasing order, false otherwise.\nIf returned false the code might behave in unexpected ways.\n\nPlease note that the colourMap can have duplicate entries even side by side.\n\n\n### Related\n\n- https://github.com/RobTillaart/Kelvin2RGB\n- https://github.com/RobTillaart/map2colour\n\n\n## Interface\n\n```cpp\n#include \"map2colour.h\"\n```\n\n### Constructor\n\n- **map2colour(uint8_t size = 7)** constructor, default size 7 to be backwards compatible.\n- **~map2colour()** destructor.\n- **map2colourFast(uint8_t size = 7)** constructor, (larger code base, more RAM and faster)\n- **~map2colourFast()** destructor.\n- **uint8_t size()** returns the size of the arrays needed (== parameter of constructor).\n- **bool begin(float \\* values, uint32_t \\* colourMap = NULL)** load the array with **size** \nboundary values and the associated array of **size** colours packed in uint32_t **0x00RRGGBB**.\nIf the colour array is not given the last given (or the default) colour array is used.\n**begin()** can be called multiple times to change the mapping.\nThe function returns false if the array of values is not in non-decreasing order.\n\n### Functions\n\n- **uint32_t map2RGB(float value)** returns RGB colour packed in an uint32_t **0x00RRGGBB**.  \nIf the value is out of range of the original values array, the value is always mapped upon the \nfirst or last colour.\n- **uint16_t map2_565(float value)** often used 16 bit colour format. \nCurrently a wrapper around **map2RGB**.\n\nNote: the arrays passed to **begin()** should both have **size** elements!\n\nThe colour array can be filled with decimal or HEX values or predefined colours can be used.\nSee below.\n\n\n## Predefined colours\n\nColours are represented as 32 bit .RGB values and have the pattern **0x00RRGGBB**.\n\nIn the file **m2c_colours.h** a number of colours are predefined.\n\n\n|  define       |  value       |  define      |  value       |\n|:--------------|:------------:|:-------------|:------------:|\n|  M2C_BLACK    |  0x00000000  |  M2C_GREEN   |  0x00008000  |\n|  M2C_SILVER   |  0x00C0C0C0  |  M2C_LIME    |  0x000FF000  |\n|  M2C_GRAY     |  0x00808080  |  M2C_OLIVE   |  0x00808000  |\n|  M2C_WHITE    |  0x00FFFFFF  |  M2C_YELLOW  |  0x00FFFF00  |\n|  M2C_MAROON   |  0x00800000  |  M2C_NAVY    |  0x00000080  |\n|  M2C_RED      |  0x00FF0000  |  M2C_BLUE    |  0x000000FF  |\n|  M2C_PURPLE   |  0x00800080  |  M2C_TEAL    |  0x00008080  |\n|  M2C_FUCHSIA  |  0x00FF00FF  |  M2C_AQUA    |  0x0000FFFF  |\n\n\nBesides these colours, the file contains also GRAY-scale VALUES M2C_GRAY_0 .. M2C_GRAY_16.\n\nMore colour definitions can be found on the internet \ne.g. https://www.w3.org/wiki/CSS/Properties/color/keywords\n\nNote that only 3 bytes of 4 of the 32 bit colour patterns are used.\nThe 4th byte might be used in the future.\n\n\n## Operation\n\nSee examples.\n\nBy changing the colour map one can get different effects. \nThe minimum to implement is an intensity effect going e.g. from black towards a colour at max intensity. \nFor this effect only two values are significant, however one must provide full size arrays.\n\n```cpp\nfloat values[7] =     { -200,      200,       200, 200, 200, 200, 200, };\nuint32_t colours[7] = { M2C_BLACK, M2C_RED,   0, 0, 0, 0, 0};\n```\n\nNote that the above colour scheme maps all colokrs above 200 to BLACK (0).\n\nAnother interesting colour scheme could be a symmetric one.\nThis could indicate 25 as an optimal value (GREEN).\n\n```cpp\nfloat values[5] =     { -50,        -25,     0,          25,        50,        75,      100};\nuint32_t colours[5] = { M2C_BLACK, M2C_RED, M2C_YELLOW, M2C_GREEN, M2C_YELLOW, M2C_RED, M2C_BLACK};\n```\n\nMore complex colour schemes are possible, up to **size** different colours.\n\n\n### Non-decreasing array\n\n(experimental in 0.1.5)\nIf you create a non-decreasing array of values one can create a break in the colour gradient. \nSee example.\n\n```cpp\nfloat values[7] =     { -200,     -90,      0,        45,               45,     150,         180 };\nuint32_t colours[7] = { M2C_BLUE, M2C_AQUA, M2C_LIME, M2C_YELLOW,       M2C_RED, M2C_YELLOW, M2C_BLUE};\n```\n\nWith **45** occurring twice in the values array above there would be no interpolation or colour gradient \nbetween the **M2C_YELLOW** and **M2C_RED** effectively resulting in 2 continuous gradients.\n\nA slightly less hard edge could be made by changing the second 45 to 46 or 47, \nso there is a small area with a very steep gradient. \n\nNote: Since 0.2.0 **begin()** will accept a non-decreasing value array and return true.\nThis was false in 0.1.5.\n\n\n## Performance\n\nIndicative performance figures measured with the performance example.\nPerformance depends on colours chosen, platform etc.\n\nNote: time in microseconds\nNote: UNO at 16 MHz, ESP32 at 240 MHz\n\n\n### version 0.1.2\n\n|  function call           |  time UNO   |  time ESP32  |\n|:-------------------------|------------:|-------------:|\n|  begin(values)           |  4          |   4          |\n|  begin(values, colours)  |  12         |   4          |\n|  map2RGB(value)          |  124 - 152  |   2 - 4      |\n|  map2_565(value)         |  124 - 168  |   2 - 4      |\n\n\n### version 0.1.3\n\n|  function call           |  time UNO   |  time ESP32  |\n|:-------------------------|------------:|-------------:|\n|  begin(values)           |   4         |   4          |\n|  begin(values, colours)  |   12        |   4          |\n|  map2RGB(value)          |   64 - 132  |   2 - 3      |\n|  map2_565(value)         |   68 - 140  |   2 - 3      |\n\n\n### version 0.1.4\n\nmap2colourFast.\n\n|  function call           |  time UNO   |  time ESP32  |  notes                  |\n|:-------------------------|------------:|-------------:|:------------------------|\n|  begin(values)           |   284       |   15         |  unexpected peak ESP32  |\n|  begin(values, colours)  |   304       |   6          |\n|  map2RGB(value)          |   40 - 104  |   1 - 2      |\n|  map2_565(value)         |   44 - 112  |   1 - 2      |\n\n\n### optimization 0.1.4\n\nOne performance optimization (trade memory for speed) is replacing the float division \nin map2RGB by a multiplication. \nThis optimization is implemented as a derived class **map2colourFast** in version 0.1.4.\n\nThis requires (size x 4) bytes RAM to hold the \\[size] factors and some ~100 bytes \nof PROGMEM for the calculation of the dividers in **begin()**.\nThe **map2RGB()** call is about 40 % faster compared to the original 0.1.2.\nAlthough the **begin()** call is ~300 us longer, it only takes a dozen **map2RGB()** calls to break even.\n\nNote: the gain for the ESP32 is less pronounced, but can still be interesting.\n\n\n### version 0.2.0\n\nmap2colourFast, slightly slower compared to 0.1.4.\nNote that the larger the size the more time it takes to find the correct interval for the value.\n\n|  function call           |  time UNO   |  time ESP32  |\n|:-------------------------|------------:|-------------:|\n|  begin(values)           |   316       |    22        |\n|  begin(values, colours)  |   332       |    7         |\n|  map2RGB(value)          |   48 - 116  |    1 - 2     |\n|  map2_565(value)         |   52 - 120  |    1 - 2     |\n\n\n## Future\n\n#### Must\n\n- update documentation\n\n#### Should\n\n- look for optimizations.\n  - cache last value?\n\n#### Could\n\n- create a memory efficient version \n  - keep a pointer to the colour array.\n  - split RGB channels for every mapping.\n  - is this useful? only for smallest RAM devices.\n- remove default array and break backwards compatibility.\n- rename **map2_565()** to **map2RGB565()**  - mapRGB888?\n- add **map2CMYK()**\n\n\n#### Wont\n\n- **uint32_t dumpColourMap()** ==\u003e not needed\n- PROGMEM for default array? ==\u003e slower, AVR specific.\n- move up the test for non-increase in **begin()** ==\u003e fail fast.\n  - conflicts with begin of fast version.\n  - user responsibility.\n- could a 4th (alpha) channel be enabled?\n  - not needed yet, would need new constants\n- faster 16 bit 565 version?\n  - only on request as a separate class map2colour565.\n- map2HSL() as extra colour space.\n  - not seen much HSL displays in \"Arduino\" world\n  - separate converter solves this.\n- add **reset()** for default array? \n  - takes too much RAM.\n- improve the constructor\n  - add **splitColorMap()**\n  - only done once so too little gain.\n- map2RGB variant that gives a colour as the delta with the previous value.\n  - user can do that fairly easy =\u003e example\n- add 3rd parameter size to **begin()** to allow smaller arrays?\n  - suppose you allocate size = 20 and want to use only 5 entries.\n  - create a new object.\n- **bool adjustColour(uint8_t index, uint32_t RGB)**    \n  - single colour adjustment\n  - returns false if index out of range.\n  - faster than calling **begin()**.\n  - division factors need to be calculated again?\n  - see no real use case.\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fmap2colour","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtillaart%2Fmap2colour","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fmap2colour/lists"}