# RGB565 Color Space (mainly for SPI TFT screens)

**URL:** <https://discourse.nodered.org/t/rgb565-color-space-mainly-for-spi-tft-screens/80574>\
**Category:** Share Your Projects\
**Created:** [15 August 2023 09:20 UTC](https://discourse.nodered.org/t/rgb565-color-space-mainly-for-spi-tft-screens/80574 "2023-08-15T09:20:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![MDAR](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mdar/32/10700_2.png) [@MDAR](https://discourse.nodered.org/u/MDAR)\
**Post date:** [15 August 2023 09:20 UTC](https://discourse.nodered.org/t/rgb565-color-space-mainly-for-spi-tft-screens/80574/1 "2023-08-15T09:20:54Z")

</div>

#RGB565 #RGB888#RGB #mqtt #M5Stick #ESP32 #gpio #colorpicker

I've got a couple of [M5StickC-Plus](https://shop.m5stack.com/collections/m5-controllers/products/m5stickc-plus-esp32-pico-mini-iot-development-kit) devices  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/e/7ed7be2574b325a4814781b3342c4e62772a377e.png)

and have them working with the NodeRED [aedes MQTT broker](https://flows.nodered.org/node/node-red-contrib-aedes), using JSON payloads.

example :-  
`{"LED":true,"LEDrate":200,"beep":true,"beepPitch":2000,"bgColour":-1,"colour":-2,"screen":2,"message":"Hello World","SerialDebug":false,"encLED":0xff0000}`

From there I can read the status of both button, adapt the screen content, set the LED and Beep.

I've even included the ability to use

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/4/e417b0fbfc035d27be7875d17885fc0a2ccba4b4.png)

- [M5-MiniEncoder](https://shop.m5stack.com/products/m5stickc-mini-encoder-hat-stm32f030)  
Encoder count,  
Encoder step value,  
Encoder direction,  
Encoder button status  
Setting Encoder LED RGB888 (on the rear on the unit)  
Clearing Encoder counter

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/d/bdb2cfebd33df919a03d60629d5eef6c5adc7954.png)

- [M5.8Encoder](https://shop.m5stack.com/products/8-encoder-unit-stm32f030)  
Read each Encoder counter  
Read each Encoder button status  
Read Encoder Switch status  
Set ALL Encoder LED (RGB888)  
Set one-by-one Encoder LED (RGB888)  
Clear all Encoder counters

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/c/acb87ae058c47c2abecddda39232d81508412cba.jpeg)

- [M5.ToF sensor](https://shop.m5stack.com/products/tof-sensor-unit)  
Adapt reporting interval  
Read distance

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/7/17e0f65b171ec55bc05b795df203f3aa8cbaf9d9.png)

As an example - [Two buttons for Grove port](https://shop.m5stack.com/products/mini-dual-button-unit)  
Any volt free contact closure will work across 0v and GPio pin/s

- Status' of both (Bottom Grove port) GPIO pins (Pin32 & Pin33) for contact closures

* * *

Initially to set the BackGround and Text colours, I simply sent a value between -1 and -9 as an INT and a couple of IF statements to map to a few of the pre-defined colour options.

However what I really wanted was to be able to use a colour picker to set them.

The problem is that while the LED components use RGB888 format values, the TFT screen uses RGB565.

I searched for days and days trying to find a simple function node to bit shift the RGB values to a limited RGB565 format.

Eventually I relented and set about doing it the long way with [BitUnloader](https://flows.nodered.org/node/node-red-contrib-bitunloader)

(I have also used "[Color Convertor](https://flows.nodered.org/node/node-red-contrib-colorspace)" in this flow, so that I can use other color spaces)

Until there is a cleaner / nicer way of doing it, here is my flow.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/8/889ce156aafafce889b1564516cdccaae968e0b8.png)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/2/32dcffd5399321bdb27021d0513fbbbfc510e436.png)

I am happy to share the MQTT flow and Arduino Script for the M5StickC-Plus if anyone is interested

```auto
[
    {
        "id": "4da8de9fdd60e66e",
        "type": "tab",
        "label": "RGB565",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "1a98fa35b22665a0",
        "type": "junction",
        "z": "4da8de9fdd60e66e",
        "x": 480,
        "y": 580,
        "wires": [
            [
                "9035c16838ab2c79",
                "adbc20cedcabb262"
            ]
        ]
    },
    {
        "id": "86c3851afdf9d02a",
        "type": "ui_colour_picker",
        "z": "4da8de9fdd60e66e",
        "name": "RGB Colour Picker Object",
        "label": "RGB BG Colour",
        "group": "c61238e556dd18bf",
        "format": "rgb",
        "outformat": "object",
        "showSwatch": true,
        "showPicker": true,
        "showValue": true,
        "showHue": false,
        "showAlpha": false,
        "showLightness": true,
        "square": "false",
        "dynOutput": "false",
        "order": 1,
        "width": 6,
        "height": 6,
        "passthru": true,
        "topic": "bgColour",
        "topicType": "str",
        "className": "",
        "x": 250,
        "y": 560,
        "wires": [
            [
                "1a98fa35b22665a0"
            ]
        ]
    },
    {
        "id": "cef5b2826321ccf3",
        "type": "ui_text",
        "z": "4da8de9fdd60e66e",
        "group": "c61238e556dd18bf",
        "order": 4,
        "width": 0,
        "height": 0,
        "name": "RGB565",
        "label": "RGB565",
        "format": "{{msg.payload}}",
        "layout": "col-center",
        "className": "",
        "style": true,
        "font": "Arial Black,Arial Black,Gadget,sans-serif",
        "fontSize": "22",
        "color": "#ff0a0a",
        "x": 1060,
        "y": 880,
        "wires": []
    },
    {
        "id": "998bd22810febe07",
        "type": "ui_text",
        "z": "4da8de9fdd60e66e",
        "group": "c61238e556dd18bf",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "RGB888",
        "label": "RGB888",
        "format": "{{msg.payload.hex}}",
        "layout": "col-center",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1280,
        "y": 540,
        "wires": []
    },
    {
        "id": "e8ccee752e20537b",
        "type": "bitunloader",
        "z": "4da8de9fdd60e66e",
        "name": "unload payload.r",
        "mode": "objectBits",
        "prop": "payload.r",
        "padding": "8",
        "x": 570,
        "y": 800,
        "wires": [
            [
                "8b56bf71bf74ef41"
            ]
        ]
    },
    {
        "id": "f7366b256e95d4cf",
        "type": "debug",
        "z": "4da8de9fdd60e66e",
        "name": "Unloaded Bits",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "RGB",
        "statusType": "msg",
        "x": 1300,
        "y": 800,
        "wires": []
    },
    {
        "id": "adbc20cedcabb262",
        "type": "function",
        "z": "4da8de9fdd60e66e",
        "name": "Store RGB",
        "func": "msg.RGB = { \n \"red\": msg.payload.r,\n \"green\": msg.payload.g,\n \"blue\": msg.payload.b\n };\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 230,
        "y": 800,
        "wires": [
            [
                "e8ccee752e20537b"
            ]
        ]
    },
    {
        "id": "8b56bf71bf74ef41",
        "type": "bitunloader",
        "z": "4da8de9fdd60e66e",
        "name": "unload payload.g",
        "mode": "objectBits",
        "prop": "payload.g",
        "padding": "8",
        "x": 810,
        "y": 800,
        "wires": [
            [
                "cf9de4e93d336edc"
            ]
        ]
    },
    {
        "id": "cf9de4e93d336edc",
        "type": "bitunloader",
        "z": "4da8de9fdd60e66e",
        "name": "unload payload.b",
        "mode": "objectBits",
        "prop": "payload.b",
        "padding": "8",
        "x": 1030,
        "y": 800,
        "wires": [
            [
                "f7366b256e95d4cf",
                "6890979584dd07d9"
            ]
        ]
    },
    {
        "id": "9c5ef762650188f6",
        "type": "bitreloader",
        "z": "4da8de9fdd60e66e",
        "name": "",
        "autoMode": "manual",
        "prop": "RGB565",
        "mode": "arrayBits",
        "x": 550,
        "y": 880,
        "wires": [
            [
                "bfaa666c199d30f5",
                "f6540d7669422884"
            ]
        ]
    },
    {
        "id": "6890979584dd07d9",
        "type": "function",
        "z": "4da8de9fdd60e66e",
        "name": "Shift RGB BITS",
        "func": "\n\nmsg.RGB565_bits = [];\n\n\n// 5 high bits from RED\nmsg.RGB565_bits[15] = msg.payload.r.b7;\nmsg.RGB565_bits[14] = msg.payload.r.b6;\nmsg.RGB565_bits[13] = msg.payload.r.b5;\nmsg.RGB565_bits[12] = msg.payload.r.b4;\nmsg.RGB565_bits[11] = msg.payload.r.b3;\n\n// 6 high bits from GREEN\nmsg.RGB565_bits[10] = msg.payload.g.b7;\nmsg.RGB565_bits[9] = msg.payload.g.b6;\nmsg.RGB565_bits[8] = msg.payload.g.b5;\nmsg.RGB565_bits[7] = msg.payload.g.b4;\nmsg.RGB565_bits[6] = msg.payload.g.b3;\nmsg.RGB565_bits[5] = msg.payload.g.b2;\n\n\n// 5 high bits from Blue\nmsg.RGB565_bits[4] = msg.payload.b.b7;\nmsg.RGB565_bits[3] = msg.payload.b.b6;\nmsg.RGB565_bits[2] = msg.payload.b.b5;\nmsg.RGB565_bits[1] = msg.payload.b.b4;\nmsg.RGB565_bits[0] = msg.payload.b.b3;\n\nmsg.RGB565 = [];\n\nmsg.RGB565 = msg.RGB565_bits;\n\nreturn msg;\n\n\n// Based on this notation\n// rgb565 = ((rgb888.r & 0xf80000) >> 8) | ((rgb888.g & 0xfc00) >> 5) | ((rgb888.b & 0xf8) >> 3);\n//\n// See \n// http://www.barth-dev.de/about-rgb565-and-how-to-convert-into-it/",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 240,
        "y": 880,
        "wires": [
            [
                "9c5ef762650188f6"
            ]
        ]
    },
    {
        "id": "551c0914dfa614ae",
        "type": "node-red-contrib-colorspace",
        "z": "4da8de9fdd60e66e",
        "name": "Convert",
        "target": "payload",
        "x": 1040,
        "y": 540,
        "wires": [
            [
                "a0c35899dc6b01b0",
                "998bd22810febe07"
            ]
        ]
    },
    {
        "id": "9035c16838ab2c79",
        "type": "function",
        "z": "4da8de9fdd60e66e",
        "name": "Rearrange payload",
        "func": "// Take an RGB component payload and arrange it ready for Color Convertor to use\n// review the Debug output for results\n\n\nmsg = {\n \"payload\":{\n \"rgb\": {\n \"red\": msg.payload.r,\n \"green\": msg.payload.g,\n \"blue\": msg.payload.b\n }\n }\n }\nreturn msg;\n\n// Use a section of the following to make use of different colour spaces.\n\n// How to use\n// You can send in the payload one of the types supported\n// \n// You can send\n// \n// RGB\n// \n// msg = {\n// \"payload\":{\n// \"rgb\": {\n// \"red\": 255,\n// \"green\": 10,\n// \"blue\": 20\n// }\n// }\n// };\n\n\n\n\n// HSV\n// \n// msg = {\n// \"payload\":{\n// \"hsv\": {\n// \"hue\": 358,\n// \"staturation\": 96,\n// \"brightness\": 100\n// }\n// }\n// };\n\n\n\n\n// HSL\n// \n// msg = {\n// \"payload\":{\n// \"hsl\": {\n// \"hue\": 358,\n// \"staturation\": 96,\n// \"lightness\": 52\n// }\n// }\n// };\n\n\n\n\n// HWB\n// \n// msg = {\n// \"payload\":{\n// \"hwb\": {\n// \"hue\": 358,\n// \"whiteness\": 4,\n// \"blackness\": 0\n// }\n// }\n// };\n\n\n// CMYK\n// \n//msg = {\n// \"payload\":{\n// \"cmyk\": {\n// \"cyan\": 0,\n// \"magenta\": 96,\n// \"yellow\": 92,\n// \"black\": 0\n// }\n// }\n// };\n\n\n// XYZ\n// \n// msg = {\n// \"payload\":{\n// \"xyz\": {\n// \"x\": 41,\n// \"y\": 22,\n// \"z\": 3\n// }\n// }\n// };\n\n\n// HEX\n// \n// msg = {\n// \"payload\":{\n// \"hex\": \"FF0A14\"\n// }\n// };\n\n\n\n// Temperature\n// \n// msg = {\n// \"payload\":{\n// \"temperatute\": 5000\n// }\n// };\n\n\n// Keyword\n// \n// msg = {\n// \"payload\":{\n// \"keyword\": \"red\"\n// }\n// };\n\n\n// Direct Color Name in Payload\n// \n// msg = {\n// \"payload\": \"red\"\n// };\n\n\n\n\n// Direct Color Temperature Name in Payload\n// \n// msg = {\n// \"payload\": \"daylight\"\n// }; ",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 850,
        "y": 540,
        "wires": [
            [
                "551c0914dfa614ae"
            ]
        ]
    },
    {
        "id": "a0c35899dc6b01b0",
        "type": "debug",
        "z": "4da8de9fdd60e66e",
        "name": "Color Converter as HEX RGB888",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload.hex",
        "statusType": "msg",
        "x": 1320,
        "y": 460,
        "wires": []
    },
    {
        "id": "bfaa666c199d30f5",
        "type": "function",
        "z": "4da8de9fdd60e66e",
        "name": "Convert to String",
        "func": "var RGB565_HEX = \"0x\"+msg.RGB565.toString(16);\nvar RGB565_NUM = msg.RGB565;\nvar NEWmsg = {}; // create a fresh MESSAGE\n\nNEWmsg.payload = RGB565_HEX;\nNEWmsg.RGB565_HEX = RGB565_HEX;\nNEWmsg.RGB565_NUM = RGB565_NUM;\n\nNEWmsg.topic = msg.topic; // retain orginal Topic from colour picker\n\nreturn NEWmsg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 810,
        "y": 880,
        "wires": [
            [
                "c8b371f3f14c965a",
                "cef5b2826321ccf3",
                "a57ca1ff064c4345",
                "08df3bdc8f9f8d7c"
            ]
        ]
    },
    {
        "id": "f6540d7669422884",
        "type": "debug",
        "z": "4da8de9fdd60e66e",
        "name": "Reloaded",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "RGB565",
        "statusType": "msg",
        "x": 560,
        "y": 960,
        "wires": []
    },
    {
        "id": "c8b371f3f14c965a",
        "type": "debug",
        "z": "4da8de9fdd60e66e",
        "name": "RGB565 As String",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "msg",
        "x": 1070,
        "y": 940,
        "wires": []
    },
    {
        "id": "cdc5baf363c5538e",
        "type": "comment",
        "z": "4da8de9fdd60e66e",
        "name": "This Flow Uses ---",
        "info": "BitUnloader - \nnode-red-contrib-bitunloader\n\nhttps://flows.nodered.org/node/node-red-contrib-bitunloader\n\nFor converting from any other Colour Space format, this Node pallette\n\nColor Converter\nnode-red-contrib-colorspace\n\nhttps://flows.nodered.org/node/node-red-contrib-colorspace\n\nSee the \"Rearrange Payload\" function mode for examples of how use different colour spaces",
        "x": 630,
        "y": 420,
        "wires": []
    },
    {
        "id": "a57ca1ff064c4345",
        "type": "ui_text",
        "z": "4da8de9fdd60e66e",
        "group": "c61238e556dd18bf",
        "order": 3,
        "width": 0,
        "height": 0,
        "name": "Colour picker topic",
        "label": "msg.topic",
        "format": "{{msg.topic}}",
        "layout": "col-center",
        "className": "",
        "style": false,
        "font": "",
        "fontSize": 16,
        "color": "#000000",
        "x": 1290,
        "y": 880,
        "wires": []
    },
    {
        "id": "8587bcb73ac642b1",
        "type": "link out",
        "z": "4da8de9fdd60e66e",
        "name": "RGB565",
        "mode": "link",
        "links": [
            "1e398a0e5223f471"
        ],
        "x": 1085,
        "y": 1100,
        "wires": []
    },
    {
        "id": "20f0d86d6e039f26",
        "type": "ui_colour_picker",
        "z": "4da8de9fdd60e66e",
        "name": "RGB Colour Picker Object",
        "label": "RGB Colour (Text)",
        "group": "c61238e556dd18bf",
        "format": "rgb",
        "outformat": "object",
        "showSwatch": true,
        "showPicker": true,
        "showValue": true,
        "showHue": false,
        "showAlpha": false,
        "showLightness": true,
        "square": "false",
        "dynOutput": "false",
        "order": 1,
        "width": 6,
        "height": 6,
        "passthru": true,
        "topic": "colour",
        "topicType": "str",
        "className": "",
        "x": 250,
        "y": 520,
        "wires": [
            [
                "1a98fa35b22665a0"
            ]
        ]
    },
    {
        "id": "08df3bdc8f9f8d7c",
        "type": "change",
        "z": "4da8de9fdd60e66e",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "RGB565_NUM",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 960,
        "y": 1020,
        "wires": [
            [
                "8587bcb73ac642b1"
            ]
        ]
    },
    {
        "id": "eb584f5bb0c818e3",
        "type": "inject",
        "z": "4da8de9fdd60e66e",
        "name": "RED bgColour",
        "props": [
            {
                "p": "payload.r",
                "v": "255",
                "vt": "num"
            },
            {
                "p": "payload.g",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "payload.b",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "bgColour",
        "x": 250,
        "y": 620,
        "wires": [
            [
                "1a98fa35b22665a0"
            ]
        ]
    },
    {
        "id": "d2153bb8e48b6806",
        "type": "inject",
        "z": "4da8de9fdd60e66e",
        "name": "Green bgColour",
        "props": [
            {
                "p": "payload.r",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "payload.g",
                "v": "255",
                "vt": "num"
            },
            {
                "p": "payload.b",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "bgColour",
        "x": 260,
        "y": 660,
        "wires": [
            [
                "1a98fa35b22665a0"
            ]
        ]
    },
    {
        "id": "241e6c15ed74d629",
        "type": "inject",
        "z": "4da8de9fdd60e66e",
        "name": "Blue bgColour",
        "props": [
            {
                "p": "payload.r",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "payload.g",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "payload.b",
                "v": "255",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "bgColour",
        "x": 270,
        "y": 700,
        "wires": [
            [
                "1a98fa35b22665a0"
            ]
        ]
    },
    {
        "id": "14da255eb653f239",
        "type": "ui_spacer",
        "z": "4da8de9fdd60e66e",
        "name": "spacer",
        "group": "c61238e556dd18bf",
        "order": 2,
        "width": 6,
        "height": 1
    },
    {
        "id": "c61238e556dd18bf",
        "type": "ui_group",
        "name": "RGB888 to RGB565",
        "tab": "e1ff5a2631fc1f9b",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": true,
        "className": ""
    },
    {
        "id": "e1ff5a2631fc1f9b",
        "type": "ui_tab",
        "name": "RGB565",
        "icon": "dashboard",
        "order": 3,
        "disabled": false,
        "hidden": false
    }
]

```

---

<div class="post-metadata">

**Author:** ![MDAR](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mdar/32/10700_2.png) [@MDAR](https://discourse.nodered.org/u/MDAR)\
**Post date:** [6 June 2024 10:26 UTC](https://discourse.nodered.org/t/rgb565-color-space-mainly-for-spi-tft-screens/80574/2 "2024-06-06T10:26:27Z")

</div>

I've updated the M5StickCPlus firmware quite a bit

to add

[RFid reader](https://shop.m5stack.com/products/rfid-unit-2-ws1850s)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/4/847dd88049ddbb9a8a7cdb742b0d228edd3ee86e.png)

and

[M5Angle8](https://shop.m5stack.com/products/8-angle-unit-with-potentiometer)  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/8/08c776caa00b3fb5a0e25e14a1cc2e2581e89e45.png)  
Including control of the 8 RGB LEDs

as well as ironing out some bugs

If anyone would like the Arduino script, just ask. (Currently version 30)

I've also created a crib sheet for the commands as I was starting to lose track of them.

> **[EncoderCueJSON.pdf](https://www.mdar.co.uk/dl/node-red/EncoderCueJSON.pdf)**
>
> 73.69 KB

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [6 June 2024 10:35 UTC](https://discourse.nodered.org/t/rgb565-color-space-mainly-for-spi-tft-screens/80574/3 "2024-06-06T10:35:08Z")

</div>

To keep the forums organised, I have moved this thread to **Share Your Projects**  
as it doesn't appear to be related to sharing a Custom Node you have developed.
