#RGB565 #RGB888 #RGB mqtt #M5Stick #ESP32 gpio #colorpicker
I've got a couple of M5StickC-Plus devices
and have them working with the NodeRED aedes MQTT broker, 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
- M5-MiniEncoder
Encoder count,
Encoder step value,
Encoder direction,
Encoder button status
Setting Encoder LED RGB888 (on the rear on the unit)
Clearing Encoder counter
- M5.8Encoder
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
- M5.ToF sensor
Adapt reporting interval
Read distance
As an example - Two buttons for Grove port
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
(I have also used "Color Convertor" 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.
I am happy to share the MQTT flow and Arduino Script for the M5StickC-Plus if anyone is interested
[
{
"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
}
]