diff --git a/.gitignore b/.gitignore index bb02e36e..789de0a9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ node_modules wled-update.sh esp01-update.sh /wled00/LittleFS -replace_fs.py \ No newline at end of file +replace_fs.py +wled00/wled00.ino.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 35308115..aaf02f12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## WLED changelog +#### Build 2302180 + +- Removed Blynk support (servers shut down on 31st Dec 2022) + #### Build 2301240 - Version bump to v0.14.0-b2 "Hoshi" diff --git a/boards/esp32_16MB-poe.json b/boards/esp32_16MB-poe.json new file mode 100644 index 00000000..a15ef9a3 --- /dev/null +++ b/boards/esp32_16MB-poe.json @@ -0,0 +1,38 @@ +{ +"build": { + "arduino": { + "ldscript": "esp32_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_ESP32_DEV -DARDUINO_ESP32_POE", + "f_cpu": "240000000L", + "f_flash": "40000000L", + "flash_mode": "dio", + "mcu": "esp32", + "variant": "esp32-poe", + "partitions": "partitions_16M.csv" +}, +"connectivity": [ + "wifi", + "bluetooth", + "ethernet", + "can" +], +"debug": { + "openocd_board": "esp-wroom-32.cfg" +}, +"frameworks": [ + "arduino", + "espidf" +], +"name": "ESP32 16MB", +"upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 2000000 +}, +"url": "https://en.wikipedia.org/wiki/ESP32", +"vendor": "Multiple" +} diff --git a/package-lock.json b/package-lock.json index 76bc09c1..f0952038 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wled", - "version": "0.14.0-b1.18", + "version": "0.14.0-b2.20", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "wled", - "version": "0.14.0-b1.18", + "version": "0.14.0-b2.20", "license": "ISC", "dependencies": { "clean-css": "^4.2.3", @@ -2939,24 +2939,6 @@ } }, "dependencies": { - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -2983,39 +2965,6 @@ "repeat-string": "^1.5.2" } }, - "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "requires": { - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, "ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", @@ -3032,9 +2981,9 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3082,9 +3031,9 @@ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -3095,68 +3044,15 @@ } }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, - "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3179,35 +3075,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } - } - }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -3257,25 +3124,20 @@ } }, "chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.6.0" } }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, "clap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", @@ -3299,11 +3161,6 @@ } } }, - "cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==" - }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -3314,14 +3171,6 @@ "wordwrap": "0.0.2" } }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, "coa": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", @@ -3330,19 +3179,6 @@ "q": "^1.1.2" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", @@ -3364,7 +3200,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "configstore": { "version": "1.4.0", @@ -3393,11 +3229,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" - }, "css-select": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", @@ -3444,24 +3275,11 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3525,19 +3343,6 @@ } } }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -3592,11 +3397,6 @@ "safer-buffer": "^2.1.0" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -3615,11 +3415,6 @@ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz", "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=" }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -3674,19 +3469,11 @@ } }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3703,14 +3490,6 @@ "is-glob": "^4.0.1" } }, - "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", - "requires": { - "ini": "^1.3.5" - } - }, "got": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", @@ -3765,12 +3544,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "he": { "version": "1.2.0", @@ -3844,11 +3618,6 @@ } } }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3870,12 +3639,7 @@ "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" }, "imurmurhash": { "version": "0.1.4", @@ -3936,46 +3700,24 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==" }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, - "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - } - }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -3986,16 +3728,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - }, - "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==" - }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -4011,11 +3743,6 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -4045,11 +3772,6 @@ "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.6.0.tgz", "integrity": "sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==" }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -4076,14 +3798,6 @@ "verror": "1.10.0" } }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "requires": { - "json-buffer": "3.0.0" - } - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -4227,21 +3941,6 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -4260,15 +3959,10 @@ "mime-db": "1.44.0" } }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } @@ -4300,152 +3994,34 @@ } }, "nodemon": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", - "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==", + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", "requires": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", + "chokidar": "^3.5.2", + "debug": "^3.2.7", "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^4.0.0" + "undefsafe": "^2.0.5" }, "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "requires": { - "package-json": "^6.3.0" - } - }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "requires": { - "rc": "^1.2.8" - } - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "supports-color": { "version": "5.5.0", @@ -4454,49 +4030,13 @@ "requires": { "has-flag": "^3.0.0" } - }, - "update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", - "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - } - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" } } }, "nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", "requires": { "abbrev": "1" } @@ -4506,11 +4046,6 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" - }, "nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", @@ -4556,11 +4091,6 @@ "os-tmpdir": "^1.0.0" } }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" - }, "package-json": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", @@ -4604,9 +4134,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pinkie": { "version": "2.0.4", @@ -4649,28 +4179,11 @@ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", - "requires": { - "escape-goat": "^2.0.0" - } - }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -4747,21 +4260,13 @@ } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } }, - "registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", - "requires": { - "rc": "^1.2.8" - } - }, "registry-url": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", @@ -4815,14 +4320,6 @@ "uuid": "^3.3.2" } }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -4859,10 +4356,20 @@ "semver": "^5.0.3" } }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + } + } }, "slide": { "version": "1.1.6", @@ -4929,40 +4436,10 @@ "strip-ansi": "^3.0.0" } }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "strip-ansi": { "version": "3.0.1", @@ -4996,11 +4473,6 @@ "whet.extend": "~0.9.9" } }, - "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==" - }, "terser": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", @@ -5031,11 +4503,6 @@ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo=" }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5079,19 +4546,6 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", @@ -5109,20 +4563,9 @@ "optional": true }, "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "requires": { - "debug": "^2.2.0" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "requires": { - "crypto-random-string": "^2.0.0" - } + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" }, "update-notifier": { "version": "0.5.0", @@ -5146,21 +4589,6 @@ "punycode": "^2.1.0" } }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": { - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5186,14 +4614,6 @@ "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=" }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "requires": { - "string-width": "^4.0.0" - } - }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index 38eff204..70e769a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wled", - "version": "0.14.0-b1.18", + "version": "0.14.0-b2.20", "description": "Tools for WLED project", "main": "tools/cdata.js", "directories": { @@ -25,7 +25,7 @@ "clean-css": "^4.2.3", "html-minifier-terser": "^5.1.1", "inliner": "^1.13.1", - "nodemon": "^2.0.4", + "nodemon": "^2.0.20", "zlib": "^1.0.5" } } diff --git a/platformio.ini b/platformio.ini index df6c8b11..88b21140 100644 --- a/platformio.ini +++ b/platformio.ini @@ -40,27 +40,36 @@ ; =================== default_envs = - esp32_4MB_max ; recommended default - esp32_4MB_all - esp32_16MB_max - esp32_16MB_all - esp8266_4MB_min - esp8266_4MB_max - esp32_4MB_PSRAM_max - esp32S3_8MB_max - wemos_shield_esp32_4MB_max - wemos_shield_esp32_4MB_ICS4343x_max - wemos_shield_esp32_4MB_SPM1423_max - wemos_shield_esp32_4MB_LineIn_max - wemos_shield_esp32_16MB_max - wemos_shield_esp32_16MB_ICS4343x_max - wemos_shield_esp32_16MB_SPM1423_max - wemos_shield_esp32_16MB_SPM1423_all - wemos_shield_esp32_16MB_LineIn_max - esp32_pico_4MB_max - esp32s2_tinyUF2_PSRAM_max - esp8266pro_16MB_min - esp01_1MB_min + esp32_4MB_M ; recommended default + esp32_4MB_M_debug + esp32_4MB_XL + esp32_16MB_M + esp32_16MB_M_debug + esp32_16MB_XL + esp8266_4MB_S + esp8266_4MB_M + wemos_shield_esp32_4MB_M + wemos_shield_esp32_4MB_ICS4343x_M + wemos_shield_esp32_4MB_SPM1423_M + wemos_shield_esp32_4MB_LineIn_M + wemos_shield_esp32_16MB_M + wemos_shield_esp32_16MB_ICS4343x_M + wemos_shield_esp32_16MB_SPM1423_M + wemos_shield_esp32_16MB_SPM1423_XL + wemos_shield_esp32_16MB_LineIn_M + esp32_pico_4MB_M + esp32_4MB_PSRAM_M + esp32S3_8MB_M + esp32s2_tinyUF2_PSRAM_M ;; experimental - only for adafruit -S2 boards with tinyUF2 bootloader !!! + esp32c3dev_4MB_M ;; experimental + esp32_4MB_V4_S ;; experimental + esp32_16MB_V4_M ;; experimental + esp32_16MB_V4_M_debug ;; experimental + esp8266pro_16MB_S + esp8266pro_16MB_M + esp01_1MB_S + esp32_16MB_M_eth + athom_music_esp32_4MB_M ; Go to MoonModules environments for environments @@ -138,6 +147,8 @@ build_flags = -D DECODE_SONY=true -D DECODE_SAMSUNG=true -D DECODE_LG=true + ;-D DECODE_RC5=true + ;-D DECODE_RC6=true ; -Dregister= # remove warnings in C++17 due to use of deprecated register keyword by the FastLED library -DWLED_USE_MY_CONFIG ; -D USERMOD_SENSORSTOMQTT @@ -183,7 +194,7 @@ upload_speed = 115200 # Please note that we don't always use the latest version of a library. # # The following libraries have been included (and some of them changd) in the source: -# ArduinoJson@5.13.5, Blynk@0.5.4(changed), E131@1.0.0(changed), Time@1.5, Timezone@1.2.1 +# ArduinoJson@5.13.5, E131@1.0.0(changed), Time@1.5, Timezone@1.2.1 # ------------------------------------------------------------------------------ lib_compat_mode = strict lib_deps = @@ -248,7 +259,8 @@ build_flags = -g -D LOROL_LITTLEFS ; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when builing with arduino-esp32 >=2.0.3 -default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv +default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv ;; WLED standard for 4MB flash: 1.4MB firmware, 1MB filesystem +;default_partitions = tools/WLED_ESP32_4MB_256KB_FS.csv ;; Alternative for 4MB flash: 1.8MB firmware, 256KB filesystem (esptool erase_flash needed before changing) lib_deps = ${env.lib_deps} @@ -281,9 +293,10 @@ lib_depsV4 = [esp32s2] build_flags = -g - -DARDUINO_ARCH_ESP32 + -DARDUINO_ARCH_ESP32 -DESP32 ;; WLEDMM -DARDUINO_ARCH_ESP32S2 -DCONFIG_IDF_TARGET_ESP32S2 + -DCONFIG_LITTLEFS_FOR_IDF_3_2 -DLFS_THREADSAFE ;; WLEDMM -D CONFIG_ASYNC_TCP_USE_WDT=0 -DCO -DARDUINO_USB_MODE=0 ;; this flag is mandatory for ESP32-S2 ! @@ -297,9 +310,10 @@ lib_deps = [esp32c3] build_flags = -g - -DARDUINO_ARCH_ESP32 + -DARDUINO_ARCH_ESP32 -DESP32 ;; WLEDMM -DARDUINO_ARCH_ESP32C3 -DCONFIG_IDF_TARGET_ESP32C3 + -DCONFIG_LITTLEFS_FOR_IDF_3_2 -DLFS_THREADSAFE ;; WLEDMM -D CONFIG_ASYNC_TCP_USE_WDT=0 -DCO -DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C3 @@ -318,6 +332,7 @@ build_flags = -g -DARDUINO_ARCH_ESP32 -DARDUINO_ARCH_ESP32S3 -DCONFIG_IDF_TARGET_ESP32S3 + -DCONFIG_LITTLEFS_FOR_IDF_3_2 -DLFS_THREADSAFE ;; WLEDMM -D CONFIG_ASYNC_TCP_USE_WDT=0 -DCO ;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry: @@ -327,7 +342,7 @@ lib_deps = ${env.lib_deps} ;; currently we need the latest NeoPixelBus dev version, because it contains important bugfixes for -S3 ;https://github.com/Makuna/NeoPixelBus.git#master ;; NPB 2.6.9 tends to crash whith IDF V4.4.3 -> use latest NeoPixelBus dev instead - makuna/NeoPixelBus @ 2.7.1 + makuna/NeoPixelBus @ ~2.7.1 https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 @@ -341,7 +356,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D WLED_DISABLE_BLYNK #-DWLED_DISABLE_2D +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 #-DWLED_DISABLE_2D lib_deps = ${esp8266.lib_deps} monitor_filters = esp8266_exception_decoder @@ -351,17 +366,17 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02 -D WLED_DISABLE_BLYNK +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02 lib_deps = ${esp8266.lib_deps} -; WLEDMM see below +;WLEDMM: see below ; [env:esp01_1m_full] ; board = esp01_1m ; platform = ${common.platform_wled_default} ; platform_packages = ${common.platform_packages} ; board_build.ldscript = ${common.ldscript_1m128k} ; build_unflags = ${common.build_unflags} -; build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA -D WLED_DISABLE_BLYNK +; build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA ; lib_deps = ${esp8266.lib_deps} [env:esp07] @@ -407,7 +422,7 @@ board = esp32dev platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 -D WLED_DISABLE_BLYNK #-D WLED_DISABLE_BROWNOUT_DET +build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET lib_deps = ${esp32.lib_deps} monitor_filters = esp32_exception_decoder board_build.partitions = ${esp32.default_partitions} @@ -417,7 +432,7 @@ board = esp32dev platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_qio80 -D WLED_DISABLE_BLYNK #-D WLED_DISABLE_BROWNOUT_DET +build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_qio80 #-D WLED_DISABLE_BROWNOUT_DET lib_deps = ${esp32.lib_deps} monitor_filters = esp32_exception_decoder board_build.partitions = ${esp32.default_partitions} @@ -430,7 +445,7 @@ platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} upload_speed = 921600 build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 -D WLED_DISABLE_BLYNK +build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 lib_deps = ${esp32.lib_deps} board_build.partitions = ${esp32.default_partitions} @@ -651,20 +666,58 @@ board_build.ldscript = ${common.ldscript_2m512k} build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 -D BTNPIN=2 -D IRPIN=5 -D WLED_MAX_BUTTONS=3 lib_deps = ${esp8266.lib_deps} -[env:athom7w] -board = esp_wroom_02 +[env:Athom_RGBCW] ;7w and 5w(GU10) bulbs +board = esp8285 platform = ${common.platform_wled_default} +platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} -build_flags = ${common.build_flags_esp8266} -D WLED_MAX_CCT_BLEND=0 -D BTNPIN=-1 -D IRPIN=-1 -D WLED_DISABLE_INFRARED +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,13,5 + -D DEFAULT_LED_TYPE=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 lib_deps = ${esp8266.lib_deps} -[env:athom15w] -board = esp_wroom_02 + +[env:Athom_15w_RGBCW] ;15w bulb +board = esp8285 platform = ${common.platform_wled_default} +platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} -build_flags = ${common.build_flags_esp8266} -D WLED_USE_IC_CCT -D BTNPIN=-1 -D IRPIN=-1 -D WLED_DISABLE_INFRARED +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,5,13 + -D DEFAULT_LED_TYPE=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 -D WLED_USE_IC_CCT lib_deps = ${esp8266.lib_deps} + +[env:Athom_3Pin_Controller] ;small controller with only data +board = esp8285 +platform = ${common.platform_wled_default} +platform_packages = ${common.platform_packages} +board_build.ldscript = ${common.ldscript_2m512k} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=0 -D RLYPIN=-1 -D LEDPIN=1 -D WLED_DISABLE_INFRARED +lib_deps = ${esp8266.lib_deps} + + +[env:Athom_4Pin_Controller] ; With clock and data interface +board = esp8285 +platform = ${common.platform_wled_default} +platform_packages = ${common.platform_packages} +board_build.ldscript = ${common.ldscript_2m512k} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=0 -D RLYPIN=12 -D LEDPIN=1 -D WLED_DISABLE_INFRARED +lib_deps = ${esp8266.lib_deps} + + +[env:Athom_5Pin_Controller] ;Analog light strip controller +board = esp8285 +platform = ${common.platform_wled_default} +platform_packages = ${common.platform_packages} +board_build.ldscript = ${common.ldscript_2m512k} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=0 -D RLYPIN=-1 DATA_PINS=4,12,14,13 -D WLED_DISABLE_INFRARED +lib_deps = ${esp8266.lib_deps} + + [env:MY9291] board = esp01_1m platform = ${common.platform_wled_default} @@ -710,7 +763,6 @@ build_flags = ${common.build_flags_esp32} -D WLED_DISABLE_BROWNOUT_DET -D WLED_D -D LEDPIN=12 -D RLYPIN=27 -D BTNPIN=34 - -D WLED_DISABLE_BLYNK -D DEFAULT_LED_COUNT=6 # Display config -D ST7789_DRIVER @@ -743,21 +795,15 @@ board_build.partitions = ${esp32.default_partitions} ; shared build flags and lib deps for minimum and maximum environment [common_mm] -build_flags_min = +build_flags_S = -Wall -Wformat -Woverflow -Wuninitialized -Winit-self -Warray-bounds ; enables more warnings -Wno-attributes -Wno-unused-variable -Wno-unused-function -Wno-deprecated-declarations ;disables some stupid warnings - -D WLED_DISABLE_BLYNK ; BLYNK is only provided for backwards compatibility (no new users accepted) ;-D WLED_DISABLE_BROWNOUT_DET ; enable if you get "brownout detected" errors at startup -D WLED_USE_MY_CONFIG ; -D WLED_USE_CIE_BRIGHTNESS_TABLE ;; experimental: use different color / brightness lookup table -D USERMOD_AUDIOREACTIVE -D UM_AUDIOREACTIVE_USE_NEW_FFT ; use latest (upstream) FFTLib, instead of older library modified by blazoncek. Slightly faster, more accurate, needs 2KB RAM extra -D USERMOD_CUSTOMEFFECTS ; WLEDMM usermod - ; -D WLED_DEBUG_HOST='"192.168.xxx.xxx"' ;; to send debug messages over network to host 192.168.x.y - FQDN is also possible - ; -D WLED_DEBUG_NET_PORT=1768 ;; port for network debugging. default = 7868 - ; -D WLED_DEBUG ; lots of generic debug messages - ; -D SR_DEBUG ; some extra debug messages from audioreactive - ; -D MIC_LOGGER ; for sound input monitoring & debugging (use arduino serial plotter) ; -D WLED_DISABLE_LOXONE ; -D WLED_DISABLE_ALEXA ; -D WLED_DISABLE_HUESYNC @@ -765,13 +811,13 @@ build_flags_min = ; -D WLED_DISABLE_INFRARED ; -D WLED_ENABLE_DMX -lib_deps_min = +lib_deps_S = https://github.com/kosme/arduinoFFT#develop @ 1.9.2 ; used for USERMOD_AUDIOREACTIVE -build_flags_max = - -D WLED_MAX_USERMODS=25 ; default only 4-6, also for _all configs takes 25 pointers in memory - ;; -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4 ewowi to softhack: move to build_flags_min? - We need a different solution - -D WLED_USE_MY_CONFIG ; include custom my_config.h ewowi to softhack: redundant as also in build_flags_min? +build_flags_M = + -D WLED_MAX_USERMODS=25 ; default only 4-6, also for _XL configs takes 25 pointers in memory + ;; -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4 ewowi to softhack: move to build_flags_S? - We need a different solution + -D WLED_USE_MY_CONFIG ; include custom my_config.h ewowi to softhack: redundant as also in build_flags_S? -D USERMOD_DALLASTEMPERATURE -D USE_ALT_DISPLAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI -D USERMOD_FOUR_LINE_DISPLAY @@ -780,19 +826,24 @@ build_flags_max = -D USERMOD_WEATHER ; WLEDMM usermod -D USERMOD_MPU6050_IMU ; gyro/accelero for USERMOD_GAMES (ONLY WORKS IF USERMOD_FOUR_LINE_DISPLAY NOT INCLUDED - I2C SHARING BUG) -D USERMOD_GAMES ; WLEDMM usermod + ;WLEDMM: only setting WLED_DEBUG_HOST is enough, ip and port can be defined in sync settings as well + -D WLED_DEBUG_HOST='"192.168.x.x"' ;; to send debug messages over network to host 192.168.x.y - FQDN is also possible + -D WLED_DEBUG_PORT=1768 ;; port for network debugging. default = 7868 -lib_deps_max = +lib_deps_M = + ;https://github.com/blazoncek/OneWire.git ; includes bugfixes for inconsistent readings OneWire@~2.3.5 ; used for USERMOD_FOUR_LINE_DISPLAY and USERMOD_DALLASTEMPERATURE olikraus/U8g2 @ ^2.28.8 ; used for USERMOD_FOUR_LINE_DISPLAY ElectronicCats/MPU6050 @ 0.6.0 ; used for USERMOD_MPU6050_IMU -lib_deps_V4_max = +lib_deps_V4_M = + ;https://github.com/blazoncek/OneWire.git ; includes bugfixes for inconsistent readings paulstoffregen/OneWire@ ^2.3.7 ; used for USERMOD_DALLASTEMPERATURE -> need newer release with bugfixes for -S3; still requires TEMPERATURE_PIN < 46 olikraus/U8g2@ ^2.34.5 ; used for USERMOD_FOUR_LINE_DISPLAY -> need newer version with bugfixes for arduino-esp32 v2.0.4 (Wire inititialization) ElectronicCats/MPU6050 @ 0.6.0 ; used for USERMOD_MPU6050_IMU claws/BH1750 @^1.2.0 ; used for USERMOD_BH1750 -build_flags_all = +build_flags_XL = -D USERMOD_BATTERY ;; enable Battery usermod -D USERMOD_BATTERY_USE_LIPO ;; use new "decharging curve" for LiPo cells -D USERMOD_BH1750 @@ -811,7 +862,7 @@ build_flags_all = -D USERMOD_VL53L0X_GESTURES -D WLED_ENABLE_PIXART -lib_deps_all = +lib_deps_XL = claws/BH1750 @^1.2.0 ; used for USERMOD_BH1750 ; adafruit/Adafruit BMP280 Library @ 2.1.0 ;; experimental for usermod USERMOD_SENSORSTOMQTT ; adafruit/Adafruit CCS811 Library @ 1.0.4 ;; experimental for usermod USERMOD_SENSORSTOMQTT @@ -825,54 +876,52 @@ lib_deps_all = ; base entries (without WLED_RELEASE_NAME) ; common defaults for all MM environments -[esp32_4MB_min_base] +[esp32_4MB_S_base] board = esp32dev platform = ${esp32.platform} upload_speed = 460800 ; or 921600 platform_packages = ${esp32.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} ${common_mm.build_flags_min} -lib_deps = ${esp32.lib_deps} ${common_mm.lib_deps_min} +build_flags = ${common.build_flags_esp32} ${common_mm.build_flags_S} +lib_deps = ${esp32.lib_deps} ${common_mm.lib_deps_S} board_build.partitions = ${esp32.default_partitions} board_build.f_flash = 80000000L ; use full 80MHz speed for flash (default = 40Mhz) board_build.flash_mode = dio ; (dio = dual i/o; more compatible than qio = quad i/o) -; monitor_filters = esp32_exception_decoder ; used to show crash details ;common default for all max environments -[esp32_4MB_max_base] -extends = esp32_4MB_min_base -build_flags = ${esp32_4MB_min_base.build_flags} ${common_mm.build_flags_max} -lib_deps = ${esp32_4MB_min_base.lib_deps} ${common_mm.lib_deps_max} -board_build.partitions = ${esp32_4MB_min_base.board_build.partitions} +[esp32_4MB_M_base] +extends = esp32_4MB_S_base +build_flags = ${esp32_4MB_S_base.build_flags} ${common_mm.build_flags_M} +lib_deps = ${esp32_4MB_S_base.lib_deps} ${common_mm.lib_deps_M} ; board_build.partitions = tools/WLED_ESP32-wrover_4MB.csv -[esp32_4MB_all_base] -extends = esp32_4MB_max_base -build_flags = ${esp32_4MB_max_base.build_flags} ${common_mm.build_flags_all} -lib_deps = ${esp32_4MB_max_base.lib_deps} ${common_mm.lib_deps_all} +[esp32_4MB_XL_base] +extends = esp32_4MB_M_base +build_flags = ${esp32_4MB_M_base.build_flags} ${common_mm.build_flags_XL} +lib_deps = ${esp32_4MB_M_base.lib_deps} ${common_mm.lib_deps_XL} ; board_build.partitions = tools/WLED_ESP32-wrover_4MB.csv ;common default for all V4 min environments -[esp32_4MB_V4_min_base] +[esp32_4MB_V4_S_base] board = esp32dev upload_speed = 460800 ; or 921600 platform = ${esp32.platformV4} platform_packages = ${esp32.platformV4_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${common_mm.build_flags_min} +build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${common_mm.build_flags_S} -Wno-misleading-indentation -Wno-format-truncation -lib_deps = ${esp32.lib_depsV4} ${common_mm.lib_deps_min} +lib_deps = ${esp32.lib_depsV4} ${common_mm.lib_deps_S} board_build.partitions = ${esp32.default_partitions} board_build.f_flash = 80000000L ; use full 80MHz speed for flash (default = 40Mhz) board_build.flash_mode = dio ; (dio = dual i/o; more compatible than qio = quad i/o) ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation ; monitor_filters = esp32_exception_decoder ; used to show crash details -[esp32_4MB_V4_max_base] -extends = esp32_4MB_V4_min_base -build_flags = ${esp32_4MB_V4_min_base.build_flags} ${common_mm.build_flags_max} -lib_deps = ${esp32_4MB_V4_min_base.lib_deps} ${common_mm.lib_deps_max} -board_build.partitions = ${esp32_4MB_V4_min_base.board_build.partitions} +[esp32_4MB_V4_M_base] +extends = esp32_4MB_V4_S_base +build_flags = ${esp32_4MB_V4_S_base.build_flags} ${common_mm.build_flags_M} +lib_deps = ${esp32_4MB_V4_S_base.lib_deps} ${common_mm.lib_deps_V4_M} +board_build.partitions = ${esp32_4MB_V4_S_base.board_build.partitions} ;board_build.flash_mode = qio ; (dio = dual i/o; more compatible than qio = quad i/o) [Shield_ICS4343x] @@ -885,14 +934,22 @@ build_flags = -D SR_DMTYPE=5 -D I2S_SDPIN=32 -D I2S_WSPIN=15 -D I2S_CKPIN=-1 ; for I2S PDM microphone -D SR_SQUELCH=3 -D SR_GAIN=75 -D SR_FREQ_PROF=7 ; SPM1423 specific +[Athom_PDMmic] +build_flags = + -D SR_DMTYPE=51 -D I2S_SDPIN=32 -D I2S_WSPIN=15 -D I2S_CKPIN=-1 ; for I2S PDM microphone Legacy mode! + -D SR_SQUELCH=10 -D SR_GAIN=40 -D SR_FREQ_PROF=7 ; SPM1423 specific + [Shield_LineIn] build_flags = -D SR_DMTYPE=4 -D MCLK_PIN=0 -D I2S_SDPIN=25 -D I2S_WSPIN=15 -D I2S_CKPIN=14 ; for audio Line-In shield -D SR_SQUELCH=2 -D SR_GAIN=40 -D SR_FREQ_PROF=1 ; CS5343 Line-In specific -[Board_ESP32_16MB] ; ESP32 with 16MB Flash -board = esp32_16MB -board_build.partitions = tools/WLED_ESP32_16MB.csv +[Debug_Flags] +build_flags = + -D WLED_DEBUG ; lots of generic debug messages + -D SR_DEBUG ; some extra debug messages from audioreactive + ; -D MIC_LOGGER ; for sound input monitoring & debugging (use arduino serial plotter) + ; NetDebug moved to build_flags_M ; end of base entries @@ -900,55 +957,94 @@ board_build.partitions = tools/WLED_ESP32_16MB.csv ; bin entries (with WLED_RELEASE_NAME) -[env:esp32_4MB_min] -extends = esp32_4MB_min_base -build_flags = ${esp32_4MB_min_base.build_flags} - -D WLED_RELEASE_NAME=esp32_4MB_min - ; RAM: [== ] 24.1% (used 78900 bytes from 327680 bytes) - ; Flash: [======== ] 83.7% (used 1315729 bytes from 1572864 bytes) +[env:esp32_4MB_S] +extends = esp32_4MB_S_base +build_flags = ${esp32_4MB_S_base.build_flags} + -D WLED_RELEASE_NAME=esp32_4MB_S +; RAM: [== ] 24.1% (used 78988 bytes from 327680 bytes) +; Flash: [========= ] 85.7% (used 1348593 bytes from 1572864 bytes) WLEDMM: Earlier 83.7 -[env:esp32_4MB_max] -extends = esp32_4MB_max_base -build_flags = ${esp32_4MB_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32_4MB_max - ; RAM: [== ] 24.4% (used 79804 bytes from 327680 bytes) - ; Flash: [========= ] 88.7% (used 1394813 bytes from 1572864 bytes) +[env:esp32_4MB_M] +extends = esp32_4MB_M_base +build_flags = ${esp32_4MB_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_4MB_M +; RAM: [== ] 24.4% (used 79956 bytes from 327680 bytes) +; Flash: [========= ] 91.1% (used 1432245 bytes from 1572864 bytes) WLEDMM: earlier 88.7 -[env:esp32_4MB_all] -extends = esp32_4MB_all_base -build_flags = ${esp32_4MB_all_base.build_flags} - -D WLED_RELEASE_NAME=esp32_4MB_all - ; RAM: [== ] 24.4% (used 79804 bytes from 327680 bytes) - ; Flash: [========= ] 88.7% (used 1394813 bytes from 1572864 bytes) +[env:esp32_4MB_XL] +extends = esp32_4MB_XL_base +build_flags = ${esp32_4MB_XL_base.build_flags} + -D WLED_RELEASE_NAME=esp32_4MB_XL +; RAM: [== ] 24.4% (used 80060 bytes from 327680 bytes) +; Flash: [==========] 95.3% (used 1499037 bytes from 1572864 bytes) -[env:esp32_16MB_max] -extends = esp32_4MB_max_base -build_flags = ${esp32_4MB_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32_16MB_max -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:esp32_16MB_M] +extends = esp32_4MB_M_base +build_flags = ${esp32_4MB_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_16MB_M +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem ; RAM: [== ] 24.4% (used 79916 bytes from 327680 bytes) ; Flash: [======= ] 67.0% (used 1405701 bytes from 2097152 bytes) ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation -[env:esp32_16MB_all] -extends = esp32_4MB_all_base -build_flags = ${esp32_4MB_all_base.build_flags} - -D WLED_RELEASE_NAME=esp32_16MB_all -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:esp32_4MB_M_debug] +extends = esp32_4MB_M_base +build_unflags = ${common.build_unflags} + -D CORE_DEBUG_LEVEL=0 +build_flags = ${esp32_4MB_M_base.build_flags} + ${Debug_Flags.build_flags} + -D CORE_DEBUG_LEVEL=2 ;; 2=warning + -D WLED_RELEASE_NAME=esp32_4MB_M_debug +monitor_filters = esp32_exception_decoder +; RAM: [== ] 24.5% (used 80292 bytes from 327680 bytes) +; Flash: [========= ] 94.5% (used 1487113 bytes from 1572864 bytes) + +[env:esp32_16MB_M_debug] +extends = esp32_4MB_M_base +build_unflags = ${common.build_unflags} + -D CORE_DEBUG_LEVEL=0 +build_flags = ${esp32_4MB_M_base.build_flags} + ${Debug_Flags.build_flags} + -D CORE_DEBUG_LEVEL=2 ;; 2=warning + -D WLED_RELEASE_NAME=esp32_16MB_M_debug +monitor_filters = esp32_exception_decoder +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem +; RAM: [== ] 24.5% (used 80292 bytes from 327680 bytes) +; Flash: [======= ] 70.9% (used 1487129 bytes from 2097152 bytes) + +[env:esp32_16MB_XL] +extends = esp32_4MB_XL_base +build_flags = ${esp32_4MB_XL_base.build_flags} + -D WLED_RELEASE_NAME=esp32_16MB_XL +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem ; RAM: [== ] 24.4% (used 79916 bytes from 327680 bytes) ; Flash: [======= ] 67.0% (used 1405701 bytes from 2097152 bytes) ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation -[env:esp8266_4MB_min] +[env:esp32_16MB_M_eth] +extends = esp32_4MB_M_base +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem +board = esp32_16MB-poe ;; needed for ethernet boards (selects "esp32-poe" as variant) +build_flags = ${esp32_4MB_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_16MB_M_eth ; This will be included in the firmware.bin filename + -D WLED_USE_ETHERNET +; RAM: [== ] 24.5% (used 80348 bytes from 327680 bytes) +; Flash: [======= ] 69.4% (used 1455233 bytes from 2097152 bytes) + +[env:esp8266_4MB_S] extends = env:d1_mini upload_speed = 460800 ;115200 board_build.f_cpu = 160000000L ;; we want 160Mhz (default = 80Mhz) build_flags = ${common.build_flags_esp8266} - -D WLED_RELEASE_NAME=esp8266_4MB_min + -D WLED_RELEASE_NAME=esp8266_4MB_S -D WLED_DISABLE_ALEXA - -D WLED_DISABLE_BLYNK -D WLED_DISABLE_HUESYNC ; -D WLED_DISABLE_2D ; -UWLED_USE_MY_CONFIG @@ -957,15 +1053,14 @@ build_flags = ${common.build_flags_esp8266} ; RAM: [====== ] 59.3% (used 48608 bytes from 81920 bytes) ; Flash: [======== ] 77.0% (used 804176 bytes from 1044464 bytes) -[env:esp8266_4MB_max] +[env:esp8266_4MB_M] extends = env:d1_mini upload_speed = 460800 ;115200 board_build.f_cpu = 160000000L ;; we want 160Mhz (default = 80Mhz) build_flags = ${common.build_flags_esp8266} - -D WLED_RELEASE_NAME=esp8266_4MB_max + -D WLED_RELEASE_NAME=esp8266_4MB_M -D WLED_MAX_USERMODS=5 ; default only 4-6 -D WLED_DISABLE_ALEXA - -D WLED_DISABLE_BLYNK -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_LOXONE ; -D USERMOD_AUDIOREACTIVE @@ -993,7 +1088,6 @@ extends = env:d1_mini board_build.filesystem = littlefs build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D WLED_DISABLE_ALEXA - -D WLED_DISABLE_BLYNK -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_LOXONE -D WLED_DISABLE_AUDIO ;WLEDMM not used anywhere @@ -1017,7 +1111,7 @@ lib_deps = ${esp8266.lib_deps} olikraus/U8g2 # @~2.33.15 Wire ; WLEDMM needed? -[env:esp8266pro_16MB_min] +[env:esp8266pro_16MB_S] extends = env:d1_mini board = d1_mini_pro ;; "D1 mini pro": ESP8266EX, 160MHz, 80KB RAM, 16MB Flash board_build.f_cpu = 160000000L ;; we want 160Mhz (default = 80Mhz) @@ -1028,10 +1122,9 @@ board_build.ldscript = ${common.ldscript_16m14m} ;; 16MB flash, use 14MB for Lit upload_speed = 460800 ;115200 build_flags = ${common.build_flags_esp8266} - -D WLED_RELEASE_NAME=esp8266pro_16MB_min + -D WLED_RELEASE_NAME=esp8266pro_16MB_S -D WLED_WATCHDOG_TIMEOUT=0 -D WLED_DISABLE_ALEXA - -D WLED_DISABLE_BLYNK -D WLED_DISABLE_HUESYNC ; -D WLED_DEBUG ; -D WLED_DISABLE_2D @@ -1042,17 +1135,53 @@ monitor_filters = esp8266_exception_decoder ; RAM: [====== ] 59.3% (used 48616 bytes from 81920 bytes) ; Flash: [======== ] 77.0% (used 804236 bytes from 1044464 bytes) -[env:esp01_1MB_min] +[env:esp8266pro_16MB_M] +extends = env:d1_mini +board = d1_mini_pro ;; "D1 mini pro": ESP8266EX, 160MHz, 80KB RAM, 16MB Flash +board_build.f_cpu = 160000000L ;; we want 160Mhz (default = 80Mhz) +;board_build.f_flash = 80000000L ;; for 80Mhz flash speed, in case your chip can handle it (default = 40Mhz) +board_build.flash_mode = qio ;; quad IO - fastest speed, in case your chip can handle it. +;;board_build.flash_mode = dout ;; use if your esp8266 becomes unstable with "qio" +board_build.ldscript = ${common.ldscript_16m14m} ;; 16MB flash, use 14MB for LittleFS + +upload_speed = 460800 ;115200 +build_flags = ${common.build_flags_esp8266} + -D WLED_RELEASE_NAME=esp8266pro_16MB_M + -D WLED_MAX_USERMODS=5 ; default only 4-6 + -D WLED_DISABLE_ALEXA + -D WLED_DISABLE_HUESYNC + -D WLED_DISABLE_LOXONE + ; -D USERMOD_AUDIOREACTIVE + ; -D USERMOD_CUSTOMEFFECTS ; to be done + -D USERMOD_PIRSWITCH + -D USERMOD_DALLASTEMPERATURE ;; disabled because it hangs during usermod setup on -S3 (autodetect broken?) + -D USERMOD_MULTI_RELAY + -D USE_ALT_DISPLAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI + -D USERMOD_FOUR_LINE_DISPLAY + -D USERMOD_MPU6050_IMU ; gyro/accelero for USERMOD_GAMES (ONLY WORKS IF USERMOD_FOUR_LINE_DISPLAY NOT INCLUDED - I2C SHARING BUG) + -D USERMOD_GAMES ; WLEDMM usermod + ; -D WLED_DEBUG +monitor_filters = esp8266_exception_decoder +lib_deps = ${esp8266.lib_deps} + OneWire@~2.3.5 ; used for USERMOD_FOUR_LINE_DISPLAY and USERMOD_DALLASTEMPERATURE + olikraus/U8g2 @ ^2.28.8 ; used for USERMOD_FOUR_LINE_DISPLAY + ElectronicCats/MPU6050 @ 0.6.0 ; used for USERMOD_MPU6050_IMU +; RAM: [====== ] 62.4% (used 51092 bytes from 81920 bytes) +; Flash: [========= ] 85.5% (used 893056 bytes from 1044464 bytes) + +[env:esp01_1MB_S] board = esp01_1m platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_1m128k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_BLYNK - -D WLED_RELEASE_NAME=esp01_1MB_min +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA + -D WLED_RELEASE_NAME=esp01_1MB_S -D WLED_DISABLE_ALEXA -D WLED_DISABLE_HUESYNC lib_deps = ${esp8266.lib_deps} +; RAM: [====== ] 59.5% (used 48748 bytes from 81920 bytes) +; Flash: [========= ] 90.7% (used 809992 bytes from 892912 bytes) # ------------------------------------------------------------------------------ @@ -1062,10 +1191,10 @@ lib_deps = ${esp8266.lib_deps} ;; When upgrading to the new framework, it might be necessary to first do a chip erase (make sure you have a backup of cfg.json and presets.json) ; compiled with ESP-IDF 4.4.1 -[env:esp32_4MB_V4_min] -extends = esp32_4MB_V4_min_base -build_flags = ${esp32_4MB_V4_min_base.build_flags} - -D WLED_RELEASE_NAME=esp32_4MB_V4_min +[env:esp32_4MB_V4_S] +extends = esp32_4MB_V4_S_base +build_flags = ${esp32_4MB_V4_S_base.build_flags} + -D WLED_RELEASE_NAME=esp32_4MB_V4_S -D WLED_WATCHDOG_TIMEOUT=0 #-D WLED_DISABLE_BROWNOUT_DET -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4; avoids errors on startup -D WLED_DISABLE_LOXONE @@ -1081,10 +1210,10 @@ build_flags = ${esp32_4MB_V4_min_base.build_flags} ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation ; compiled with ESP-IDF 4.4.1 -[env:esp32_4MB_V4_max] -extends = esp32_4MB_V4_max_base -build_flags = ${esp32_4MB_V4_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32_4MB_V4_max +[env:esp32_4MB_V4_M] +extends = esp32_4MB_V4_M_base +build_flags = ${esp32_4MB_V4_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_4MB_V4_M -D WLED_WATCHDOG_TIMEOUT=0 #-D WLED_DISABLE_BROWNOUT_DET -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4; avoids errors on startup ; RAM: [== ] 24.8% (used 81316 bytes from 327680 bytes) @@ -1099,24 +1228,42 @@ build_flags = ${esp32_4MB_V4_max_base.build_flags} ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation ; compiled with ESP-IDF 4.4.1 -[env:esp32_16MB_V4_max] -extends = esp32_4MB_V4_max_base -build_flags = ${esp32_4MB_V4_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32_16MB_V4_max +[env:esp32_16MB_V4_M] +extends = esp32_4MB_V4_M_base +build_flags = ${esp32_4MB_V4_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_16MB_V4_M -D WLED_WATCHDOG_TIMEOUT=0 #-D WLED_DISABLE_BROWNOUT_DET -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4; avoids errors on startup -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem ; RAM: [== ] 24.8% (used 81316 bytes from 327680 bytes) ; Flash: [======= ] 72.9% (used 1528253 bytes from 2097152 bytes) +[env:esp32_16MB_V4_M_debug] +extends = esp32_4MB_V4_M_base +build_unflags = ${common.build_unflags} + -D CORE_DEBUG_LEVEL=0 +build_flags = ${esp32_4MB_V4_M_base.build_flags} + ${Debug_Flags.build_flags} + -D CORE_DEBUG_LEVEL=4 ;; 0=none, 1=error, 2=warning, 3=info, 4=debug, 5=verbose + -D WLED_RELEASE_NAME=esp32_16MB_V4_M_debug + -D WLED_WATCHDOG_TIMEOUT=0 #-D WLED_DISABLE_BROWNOUT_DET + -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4; avoids errors on startup +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem +monitor_filters = esp32_exception_decoder +; RAM: [=== ] 25.0% (used 82008 bytes from 327680 bytes) +; Flash: [======== ] 78.1% (used 1638193 bytes from 2097152 bytes) WLEDMM: Earlier 76.9 + ;; experimental environment for boards with PSRAM (needs ESP-IDF 4.4.1). -[env:esp32_4MB_PSRAM_max] -extends = esp32_4MB_V4_max_base +[env:esp32_4MB_PSRAM_M] +extends = esp32_4MB_V4_M_base board = lolin_d32_pro ;board = esp32cam -build_flags = ${esp32_4MB_V4_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32_4MB_PSRAM_max +build_flags = ${esp32_4MB_V4_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_4MB_PSRAM_M -D WLED_WATCHDOG_TIMEOUT=0 #-D WLED_DISABLE_BROWNOUT_DET -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4; avoids errors on startup -D WLED_USE_PSRAM @@ -1129,14 +1276,16 @@ build_flags = ${esp32_4MB_V4_max_base.build_flags} -D WLED_DISABLE_HUESYNC ;RAM 122 bytes; FLASH 6308 bytes ; RAM: [== ] 24.7% (used 80948 bytes from 327680 bytes) ; Flash: [==========] 97.4% (used 1532485 bytes from 1572864 bytes) - ;-D WLED_DISABLE_INFRARED ;RAM 136 bytes; FLASH 24492 bytes + -D WLED_DISABLE_INFRARED ;RAM 136 bytes; FLASH 24492 bytes ewowi: disabled to stay below 100% + ; RAM: [== ] 24.7% (used 81000 bytes from 327680 bytes) + ; Flash: [==========] 98.6% (used 1550569 bytes from 1572864 bytes) ; -D WLED_ENABLE_DMX ; -D WLED_DEBUG ; -D SR_DEBUG ; -D MIC_LOGGER -[env:esp32S3_8MB_max] -extends = esp32_4MB_V4_max_base +[env:esp32S3_8MB_M] +extends = esp32_4MB_V4_M_base board = esp32-s3-devkitc-1 build_unflags = -D USERMOD_DALLASTEMPERATURE ;; disabled because it hangs during usermod setup on -S3 (autodetect broken?) @@ -1145,12 +1294,14 @@ build_unflags = -D USERMOD_ROTARY_ENCODER_UI ;; see above -D WLED_ENABLE_DMX ;; disabled because it does not work with ESP-IDF 4.4.x (buggy driver in SparkFunDMX) -build_flags = ${esp32_4MB_V4_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32S3_8MB_max - -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=0 -D ARDUINO_USB_MSC_ON_BOOT=0 -D ARDUINO_USB_DFU_ON_BOOT=0 - -D WLED_WATCHDOG_TIMEOUT=0 +build_flags = ${common.build_flags} ${esp32s3.build_flags} -Wno-misleading-indentation -Wno-format-truncation + ${common_mm.build_flags_S} ${common_mm.build_flags_M} + -D WLED_RELEASE_NAME=esp32S3_8MB_M + -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=0 -D ARDUINO_USB_MSC_ON_BOOT=0 -D ARDUINO_USB_DFU_ON_BOOT=0 ;; for Serial-to-USB chip + ;; -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MSC_ON_BOOT=0 -D ARDUINO_USB_DFU_ON_BOOT=0 ;; for Hardware-CDC USB mode + ;; -D WLED_DISABLE_ADALIGHT ;; disables serial protocols when using CDC USB (Serial RX will receive junk commands when RX pin is unconnected, unless its pulled down by resistor) + -D WLED_WATCHDOG_TIMEOUT=0 -D CONFIG_ASYNC_TCP_USE_WDT=0 ; -D U8X8_HAVE_2ND_HW_I2C ;; experimental - tells U8g2 lib that a second HW I2C unit exists - -D WLED_DISABLE_BLYNK ;; seems that BLYNK does not work on -S3 -D WLED_DISABLE_LOXONE ; FLASH 1272 bytes -D WLED_DISABLE_ALEXA ; RAM 116 bytes; FLASH 13524 bytes ; -D WLED_DISABLE_MQTT ; RAM 216 bytes; FLASH 16496 bytes @@ -1174,7 +1325,7 @@ build_flags = ${esp32_4MB_V4_max_base.build_flags} ; -D WLED_DEBUG ; -D SR_DEBUG ; -D MIC_LOGGER -lib_deps = ${esp32s3.lib_deps} ${common_mm.lib_deps_min} ${common_mm.lib_deps_V4_max} +lib_deps = ${esp32s3.lib_deps} ${common_mm.lib_deps_S} ${common_mm.lib_deps_V4_M} ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation board_build.partitions = tools/WLED_ESP32_8MB.csv board_build.flash_mode = qio @@ -1183,13 +1334,13 @@ board_build.flash_mode = qio ;; MM max for Adafruit QT Py ESP32-S2 -> 4MB flash, PSRAM, and tinyUF2 bootloader ;; to ewowi - i'll optimize this entry later, as a few things can be inherited for sure. To softhack: sure ;-) -[env:esp32s2_tinyUF2_PSRAM_max] -extends = esp32_4MB_V4_min_base +[env:esp32s2_tinyUF2_PSRAM_M] +extends = esp32_4MB_V4_S_base platform = ${esp32.platformV4} platform_packages = ${esp32.platformV4_packages} board = adafruit_qtpy_esp32s2 -board_build.partitions = tools/partitions-4MB-tinyuf2_spiffs.csv ;; this is needed for tinyUF2 bootloader! +board_build.partitions = tools/partitions-4MB_spiffs-tinyuf2.csv ;; this is needed for tinyUF2 bootloader! Filename has to end in "tinyuf2.csv" board_build.f_flash = 80000000L board_build.flash_mode = qio upload_speed = 256000 ;; 921600 @@ -1200,17 +1351,21 @@ build_unflags = ${common.build_unflags} -D USERMOD_ROTARY_ENCODER_UI ;; see above -D WLED_ENABLE_DMX ;; disabled because it does not work with ESP-IDF 4.4.x (buggy driver in SparkFunDMX) -build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${esp32s2.build_flags} +build_flags = ${common.build_flags} ${esp32s2.build_flags} + ; ${Debug_Flags.build_flags} ;ewowi: enabling debug causes Error: The program size (1463330 bytes) is greater than maximum allowed (1441792 bytes) -D WLED_WATCHDOG_TIMEOUT=0 -D CONFIG_ASYNC_TCP_USE_WDT=0 - ${common_mm.build_flags_min} ${common_mm.build_flags_max} + ${common_mm.build_flags_S} ${common_mm.build_flags_M} -Wno-misleading-indentation -Wno-format-truncation - -D WLED_RELEASE_NAME=esp32S2_4MB_UF2_max + -D WLED_RELEASE_NAME=esp32S2_4MB_UF2_M -DARDUINO_USB_CDC_ON_BOOT=1 ;; mandatory, otherwise USB does not work!! + -D WLED_DISABLE_ADALIGHT ;; disables serial protocols when using CDC USB (Serial RX will receive junk commands, unless its pulled down by resistor) -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -D SERVERNAME='"WLED-S2"' -D WLED_USE_PSRAM -D WLED_DISABLE_INFRARED ;; save flash space -D WLED_DISABLE_ALEXA ;; save flash space + -D WLED_DISABLE_HUESYNC ;; save flash space + -D WLED_DISABLE_LOXONE ;; save flash space -D LEDPIN=39 ;; onboard neopixel LED. Attach your own LEDs to GPIO 7 or GPIO 6 -D BTNPIN=0 ;-D RLYPIN=6 @@ -1227,26 +1382,22 @@ build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${esp32s2.build_flags -D MCLK_PIN=18 ;-D STATUSLED=-1 -D WLED_USE_MY_CONFIG - ; -D WLED_DEBUG_HOST='"192.168.xxx.xxx"' ;; to send debug messages over network to host 192.168.x.y - FQDN is also possible - ; -D WLED_DEBUG_NET_PORT=1768 ;; port for network debugging. default = 7868 - ; -D WLED_DEBUG - ; -D SR_DEBUG - ; -D MIC_LOGGER -lib_deps = ${env.lib_deps} ${esp32s2.lib_deps} ${common_mm.lib_deps_min} ${common_mm.lib_deps_V4_max} +lib_deps = ${env.lib_deps} ${esp32s2.lib_deps} ${common_mm.lib_deps_S} ${common_mm.lib_deps_V4_M} lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation monitor_filters = esp32_exception_decoder -; RAM: [=== ] 25.6% (used 83796 bytes from 327680 bytes) -; Flash: [==========] 97.7% (used 1408626 bytes from 1441792 bytes) +; RAM: [=== ] 25.4% (used 83324 bytes from 327680 bytes) +; Flash: [==========] 98.6% (used 1421778 bytes from 1441792 bytes) ;; MM max environment for ESP32-C3 -> 4MB flash, no PSRAM ;; to ewowi - i'll optimize this entry later ;-) really, I mean -[env:esp32c3dev_4MB_max] -extends = esp32_4MB_V4_min_base +[env:esp32c3dev_4MB_M] +extends = esp32_4MB_V4_S_base ;platform = ${esp32.platformV4} ;platform_packages = ${esp32.platformV4_packages} platform = espressif32@~5.2.0 ;; alternative platform, might help in case you experience bootloops due to corrupted flash filesystem platform_packages = board = esp32-c3-devkitm-1 +;board_build.partitions = tools/WLED_ESP32_2MB_noOTA.csv ;; for boards with 2MB flash only (like some Ai-Thinker ESP32-C3-12F models) upload_speed = 256000 ;; 921600 build_unflags = ${common.build_unflags} @@ -1256,12 +1407,14 @@ build_unflags = ${common.build_unflags} -D USERMOD_ROTARY_ENCODER_UI ;; see above -D WLED_ENABLE_DMX ;; disabled because it does not work with ESP-IDF 4.4.x (buggy driver in SparkFunDMX) -build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${esp32c3.build_flags} +build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_WATCHDOG_TIMEOUT=0 -D CONFIG_ASYNC_TCP_USE_WDT=0 - ${common_mm.build_flags_min} ${common_mm.build_flags_max} + ${common_mm.build_flags_S} ${common_mm.build_flags_M} -Wno-misleading-indentation -Wno-format-truncation - -D WLED_RELEASE_NAME=esp32c3dev_4MB_max + -D WLED_RELEASE_NAME=esp32c3dev_4MB_M + ; -D WLED_DISABLE_OTA ;; OTA is not possible for boards with 2MB flash only (like some Ai-Thinker ESP32-C3-12F models) ; -DARDUINO_USB_CDC_ON_BOOT=1 ;; enable CDC USB -> needed for debugging over serial USB + ; -D WLED_DISABLE_ADALIGHT ;; to disable serial protocols when using CDC USB (Serial RX will receive junk commands, unless its pulled down by resistor) -DARDUINO_USB_CDC_ON_BOOT=0 ;; disable CDC USB -D SERVERNAME='"WLED-C3"' ;-D WLEDMM_WIFI_POWERON_HACK ;; use this _only_ if your device is not able to make a WiFI connection! @@ -1276,7 +1429,7 @@ build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${esp32c3.build_flags -D SR_DMTYPE=1 -D I2S_SDPIN=5 -D I2S_WSPIN=6 -D I2S_CKPIN=4 -D MCLK_PIN=7 -D WLED_USE_MY_CONFIG -lib_deps = ${env.lib_deps} ${esp32c3.lib_deps} ${common_mm.lib_deps_min} ${common_mm.lib_deps_V4_max} +lib_deps = ${env.lib_deps} ${esp32c3.lib_deps} ${common_mm.lib_deps_S} ${common_mm.lib_deps_V4_M} ;lib_ignore = IRremoteESP8266 ; use with WLED_DISABLE_INFRARED for faster compilation ;monitor_filters = esp32_exception_decoder @@ -1284,9 +1437,9 @@ lib_deps = ${env.lib_deps} ${esp32c3.lib_deps} ${common_mm.lib_deps_min} ${commo # custom board environments # ------------------------------------------------------------------------------ -[wemos_shield_esp32_4MB_max_base] -extends = esp32_4MB_max_base -build_flags = ${esp32_4MB_max_base.build_flags} +[wemos_shield_esp32_4MB_M_base] +extends = esp32_4MB_M_base +build_flags = ${esp32_4MB_M_base.build_flags} -D ABL_MILLIAMPS_DEFAULT=9500 ; Wemos max 10A -D LEDPIN=16 -D RLYPIN=19 @@ -1297,115 +1450,139 @@ build_flags = ${esp32_4MB_max_base.build_flags} -D FLD_PIN_SCL=-1 -D FLD_PIN_SDA=-1 ; use global! -D HW_PIN_SCL=22 -D HW_PIN_SDA=21 -D HW_PIN_CLOCKSPI=-1 -D HW_PIN_MOSISPI=-1 -D HW_PIN_MISOSPI=-1 ; WLEDMM: is now also default but just to show we didn't agree on wemos pins for spi yet - -D ENCODER_DT_PIN=35 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=39 ;WLEDMM spec by @SERG74: use 35 and 39 instead of 18 and 19 (conflicts) + -D ENCODER_DT_PIN=35 -D ENCODER_CLK_PIN=39 -D ENCODER_SW_PIN=5 ; WLEDMM spec by @SERG74: use 35 and 39 instead of 18 and 19 (conflicts) -D PIR_SENSOR_PIN=-1 -D PWM_PIN=-1 ; -D WLED_USE_MY_CONFIG -[wemos_shield_esp32_4MB_all_base] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${common_mm.build_flags_all} -lib_deps = ${wemos_shield_esp32_4MB_max_base.lib_deps} ${common_mm.lib_deps_all} +[wemos_shield_esp32_4MB_XL_base] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${common_mm.build_flags_XL} +lib_deps = ${wemos_shield_esp32_4MB_M_base.lib_deps} ${common_mm.lib_deps_XL} -[env:wemos_shield_esp32_4MB_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_max +[env:wemos_shield_esp32_4MB_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_M ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [========= ] 88.6% (used 1393421 bytes from 1572864 bytes) -[env:wemos_shield_esp32_4MB_ICS4343x_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${Shield_ICS4343x.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_ICS4343x_max +[env:wemos_shield_esp32_4MB_ICS4343x_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${Shield_ICS4343x.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_ICS4343x_M ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [========= ] 88.6% (used 1393421 bytes from 1572864 bytes) -[env:wemos_shield_esp32_4MB_SPM1423_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${Shield_SPM1423.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_SPM1423_max +[env:wemos_shield_esp32_4MB_SPM1423_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${Shield_SPM1423.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_SPM1423_M ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [========= ] 88.6% (used 1393421 bytes from 1572864 bytes) -[env:wemos_shield_esp32_4MB_LineIn_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${Shield_LineIn.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_LineIn_max +[env:wemos_shield_esp32_4MB_LineIn_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${Shield_LineIn.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_4MB_LineIn_M -[env:wemos_shield_esp32_16MB_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_max -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:wemos_shield_esp32_16MB_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_M +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem +;board_build.flash_mode = qio ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [======= ] 66.4% (used 1393421 bytes from 2097152 bytes) -[env:wemos_shield_esp32_16MB_ICS4343x_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${Shield_ICS4343x.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_ICS4343x_max -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:wemos_shield_esp32_16MB_ICS4343x_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${Shield_ICS4343x.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_ICS4343x_M +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [========= ] 88.6% (used 1393421 bytes from 1572864 bytes) -[env:wemos_shield_esp32_16MB_ICS4343x_all] -extends = wemos_shield_esp32_4MB_all_base -build_flags = ${wemos_shield_esp32_4MB_all_base.build_flags} ${Shield_ICS4343x.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_ICS4343x_all -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:wemos_shield_esp32_16MB_ICS4343x_XL] +extends = wemos_shield_esp32_4MB_XL_base +build_flags = ${wemos_shield_esp32_4MB_XL_base.build_flags} ${Shield_ICS4343x.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_ICS4343x_XL +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem ; RAM: [== ] 24.4% (used 80044 bytes from 327680 bytes) ; Flash: [======= ] 67.9% (used 1424185 bytes from 2097152 bytes) -monitor_filters = esp32_exception_decoder ; used to show crash details -[env:wemos_shield_esp32_16MB_SPM1423_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${Shield_SPM1423.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_SPM1423_max -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:wemos_shield_esp32_16MB_SPM1423_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${Shield_SPM1423.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_SPM1423_M +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [========= ] 88.6% (used 1393421 bytes from 1572864 bytes) -monitor_filters = esp32_exception_decoder ; used to show crash details -[env:wemos_shield_esp32_16MB_SPM1423_all] -extends = wemos_shield_esp32_4MB_all_base -build_flags = ${wemos_shield_esp32_4MB_all_base.build_flags} ${Shield_SPM1423.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_SPM1423_all -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:wemos_shield_esp32_16MB_SPM1423_XL] +extends = wemos_shield_esp32_4MB_XL_base +build_flags = ${wemos_shield_esp32_4MB_XL_base.build_flags} ${Shield_SPM1423.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_SPM1423_XL +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem ; RAM: [== ] 24.4% (used 79820 bytes from 327680 bytes) ; Flash: [========= ] 88.6% (used 1393421 bytes from 1572864 bytes) -monitor_filters = esp32_exception_decoder ; used to show crash details -[env:wemos_shield_esp32_16MB_LineIn_max] -extends = wemos_shield_esp32_4MB_max_base -build_flags = ${wemos_shield_esp32_4MB_max_base.build_flags} ${Shield_LineIn.build_flags} - -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_LineIn_max -board = ${Board_ESP32_16MB.board} -board_build.partitions = ${Board_ESP32_16MB.board_build.partitions} +[env:wemos_shield_esp32_16MB_LineIn_M] +extends = wemos_shield_esp32_4MB_M_base +build_flags = ${wemos_shield_esp32_4MB_M_base.build_flags} ${Shield_LineIn.build_flags} + -D WLED_RELEASE_NAME=wemos_shield_esp32_16MB_LineIn_M +board = esp32_16MB +board_build.partitions = tools/WLED_ESP32_16MB.csv ;; WLED standard for 16MB flash: 2MB firmware, 12 MB filesystem +;board_build.partitions = tools/WLED_ESP32_16MB_9MB_FS.csv ;; WLED extended for 16MB flash: 3.2MB firmware, 9 MB filesystem + +[env:athom_music_esp32_4MB_M] +extends = esp32_4MB_M_base +build_flags = ${esp32_4MB_M_base.build_flags} ${Athom_PDMmic.build_flags} + -D WLED_AP_SSID_UNIQUE + -D WLED_RELEASE_NAME=athom_music_esp32_4MB_M + -D ABL_MILLIAMPS_DEFAULT=14500 ; max 15A + -D WLED_DISABLE_MQTT -D WLED_DISABLE_LOXONE + -D WLED_DISABLE_ADALIGHT ;to get 4ld working + -D BTNPIN=0 -D RLYPIN=2 -D IRPIN=25 -D IRTYPE=9 -D LEDPIN=18 -D + -D AUDIOPIN=-1 + ; -D TEMPERATURE_PIN=23 + -D FLD_PIN_SCL=-1 -D FLD_PIN_SDA=-1 ; use global! + -D HW_PIN_SCL=3 -D HW_PIN_SDA=1 ;4ld uses rx and tx + -D HW_PIN_CLOCKSPI=-1 -D HW_PIN_MOSISPI=-1 -D HW_PIN_MISOSPI=-1 ; WLEDMM: is now also default but just to show we didn't agree on wemos pins for spi yet + ; -D ENCODER_DT_PIN=35 -D ENCODER_CLK_PIN=39 -D ENCODER_SW_PIN=5 ; WLEDMM spec by @SERG74: use 35 and 39 instead of 18 and 19 (conflicts) + ; -D PIR_SENSOR_PIN=-1 + ; -D PWM_PIN=-1 + ; -D WLED_USE_MY_CONFIG ; ESP32 WLED pico board with builtin ICS-43432 microphpone -[env:esp32_pico_4MB_max] -extends = esp32_4MB_max_base +[env:esp32_pico_4MB_M] +extends = esp32_4MB_M_base board = pico32 -build_flags = ${esp32_4MB_max_base.build_flags} - -D WLED_RELEASE_NAME=esp32_pico_4MB_max +board_build.flash_mode = dout ;; (dout = dual out; more compatible than qio = quad i/o) +upload_speed = 256000 ;; or 115200 ;; or 460800 ; or 921600 (slower speeds are better when flashing without a soldered connection) + +build_flags = ${esp32_4MB_M_base.build_flags} + -D WLED_RELEASE_NAME=esp32_pico_4MB_M -D WLED_DISABLE_BROWNOUT_DET -D SERVERNAME='"WLED-pico32"' ; -D WLED_WATCHDOG_TIMEOUT=60 + -D WLED_DISABLE_ADALIGHT ;; WLEDMM this board does not have a serial-to-USB chip. Better to disable serial protocols, to avoid crashes (see upstream #3128) ; -D WLED_DEBUG ; -D SR_DEBUG -D LEDPIN=2 - -D RLYPIN=-1 - -D BTNPIN=-1 - -D IRPIN=-1 + -D RLYPIN=-1 -D BTNPIN=-1 -D IRPIN=-1 -D HW_PIN_SCL=22 -D HW_PIN_SDA=21 -D SR_DMTYPE=1 -D I2S_SDPIN=25 -D I2S_WSPIN=15 -D I2S_CKPIN=14 - -D SR_SQUELCH=5 -D SR_GAIN=30 -D SR_FREQ_PROF=5 ; ICS-43434 specific + -D SR_SQUELCH=5 -D SR_GAIN=30 -D SR_FREQ_PROF=5 ; ICS-4343x specific ; -D MCLK_PIN=0 -D SR_ENABLE_DEFAULT ;; enable at first start - no need to manually set "enable", then reboot ; -D WLED_USE_MY_CONFIG @@ -1415,5 +1592,36 @@ build_flags = ${esp32_4MB_max_base.build_flags} ; -D WLED_DISABLE_MQTT ; -D WLED_DISABLE_INFRARED ; -D WLED_ENABLE_DMX -; RAM: [== ] 24.4% (used 79804 bytes from 327680 bytes) -; Flash: [========= ] 88.6% (used 1394241 bytes from 1572864 bytes) +; RAM: [== ] 24.4% (used 79812 bytes from 327680 bytes) +; Flash: [========= ] 90.4% (used 1422581 bytes from 1572864 bytes) + + +;; experimental +;; PICO environment with ESP-IDF v4.4.1 / arduino-esp32 v2.0.4 +[env:esp32_pico_4MB_V4_S] +extends = esp32_4MB_V4_S_base +board = pico32 +;platform = espressif32@~5.2.0 ;; alternative platform, might help in case you experience bootloops due to corrupted flash filesystem +;platform_packages = +upload_speed = 256000 ;; or 115200 ;; or 460800 ; or 921600 (slower speeds are better when flashing without a soldered connection) + +build_flags = ${esp32_4MB_V4_S_base.build_flags} + -D ARDUINO_USB_CDC_ON_BOOT=0 ; needed for arduino-esp32 >=2.0.4; avoids errors on startup + -D WLED_RELEASE_NAME=esp32_pico_4MB_V4_S + -D WLED_DISABLE_BROWNOUT_DET + -D SERVERNAME='"WLED-pico32-V4"' + -D WLED_WATCHDOG_TIMEOUT=0 + -D WLED_DISABLE_ADALIGHT ;; WLEDMM this board does not have a serial-to-USB chip. Better to disable serial protocols, to avoid crashes (see upstream #3128) + ; -D WLED_WATCHDOG_TIMEOUT=60 + ; -D WLED_DEBUG + ; -D SR_DEBUG + -D LEDPIN=2 + -D RLYPIN=-1 -D BTNPIN=-1 -D IRPIN=-1 + -D HW_PIN_SCL=22 -D HW_PIN_SDA=21 + -D SR_DMTYPE=1 -D I2S_SDPIN=25 -D I2S_WSPIN=15 -D I2S_CKPIN=14 + -D SR_SQUELCH=5 -D SR_GAIN=30 -D SR_FREQ_PROF=5 ; ICS-4343x specific + ; -D MCLK_PIN=0 + -D SR_ENABLE_DEFAULT ;; enable audioreactive at first start - no need to manually set "enable", then reboot + ; -D WLED_USE_MY_CONFIG +; RAM: [== ] 24.5% (used 80436 bytes from 327680 bytes) +; Flash: [========= ] 93.9% (used 1476341 bytes from 1572864 bytes) diff --git a/platformio_override.ini.sample b/platformio_override.ini.sample index cd81c517..d6ea5d96 100644 --- a/platformio_override.ini.sample +++ b/platformio_override.ini.sample @@ -26,7 +26,6 @@ build_flags = ${common.build_flags_esp8266} ; disable specific features ; -D WLED_DISABLE_OTA ; -D WLED_DISABLE_ALEXA -; -D WLED_DISABLE_BLYNK ; -D WLED_DISABLE_HUESYNC ; -D WLED_DISABLE_INFRARED ; -D WLED_DISABLE_WEBSOCKETS diff --git a/readme.md b/readme.md index 15aaf885..fc5660c4 100644 --- a/readme.md +++ b/readme.md @@ -34,8 +34,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control ## 💡 Supported light control interfaces - WLED app for [Android](https://play.google.com/store/apps/details?id=com.aircoookie.WLED) and [iOS](https://apps.apple.com/us/app/wled/id1475695033) - JSON and HTTP request APIs -- MQTT -- Blynk IoT +- MQTT - E1.31, Art-Net, DDP and TPM2.net - [diyHue](https://github.com/diyhue/diyHue) (Wled is supported by diyHue, including Hue Sync Entertainment under udp. Thanks to [Gregory Mallios](https://github.com/gmallios)) - [Hyperion](https://github.com/hyperion-project/hyperion.ng) diff --git a/tools/SoundReactive_ESP32_16MB.csv b/tools/SoundReactive_ESP32_16MB.csv deleted file mode 100644 index e547a824..00000000 --- a/tools/SoundReactive_ESP32_16MB.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offsaet, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x200000, -app1, app, ota_1, 0x210000, 0x200000, -spiffs, data, spiffs, 0x410000, 0x7f0000, diff --git a/tools/WLED_ESP32_16MB_9MB_FS.csv b/tools/WLED_ESP32_16MB_9MB_FS.csv new file mode 100644 index 00000000..9ecac04e --- /dev/null +++ b/tools/WLED_ESP32_16MB_9MB_FS.csv @@ -0,0 +1,8 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x300000, +app1, app, ota_1, 0x310000,0x300000, +spiffs, data, spiffs, 0x610000,0x9E0000, +coredump, data, coredump,0xFF0000,0x10000, +# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage \ No newline at end of file diff --git a/tools/WLED_ESP32_2MB_noOTA.csv b/tools/WLED_ESP32_2MB_noOTA.csv new file mode 100644 index 00000000..7a1cf15f --- /dev/null +++ b/tools/WLED_ESP32_2MB_noOTA.csv @@ -0,0 +1,5 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +app0, app, ota_0, 0x10000, 1536K, +spiffs, data, spiffs, 0x190000, 384K, diff --git a/tools/WLED_ESP32_4MB_256KB_FS.csv b/tools/WLED_ESP32_4MB_256KB_FS.csv new file mode 100644 index 00000000..f9e1be26 --- /dev/null +++ b/tools/WLED_ESP32_4MB_256KB_FS.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1D0000, +app1, app, ota_1, 0x1E0000,0x1D0000, +spiffs, data, spiffs, 0x3B0000,0x40000, +coredump, data, coredump,0x3F0000,0x10000, \ No newline at end of file diff --git a/tools/partitions-4MB-tinyuf2_spiffs.csv b/tools/partitions-4MB_spiffs-tinyuf2.csv similarity index 100% rename from tools/partitions-4MB-tinyuf2_spiffs.csv rename to tools/partitions-4MB_spiffs-tinyuf2.csv diff --git a/usermods/BH1750_v2/usermod_bh1750.h b/usermods/BH1750_v2/usermod_bh1750.h index 360c28db..77a57efb 100644 --- a/usermods/BH1750_v2/usermod_bh1750.h +++ b/usermods/BH1750_v2/usermod_bh1750.h @@ -2,13 +2,12 @@ // #warning **** Included USERMOD_BH1750 **** #ifndef WLED_ENABLE_MQTT -#error "This user mod requires MQTT to be enabled." +#warning "This user mod expects MQTT to be enabled." #endif #pragma once #include // WLEDMM: make sure that I2C drivers have the "right" Wire Object -#include #include "wled.h" #include @@ -20,7 +19,8 @@ // the min frequency to check photoresistor, 500 ms #ifndef USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL -#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 500 +//#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 500 +#define USERMOD_BH1750_MIN_MEASUREMENT_INTERVAL 2500 // WLEDMM this makes more sense #endif // how many seconds after boot to take first measurement, 10 seconds @@ -30,7 +30,7 @@ // only report if differance grater than offset value #ifndef USERMOD_BH1750_OFFSET_VALUE -#define USERMOD_BH1750_OFFSET_VALUE 1 +#define USERMOD_BH1750_OFFSET_VALUE 2 // WLEDMM this makes more sense #endif class Usermod_BH1750 : public Usermod @@ -91,14 +91,17 @@ private: // set up Home Assistant discovery entries void _mqttInitialize() { +#ifdef WLED_ENABLED_MQTT mqttLuminanceTopic = String(mqttDeviceTopic) + F("/brightness"); if (HomeAssistantDiscovery) _createMqttSensor(F("Brightness"), mqttLuminanceTopic, F("Illuminance"), F(" lx")); +#endif } // Create an MQTT Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement) { +#ifdef WLED_ENABLED_MQTT String t = String(F("homeassistant/sensor/")) + mqttClientID + F("/") + name + F("/config"); StaticJsonDocument<600> doc; @@ -125,11 +128,13 @@ private: DEBUG_PRINTLN(temp); mqtt->publish(t.c_str(), 0, true, temp.c_str()); +#endif } public: void setup() { +#if 0 bool HW_Pins_Used = (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda); // note whether architecture-based hardware SCL/SDA pins used PinOwner po = PinOwner::UM_BH1750; // defaults to being pinowner for SCL/SDA pins if (HW_Pins_Used) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins @@ -147,13 +152,18 @@ public: #else //Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed. #endif +#endif + if (!enabled) return; if (!pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously sensorFound = false; - enabled = false; + //enabled = false; + USER_PRINTLN(F("BH1750: failed to join I2C bus.")); return; } sensorFound = lightMeter.begin(); + if (sensorFound) { USER_PRINTLN(F("BH1750 sensor found.")); } + else{ USER_PRINTLN(F("BH1750 sensor not found.")); } initDone = true; } @@ -226,7 +236,7 @@ public: lux_json.add(F(" sec until read")); return; } else { - lux_json.add(lastLux); + lux_json.add(round(lastLux)); // WLEDMM lux_json.add(F(" lx")); } } @@ -295,6 +305,7 @@ public: } else { DEBUG_PRINTLN(F(" config (re)loaded.")); // changing parameters from settings page +#if 0 bool pinsChanged = false; for (byte i=0; i<2; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; } // check if any pins changed if (pinsChanged) { //if pins changed, deallocate old pins and allocate new ones @@ -305,6 +316,9 @@ public: for (byte i=0; i<2; i++) ioPin[i] = newPin[i]; setup(); } +#else + if (enabled && !sensorFound) setup(); +#endif // use "return !top["newestParameter"].isNull();" when updating Usermod with new features return !top[F("pin")].isNull(); } diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index 099c59da..288edb32 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -371,6 +371,7 @@ public: * onStateChanged() is used to detect WLED state change */ void onStateChange(uint8_t mode) { + if (!initDone) return; DEBUG_PRINT(F("PIR: offTimerStart=")); DEBUG_PRINTLN(offTimerStart); if (PIRtriggered && offTimerStart) { // checking PIRtriggered and offTimerStart will prevent cancellation upon On trigger diff --git a/usermods/RTC/usermod_rtc.h b/usermods/RTC/usermod_rtc.h index f25e16e3..08b92ef1 100644 --- a/usermods/RTC/usermod_rtc.h +++ b/usermods/RTC/usermod_rtc.h @@ -6,6 +6,8 @@ #include "src/dependencies/time/DS1307RTC.h" #include "wled.h" +#define RTC_DELTA 2 // only modify RTC time if delta exceeds this number of seconds + //Connect DS1307 to standard I2C pins (ESP32: GPIO 21 (SDA)/GPIO 22 (SCL)) class RTCUsermod : public Usermod { @@ -36,6 +38,7 @@ class RTCUsermod : public Usermod { if (rtcTime) { toki.setTime(rtcTime,TOKI_NO_MS_ACCURACY,TOKI_TS_RTC); updateLocalTime(); + USER_PRINTLN(F("Localtime updated from RTC.")); } else { if (!RTC.chipPresent()) disabled = true; //don't waste time if H/W error } @@ -45,7 +48,24 @@ class RTCUsermod : public Usermod { if (strip.isUpdating()) return; if (!disabled && toki.isTick()) { time_t t = toki.second(); - if (abs(t - RTC.get())> 2) RTC.set(t); //set RTC to NTP/UI-provided value - WLEDMM allow up to 3 sec deviation + + if (abs(t - RTC.get())> RTC_DELTA) { // WLEDMM only consider time diffs > 2 seconds + if ( (toki.getTimeSource() == TOKI_TS_NTP) + ||( (toki.getTimeSource() != TOKI_TS_NONE) && (toki.getTimeSource() != TOKI_TS_RTC) + && (toki.getTimeSource() != TOKI_TS_BAD) && (toki.getTimeSource() != TOKI_TS_UDP_SEC) && (toki.getTimeSource() != TOKI_TS_UDP))) + { // WLEMM update RTC if we have a reliable time source + RTC.set(t); //set RTC to NTP/UI-provided value - WLEDMM allow up to 3 sec deviation + USER_PRINTLN(F("RTC updated using localtime.")); + } else { + // WLEDMM if no reliable time -> update from RTC + time_t rtcTime = RTC.get(); + if (rtcTime) { + toki.setTime(rtcTime,TOKI_NO_MS_ACCURACY,TOKI_TS_RTC); + updateLocalTime(); + USER_PRINTLN(F("Localtime updated from RTC.")); + } + } + } } } diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index 153a502f..885f445e 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -21,7 +21,6 @@ class UsermodTemperature : public Usermod { private: - bool initDone = false; OneWire *oneWire; // GPIO pin used for sensor (with a default compile-time fallback) int8_t temperaturePin = TEMPERATURE_PIN; @@ -45,13 +44,9 @@ class UsermodTemperature : public Usermod { // temperature if flashed to a board without a sensor attached byte sensorFound; - bool enabled = true; - bool HApublished = false; // strings to reduce flash memory usage (used more than twice) - static const char _name[]; - static const char _enabled[]; static const char _readInterval[]; static const char _parasite[]; static const char _parasitePin[]; @@ -163,6 +158,7 @@ class UsermodTemperature : public Usermod { #endif public: + UsermodTemperature(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM: this shouldn't be necessary (passthrough of constructor), maybe because Usermod is an abstract class void setup() { int retries = 10; @@ -325,9 +321,10 @@ class UsermodTemperature : public Usermod { * addToConfig() (called from set.cpp) stores persistent properties to cfg.json */ void addToConfig(JsonObject &root) { + Usermod::addToConfig(root); + JsonObject top = root[FPSTR(_name)]; + // we add JSON object: {"Temperature": {"pin": 0, "degC": true}} - JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname - top[FPSTR(_enabled)] = enabled; top["pin"] = temperaturePin; // usermodparam top["degC"] = degC; // usermodparam top[FPSTR(_readInterval)] = readingInterval / 1000; @@ -342,17 +339,18 @@ class UsermodTemperature : public Usermod { * The function should return true if configuration was successfully loaded or false if there was no configuration. */ bool readFromConfig(JsonObject &root) { + bool configComplete = Usermod::readFromConfig(root); + JsonObject top = root[FPSTR(_name)]; + // we look for JSON object: {"Temperature": {"pin": 0, "degC": true}} int8_t newTemperaturePin = temperaturePin; DEBUG_PRINT(FPSTR(_name)); - JsonObject top = root[FPSTR(_name)]; if (top.isNull()) { DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); return false; } - enabled = top[FPSTR(_enabled)] | enabled; newTemperaturePin = top["pin"] | newTemperaturePin; degC = top["degC"] | degC; readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000; @@ -398,8 +396,6 @@ class UsermodTemperature : public Usermod { }; // strings to reduce flash memory usage (used more than twice) -const char UsermodTemperature::_name[] PROGMEM = "Temperature"; -const char UsermodTemperature::_enabled[] PROGMEM = "enabled"; const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s"; const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr"; const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin"; diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 865049db..99d6d7bf 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -29,9 +29,9 @@ // #define SR_DEBUG // generic SR DEBUG messages #ifdef SR_DEBUG - #define DEBUGSR_PRINT(x) DEBUGOUT.print(x) - #define DEBUGSR_PRINTLN(x) DEBUGOUT.println(x) - #define DEBUGSR_PRINTF(x...) DEBUGOUT.printf(x) + #define DEBUGSR_PRINT(x) DEBUGOUT(x) + #define DEBUGSR_PRINTLN(x) DEBUGOUTLN(x) + #define DEBUGSR_PRINTF(x...) DEBUGOUTF(x) #else #define DEBUGSR_PRINT(x) #define DEBUGSR_PRINTLN(x) @@ -55,10 +55,10 @@ #endif #if defined(MIC_LOGGER) || defined(FFT_SAMPLING_LOG) - #define PLOT_PRINT(x) DEBUGOUT.print(x) - #define PLOT_PRINTLN(x) DEBUGOUT.println(x) - #define PLOT_PRINTF(x...) DEBUGOUT.printf(x) - #define PLOT_FLUSH() DEBUGOUT.flush() + #define PLOT_PRINT(x) DEBUGOUT(x) + #define PLOT_PRINTLN(x) DEBUGOUTLN(x) + #define PLOT_PRINTF(x...) DEBUGOUTF(x) + #define PLOT_FLUSH() DEBUGOUTFlush() #else #define PLOT_PRINT(x) #define PLOT_PRINTLN(x) @@ -123,6 +123,15 @@ static AudioSource *audioSource = nullptr; static volatile bool disableSoundProcessing = false; // if true, sound processing (FFT, filters, AGC) will be suspended. "volatile" as its shared between tasks. static bool useBandPassFilter = false; // if true, enables a bandpass filter 80Hz-16Khz to remove noise. Applies before FFT. +//WLEDMM add experimental settings +static uint8_t micLevelMethod = 0; // 0=old "floating" miclev, 1=new "freeze" mode, 2=fast freeze mode (mode 2 may not work for you) +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) +static uint8_t averageByRMS = false; // false: use mean value, true: use RMS (root mean squared). use simpler method on slower MCUs. +#else +static uint8_t averageByRMS = true; // false: use mean value, true: use RMS (root mean squared). use better method on fast MCUs. +#endif +static uint8_t freqDist = 0; // 0=old 1=rightshift mode + // audioreactive variables shared with FFT task static float micDataReal = 0.0f; // MicIn data with full 24bit resolution - lowest 8bit after decimal point static float multAgc = 1.0f; // sample * multAgc = sampleAgc. Our AGC multiplier @@ -136,7 +145,7 @@ static float volumeSmth = 0.0f; // either sampleAvg or sampleAgc depending // peak detection static bool samplePeak = false; // Boolean flag for peak - used in effects. Responding routine may reset this flag. Auto-reset after strip.getMinShowDelay() -static uint8_t maxVol = 10; // Reasonable value for constant volume for 'peak detector', as it won't always trigger (deprecated) +static uint8_t maxVol = 31; // (was 10) Reasonable value for constant volume for 'peak detector', as it won't always trigger (deprecated) static uint8_t binNum = 8; // Used to select the bin for FFT based beat detection (deprecated) static bool udpSamplePeak = false; // Boolean flag for peak. Set at the same tiem as samplePeak, but reset by transmitAudioData static unsigned long timeOfPeak = 0; // time of last sample peak detection. @@ -264,7 +273,8 @@ constexpr uint16_t samplesFFT = 512; // Samples in an FFT batch - Thi constexpr uint16_t samplesFFT_2 = 256; // meaningfull part of FFT results - only the "lower half" contains useful information. // the following are observed values, supported by a bit of "educated guessing" //#define FFT_DOWNSCALE 0.65f // 20kHz - downscaling factor for FFT results - "Flat-Top" window @20Khz, old freq channels -#define FFT_DOWNSCALE 0.46f // downscaling factor for FFT results - for "Flat-Top" window @22Khz, new freq channels +//#define FFT_DOWNSCALE 0.46f // downscaling factor for FFT results - for "Flat-Top" window @22Khz, new freq channels +#define FFT_DOWNSCALE 0.40f // downscaling factor for FFT results, RMS averaging #define LOG_256 5.54517744f // log(256) // These are the input and output vectors. Input vectors receive computed results from FFT. @@ -303,23 +313,28 @@ static float mapf(float x, float in_min, float in_max, float out_min, float out_ } // compute average of several FFT resut bins -#if 1 // linear average -static float fftAddAvg(int from, int to) { +// linear average +static float fftAddAvgLin(int from, int to) { float result = 0.0f; for (int i = from; i <= to; i++) { result += vReal[i]; } return result / float(to - from + 1); } -#else // RMS average -static float fftAddAvg(int from, int to) { +// RMS average +static float fftAddAvgRMS(int from, int to) { double result = 0.0; for (int i = from; i <= to; i++) { result += vReal[i] * vReal[i]; } return sqrtf(result / float(to - from + 1)); } -#endif + +static float fftAddAvg(int from, int to) { + if (from == to) return vReal[from]; // small optimization + if (averageByRMS) return fftAddAvgRMS(from, to); // use SMS + else return fftAddAvgLin(from, to); // use linear average +} #if defined(CONFIG_IDF_TARGET_ESP32C3) constexpr bool skipSecondFFT = true; @@ -512,35 +527,67 @@ void FFTcode(void * parameter) fftCalc[14] = fftAddAvg(147,194); // 2940 - 3900 fftCalc[15] = fftAddAvg(194,250); // 3880 - 5000 // avoid the last 5 bins, which are usually inaccurate #else - /* new mapping, optimized for 22050 Hz by softhack007 */ + //WLEDMM: different distributions + if (freqDist == 0) { + /* new mapping, optimized for 22050 Hz by softhack007 --- update: removed overlap */ // bins frequency range if (useBandPassFilter) { // skip frequencies below 100hz - fftCalc[ 0] = 0.8f * fftAddAvg(3,4); - fftCalc[ 1] = 0.9f * fftAddAvg(4,5); - fftCalc[ 2] = fftAddAvg(5,6); - fftCalc[ 3] = fftAddAvg(6,7); + fftCalc[ 0] = 0.8f * fftAddAvg(3,3); + fftCalc[ 1] = 0.9f * fftAddAvg(4,4); + fftCalc[ 2] = fftAddAvg(5,5); + fftCalc[ 3] = fftAddAvg(6,6); // don't use the last bins from 206 to 255. fftCalc[15] = fftAddAvg(165,205) * 0.75f; // 40 7106 - 8828 high -- with some damping } else { - fftCalc[ 0] = fftAddAvg(1,2); // 1 43 - 86 sub-bass - fftCalc[ 1] = fftAddAvg(2,3); // 1 86 - 129 bass - fftCalc[ 2] = fftAddAvg(3,5); // 2 129 - 216 bass - fftCalc[ 3] = fftAddAvg(5,7); // 2 216 - 301 bass + midrange + fftCalc[ 0] = fftAddAvg(1,1); // 1 43 - 86 sub-bass + fftCalc[ 1] = fftAddAvg(2,2); // 1 86 - 129 bass + fftCalc[ 2] = fftAddAvg(3,4); // 2 129 - 216 bass + fftCalc[ 3] = fftAddAvg(5,6); // 2 216 - 301 bass + midrange // don't use the last bins from 216 to 255. They are usually contaminated by aliasing (aka noise) fftCalc[15] = fftAddAvg(165,215) * 0.70f; // 50 7106 - 9259 high -- with some damping } - fftCalc[ 4] = fftAddAvg(7,10); // 3 301 - 430 midrange - fftCalc[ 5] = fftAddAvg(10,13); // 3 430 - 560 midrange - fftCalc[ 6] = fftAddAvg(13,19); // 5 560 - 818 midrange - fftCalc[ 7] = fftAddAvg(19,26); // 7 818 - 1120 midrange -- 1Khz should always be the center ! - fftCalc[ 8] = fftAddAvg(26,33); // 7 1120 - 1421 midrange - fftCalc[ 9] = fftAddAvg(33,44); // 9 1421 - 1895 midrange - fftCalc[10] = fftAddAvg(44,56); // 12 1895 - 2412 midrange + high mid - fftCalc[11] = fftAddAvg(56,70); // 14 2412 - 3015 high mid - fftCalc[12] = fftAddAvg(70,86); // 16 3015 - 3704 high mid - fftCalc[13] = fftAddAvg(86,104); // 18 3704 - 4479 high mid - fftCalc[14] = fftAddAvg(104,165) * 0.88f; // 61 4479 - 7106 high mid + high -- with slight damping + fftCalc[ 4] = fftAddAvg(7,9); // 3 301 - 430 midrange + fftCalc[ 5] = fftAddAvg(10,12); // 3 430 - 560 midrange + fftCalc[ 6] = fftAddAvg(13,18); // 5 560 - 818 midrange + fftCalc[ 7] = fftAddAvg(19,25); // 7 818 - 1120 midrange -- 1Khz should always be the center ! + fftCalc[ 8] = fftAddAvg(26,32); // 7 1120 - 1421 midrange + fftCalc[ 9] = fftAddAvg(33,43); // 9 1421 - 1895 midrange + fftCalc[10] = fftAddAvg(44,55); // 12 1895 - 2412 midrange + high mid + fftCalc[11] = fftAddAvg(56,69); // 14 2412 - 3015 high mid + fftCalc[12] = fftAddAvg(70,85); // 16 3015 - 3704 high mid + fftCalc[13] = fftAddAvg(86,103); // 18 3704 - 4479 high mid + fftCalc[14] = fftAddAvg(104,164) * 0.88f; // 61 4479 - 7106 high mid + high -- with slight damping + } + else if (freqDist == 1) { //WLEDMM: Rightshft: note ewowi: frequencies in comments are not correct + if (useBandPassFilter) { + // skip frequencies below 100hz + fftCalc[ 0] = 0.8f * fftAddAvg(1,1); + fftCalc[ 1] = 0.9f * fftAddAvg(2,2); + fftCalc[ 2] = fftAddAvg(3,3); + fftCalc[ 3] = fftAddAvg(4,4); + // don't use the last bins from 206 to 255. + fftCalc[15] = fftAddAvg(165,205) * 0.75f; // 40 7106 - 8828 high -- with some damping + } else { + fftCalc[ 0] = fftAddAvg(1,1); // 1 43 - 86 sub-bass + fftCalc[ 1] = fftAddAvg(2,2); // 1 86 - 129 bass + fftCalc[ 2] = fftAddAvg(3,3); // 2 129 - 216 bass + fftCalc[ 3] = fftAddAvg(4,4); // 2 216 - 301 bass + midrange + // don't use the last bins from 216 to 255. They are usually contaminated by aliasing (aka noise) + fftCalc[15] = fftAddAvg(165,215) * 0.70f; // 50 7106 - 9259 high -- with some damping + } + fftCalc[ 4] = fftAddAvg(5,6); // 3 301 - 430 midrange + fftCalc[ 5] = fftAddAvg(7,8); // 3 430 - 560 midrange + fftCalc[ 6] = fftAddAvg(9,10); // 5 560 - 818 midrange + fftCalc[ 7] = fftAddAvg(11,13); // 7 818 - 1120 midrange -- 1Khz should always be the center ! + fftCalc[ 8] = fftAddAvg(14,18); // 7 1120 - 1421 midrange + fftCalc[ 9] = fftAddAvg(19,25); // 9 1421 - 1895 midrange + fftCalc[10] = fftAddAvg(26,36); // 12 1895 - 2412 midrange + high mid + fftCalc[11] = fftAddAvg(37,45); // 14 2412 - 3015 high mid + fftCalc[12] = fftAddAvg(46,66); // 16 3015 - 3704 high mid + fftCalc[13] = fftAddAvg(67,97); // 18 3704 - 4479 high mid + fftCalc[14] = fftAddAvg(98,164) * 0.88f; // 61 4479 - 7106 high mid + high -- with slight damping + } #endif } else { // noise gate closed - just decay old values isFirstRun = false; @@ -1057,6 +1104,10 @@ class AudioReactive : public Usermod { const float weighting = 0.2f; // Exponential filter weighting. Will be adjustable in a future release. const float weighting2 = 0.073f; // Exponential filter weighting, for rising signal (a bit more robust against spikes) const int AGC_preset = (soundAgc > 0)? (soundAgc-1): 0; // make sure the _compiler_ knows this value will not change while we are inside the function + static bool isFrozen = false; + static bool haveSilence = true; + static unsigned long lastSoundTime = 0; // for delaying un-freeze + static unsigned long startuptime = 0; // "fast freeze" mode: do not interfere during first 12 seconds (filter startup time) #ifdef WLED_DISABLE_SOUND micIn = inoise8(millis(), millis()); // Simulated analog read @@ -1079,8 +1130,15 @@ class AudioReactive : public Usermod { #endif #endif - micLev += (micDataReal-micLev) / 12288.0f; - if(micIn < micLev) micLev = ((micLev * 31.0f) + micDataReal) / 32.0f; // align MicLev to lowest input signal + if (startuptime == 0) startuptime = millis(); // fast freeze mode - remember filter startup time + if ((micLevelMethod < 1) || !isFrozen) { // following the input level, UNLESS mic Level was frozen + micLev += (micDataReal-micLev) / 12288.0f; + } + + if(micDataReal < (micLev-0.24)) { // MicLev above input signal: + micLev = ((micLev * 31.0f) + micDataReal) / 32.0f; // always align MicLev to lowest input signal + if (!haveSilence) isFrozen = true; // freeze mode: freeze micLevel so it cannot rise again + } micIn -= micLev; // Let's center it to 0 now // Using an exponential filter to smooth out the signal. We'll add controls for this in a future release. @@ -1093,10 +1151,26 @@ class AudioReactive : public Usermod { expAdjF = fabsf(expAdjF); // Now (!) take the absolute value + if ((micLevelMethod == 2) && !haveSilence && (expAdjF >= (1.5f * float(soundSquelch)))) + isFrozen = true; // fast freeze mode: freeze micLevel once the volume rises 50% above squelch + //expAdjF = (micInNoDC <= soundSquelch) ? 0: expAdjF; // simple noise gate - experimental expAdjF = (expAdjF <= soundSquelch) ? 0: expAdjF; // simple noise gate if ((soundSquelch == 0) && (expAdjF < 0.25f)) expAdjF = 0; // do something meaningfull when "squelch = 0" + if (expAdjF <= 0.5f) + haveSilence = true; + else { + lastSoundTime = millis(); + haveSilence = false; + } + + // un-freeze micLev + if (micLevelMethod == 0) isFrozen = false; + if ((micLevelMethod == 1) && isFrozen && haveSilence && ((millis() - lastSoundTime) > 4000)) isFrozen = false; // normal freeze: 4 seconds silence needed + if ((micLevelMethod == 2) && isFrozen && haveSilence && ((millis() - lastSoundTime) > 6000)) isFrozen = false; // fast freeze: 6 seconds silence needed + if ((micLevelMethod == 2) && (millis() - startuptime < 12000)) isFrozen = false; // fast freeze: no freeze in first 12 seconds (filter startup phase) + tmpSample = expAdjF; micIn = abs(micIn); // And get the absolute value of each sample @@ -1360,6 +1434,7 @@ class AudioReactive : public Usermod { case 0: //ADC analog #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) case 5: //PDM Microphone + case 51: //legacy PDM Microphone #endif #endif case 1: @@ -1397,6 +1472,13 @@ class AudioReactive : public Usermod { delay(100); if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin); break; + case 51: + DEBUGSR_PRINT(F("AR: Legacy PDM Microphone - ")); DEBUGSR_PRINTLN(F(I2S_PDM_MIC_CHANNEL_TEXT)); + audioSource = new I2SSource(SAMPLE_RATE, BLOCK_SIZE, 1.0f); + useBandPassFilter = true; + delay(100); + if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin); + break; #endif #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) // ADC over I2S is only possible on "classic" ESP32 @@ -1530,7 +1612,7 @@ class AudioReactive : public Usermod { #if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS) // complain when audio userloop has been delayed for long time. Currently we need userloop running between 500 and 1500 times per second. - if ((userloopDelay > /*23*/ 30) && !disableSoundProcessing && (audioSyncEnabled == 0)) { + if ((userloopDelay > /*23*/ 65) && !disableSoundProcessing && (audioSyncEnabled == 0)) { USER_PRINTF("[AR userLoop] hickup detected -> was inactive for last %d millis!\n", userloopDelay); } #endif @@ -1666,14 +1748,15 @@ class AudioReactive : public Usermod { connected(); // resume UDP } else // xTaskCreatePinnedToCore( - xTaskCreate( // no need to "pin" this task to core #0 +// xTaskCreate( // no need to "pin" this task to core #0 + xTaskCreateUniversal( FFTcode, // Function to implement the task "FFT", // Name of the task 5000, // Stack size in words NULL, // Task input parameter 1, // Priority of the task &FFT_Task // Task handle -// , 0 // Core where the task should run + , 0 // Core where the task should run ); } micDataReal = 0.0f; // just to be sure @@ -1773,7 +1856,10 @@ class AudioReactive : public Usermod { if (audioSource->getType() == AudioSource::Type_I2SAdc) { infoArr.add(F("ADC analog")); } else { - infoArr.add(F("I2S digital")); + if (dmType != 51) + infoArr.add(F("I2S digital")); + else + infoArr.add(F("legacy I2S PDM")); } // input level or "silence" if (maxSample5sec > 1.0) { @@ -1786,7 +1872,7 @@ class AudioReactive : public Usermod { } else { // error during audio source setup infoArr.add(F("not initialized")); - infoArr.add(F(" - check GPIO config")); + infoArr.add(F(" - check pin settings")); } } @@ -1950,6 +2036,12 @@ class AudioReactive : public Usermod { cfg[F("gain")] = sampleGain; cfg[F("AGC")] = soundAgc; + //WLEDMM: experimental settings + JsonObject poweruser = top.createNestedObject("experiments"); + poweruser[F("micLev")] = micLevelMethod; + poweruser[F("freqDist")] = freqDist; + poweruser[F("freqRMS")] = averageByRMS; + JsonObject dynLim = top.createNestedObject("dynamics"); dynLim[F("limiter")] = limiterOn; dynLim[F("rise")] = attackTime; @@ -1998,7 +2090,11 @@ class AudioReactive : public Usermod { if (dmType == 0) dmType = SR_DMTYPE; // MCU does not support analog #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) if (dmType == 5) dmType = SR_DMTYPE; // MCU does not support PDM + if (dmType == 51) dmType = SR_DMTYPE; // MCU does not support legacy PDM #endif + #else + if (dmType == 5) useBandPassFilter = true; // enable filter for PDM + if (dmType == 51) useBandPassFilter = true /*false*/; // switch on filter for legacy PDM #endif configComplete &= getJsonValue(top[FPSTR(_digitalmic)]["pin"][0], i2ssdPin); @@ -2012,6 +2108,11 @@ class AudioReactive : public Usermod { configComplete &= getJsonValue(top["config"][F("gain")], sampleGain); configComplete &= getJsonValue(top["config"][F("AGC")], soundAgc); + //WLEDMM: experimental settings + configComplete &= getJsonValue(top["experiments"][F("micLev")], micLevelMethod); + configComplete &= getJsonValue(top["experiments"][F("freqDist")], freqDist); + configComplete &= getJsonValue(top["experiments"][F("freqRMS")], averageByRMS); + configComplete &= getJsonValue(top["dynamics"][F("limiter")], limiterOn); configComplete &= getJsonValue(top["dynamics"][F("rise")], attackTime); configComplete &= getJsonValue(top["dynamics"][F("fall")], decayTime); @@ -2064,12 +2165,17 @@ class AudioReactive : public Usermod { #else oappend(SET_F("addOption(dd,'Generic I2S with Mclk',4);")); #endif - #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) + #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) #if SR_DMTYPE==5 oappend(SET_F("addOption(dd,'Generic I2S PDM (⎌)',5);")); #else oappend(SET_F("addOption(dd,'Generic I2S PDM',5);")); #endif + #if SR_DMTYPE==51 + oappend(SET_F("addOption(dd,'.Legacy I2S PDM ☾ (⎌)',51);")); + #else + oappend(SET_F("addOption(dd,'.Legacy I2S PDM ☾',51);")); + #endif #endif #ifdef SR_SQUELCH @@ -2085,6 +2191,23 @@ class AudioReactive : public Usermod { oappend(SET_F("addOption(dd,'Vivid',2);")); oappend(SET_F("addOption(dd,'Lazy',3);")); + //WLEDMM: experimental settings + oappend(SET_F("dd=addDropdown('AudioReactive','experiments:micLev');")); + oappend(SET_F("addOption(dd,'Floating (⎌)',0);")); + oappend(SET_F("addOption(dd,'Freeze',1);")); + oappend(SET_F("addOption(dd,'Fast Freeze',2);")); + oappend(SET_F("addInfo('AudioReactive:experiments:micLev',1,'☾');")); + + oappend(SET_F("dd=addDropdown('AudioReactive','experiments:freqDist');")); + oappend(SET_F("addOption(dd,'Normal (⎌)',0);")); + oappend(SET_F("addOption(dd,'RightShift',1);")); + oappend(SET_F("addInfo('AudioReactive:experiments:freqDist',1,'☾');")); + + oappend(SET_F("dd=addDropdown('AudioReactive','experiments:freqRMS');")); + oappend(SET_F("addOption(dd,'Off (⎌)',0);")); + oappend(SET_F("addOption(dd,'On',1);")); + oappend(SET_F("addInfo('AudioReactive:experiments:freqRMS',1,'☾');")); + oappend(SET_F("dd=addDropdown('AudioReactive','dynamics:limiter');")); oappend(SET_F("addOption(dd,'Off',0);")); oappend(SET_F("addOption(dd,'On',1);")); @@ -2155,6 +2278,7 @@ class AudioReactive : public Usermod { #else oappend(SET_F("addOption(dd,'userdefined #2',9);")); #endif + oappend(SET_F("addInfo('AudioReactive:frequency:profile',1,'☾');")); oappend(SET_F("dd=addDropdown('AudioReactive','sync:mode');")); oappend(SET_F("addOption(dd,'Off',0);")); diff --git a/usermods/blynk_relay_control/README.md b/usermods/blynk_relay_control/README.md deleted file mode 100644 index f4832c08..00000000 --- a/usermods/blynk_relay_control/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Blynk controllable relay -Enables controlling a relay state via user variables. Allows the user variables to be set via Blynk. - -Optionally, the servo can have a reset timer to return to its default state after a user definable interval. The interval is set via userVar1. - -## Instalation - -Replace the WLED06_usermod.ino file in Aircoookies WLED folder, with the one here. - -## Customizations - -Update the following parameters in WLED06_usermod.ino to configure the mod's behavior: - -```cpp -//Which pin is the relay connected to -#define RELAY_PIN 5 -//Which pin state should the relay default to -#define RELAY_PIN_DEFAULT LOW -//If >0 The controller returns to RELAY_PIN_DEFAULT after this time, in milliseconds -#define RELAY_PIN_TIMER_DEFAULT 3000 - -//Blynk virtual pin for controlling relay -#define BLYNK_USER_VAR0_PIN V9 -//Blynk virtual pin for controlling relay timer -#define BLYNK_USER_VAR1_PIN V10 -//Number of milliseconds between Blynk updates -#define BLYNK_RELAY_UPDATE_INTERVAL 5000 -``` diff --git a/usermods/blynk_relay_control/wled06_usermod.ino b/usermods/blynk_relay_control/wled06_usermod.ino deleted file mode 100644 index d4028ea5..00000000 --- a/usermods/blynk_relay_control/wled06_usermod.ino +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file allows you to add own functionality to WLED more easily - * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) - * bytes 2400+ are currently ununsed, but might be used for future wled features - */ - -//Use userVar0 (API calls &U0=, uint16_t) to set relay state -#define relayPinState userVar0 -//Use userVar1 (API calls &U1=, uint16_t) to set relay timer duration -//Ignored if 0, otherwise number of milliseconds to allow relay to stay in -//non default state. -#define relayTimerInterval userVar1 - -//Which pin is the relay connected to -#define RELAY_PIN 5 -//Which pin state should the relay default to -#define RELAY_PIN_DEFAULT LOW -//If >0 The controller returns to RELAY_PIN_DEFAULT after this time in milliseconds -#define RELAY_PIN_TIMER_DEFAULT 3000 - -//Blynk virtual pin for controlling relay -#define BLYNK_USER_VAR0_PIN V9 -//Blynk virtual pin for controlling relay timer -#define BLYNK_USER_VAR1_PIN V10 -//Number of milliseconds between updating blynk -#define BLYNK_RELAY_UPDATE_INTERVAL 5000 - -//Is the timer for resetting the relay active -bool relayTimerStarted = false; -//millis() time after which relay will be reset -unsigned long relayTimeToDefault = 0; -//millis() time after which relay vars in Blynk will be sent -unsigned long relayBlynkUpdateTime = 0; - -//gets called once at boot. Do all initialization that doesn't depend on network here -void userSetup() -{ - relayPinState = RELAY_PIN_DEFAULT; - relayTimerInterval = RELAY_PIN_TIMER_DEFAULT; - pinMode(RELAY_PIN, OUTPUT); - digitalWrite(RELAY_PIN, relayPinState); -} - -//gets called every time WiFi is (re-)connected. Initialize own network interfaces here -void userConnected() -{ -} - -//loop. You can use "if (WLED_CONNECTED)" to check for successful connection -void userLoop() -{ - //Normalize relayPinState to an accepted value - if (relayPinState != HIGH && relayPinState != LOW) { - relayPinState = RELAY_PIN_DEFAULT; - } - //If relay changes and relayTimerInterval is set, start a timer to change back - if (relayTimerInterval != 0 && - relayPinState != RELAY_PIN_DEFAULT && - !relayTimerStarted ) { - relayTimerStarted = true; - relayTimeToDefault = millis() + relayTimerInterval; - } - //If manually changed back to default, cancel timer - if (relayTimerStarted && relayPinState == RELAY_PIN_DEFAULT ) { - relayTimerStarted = false; - } - //If timer completes, set relay back to default - if (relayTimerStarted && millis() > relayTimeToDefault) { - relayPinState = RELAY_PIN_DEFAULT; - relayTimerStarted = false; - } - digitalWrite(RELAY_PIN, relayPinState); - updateRelayBlynk(); -} - -//Update Blynk with state of userVars at BLYNK_RELAY_UPDATE_INTERVAL -void updateRelayBlynk() -{ - if (!WLED_CONNECTED) return; - if (relayBlynkUpdateTime > millis()) return; - Blynk.virtualWrite(BLYNK_USER_VAR0_PIN, userVar0); - Blynk.virtualWrite(BLYNK_USER_VAR1_PIN, userVar1); - relayBlynkUpdateTime = millis() + BLYNK_RELAY_UPDATE_INTERVAL; -} - -//Add Blynk callback for setting userVar0 -BLYNK_WRITE(BLYNK_USER_VAR0_PIN) -{ - userVar0 = param.asInt(); -} -//Add Blynk callback for setting userVar1 -BLYNK_WRITE(BLYNK_USER_VAR1_PIN) -{ - userVar1 = param.asInt(); -} diff --git a/usermods/customeffects/customeffects.js b/usermods/customeffects/customeffects.js index 1011ebe0..a5198847 100644 --- a/usermods/customeffects/customeffects.js +++ b/usermods/customeffects/customeffects.js @@ -98,17 +98,18 @@ function populateCEEditor(name, segID)

- +
- -
+ +


Compile and Run Log

Run log > 3 seconds is send to Serial Ouput.
- 🥚 - 🥚`; + 🥚 + 🥚 + 🥚`; d.getElementById('kceEditor').innerHTML = cn; @@ -122,14 +123,15 @@ function populateCEEditor(name, segID) }); } -function downloadCEFile(url, name) { +function downloadGHFile(url, name, save=false, warn=false) { //Githubfile if (url == "CE") url = "https://raw.githubusercontent.com/MoonModules/WLED-Effects/master/CustomEffects/wled/"; if (url == "HBB") url = "https://raw.githubusercontent.com/MoonModules/WLED-Effects/master/Presets/HB_PresetPack210808_32x32_16seg/Base%20pack/"; if (url == "HBE") url = "https://raw.githubusercontent.com/MoonModules/WLED-Effects/master/Presets/HB_PresetPack210808_32x32_16seg/Effects%20pack/"; + if (url == "LM") url = "https://raw.githubusercontent.com/MoonModules/WLED-Effects/master/Ledmaps/"; fetchAndExecute(url, name, function(text) { - if (name == "wledv033.json" || name == "presets.json") { - if (!confirm('Are you sure to download/overwrite ' + name + '?')) + if (save) { + if (warn && !confirm('Are you sure to download/overwrite ' + name + '?')) return; uploadFileWithText("/" + name, text); } @@ -140,7 +142,7 @@ function downloadCEFile(url, name) { } }, function(error){ showToast(error); - console.log(error); + console.log(url + name,error); }); return; diff --git a/usermods/mpu6050_imu/usermod_mpu6050_imu.h b/usermods/mpu6050_imu/usermod_mpu6050_imu.h index d839c0df..e923e1f9 100644 --- a/usermods/mpu6050_imu/usermod_mpu6050_imu.h +++ b/usermods/mpu6050_imu/usermod_mpu6050_imu.h @@ -65,9 +65,9 @@ #undef DEBUG_PRINTF #ifdef WLED_DEBUG - #define DEBUG_PRINT(x) DEBUGOUT.print(x) - #define DEBUG_PRINTLN(x) DEBUGOUT.println(x) - #define DEBUG_PRINTF(x...) DEBUGOUT.printf(x) + #define DEBUG_PRINT(x) DEBUGOUT(x) + #define DEBUG_PRINTLN(x) DEBUGOUTLN(x) + #define DEBUG_PRINTF(x...) DEBUGOUTF(x) #else #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) @@ -93,18 +93,22 @@ void IRAM_ATTR dmpDataReady() { class MPU6050Driver : public Usermod { private: MPU6050 mpu; - bool enabled = true; unsigned long lastUMRun = millis(); // MPU control/status vars - bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer + // strings to reduce flash memory usage (used more than twice) + static const char _INT_pin[]; + public: + MPU6050Driver(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM: this shouldn't be necessary (passthrough of constructor), maybe because Usermod is an abstract class + + bool dmpReady = false; // set true if DMP init was successful // WLEDMM expose this info in public interface // orientation/motion vars Quaternion qat; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements @@ -122,7 +126,11 @@ class MPU6050Driver : public Usermod { #endif void setup() { - // WLEDMM begin + // WLEDMM begin + if (!enabled) { + dmpReady = false; + return; + } USER_PRINTLN(F("mpu setup")); PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } }; if ((i2c_scl < 0) || (i2c_sda < 0)) { @@ -171,16 +179,26 @@ class MPU6050Driver : public Usermod { // initialize device DEBUG_PRINT_IMULN(F("Initializing I2C devices...")); // WLEDMM begin - if (!pinManager.allocatePin(INTERRUPT_PIN, false, PinOwner::UM_Unspecified)) + if ((INTERRUPT_PIN < 0) || (!pinManager.isPinINT(INTERRUPT_PIN))) { + //enabled = false; + USER_PRINTF("mpu6050: warning - interrupt GPIO %d does not support interrupts.\n", INTERRUPT_PIN); + //INTERRUPT_PIN = -1; + //return; + } + if ((INTERRUPT_PIN >= 0) && (pinManager.getPinOwner(INTERRUPT_PIN) != PinOwner::UM_IMU) // only allocate pin if we don't ownn it already + && !pinManager.allocatePin(INTERRUPT_PIN, false, PinOwner::UM_IMU)) { //enabled = false; USER_PRINTF("mpu6050: warning - failed to allocate interrupt GPIO %d\n", INTERRUPT_PIN); + //INTERRUPT_PIN = -1; //return; } // WLEDMM end mpu.initialize(); - pinMode(INTERRUPT_PIN, INPUT); + if (INTERRUPT_PIN >= 0) { // WLEDMM only if pin is valid + pinMode(INTERRUPT_PIN, INPUT); + } // verify connection DEBUG_PRINT_IMULN(F("Testing device connections...")); @@ -214,11 +232,13 @@ class MPU6050Driver : public Usermod { DEBUG_PRINT_IMULN(F("Enabling DMP...")); mpu.setDMPEnabled(true); - // enable Arduino interrupt detection - DEBUG_PRINT_IMU(F("Enabling interrupt detection (Arduino external interrupt ")); - DEBUG_PRINT_IMU(digitalPinToInterrupt(INTERRUPT_PIN)); - DEBUG_PRINT_IMULN(F(")...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); + if (INTERRUPT_PIN >= 0) { + // enable Arduino interrupt detection + DEBUG_PRINT_IMU(F("Enabling interrupt detection (Arduino external interrupt ")); + DEBUG_PRINT_IMU(digitalPinToInterrupt(INTERRUPT_PIN)); + DEBUG_PRINT_IMULN(F(")...")); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); + } mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it @@ -235,7 +255,9 @@ class MPU6050Driver : public Usermod { DEBUG_PRINT(F("DMP Initialization failed (code ")); DEBUG_PRINT(devStatus); DEBUG_PRINTLN(")"); + dmpReady = false; } + initDone = true; } void connected() { @@ -244,6 +266,7 @@ class MPU6050Driver : public Usermod { void loop() { // if programming failed, don't try to do anything + if (!initDone) return; if (!enabled || (strip.isUpdating() && (millis() - lastUMRun < 2))) return; // be nice, but not too nice lastUMRun = millis(); // update time keeping @@ -265,12 +288,15 @@ class MPU6050Driver : public Usermod { void addToJsonInfo(JsonObject& root) { + if (!initDone) return; + if (!enabled && !dmpReady) return; // WLEDMM no info when usermod disabled JsonObject user = root["u"]; if (user.isNull()) user = root.createNestedObject("u"); StaticJsonDocument<800> doc; //measured 528 // WLEDMM added some margin (was 600) JsonObject imu_meas = doc.createNestedObject("IMU"); + //JsonObject imu_meas = user.createNestedObject("IMU"); #ifdef WLED_DEBUG JsonArray quat_json = imu_meas.createNestedArray("Quat"); quat_json.add(qat.w); @@ -328,29 +354,64 @@ class MPU6050Driver : public Usermod { //{ //} - // void addToConfig(JsonObject& root) - // { - // JsonObject top = root.createNestedObject("MPU6050"); - // top[FPSTR("enabled")] = enabled; + // void addToConfig(JsonObject& root) + // { + // Usermod::addToConfig(root); + // JsonObject top = root[FPSTR(_name)]; + // // //JsonObject interruptPin = top.createNestedObject(FPSTR(_INT_pin)); + // // //interruptPin["pin"] = INTERRUPT_PIN; + // // DEBUG_PRINTLN(F("MPU6050 IMU config saved.")); + // } - // JsonObject interruptPin = top.createNestedObject(FPSTR("interruptPin")); - // interruptPin["pin"] = interruptPin; - // } + //WLEDMM: add appendConfigData + void appendConfigData() + { + oappend(SET_F("addHB('mpu6050-IMU');")); + /* + #ifdef MPU6050_INT_GPIO + oappend(SET_F("xOpt('mpu6050-IMU:interrupt_pin',0,' ⎌',")); oappendi(MPU6050_INT_GPIO); oappend(");"); + #endif + //WLEDMM add errorMessage to um settings + if (strcmp(errorMessage, "") != 0) { + oappend(SET_F("addInfo('errorMessage', 0, 'error: ")); oappend(errorMessage); oappend("! Correct and reboot');"); + } + */ + } - // bool readFromConfig(JsonObject& root) - // { - // JsonObject top = root[FPSTR("MPU6050")]; - // bool configComplete = !top.isNull(); + bool readFromConfig(JsonObject& root) + { + bool configComplete = Usermod::readFromConfig(root); + JsonObject top = root[FPSTR(_name)]; - // configComplete &= getJsonValue(top[FPSTR("enabled")], enabled); - // configComplete &= getJsonValue(top[FPSTR("interruptPin")]["pin"], interruptPin); + if (top.isNull()) { + DEBUG_PRINT(FPSTR(_name)); + DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); + return false; + } - // return configComplete; - // } + //configComplete &= getJsonValue(top[FPSTR(_INT_pin)]["pin"], INTERRUPT_PIN); + + DEBUG_PRINT(FPSTR(_name)); + if (!initDone) { + // first run: reading from cfg.json + DEBUG_PRINTLN(F(" config loaded.")); + } else { + DEBUG_PRINTLN(F(" config (re)loaded.")); + if (enabled || dmpReady) setup(); // re-run setup if user has checked "enabled" + if (!enabled) dmpReady = false; // not enabled inplies "no DMP data ready" + } + + return configComplete; + // use "return !top["newestParameter"].isNull();" when updating Usermod with new features + //return !top[FPSTR(_INT_pin)].isNull(); + } uint16_t getId() { return USERMOD_ID_IMU; } -}; \ No newline at end of file +}; + +// strings to reduce flash memory usage (used more than twice) +const char MPU6050Driver::_INT_pin[] PROGMEM = "interrupt_pin"; diff --git a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h index e8806609..e2b65910 100644 --- a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h +++ b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h @@ -79,6 +79,10 @@ class AutoSaveUsermod : public Usermod { month(localTime), day(localTime), hour(localTime), minute(localTime), second(localTime)); cacheInvalidate++; // force reload of presets + DEBUG_PRINT(F("UM autosave: saving preset ")); + DEBUG_PRINT(autoSavePreset); + DEBUG_PRINT(F(" => ")); + DEBUG_PRINTLN(presetNameBuffer); savePreset(autoSavePreset, presetNameBuffer); } @@ -86,7 +90,7 @@ class AutoSaveUsermod : public Usermod { #ifdef USERMOD_FOUR_LINE_DISPLAY if (display != nullptr) { display->wakeDisplay(); - display->overlay("Settings", "Auto Saved", 1500); + if (display->canDraw()) display->overlay("Settings", "Auto Saved", 1500); // WLEDMM bugfix } #endif } diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h index ebe066c3..44867c82 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h @@ -3,7 +3,7 @@ #include // WLEDMM: make sure that I2C drivers have the "right" Wire Object #include #undef U8X8_NO_HW_I2C // WLEDMM: we do want I2C hardware drivers - if possible -//#define WIRE_INTERFACES_COUNT 2 // experimental - tell U8x8Lib that there is a econd Wire unit +//#define WIRE_INTERFACES_COUNT 2 // experimental - tell U8x8Lib that there is a second Wire unit #include "wled.h" #include // from https://github.com/olikraus/u8g2/ @@ -13,6 +13,8 @@ #define FLD_ESP32_USE_THREADS // comment out to use 0.13.x behviour without parallel update task - slower, but more robust. May delay other tasks like LEDs or audioreactive!! #endif +//#define OLD_4LD_FONTS // comment out if you prefer the "classic" look with blocky fonts (saves 1K flash) + // // Insired by the usermod_v2_four_line_display // @@ -115,6 +117,23 @@ class FourLineDisplayUsermod : public Usermod { // HW interface & configuration U8X8 *u8x8 = nullptr; // pointer to U8X8 display object +#if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS) + // semaphores - needed on ESP32 only, as we use a separate task to update the display + SemaphoreHandle_t drawMux = xSemaphoreCreateBinary(); // for drawstring and drawglyph functions (to prevent concurrent access to HW) + SemaphoreHandle_t drawMuxBig = xSemaphoreCreateBinary(); // for draw2x2GlyphIcons() and showCurrentEffectOrPalette() - more complex and not thread-safe + const TickType_t maxWait = 300 * portTICK_PERIOD_MS; // wait max. 300ms (drawstring semaphore) + const TickType_t maxWaitLong = 800 * portTICK_PERIOD_MS; // wait max. 800ms (big drawing semaphore) + #define FLD_SemaphoreTake(x,t) xSemaphoreTake((x),(t)) + #define FLD_SemaphoreGive(x) xSemaphoreGive(x) +#else + // 8266 or no tasks - no semaphores + #define FLD_SemaphoreTake(x,t) pdTRUE + #define FLD_SemaphoreGive(x) + #if !defined(ARDUINO_ARCH_ESP32) && !defined(pdTRUE) + #define pdTRUE true + #endif +#endif + #ifndef FLD_SPI_DEFAULT int8_t ioPin[5] = {FLD_PIN_SCL, FLD_PIN_SDA, -1, -1, -1}; // I2C pins: SCL, SDA uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000) @@ -124,7 +143,7 @@ class FourLineDisplayUsermod : public Usermod { #endif DisplayType type = FLD_TYPE; // display type - bool typeOK = false; //WLEDMM: instead of type == NULL and type=NULL. Intially false, as display was not initialized yet + bool typeOK = false; //WLEDMM: instead of type == NULL and type=NULL. Initially false, as display was not initialized yet bool flip = false; // flip display 180° uint8_t contrast = 10; // screen contrast uint8_t lineHeight = 1; // 1 row or 2 rows @@ -193,7 +212,7 @@ class FourLineDisplayUsermod : public Usermod { // some displays need this to properly apply contrast void setVcomh(bool highContrast) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it - if (!canDraw()) return; // don't interfere with ongoing draw + if (u8x8 == nullptr) return; u8x8_t *u8x8_struct = u8x8->getU8x8(); u8x8_cad_StartTransfer(u8x8_struct); @@ -207,33 +226,77 @@ class FourLineDisplayUsermod : public Usermod { */ void setFlipMode(uint8_t mode) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it - if (canDraw()) u8x8->setFlipMode(mode); + if (u8x8 == nullptr) return; + u8x8->setFlipMode(mode); } void setContrast(uint8_t contrast) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it - if (canDraw()) u8x8->setContrast(contrast); + if (u8x8 == nullptr) return; + u8x8->setContrast(contrast); } void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it - u8x8->setFont(u8x8_font_chroma48medium8_r); // crashes randomly on ESP32 - if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string); // crashes randomly on ESP32 + if (u8x8 == nullptr) return; + if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex + +#if defined(ARDUINO_ARCH_ESP32) && !defined(OLD_4LD_FONTS) // WLEDMM use nicer 2x2 font on ESP32 + if (!ignoreLH && lineHeight==2) { + if(strlen(string) > 3) // WLEDMM little hack - less than 3 chars -> show in bold + u8x8->setFont(u8x8_font_7x14_1x2_r); // normal + else + u8x8->setFont(u8x8_font_8x13B_1x2_r); // bold + u8x8->drawString(col, row, string); + } + else { + u8x8->setFont(u8x8_font_chroma48medium8_r); + u8x8->drawString(col, row, string); + } +#else + u8x8->setFont(u8x8_font_chroma48medium8_r); + if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string); else u8x8->drawString(col, row, string); +#endif + FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } void draw2x2String(uint8_t col, uint8_t row, const char *string) { if (!typeOK || !enabled) return; + if (u8x8 == nullptr) return; + if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex +#if defined(ARDUINO_ARCH_ESP32) && !defined(OLD_4LD_FONTS) // WLEDMM use nicer 2x2 font on ESP32 + if (lineHeight==2) { // WLEDMM use 2x3 on 128x64 displays + //u8x8->setFont(u8x8_font_profont29_2x3_r); // sans serif 2x3 + u8x8->setFont(u8x8_font_courB18_2x3_r); // courier bold 2x3 + u8x8->drawString(col, row + (row >3? 1:0), string); + } else { + //u8x8->setFont(u8x8_font_lucasarts_scumm_subtitle_o_2x2_r); + //u8x8->setFont(u8x8_font_lucasarts_scumm_subtitle_r_2x2_r); + u8x8->setFont(u8x8_font_px437wyse700b_2x2_r); + u8x8->drawString(col, row, string); + } +#else u8x8->setFont(u8x8_font_chroma48medium8_r); - u8x8->draw2x2String(col, row, string); + if (lineHeight==2) { // WLEDMM use 2x3 on 128x64 displays + u8x8->draw2x2String(col, row + (row >3? 1:0), string); + } else { + u8x8->draw2x2String(col, row, string); + } +#endif + FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false) { if (!typeOK || !enabled) return; + if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex u8x8->setFont(font); if (!ignoreLH && lineHeight==2) u8x8->draw1x2Glyph(col, row, glyph); else u8x8->drawGlyph(col, row, glyph); + FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } void draw2x2Glyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font) { if (!typeOK || !enabled) return; + if (FLD_SemaphoreTake(drawMux, maxWait) != pdTRUE) return; // WLEDMM acquire draw mutex u8x8->setFont(font); u8x8->draw2x2Glyph(col, row, glyph); + FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } uint8_t getCols() { if (!typeOK || !enabled) return 0; @@ -242,10 +305,13 @@ class FourLineDisplayUsermod : public Usermod { void clear() { if (!typeOK || !enabled) return; if (nullptr == u8x8) return; // prevents some crashes + if (FLD_SemaphoreTake(drawMux, maxWaitLong ) != pdTRUE) return; // WLEDMM acquire draw mutex - clear() can take very long in software I2C mode u8x8->clear(); // crashes randomly on ESP32 + FLD_SemaphoreGive(drawMux); // WLEDMM release draw mutex } void setPowerSave(uint8_t save) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it + if (u8x8 == nullptr) return; u8x8->setPowerSave(save); } @@ -257,6 +323,7 @@ class FourLineDisplayUsermod : public Usermod { void draw2x2GlyphIcons() { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it + if (FLD_SemaphoreTake(drawMuxBig, maxWaitLong) != pdTRUE) return; // WLEDMM acquire BIG draw mutex if (lineHeight == 2) { drawGlyph( 1, 0, 1, u8x8_4LineDisplay_WLED_icons_2x2, true); //brightness icon drawGlyph( 5, 0, 2, u8x8_4LineDisplay_WLED_icons_2x2, true); //speed icon @@ -270,6 +337,7 @@ class FourLineDisplayUsermod : public Usermod { drawGlyph(15, 2, 4, u8x8_4LineDisplay_WLED_icons_1x1); //palette icon drawGlyph(15, 3, 5, u8x8_4LineDisplay_WLED_icons_1x1); //effect icon } + FLD_SemaphoreGive(drawMuxBig); // WLEDMM release BIG draw mutex } /** @@ -305,10 +373,21 @@ class FourLineDisplayUsermod : public Usermod { } snprintf_P(lineBuffer,LINE_BUFFER_SIZE, PSTR("%2d:%02d"), (useAMPM ? AmPmHour : hourCurrent), minuteCurrent); draw2x2String(2, lineHeight*2, lineBuffer); //draw hour, min. blink ":" depending on odd/even seconds - if (useAMPM) drawString(12, lineHeight*2, (isitAM ? "AM" : "PM"), true); //draw am/pm if using 12 time + if (useAMPM) drawString(12, lineHeight*2 + (lineHeight-1), (isitAM ? "AM" : "PM"), true); //draw am/pm if using 12 time drawStatusIcons(); //icons power, wifi, timer, etc + if (lineHeight > 1) { // WLEDMM use extra space for useful information + strncpy_P(lineBuffer, PSTR(" "), LINE_BUFFER_SIZE); + if (apActive) strncpy_P(lineBuffer, PSTR(" AP mode "), LINE_BUFFER_SIZE); + else if (!WLED_CONNECTED) strncpy_P(lineBuffer, PSTR(" NO NET "), LINE_BUFFER_SIZE); + if (WLED_MQTT_CONNECTED) lineBuffer[9] = 'M'; // "MQTT" + if (realtimeMode && !realtimeOverride) lineBuffer[10] = 'X'; // "eXternal control" + //if (transitionActive) lineBuffer[11] = 'T'; + //if (stateChanged) lineBuffer[12] = 'C'; + drawString(1, 0, lineBuffer, false); + } + knownMinute = minuteCurrent; knownHour = hourCurrent; } @@ -316,7 +395,10 @@ class FourLineDisplayUsermod : public Usermod { lastSecond = secondCurrent; draw2x2String(6, lineHeight*2, secondCurrent%2 ? " " : ":"); snprintf_P(lineBuffer, LINE_BUFFER_SIZE, PSTR("%02d"), secondCurrent); - drawString(12, lineHeight*2+1, lineBuffer, true); // even with double sized rows print seconds in 1 line + if (useAMPM) + drawString(12, lineHeight*2+1 + (lineHeight-1), lineBuffer, true); // even with double sized rows print seconds in 1 line // WLEDMM move it a bit lower + else + drawString(12, lineHeight*2+1, lineBuffer, true); // even with double sized rows print seconds in 1 line } drawing = false; } @@ -326,7 +408,7 @@ class FourLineDisplayUsermod : public Usermod { // gets called once at boot. Do all initialization that doesn't depend on // network here void setup() { - if (!enabled) return; // typeOK = true will be set after successfull setup + if (!enabled) return; // typeOK = true will be set after successful setup bool isHW, isSPI = (type == SSD1306_SPI || type == SSD1306_SPI64); PinOwner po = PinOwner::UM_FourLineDisplay; @@ -334,8 +416,17 @@ class FourLineDisplayUsermod : public Usermod { if (ioPin[0] < 0 || ioPin[1] < 0) { ioPin[0] = spi_sclk; ioPin[1] = spi_mosi; + } else { + if ((spi_sclk < 0) && (spi_mosi < 0)) { // WLEDMM UM pins are valid, but global = -1 --> copy pins to "global" + spi_sclk = ioPin[0]; + spi_mosi = ioPin[1]; + } } + if ((ioPin[0] < 0 || ioPin[1] < 0) && (spi_sclk < 0 || spi_mosi < 0)) { // invalid pins, or "use global" and global pins not defined + typeOK=false; strcpy(errorMessage, PSTR("SPI No Pins defined")); return; } //WLEDMM bugfix - ensure that "final" GPIO are valid + isHW = (ioPin[0]==spi_sclk && ioPin[1]==spi_mosi); + if ((ioPin[0] == -1) || (ioPin[1] == -1)) isHW = true; // WLEDMM "use global" = hardware PinManagerPinType cspins[3] = { { ioPin[2], true }, { ioPin[3], true }, { ioPin[4], true } }; if (!pinManager.allocateMultiplePins(cspins, 3, PinOwner::UM_FourLineDisplay)) { typeOK=false; strcpy(errorMessage, PSTR("SPI3 alloc pins failed")); return; } if (isHW) po = PinOwner::HW_SPI; // allow multiple allocations of HW I2C bus pins @@ -347,19 +438,21 @@ class FourLineDisplayUsermod : public Usermod { return; } } else { - if (ioPin[0] < 0 || ioPin[1] < 0) { - ioPin[0] = i2c_scl; - ioPin[1] = i2c_sda; - } + //if (ioPin[0] < 0 || ioPin[1] < 0) { //WLEDMM do _not_ copy global pins !! + // ioPin[0] = i2c_scl; + // ioPin[1] = i2c_sda; + //} isHW = (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda); + if ((ioPin[0] == -1) || (ioPin[1] == -1)) isHW = true; // WLEDMM "use global" = hardware // isHW = true; if (isHW) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins PinManagerPinType pins[2] = { {ioPin[0], true }, { ioPin[1], true } }; - if (ioPin[0] < 0 || ioPin[1] < 0) { typeOK=false; strcpy(errorMessage, PSTR("I2C No Pins defined")); return; } //WLEDMM bugfix - ensure that "final" GPIO are valid + if ((ioPin[0] < 0 || ioPin[1] < 0) && (i2c_scl < 0 || i2c_sda < 0)) { // invalid pins, or "use global" and global pins not defined + typeOK=false; strcpy(errorMessage, PSTR("I2C No Pins defined")); return; } //WLEDMM bugfix - ensure that "final" GPIO are valid if (isHW) { - if (!pinManager.joinWire(ioPin[1], ioPin[0])) { typeOK=false; strcpy(errorMessage, PSTR("I2C init failed")); return; } // WLEDMM join the HW bus + if (!pinManager.joinWire(i2c_sda, i2c_scl)) { typeOK=false; strcpy(errorMessage, PSTR("I2C HW init failed")); return; } // WLEDMM join the HW bus } else { if (!pinManager.allocateMultiplePins(pins, 2, po)) { typeOK=false; strcpy(errorMessage, PSTR("I2C Alloc pins failed")); return; } // WLEDMM use software bus } @@ -442,7 +535,7 @@ class FourLineDisplayUsermod : public Usermod { if (nullptr == u8x8) { USER_PRINTLN(F("Display init failed.")); - pinManager.deallocateMultiplePins((const uint8_t*)ioPin, isSPI ? 5 : 2, po); + if (!isHW || !isSPI) pinManager.deallocateMultiplePins((const uint8_t*)ioPin, isSPI ? 5 : 2, po); // WLEDMM do not de-alloc global pins typeOK=false; strcpy(errorMessage, PSTR("Display init failed")); return; @@ -457,15 +550,24 @@ class FourLineDisplayUsermod : public Usermod { u8x8->setBusClock(ioFrequency); // can be used for SPI too u8x8->begin(); typeOK = true; - drawing = false; + reDrawing = false; + drawing = true; setFlipMode(flip); setVcomh(contrastFix); setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255 setPowerSave(0); + drawing = false; + + // init semaphores to enable drawing + FLD_SemaphoreGive(drawMux); + FLD_SemaphoreGive(drawMuxBig); + + onUpdateBegin(false); // create Display task // WLEDMM bugfix: before drawing anything + delay(200); + //drawString(0, 0, "Loading..."); overlayLogo(3500); - onUpdateBegin(false); // create Display task initDone = true; } @@ -502,6 +604,7 @@ class FourLineDisplayUsermod : public Usermod { //function to to check if a redraw or overlay draw is active. Needed for UM Rotary, to avoid random/concurrent drawing bool canDraw(void) { + if (!typeOK || !enabled || !initDone) return(false); // WLEDMM make sure the display is initialized before we try to draw on it #if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS) // only necessary on ESP32 if (drawing) return(false); // overlay draws someting if (reDrawing) return(false); // redraw task draws something @@ -609,7 +712,7 @@ class FourLineDisplayUsermod : public Usermod { // and turn it back on if it changed. clear(); sleepOrClock(true); - } else if (displayTurnedOff && ntpEnabled) { + } else if (displayTurnedOff) { // WLEDMM removed "&& ntpEnabled" showTime(); } return; @@ -689,7 +792,7 @@ class FourLineDisplayUsermod : public Usermod { if (lineHeight==2) { col--; } else { row++; } drawGlyph(col, row, (bri > 0 ? 9 : 0), u8x8_4LineDisplay_WLED_icons_1x1, true); // power icon if (lineHeight==2) { col--; } else { col = row = 0; } - drawGlyph(col, row, (nightlightActive ? 6 : 0), u8x8_4LineDisplay_WLED_icons_1x1, true); // moon icon for nighlight mode + drawGlyph(col, row, (nightlightActive ? 6 : 0), u8x8_4LineDisplay_WLED_icons_1x1, true); // moon icon for nightlight mode } /** @@ -702,7 +805,7 @@ class FourLineDisplayUsermod : public Usermod { markColNum = newMarkColNum; } - //Draw the arrow for the current setting beiong changed + //Draw the arrow for the current setting being changed void drawArrow() { if (markColNum != 255 && markLineNum !=255) drawGlyph(markColNum, markLineNum*lineHeight, 21, u8x8_4LineDisplay_WLED_icons_1x1); } @@ -712,6 +815,8 @@ class FourLineDisplayUsermod : public Usermod { void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row) { char lineBuffer[MAX_JSON_CHARS] = { '\0' }; if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it + if (FLD_SemaphoreTake(drawMuxBig, maxWaitLong) != pdTRUE) return; // WLEDMM acquire BIG draw mutex + if (overlayUntil == 0) { // Find the mode name in JSON uint8_t printedChars = extractModeName(inputEffPal, qstring, lineBuffer, MAX_JSON_CHARS-1); @@ -769,6 +874,8 @@ class FourLineDisplayUsermod : public Usermod { drawString(1, row*lineHeight, smallBuffer3, true); } } + + FLD_SemaphoreGive(drawMuxBig); // WLEDMM release BIG draw mutex } /** @@ -779,6 +886,7 @@ class FourLineDisplayUsermod : public Usermod { */ bool wakeDisplay() { if (!typeOK || !enabled) return false; + if (!initDone) return false; if (displayTurnedOff) { unsigned long now = millis(); while (drawing && millis()-now < 250) delay(1); // wait if someone else is drawing @@ -800,6 +908,7 @@ class FourLineDisplayUsermod : public Usermod { */ void overlay(const char* line1, long showHowLong, byte glyphType) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it + if (!initDone) return; // WLEDMM bugfix unsigned long now = millis(); while (drawing && millis()-now < 250) delay(1); // wait if someone else is drawing while ((reDrawing && overlayUntil == 0) && (millis()-now < 250)) delay(10); // wait if someone else is re-drawing @@ -888,6 +997,7 @@ class FourLineDisplayUsermod : public Usermod { */ void overlay(const char* line1, const char* line2, long showHowLong) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it + if (!initDone) return; // WLEDMM bugfix unsigned long now = millis(); while (drawing && millis()-now < 250) delay(1); // wait if someone else is drawing while ((reDrawing && overlayUntil == 0) && (millis()-now < 250)) delay(10); // wait if someone else is re-drawing @@ -911,6 +1021,7 @@ class FourLineDisplayUsermod : public Usermod { void networkOverlay(const char* line1, long showHowLong) { if (!typeOK || !enabled) return; // WLEDMM make sure the display is initialized before we try to draw on it + if (!initDone) return; // WLEDMM bugfix unsigned long now = millis(); while (drawing && millis()-now < 250) delay(1); // wait if someone else is drawing drawing = true; @@ -952,10 +1063,11 @@ class FourLineDisplayUsermod : public Usermod { /** * Enable sleep (turn the display off) or clock mode. */ - void sleepOrClock(bool enabled) { - if (enabled) { + void sleepOrClock(bool sleepEnable) { + if (sleepEnable) { displayTurnedOff = true; - if (clockMode && ntpEnabled) { + //setContrast(contrastFix? 2+ contrast/4 : 0); // un-comment to dim display in "clock mode" + if (clockMode) { // WLEDMM removed " && ntpEnabled" knownMinute = knownHour = 99; showTime(); } else @@ -963,6 +1075,7 @@ class FourLineDisplayUsermod : public Usermod { } else { displayTurnedOff = false; setPowerSave(0); + //setContrast(contrast); // un-comment to restore display brightness on wakeup } } @@ -1285,8 +1398,9 @@ class FourLineDisplayUsermod : public Usermod { bool isHW = (oldPin[0]==spi_sclk && oldPin[1]==spi_mosi); if (isHW) po = PinOwner::HW_SPI; } else { - bool isHW = (oldPin[0]==i2c_scl && oldPin[1]==i2c_sda); - if (isHW) po = PinOwner::HW_I2C; + //bool isHW = (oldPin[0]==i2c_scl && oldPin[1]==i2c_sda); + //if ((ioPin[0] == -1) || (ioPin[1] == -1)) isHW = true; // WLEDMM "use global" = hardware + //if (isHW) po = PinOwner::HW_I2C; // WLEDMM don't try to de-alloc HW pins. } pinManager.deallocateMultiplePins((const uint8_t *)oldPin, 2, po); type = newType; @@ -1333,3 +1447,8 @@ const char FourLineDisplayUsermod::_contrastFix[] PROGMEM = "contrastFix"; #ifdef ARDUINO_ARCH_ESP32 FourLineDisplayUsermod *FourLineDisplayUsermod::instance = nullptr; #endif + +// WLEDMM clean up some macros, so they don't cause problems in other usermods +#undef FLD_SemaphoreTake +#undef FLD_SemaphoreGive + diff --git a/usermods/usermod_v2_games/usermod_v2_games.h b/usermods/usermod_v2_games/usermod_v2_games.h index 5256f5c5..0c23ce59 100644 --- a/usermods/usermod_v2_games/usermod_v2_games.h +++ b/usermods/usermod_v2_games/usermod_v2_games.h @@ -183,7 +183,7 @@ uint16_t mode_IMUTest(void) { uint8_t y = 0; - if (IMU != nullptr) { + if ((IMU != nullptr) && (IMU->dmpReady)) { SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.x+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE); SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.y+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE); SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.z+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE); @@ -280,7 +280,7 @@ uint16_t mode_3DIMUCube(void) { float roll = 0; #ifdef USERMOD_MPU6050_IMU - if (IMU != nullptr) { + if ((IMU != nullptr) && (IMU->dmpReady)) { yaw = -IMU->ypr[0]; pitch = IMU->ypr[1]; roll = IMU->ypr[2]; diff --git a/usermods/usermod_v2_klipper_percentage/readme.md b/usermods/usermod_v2_klipper_percentage/readme.md new file mode 100644 index 00000000..0619bf85 --- /dev/null +++ b/usermods/usermod_v2_klipper_percentage/readme.md @@ -0,0 +1,40 @@ +# Klipper Percentage Usermod +This usermod polls the Klipper API every 10s for the progressvalue. +The leds are then filled with a solid color according to that progress percentage. +the solid color is the secondary color of the segment. + +A corresponding curl command would be: +``` +curl --location --request GET 'http://[]/printer/objects/query?virtual_sdcard=progress' +``` +## Usage +Compile the source with the buildflag `-D USERMOD_KLIPPER_PERCENTAGE` added. + +You can also use the WLBD bot in the Discord by simply extending an exsisting build enviroment: +``` +[env:esp32klipper] +extends = env:esp32dev +build_flags = ${common.build_flags_esp32} -D USERMOD_KLIPPER_PERCENTAGE +``` + +## Settings + +### Enabled: +Checkbox to enable or disable the overlay + +### Klipper IP: +IP adress of your Klipper instance you want to poll. ESP has to be restarted after change + +### Direction : +0 = normal + +1 = reversed + +2 = center + +----- +Author: + +Sören Willrodt + +Discord: Sören#5281 \ No newline at end of file diff --git a/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.h b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.h new file mode 100644 index 00000000..0e19cc80 --- /dev/null +++ b/usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.h @@ -0,0 +1,222 @@ +#pragma once + +#include "wled.h" + +class klipper_percentage : public Usermod +{ +private: + unsigned long lastTime = 0; + String ip = "192.168.25.207"; + WiFiClient wifiClient; + char errorMessage[100] = ""; + int printPercent = 0; + int direction = 0; // 0 for along the strip, 1 for reversed direction + + static const char _name[]; + static const char _enabled[]; + bool enabled = false; + + void httpGet(WiFiClient &client, char *errorMessage) + { + // https://arduinojson.org/v6/example/http-client/ + // is this the most compact way to do http get and put it in arduinojson object??? + // would like async response ... ??? + client.setTimeout(10000); + if (!client.connect(ip.c_str(), 80)) + { + strcat(errorMessage, PSTR("Connection failed")); + } + else + { + // Send HTTP request + client.println(F("GET /printer/objects/query?virtual_sdcard=progress HTTP/1.0")); + client.println("Host: " + ip); + client.println(F("Connection: close")); + if (client.println() == 0) + { + strcat(errorMessage, PSTR("Failed to send request")); + } + else + { + // Check HTTP status + char status[32] = {0}; + client.readBytesUntil('\r', status, sizeof(status)); + if (strcmp(status, "HTTP/1.1 200 OK") != 0) + { + strcat(errorMessage, PSTR("Unexpected response: ")); + strcat(errorMessage, status); + } + else + { + // Skip HTTP headers + char endOfHeaders[] = "\r\n\r\n"; + if (!client.find(endOfHeaders)) + { + strcat(errorMessage, PSTR("Invalid response")); + } + } + } + } + } + +public: + void setup() + { + } + + void connected() + { + } + + void loop() + { + if (enabled) + { + if (WLED_CONNECTED) + { + if (millis() - lastTime > 10000) + { + httpGet(wifiClient, errorMessage); + if (strcmp(errorMessage, "") == 0) + { + PSRAMDynamicJsonDocument klipperDoc(4096); // in practive about 2673 + DeserializationError error = deserializeJson(klipperDoc, wifiClient); + if (error) + { + strcat(errorMessage, PSTR("deserializeJson() failed: ")); + strcat(errorMessage, error.c_str()); + } + printPercent = (int)(klipperDoc["result"]["status"]["virtual_sdcard"]["progress"].as() * 100); + + DEBUG_PRINT("Percent: "); + DEBUG_PRINTLN((int)(klipperDoc["result"]["status"]["virtual_sdcard"]["progress"].as() * 100)); + DEBUG_PRINT("LEDs: "); + DEBUG_PRINTLN(direction == 2 ? (strip.getLengthTotal() / 2) * printPercent / 100 : strip.getLengthTotal() * printPercent / 100); + } + else + { + DEBUG_PRINTLN(errorMessage); + DEBUG_PRINTLN(ip); + } + lastTime = millis(); + } + } + } + } + + void addToConfig(JsonObject &root) + { + JsonObject top = root.createNestedObject("Klipper Printing Percentage"); + top["Enabled"] = enabled; + top["Klipper IP"] = ip; + top["Direction"] = direction; + } + + bool readFromConfig(JsonObject &root) + { + // default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor + // setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed) + + JsonObject top = root["Klipper Printing Percentage"]; + + bool configComplete = !top.isNull(); + configComplete &= getJsonValue(top["Klipper IP"], ip); + configComplete &= getJsonValue(top["Enabled"], enabled); + configComplete &= getJsonValue(top["Direction"], direction); + return configComplete; + } + + /* + * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. + * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. + * Below it is shown how this could be used for e.g. a light sensor + */ + void addToJsonInfo(JsonObject &root) + { + JsonObject user = root["u"]; + if (user.isNull()) + user = root.createNestedObject("u"); + + JsonArray infoArr = user.createNestedArray(FPSTR(_name)); + String uiDomString = F(""); + infoArr.add(uiDomString); + } + + void addToJsonState(JsonObject &root) + { + JsonObject usermod = root[FPSTR(_name)]; + if (usermod.isNull()) + { + usermod = root.createNestedObject(FPSTR(_name)); + } + usermod["on"] = enabled; + } + void readFromJsonState(JsonObject &root) + { + JsonObject usermod = root[FPSTR(_name)]; + if (!usermod.isNull()) + { + if (usermod[FPSTR(_enabled)].is()) + { + enabled = usermod[FPSTR(_enabled)].as(); + } + } + } + + /* + * handleOverlayDraw() is called just before every show() (LED strip update frame) after effects have set the colors. + * Use this to blank out some LEDs or set them to a different color regardless of the set effect mode. + * Commonly used for custom clocks (Cronixie, 7 segment) + */ + void handleOverlayDraw() + { + if (enabled) + { + if (direction == 0) // normal + { + for (int i = 0; i < strip.getLengthTotal() * printPercent / 100; i++) + { + strip.setPixelColor(i, strip.getSegment(0).colors[1]); + } + } + else if (direction == 1) // reversed + { + for (int i = 0; i < strip.getLengthTotal() * printPercent / 100; i++) + { + strip.setPixelColor(strip.getLengthTotal() - i, strip.getSegment(0).colors[1]); + } + } + else if (direction == 2) // center + { + for (int i = 0; i < (strip.getLengthTotal() / 2) * printPercent / 100; i++) + { + strip.setPixelColor((strip.getLengthTotal() / 2) + i, strip.getSegment(0).colors[1]); + strip.setPixelColor((strip.getLengthTotal() / 2) - i, strip.getSegment(0).colors[1]); + } + } + else + { + direction = 0; + } + } + } + + /* + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() + { + return USERMOD_ID_KLIPPER; + } +}; +const char klipper_percentage::_name[] PROGMEM = "Klipper_Percentage"; +const char klipper_percentage::_enabled[] PROGMEM = "enabled"; \ No newline at end of file diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index 526ee7a0..96539658 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -348,8 +348,10 @@ public: findCurrentEffectAndPalette(); } - if (modes_alpha_indexes[effectCurrentIndex] != effectCurrent || palettes_alpha_indexes[effectPaletteIndex] != effectPalette) { - currentEffectAndPaletteInitialized = false; + if (modes_alpha_indexes != nullptr) { // WLEDMM bugfix + if (modes_alpha_indexes[effectCurrentIndex] != effectCurrent || palettes_alpha_indexes[effectPaletteIndex] != effectPalette) { + currentEffectAndPaletteInitialized = false; + } } if (currentTime - loopTime >= 2) // 2ms since last check of encoder = 500Hz @@ -469,11 +471,13 @@ public: void displayNetworkInfo() { #ifdef USERMOD_FOUR_LINE_DISPLAY + if (display != nullptr) display->networkOverlay(PSTR("NETWORK INFO"), 10000); #endif } void findCurrentEffectAndPalette() { + if (modes_alpha_indexes == nullptr) return; // WLEDMM bugfix currentEffectAndPaletteInitialized = true; for (uint8_t i = 0; i < strip.getModeCount(); i++) { if (modes_alpha_indexes[i] == effectCurrent) { @@ -510,7 +514,8 @@ public: // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa //setValuesFromFirstSelectedSeg(); //to make transition work on main segment (should no longer be required) stateUpdated(CALL_MODE_BUTTON); - updateInterfaces(CALL_MODE_BUTTON); + if ((millis() - lastInterfaceUpdate) > INTERFACE_UPDATE_COOLDOWN) // WLEDMM respect cooldown times, to avoid crash in AsyncWebSocketMessageBuffer + updateInterfaces(CALL_MODE_BUTTON); } void changeBrightness(bool increase) { @@ -522,7 +527,10 @@ public: } display->updateRedrawTime(); #endif - bri = max(min((increase ? bri+fadeAmount : bri-fadeAmount), 255), 0); + byte lastBri = bri; + if (bri < 40) bri = max(min((increase ? bri+fadeAmount/2 : bri-fadeAmount/2), 255), 0); // WLEDMM slower steps when brightness < 16% + else bri = max(min((increase ? bri+fadeAmount : bri-fadeAmount), 255), 0); + if (lastBri != bri) stateChanged = true; // WLEDMM bugfix lampUdated(); #ifdef USERMOD_FOUR_LINE_DISPLAY if (display->canDraw()) // only draw if nothing else is drawing @@ -541,7 +549,7 @@ public: display->updateRedrawTime(); #endif effectCurrentIndex = max(min((increase ? effectCurrentIndex+1 : effectCurrentIndex-1), strip.getModeCount()-1), 0); - effectCurrent = modes_alpha_indexes[effectCurrentIndex]; + if (modes_alpha_indexes != nullptr) effectCurrent = modes_alpha_indexes[effectCurrentIndex]; stateChanged = true; if (applyToAll) { for (byte i=0; i?');")); - + oappend(SET_F("addHB('Weather');")); // WLEDMM + oappend(SET_F("dd=addDropdown('Weather','units');")); oappend(SET_F("addOption(dd,'Kelvin',0);")); oappend(SET_F("addOption(dd,'Celcius',1);")); @@ -349,9 +348,6 @@ class WeatherUsermod : public Usermod { } }; -// strings to reduce flash memory usage (used more than twice) -const char WeatherUsermod::_name[] PROGMEM = "Weather"; - // example openweathermap data // {"cod":"200","message":0,"cnt":40,"list":[ // {"dt":1663945200,"main":{"temp":18.05,"feels_like":17.79,"temp_min":17.64,"temp_max":18.05,"pressure":1014,"sea_level":1014,"grnd_level":1013,"humidity":72,"temp_kf":0.41},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":4.32,"deg":238,"gust":5.6},"visibility":10000,"pop":0.48,"rain":{"3h":0.15},"sys":{"pod":"d"},"dt_txt":"2022-09-23 15:00:00"}, diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 8915e118..f2e3801d 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -124,7 +124,7 @@ uint16_t blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) { uint16_t mode_blink(void) { return blink(SEGCOLOR(0), SEGCOLOR(1), false, true); } -static const char _data_FX_MODE_BLINK[] PROGMEM = "Blink@!,Duty cycle;!,!;!"; +static const char _data_FX_MODE_BLINK[] PROGMEM = "Blink@!,Duty cycle;!,!;!;01"; /* @@ -133,7 +133,7 @@ static const char _data_FX_MODE_BLINK[] PROGMEM = "Blink@!,Duty cycle;!,!;!"; uint16_t mode_blink_rainbow(void) { return blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), false, false); } -static const char _data_FX_MODE_BLINK_RAINBOW[] PROGMEM = "Blink Rainbow@Frequency,Blink duration;!,!;!"; +static const char _data_FX_MODE_BLINK_RAINBOW[] PROGMEM = "Blink Rainbow@Frequency,Blink duration;!,!;!;01"; /* @@ -142,7 +142,7 @@ static const char _data_FX_MODE_BLINK_RAINBOW[] PROGMEM = "Blink Rainbow@Frequen uint16_t mode_strobe(void) { return blink(SEGCOLOR(0), SEGCOLOR(1), true, true); } -static const char _data_FX_MODE_STROBE[] PROGMEM = "Strobe@!;!,!;!"; +static const char _data_FX_MODE_STROBE[] PROGMEM = "Strobe@!;!,!;!;01"; /* @@ -151,7 +151,7 @@ static const char _data_FX_MODE_STROBE[] PROGMEM = "Strobe@!;!,!;!"; uint16_t mode_strobe_rainbow(void) { return blink(SEGMENT.color_wheel(SEGENV.call & 0xFF), SEGCOLOR(1), true, false); } -static const char _data_FX_MODE_STROBE_RAINBOW[] PROGMEM = "Strobe Rainbow@!;,!;!"; +static const char _data_FX_MODE_STROBE_RAINBOW[] PROGMEM = "Strobe Rainbow@!;,!;!;01"; /* @@ -350,7 +350,7 @@ uint16_t mode_breath(void) { return FRAMETIME; } -static const char _data_FX_MODE_BREATH[] PROGMEM = "Breathe@!;!,!;!"; +static const char _data_FX_MODE_BREATH[] PROGMEM = "Breathe@!;!,!;!;01"; /* @@ -366,7 +366,7 @@ uint16_t mode_fade(void) { return FRAMETIME; } -static const char _data_FX_MODE_FADE[] PROGMEM = "Fade@!;!,!;!"; +static const char _data_FX_MODE_FADE[] PROGMEM = "Fade@!;!,!;!;01"; /* @@ -754,7 +754,7 @@ uint16_t mode_multi_strobe(void) { return FRAMETIME; } -static const char _data_FX_MODE_MULTI_STROBE[] PROGMEM = "Strobe Mega@!,!;!,!;!"; +static const char _data_FX_MODE_MULTI_STROBE[] PROGMEM = "Strobe Mega@!,!;!,!;!;01"; /* @@ -976,6 +976,7 @@ static const char _data_FX_MODE_COLORFUL[] PROGMEM = "Colorful@!,Saturation;1,2, * Emulates a traffic light. */ uint16_t mode_traffic_light(void) { + if (SEGLEN == 1) return mode_static(); for (int i=0; i < SEGLEN; i++) SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); uint32_t mdelay = 500; @@ -1008,6 +1009,7 @@ static const char _data_FX_MODE_TRAFFIC_LIGHT[] PROGMEM = "Traffic Light@!,US st */ #define FLASH_COUNT 4 uint16_t mode_chase_flash(void) { + if (SEGLEN == 1) return mode_static(); uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for (int i = 0; i < SEGLEN; i++) { @@ -1037,6 +1039,7 @@ static const char _data_FX_MODE_CHASE_FLASH[] PROGMEM = "Chase Flash@!;Bg,Fx;!"; * Prim flashes running, followed by random color. */ uint16_t mode_chase_flash_random(void) { + if (SEGLEN == 1) return mode_static(); uint8_t flash_step = SEGENV.call % ((FLASH_COUNT * 2) + 1); for (int i = 0; i < SEGENV.aux1; i++) { @@ -1170,6 +1173,7 @@ static const char _data_FX_MODE_DUAL_LARSON_SCANNER[] PROGMEM = "Scanner Dual@!, * Firing comets from one end. "Lighthouse" */ uint16_t mode_comet(void) { + if (SEGLEN == 1) return mode_static(); uint16_t counter = strip.now * ((SEGMENT.speed >>2) +1); uint16_t index = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) SEGENV.aux0 = index; @@ -1197,7 +1201,8 @@ static const char _data_FX_MODE_COMET[] PROGMEM = "Lighthouse@!,Fade rate;!,!;!" * Fireworks function. */ uint16_t mode_fireworks() { - const uint16_t width = strip.isMatrix ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); + if (SEGLEN == 1) return mode_static(); + const uint16_t width = SEGMENT.is2D() ? SEGMENT.virtualWidth() : SEGMENT.virtualLength(); const uint16_t height = SEGMENT.virtualHeight(); if (SEGENV.call == 0) { @@ -1211,18 +1216,18 @@ uint16_t mode_fireworks() { bool valid1 = (SEGENV.aux0 < width*height); bool valid2 = (SEGENV.aux1 < width*height); uint32_t sv1 = 0, sv2 = 0; - if (valid1) sv1 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color - if (valid2) sv2 = strip.isMatrix ? SEGMENT.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : SEGMENT.getPixelColor(SEGENV.aux1); + if (valid1) sv1 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color + if (valid2) sv2 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : SEGMENT.getPixelColor(SEGENV.aux1); if (!SEGENV.step) SEGMENT.blur(16); - if (valid1) { if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur - if (valid2) { if (strip.isMatrix) SEGMENT.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur + if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur + if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur for (int i=0; i> 1)) == 0) { uint16_t index = random16(width*height); uint16_t j = index % width, k = index / width; uint32_t col = SEGMENT.color_from_palette(random8(), false, false, 0); - if (strip.isMatrix) SEGMENT.setPixelColorXY(j, k, col); + if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(j, k, col); else SEGMENT.setPixelColor(index, col); SEGENV.aux1 = SEGENV.aux0; // old spark SEGENV.aux0 = index; // remember where spark occured @@ -1234,8 +1239,8 @@ static const char _data_FX_MODE_FIREWORKS[] PROGMEM = "Fireworks@,Frequency;!,!; //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h -uint16_t mode_rain() -{ +uint16_t mode_rain() { + if (SEGLEN == 1) return mode_static(); const uint16_t width = SEGMENT.virtualWidth(); const uint16_t height = SEGMENT.virtualHeight(); SEGENV.step += FRAMETIME; @@ -1294,7 +1299,7 @@ uint16_t mode_fire_flicker(void) { SEGENV.step = it; return FRAMETIME; } -static const char _data_FX_MODE_FIRE_FLICKER[] PROGMEM = "Fire Flicker@!,!;!;!;;pal=0"; //WLEDMM pal=0 +static const char _data_FX_MODE_FIRE_FLICKER[] PROGMEM = "Fire Flicker@!,!;!;!;01;pal=0"; //WLEDMM pal=0 /* @@ -1345,8 +1350,8 @@ static const char _data_FX_MODE_LOADING[] PROGMEM = "Loading@!,Fade;!,!;!;;ix=16 //American Police Light with all LEDs Red and Blue -uint16_t police_base(uint32_t color1, uint32_t color2) -{ +uint16_t police_base(uint32_t color1, uint32_t color2) { + if (SEGLEN == 1) return mode_static(); uint16_t delay = 1 + (FRAMETIME<<3) / SEGLEN; // longer segments should change faster uint32_t it = strip.now / map(SEGMENT.speed, 0, 255, delay<<4, delay); uint16_t offset = it % SEGLEN; @@ -1794,9 +1799,9 @@ uint16_t mode_oscillate(void) { } } - for (int i=0; i < SEGLEN; i++) { + for (int i = 0; i < SEGLEN; i++) { uint32_t color = BLACK; - for (int j=0; j < numOscillators; j++) { + for (int j = 0; j < numOscillators; j++) { if(i >= oscillators[j].pos - oscillators[j].size && i <= oscillators[j].pos + oscillators[j].size) { color = (color == BLACK) ? SEGCOLOR(j) : color_blend(color, SEGCOLOR(j), 128); } @@ -1812,6 +1817,7 @@ static const char _data_FX_MODE_OSCILLATE[] PROGMEM = "Oscillate"; //TODO uint16_t mode_lightning(void) { + if (SEGLEN == 1) return mode_static(); uint16_t ledstart = random16(SEGLEN); // Determine starting location of flash uint16_t ledlen = 1 + random16(SEGLEN -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/random8(1, 3); @@ -1872,7 +1878,6 @@ uint16_t mode_pride_2015(void) { sPseudotime += duration * msmultiplier; sHue16 += duration * beatsin88( 400, 5,9); uint16_t brightnesstheta16 = sPseudotime; - CRGB fastled_col; for (int i = 0 ; i < SEGLEN; i++) { hue16 += hueinc16; @@ -1898,6 +1903,7 @@ static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;"; //eight colored dots, weaving in and out of sync with each other uint16_t mode_juggle(void) { + if (SEGLEN == 1) return mode_static(); if (SEGENV.call == 0) { SEGMENT.setUpLeds(); //lossless getPixelColor() SEGMENT.fill(BLACK); @@ -1967,6 +1973,7 @@ static const char _data_FX_MODE_PALETTE[] PROGMEM = "Palette@Cycle speed;;!;;c3= // feel of your fire: COOLING (used in step 1 above) (Speed = COOLING), and SPARKING (used // in step 3 above) (Effect Intensity = Sparking). uint16_t mode_fire_2012() { + if (SEGLEN == 1) return mode_static(); const uint16_t strips = SEGMENT.nrOfVStrips(); if (!SEGENV.allocateData(strips * SEGLEN)) return mode_static(); //allocation failed byte* heat = SEGENV.data; @@ -2267,6 +2274,7 @@ static const char _data_FX_MODE_LAKE[] PROGMEM = "Lake@!;Fx;!"; // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain uint16_t mode_meteor() { + if (SEGLEN == 1) return mode_static(); if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed byte* trail = SEGENV.data; @@ -2304,6 +2312,7 @@ static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail length;!;!"; // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain uint16_t mode_meteor_smooth() { + if (SEGLEN == 1) return mode_static(); if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed byte* trail = SEGENV.data; @@ -2341,6 +2350,7 @@ static const char _data_FX_MODE_METEOR_SMOOTH[] PROGMEM = "Meteor Smooth@!,Trail //Railway Crossing / Christmas Fairy lights uint16_t mode_railway() { + if (SEGLEN == 1) return mode_static(); uint16_t dur = (256 - SEGMENT.speed) * 40; uint16_t rampdur = (dur * SEGMENT.intensity) >> 8; if (SEGENV.step > dur) @@ -2441,6 +2451,7 @@ uint16_t ripple_base() uint16_t mode_ripple(void) { + if (SEGLEN == 1) return mode_static(); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); return ripple_base(); } @@ -2448,6 +2459,7 @@ static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #,,,,,Overlay; uint16_t mode_ripple_rainbow(void) { + if (SEGLEN == 1) return mode_static(); if (SEGENV.call ==0) { SEGENV.aux0 = random8(); SEGENV.aux1 = random8(); @@ -2612,6 +2624,7 @@ static const char _data_FX_MODE_TWINKLECAT[] PROGMEM = "Twinklecat@!,Twinkle rat //inspired by https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectBlinkingHalloweenEyes uint16_t mode_halloween_eyes() { + if (SEGLEN == 1) return mode_static(); const uint16_t maxWidth = strip.isMatrix ? SEGMENT.virtualWidth() : SEGLEN; const uint16_t HALLOWEEN_EYE_SPACE = MAX(2, strip.isMatrix ? SEGMENT.virtualWidth()>>4: SEGLEN>>5); const uint16_t HALLOWEEN_EYE_WIDTH = HALLOWEEN_EYE_SPACE/2; @@ -2721,6 +2734,7 @@ static const char _data_FX_MODE_TRI_STATIC_PATTERN[] PROGMEM = "Solid Pattern Tr uint16_t spots_base(uint16_t threshold) { + if (SEGLEN == 1) return mode_static(); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); uint16_t maxZones = SEGLEN >> 2; @@ -2776,6 +2790,7 @@ typedef struct Ball { * Bouncing Balls Effect */ uint16_t mode_bouncing_balls(void) { + if (SEGLEN == 1) return mode_static(); //allocate segment data const uint16_t strips = SEGMENT.nrOfVStrips(); // adapt for 2D const size_t maxNumBalls = 16; @@ -2848,6 +2863,7 @@ static const char _data_FX_MODE_BOUNCINGBALLS[] PROGMEM = "Bouncing Balls@Gravit * Sinelon stolen from FASTLED examples */ uint16_t sinelon_base(bool dual, bool rainbow=false) { + if (SEGLEN == 1) return mode_static(); SEGMENT.fade_out(SEGMENT.intensity); uint16_t pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1); if (SEGENV.call == 0) SEGENV.aux0 = pos; @@ -2945,6 +2961,7 @@ typedef struct Spark { * modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h */ uint16_t mode_popcorn(void) { + if (SEGLEN == 1) return mode_static(); //allocate segment data uint16_t strips = SEGMENT.nrOfVStrips(); uint16_t dataSize = sizeof(spark) * maxNumPopcorn; @@ -3087,7 +3104,7 @@ uint16_t mode_candle() { return candle(false); } -static const char _data_FX_MODE_CANDLE[] PROGMEM = "Candle@!,!;!,!;!;1;sx=96,ix=224,pal=0"; +static const char _data_FX_MODE_CANDLE[] PROGMEM = "Candle@!,!;!,!;!;01;sx=96,ix=224,pal=0"; uint16_t mode_candle_multi() @@ -3118,6 +3135,7 @@ typedef struct particle { } star; uint16_t mode_starburst(void) { + if (SEGLEN == 1) return mode_static(); uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640 uint8_t segs = strip.getActiveSegmentsNum(); if (segs <= (strip.getMaxSegments() /2)) maxData *= 2; //ESP8266: 512 if <= 8 segs ESP32: 1280 if <= 16 segs @@ -3237,6 +3255,7 @@ static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chanc */ uint16_t mode_exploding_fireworks(void) { + if (SEGLEN == 1) return mode_static(); const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); @@ -3371,6 +3390,7 @@ static const char _data_FX_MODE_EXPLODING_FIREWORKS[] PROGMEM = "Fireworks 1D@Gr */ uint16_t mode_drip(void) { + if (SEGLEN == 1) return mode_static(); //allocate segment data uint16_t strips = SEGMENT.nrOfVStrips(); const int maxNumDrops = 4; @@ -3468,6 +3488,7 @@ typedef struct Tetris { } tetris; uint16_t mode_tetrix(void) { + if (SEGLEN == 1) return mode_static(); uint16_t strips = SEGMENT.nrOfVStrips(); // allow running on virtual strips (columns in 2D segment) uint16_t dataSize = sizeof(tetris); if (!SEGENV.allocateData(dataSize * strips)) return mode_static(); //allocation failed @@ -3510,7 +3531,7 @@ uint16_t mode_tetrix(void) { if (drop->pos > drop->stack) { // fall until top of stack drop->pos -= drop->speed; // may add gravity as: speed += gravity if (int(drop->pos) < int(drop->stack)) drop->pos = drop->stack; - for (int i=int(drop->pos); ipos); i < SEGLEN; i++) { uint32_t col = ipos)+drop->brick ? SEGMENT.color_from_palette(drop->col, false, false, 0) : SEGCOLOR(1); SEGMENT.setPixelColor(indexToVStrip(i, stripNr), col); } @@ -3525,7 +3546,7 @@ uint16_t mode_tetrix(void) { drop->brick = 0; // reset brick size (no more growing) if (drop->step > millis()) { // allow fading of virtual strip - for (int i=0; istack = 0; // reset brick stack size drop->step = 0; // proceed with next brick @@ -3652,7 +3673,7 @@ uint16_t mode_heartbeat(void) { return FRAMETIME; } -static const char _data_FX_MODE_HEARTBEAT[] PROGMEM = "Heartbeat@!,!;!,!;!;;m12=1"; //Bar +static const char _data_FX_MODE_HEARTBEAT[] PROGMEM = "Heartbeat@!,!;!,!;!;01;m12=1"; //Bar // "Pacifica" @@ -3776,6 +3797,7 @@ static const char _data_FX_MODE_PACIFICA[] PROGMEM = "Pacifica@!,Angle;;!;;pal=5 * Mode simulates a gradual sunrise */ uint16_t mode_sunrise() { + if (SEGLEN == 1) return mode_static(); //speed 0 - static sun //speed 1 - 60: sunrise time in minutes //speed 60 - 120 : sunset time in minutes - 60; @@ -3869,7 +3891,7 @@ static const char _data_FX_MODE_PHASEDNOISE[] PROGMEM = "Phased Noise@!,!;!,!;!" uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through. - for (int i = 0; i SEGMENT.intensity) pixBri = 0; @@ -3931,7 +3953,7 @@ uint16_t mode_sinewave(void) { // Adjustable sinewave. By Andrew Tul SEGENV.step += SEGMENT.speed/16; // Speed of animation. uint16_t freq = SEGMENT.intensity/4;//SEGMENT.fft2/8; // Frequency of the signal. - for (int i=0; i> 4)); uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment @@ -4037,6 +4060,7 @@ typedef struct Spotlight { */ uint16_t mode_dancing_shadows(void) { + if (SEGLEN == 1) return mode_static(); uint8_t numSpotlights = map(SEGMENT.intensity, 0, 255, 2, SPOT_MAX_COUNT); // 49 on 32 segment ESP32, 17 on 16 segment ESP8266 bool initialize = SEGENV.aux0 != numSpotlights; SEGENV.aux0 = numSpotlights; @@ -4163,7 +4187,7 @@ uint16_t mode_washing_machine(void) { SEGENV.step += (speed * 128.0f); - for (int i=0; i> 7)); SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(col, false, PALETTE_SOLID_WRAP, 3)); } @@ -4500,7 +4524,7 @@ static const char _data_FX_MODE_AURORA[] PROGMEM = "Aurora@!,!;1,2,3;!;;sx=24,pa // 16 bit perlinmove. Use Perlin Noise instead of sinewaves for movement. By Andrew Tuline. // Controls are speed, # of pixels, faderate. uint16_t mode_perlinmove(void) { - + if (SEGLEN == 1) return mode_static(); SEGMENT.fade_out(255-SEGMENT.custom1); for (int i = 0; i < SEGMENT.intensity/16 + 1; i++) { uint16_t locn = inoise16(millis()*128/(260-SEGMENT.speed)+i*15000, millis()*128/(260-SEGMENT.speed)); // Get a new pixel location from moving noise. @@ -5796,8 +5820,8 @@ uint16_t mode_2Dfloatingblobs(void) { } } uint32_t c = SEGMENT.color_from_palette(blob->color[i], false, false, 0); - if (blob->r[i] > 1.f) SEGMENT.fill_circle(blob->y[i], blob->x[i], roundf(blob->r[i]), c); - else SEGMENT.setPixelColorXY(blob->y[i], blob->x[i], c); + if (blob->r[i] > 1.f) SEGMENT.fill_circle(blob->x[i], blob->y[i], roundf(blob->r[i]), c); + else SEGMENT.setPixelColorXY(blob->x[i], blob->y[i], c); // move x if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f)); else if (blob->x[i] - blob->r[i] <= 0) blob->x[i] += (blob->sX[i] * (blob->x[i] / blob->r[i] + 0.005f)); @@ -6363,7 +6387,7 @@ uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline. SEGENV.aux0 = secondHand; int pixBri = volumeRaw * SEGMENT.intensity / 64; - for (int i=0; ithisphase += beatsin8(6,-4,4); // You can change direction and speed individually. plasmoip->thatphase += beatsin8(7,-4,4); // Two phase values to make a complex pattern. By Andrew Tuline. - for (int i=0; ithisphase) & 0xFF)/2; thisbright += cos8(((i*(97 +(5*SEGMENT.speed/32)))+plasmoip->thatphase) & 0xFF)/2; // Let's munge the brightness a bit and animate it all with the phases. @@ -7087,7 +7111,7 @@ uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tulin } else { SEGMENT.setPixelColor(SEGLEN-1, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(pixCol+SEGMENT.intensity, false, PALETTE_SOLID_WRAP, 0), (int)my_magnitude)); } - for (int i=0; i(SEGENV.data); //array of previous bar heights per frequency band @@ -7131,12 +7156,39 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. int fadeoutDelay = (256 - SEGMENT.speed) / 64; if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(SEGMENT.speed); + uint16_t lastBandHeight = 0; // WLEDMM: for smoothing out bars + + //WLEDMM: evenly ditribut bands + float bandwidth = (float)cols / NUM_BANDS; + float remaining = bandwidth; + uint8_t band = 0; for (int x=0; x < cols; x++) { - uint8_t band = map(x, 0, cols-1, 0, NUM_BANDS - 1); - if (NUM_BANDS < 16) band = map(band, 0, NUM_BANDS - 1, 0, 15); // always use full range. comment out this line to get the previous behaviour. - band = constrain(band, 0, 15); - uint16_t colorIndex = band * 17; - uint16_t barHeight = map(fftResult[band], 0, 255, 0, rows); // do not subtract -1 from rows here + //WLEDMM if not enough remaining + if (remaining < 1) {band++; remaining+= bandwidth;} //increase remaining but keep the current remaining + remaining--; //consume remaining + + // Serial.printf("x %d b %d n %d w %f %f\n", x, band, NUM_BANDS, bandwidth, remaining); + uint8_t frBand = ((NUM_BANDS < 16) && (NUM_BANDS > 1)) ? map(band, 0, NUM_BANDS - 1, 0, 15):band; // always use full range. comment out this line to get the previous behaviour. + // frBand = constrain(frBand, 0, 15); //WLEDMM can never be out of bounds (I think...) + uint16_t colorIndex = frBand * 17; //WLEDMM 0.255 + uint16_t bandHeight = fftResult[frBand]; // WLEDMM we use the original ffResult, to preserve accuracy + + // WLEDMM begin - smooth out bars + if ((x > 0) && (x < (cols-1)) && (SEGMENT.check2)) { + // get height of next (right side) bar + uint8_t nextband = (remaining < 1)? band +1: band; + nextband = constrain(nextband, 0, 15); // just to be sure + frBand = ((NUM_BANDS < 16) && (NUM_BANDS > 1)) ? map(nextband, 0, NUM_BANDS - 1, 0, 15):nextband; // always use full range. comment out this line to get the previous behaviour. + uint16_t nextBandHeight = fftResult[frBand]; + // smooth Band height + bandHeight = (7*bandHeight + 3*lastBandHeight + 3*nextBandHeight) / 12; // yeees, its 12 not 13 (10% amplification) + bandHeight = constrain(bandHeight, 0, 255); // remove potential over/underflows + colorIndex = map(x, 0, cols-1, 0, 255); //WLEDMM + } + lastBandHeight = bandHeight; // remember BandHeight (left side) for next iteration + uint16_t barHeight = map(bandHeight, 0, 255, 0, rows); // Now we map bandHeight to barHeight. do not subtract -1 from rows here + // WLEDMM end + if (barHeight > rows) barHeight = rows; // WLEDMM map() can "overshoot" due to rounding errors if (barHeight > previousBarHeight[x]) previousBarHeight[x] = barHeight; //drive the peak up @@ -7148,7 +7200,7 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. ledColor = SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0); SEGMENT.setPixelColorXY(x, rows-1 - y, ledColor); } - if ((previousBarHeight[x] > 0) && (previousBarHeight[x] < rows)) // WLEDMM avoid "overshooting" into other segments + if ((SEGMENT.intensity < 255) && (previousBarHeight[x] > 0) && (previousBarHeight[x] < rows)) // WLEDMM avoid "overshooting" into other segments SEGMENT.setPixelColorXY(x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor); if (rippleTime && previousBarHeight[x]>0) previousBarHeight[x]--; //delay/ripple effect @@ -7156,13 +7208,13 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. #ifdef SR_DEBUG // WLEDMM: abuse top left/right pixels for peak detection debugging - SEGMENT.setPixelColorXY(cols-1, rows-1, (samplePeak > 0) ? GREEN : BLACK); - if (samplePeak > 0) SEGMENT.setPixelColorXY(0, rows-1, GREEN); + SEGMENT.setPixelColorXY(cols-1, 0, (samplePeak > 0) ? GREEN : BLACK); + if (samplePeak > 0) SEGMENT.setPixelColorXY(0, 0, GREEN); // WLEDMM end #endif return FRAMETIME; } // mode_2DGEQ() -static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ ☾@Fade speed,Ripple decay,# of bands,,,Color bars;!,,Peaks;!;2f;c1=255,c2=64,pal=11,si=0"; // Beatsin +static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ ☾@Fade speed,Ripple decay,# of bands,,,Color bars,Smooth bars ☾;!,,Peaks;!;2f;c1=255,c2=64,pal=11,si=0"; // Beatsin ///////////////////////// diff --git a/wled00/FX.h b/wled00/FX.h index 86ecd39e..7ceb8aa5 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -72,7 +72,11 @@ #ifndef MAX_NUM_SEGMENTS #define MAX_NUM_SEGMENTS 32 #endif - #define MAX_SEGMENT_DATA 32767 + #if defined(ARDUINO_ARCH_ESP32S2) + #define MAX_SEGMENT_DATA 24576 + #else + #define MAX_SEGMENT_DATA 32767 + #endif #endif /* How much data bytes each segment should max allocate to leave enough space for other segments, @@ -322,8 +326,8 @@ typedef enum mapping1D2D { M12_pArc = 2, M12_pCorner = 3, M12_jMap = 4, //WLEDMM jMap - M12_sCircle = 5, //WLEDMM jMap - M12_sBlock = 6 //WLEDMM jMap + M12_sCircle = 5, //WLEDMM Circle + M12_sBlock = 6 //WLEDMM Block } mapping1D2D_t; // segment, 72 bytes @@ -465,7 +469,7 @@ typedef struct Segment { _dataLen(0), _t(nullptr) { - refreshLightCapabilities(); + //refreshLightCapabilities(); } Segment(uint16_t sStartX, uint16_t sStopX, uint16_t sStartY, uint16_t sStopY) : Segment(sStartX, sStopX) { @@ -501,6 +505,9 @@ typedef struct Segment { inline bool isSelected(void) const { return selected; } inline bool isActive(void) const { return stop > start; } inline bool is2D(void) const { return (width()>1 && height()>1); } + inline bool hasRGB(void) const { return _isRGB; } + inline bool hasWhite(void) const { return _hasW; } + inline bool isCCT(void) const { return _isCCT; } inline uint16_t width(void) const { return stop - start; } // segment width in physical pixels (length if 1D) inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels @@ -668,7 +675,6 @@ class WS2812FX { // 96 bytes isMatrix(false), #ifndef WLED_DISABLE_2D panels(1), - matrix{0,0,0,0}, #endif // semi-private (just obscured) used in effect functions through macros _currentPalette(CRGBPalette16(CRGB::Black)), @@ -721,7 +727,6 @@ class WS2812FX { // 96 bytes finalizeInit(), service(void), setMode(uint8_t segid, uint8_t m), - setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setColor(uint8_t slot, uint32_t c), setCCT(uint16_t k), setBrightness(uint8_t b, bool direct = false), @@ -737,10 +742,10 @@ class WS2812FX { // 96 bytes setPixelColor(int n, uint32_t c), show(void), setTargetFps(uint8_t fps), - deserializeMap(uint8_t n=0), enumerateLedmaps(); //WLEDMM (from fcn_declare) - void fill(uint32_t c) { for (int i = 0; i < _length; i++) setPixelColor(i, c); } // fill whole strip with color (inline) + void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); } + void fill(uint32_t c) { for (int i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline) void addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp void setupEffectData(void); // add default effects to the list; defined in FX.cpp @@ -758,7 +763,8 @@ class WS2812FX { // 96 bytes hasCCTBus(void), // return true if the strip is being sent pixel updates isUpdating(void), - useLedsArray = true; //WLEDMM default true as recommended for overlapping segments + deserializeMap(uint8_t n=0), + useLedsArray = false; inline bool isServicing(void) { return _isServicing; } inline bool hasWhiteChannel(void) {return _hasWhiteChannel;} @@ -787,17 +793,17 @@ class WS2812FX { // 96 bytes ablMilliampsMax, currentMilliamps, getLengthPhysical(void), + getLengthTotal(void), // will include virtual/nonexistent pixels in matrix getFps(); inline uint16_t getFrameTime(void) { return _frametime; } inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } - inline uint16_t getLengthTotal(void) { return _length; } + inline uint16_t getLength(void) { return _length; } // 2D matrix may have less pixels than W*H inline uint16_t getTransition(void) { return _transitionDur; } uint32_t now, timebase, - currentColor(uint32_t colorNew, uint8_t tNr), getPixelColor(uint16_t); inline uint32_t getLastShow(void) { return _lastShow; } @@ -825,9 +831,9 @@ class WS2812FX { // 96 bytes panelsH, //WLEDMM needs to be stored as well panelsV; //WLEDMM needs to be stored as well + //WLEDMM: keep storing basic 2d setup bool - bOrA; //WLEDMM basic or advanced - + bOrA = false; //WLEDMM basic or advanced, default basic struct { bool bottomStart : 1; bool rightStart : 1; @@ -839,7 +845,7 @@ class WS2812FX { // 96 bytes bool rightStart : 1; bool vertical : 1; bool serpentine : 1; - } panelO; //WLEDMM panelOrientation + } panelO; //panelOrientation typedef struct panel_t { uint8_t xOffset; // x offset relative to the top left of matrix in LEDs. WLEDMM 8 bits/256 is enough @@ -855,12 +861,19 @@ class WS2812FX { // 96 bytes bool serpentine : 1; // is serpentine? }; }; + panel_t() + : xOffset(0) + , yOffset(0) + , width(8) + , height(8) + , options(0) + {} } Panel; std::vector panel; #endif void - setUpMatrix(bool reset = true), //WLEDMM: add reset option to switch on/off reset of customMappingTable + setUpMatrix(), setPixelColorXY(int x, int y, uint32_t c); // outsmart the compiler :) by correctly overloading diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index a35cc6a9..84335dd8 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -34,15 +34,12 @@ // note: matrix may be comprised of multiple panels each with different orientation // but ledmap takes care of that. ledmap is constructed upon initialization // so matrix should disable regular ledmap processing -void WS2812FX::setUpMatrix(bool reset) { +void WS2812FX::setUpMatrix() { #ifndef WLED_DISABLE_2D // erase old ledmap, just in case. - if (reset) { //WLEDMM: add reset option to switch on/off reset of customMappingTable - if (customMappingTable != nullptr) delete[] customMappingTable; - customMappingTable = nullptr; - customMappingSize = 0; - loadedLedmap = 0; - } + if (customMappingTable != nullptr) delete[] customMappingTable; + customMappingTable = nullptr; + customMappingSize = 0; // isMatrix is set in cfg.cpp or set.cpp if (isMatrix) { @@ -59,30 +56,60 @@ void WS2812FX::setUpMatrix(bool reset) { } } - if (reset) { //WLEDMM: add reset option to switch on/off reset of customMappingTable - // safety check - if (Segment::maxWidth * Segment::maxHeight > MAX_LEDS || Segment::maxWidth <= 1 || Segment::maxHeight <= 1) { - DEBUG_PRINTF("2D Bounds error. %d x %d\n", Segment::maxWidth, Segment::maxHeight); - isMatrix = false; - Segment::maxWidth = _length; - Segment::maxHeight = 1; - panels = 0; - panel.clear(); // release memory allocated by panels - resetSegments(true); //WLEDMM bounds only - return; - } - - customMappingTable = new uint16_t[Segment::maxWidth * Segment::maxHeight]; + // safety check + if (Segment::maxWidth * Segment::maxHeight > MAX_LEDS || Segment::maxWidth <= 1 || Segment::maxHeight <= 1) { + DEBUG_PRINTF("2D Bounds error. %d x %d\n", Segment::maxWidth, Segment::maxHeight); + isMatrix = false; + Segment::maxWidth = _length; + Segment::maxHeight = 1; + panels = 0; + panel.clear(); // release memory allocated by panels + resetSegments(true); //WLEDMM bounds only + return; } + customMappingTable = new uint16_t[Segment::maxWidth * Segment::maxHeight]; + if (customMappingTable != nullptr) { - uint16_t customMappingSizeLedmap = customMappingSize; customMappingSize = Segment::maxWidth * Segment::maxHeight; - uint16_t *customMappingTableCombi = nullptr; //WLEDMM: Idea @Troy#2642 - if (customMappingSizeLedmap > 0) { //WLEDMM: @Troy#2642 : include ledmap = 0 as default ledmap - customMappingTableCombi = new uint16_t[customMappingSize]; - for (int i=0; i(); + gapSize = map.size(); + if (!map.isNull() && gapSize >= customMappingSize) { // not an empty map + gapTable = new int8_t[gapSize]; + if (gapTable) for (size_t i = 0; i < gapSize; i++) { + gapTable[i] = constrain(map[i], -1, 1); + } + } + } + DEBUG_PRINTLN(F("Gaps loaded.")); + releaseJSONBufferLock(); } uint16_t x, y, pix=0; //pixel @@ -91,30 +118,22 @@ void WS2812FX::setUpMatrix(bool reset) { uint16_t h = p.vertical ? p.height : p.width; uint16_t v = p.vertical ? p.width : p.height; for (size_t j = 0; j < v; j++){ - for(size_t i = 0; i < h; i++, pix++) { + for(size_t i = 0; i < h; i++) { y = (p.vertical?p.rightStart:p.bottomStart) ? v-j-1 : j; x = (p.vertical?p.bottomStart:p.rightStart) ? h-i-1 : i; x = p.serpentine && j%2 ? h-x-1 : x; - uint16_t index = (p.yOffset + (p.vertical?x:y)) * Segment::maxWidth + p.xOffset + (p.vertical?y:x); - if (customMappingSizeLedmap > 0) { //WLEDMM: @Troy#2642 : include ledmap = 0 as default ledmap - if (index < customMappingSizeLedmap && customMappingTable[index] < customMappingSize) - customMappingTableCombi[customMappingTable[index]] = pix; //WLEDMM: allow for 2 transitions if reset = false (ledmap and logical to physical) - } - else - customMappingTable[index] = pix; + size_t index = (p.yOffset + (p.vertical?x:y)) * Segment::maxWidth + p.xOffset + (p.vertical?y:x); + if (!gapTable || (gapTable && gapTable[index] > 0)) customMappingTable[index] = pix; // a useful pixel (otherwise -1 is retained) + if (!gapTable || (gapTable && gapTable[index] >= 0)) pix++; // not a missing pixel } } } - if (customMappingSizeLedmap > 0) { //WLEDMM: @Troy#2642 : include ledmap = 0 as default ledmap - for (size_t i = 0; i < customMappingSize; i++) { - customMappingTable[i] = customMappingTableCombi[i]; - } - delete[] customMappingTableCombi; - } + // delete gap array as we no longer need it + if (gapTable) delete[] gapTable; #ifdef WLED_DEBUG - DEBUG_PRINTF("Matrix ledmap: %d\n", loadedLedmap); + DEBUG_PRINTF("Matrix ledmap: \n"); for (uint16_t i=0; i= customMappingSize) return; #else uint16_t index = x; - if (index >= _length) return; #endif if (index < customMappingSize) index = customMappingTable[index]; + if (index >= _length) return; busses.setPixelColor(index, col); } @@ -155,12 +173,11 @@ void IRAM_ATTR_YN WS2812FX::setPixelColorXY(int x, int y, uint32_t col) //WLEDMM uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { #ifndef WLED_DISABLE_2D uint16_t index = (y * Segment::maxWidth + x); - if (index >= customMappingSize) return 0; // customMappingSize is always W * H of matrix in 2D setup #else uint16_t index = x; - if (index >= _length) return 0; #endif if (index < customMappingSize) index = customMappingTable[index]; + if (index >= _length) return 0; return busses.getPixelColor(index); } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index c666d913..3227b158 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -81,7 +81,7 @@ uint16_t Segment::maxHeight = 1; // copy constructor Segment::Segment(const Segment &orig) { //DEBUG_PRINTLN(F("-- Copy segment constructor --")); - memcpy(this, &orig, sizeof(Segment)); + memcpy((void*)this, (void*)&orig, sizeof(Segment)); name = nullptr; data = nullptr; _dataLen = 0; @@ -97,7 +97,7 @@ Segment::Segment(const Segment &orig) { // move constructor Segment::Segment(Segment &&orig) noexcept { //DEBUG_PRINTLN(F("-- Move segment constructor --")); - memcpy(this, &orig, sizeof(Segment)); + memcpy((void*)this, (void*)&orig, sizeof(Segment)); orig.name = nullptr; orig.data = nullptr; orig._dataLen = 0; @@ -116,7 +116,7 @@ Segment& Segment::operator= (const Segment &orig) { if (leds && !Segment::_globalLeds) free(leds); deallocateData(); // copy source - memcpy(this, &orig, sizeof(Segment)); + memcpy((void*)this, (void*)&orig, sizeof(Segment)); // erase pointers to allocated data name = nullptr; data = nullptr; @@ -141,7 +141,7 @@ Segment& Segment::operator= (Segment &&orig) noexcept { deallocateData(); // free old runtime data if (_t) delete _t; if (leds && !Segment::_globalLeds) free(leds); - memcpy(this, &orig, sizeof(Segment)); + memcpy((void*)this, (void*)&orig, sizeof(Segment)); orig.name = nullptr; orig.data = nullptr; orig._dataLen = 0; @@ -188,7 +188,8 @@ void Segment::deallocateData() { void Segment::resetIfRequired() { if (reset) { if (leds && !Segment::_globalLeds) { free(leds); leds = nullptr; } - //if (_t) { delete _t; _t = nullptr; transitional = false; } + if (transitional && _t) { transitional = false; delete _t; _t = nullptr; } + deallocateData(); next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; reset = false; // setOption(SEG_OPTION_RESET, false); } @@ -230,7 +231,7 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { case FX_MODE_NOISE16_4 : pal = 26; break; // landscape 33 case FX_MODE_GLITTER : pal = 11; break; // rainbow colors case FX_MODE_SUNRISE : pal = 35; break; // heat palette - case FX_MODE_FLOW : pal = 6; break; // party + case FX_MODE_RAILWAY : pal = 3; break; // prim + sec } switch (pal) { case 0: //default palette. Exceptions for specific effects above @@ -442,6 +443,10 @@ void Segment::set(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t o bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed if (slot >= NUM_COLORS || c == colors[slot]) return false; + if (!_isRGB && !_hasW) { + if (slot == 0 && c == BLACK) return false; // on/off segment cannot have primary color black + if (slot == 1 && c != BLACK) return false; // on/off segment cannot have secondary color non black + } if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change colors[slot] = c; stateChanged = true; // send UDP/WS broadcast @@ -575,12 +580,12 @@ class JMapC { char previousSegmentName[50] = ""; ~JMapC() { - Serial.println("~JMapC"); + USER_PRINTLN("~JMapC"); deletejVectorMap(); } void deletejVectorMap() { if (jVectorMap.size() > 0) { - Serial.println("delete jVectorMap"); + USER_PRINTLN("delete jVectorMap"); for (size_t i=0; i>16; // hack to allow running on virtual strips (2D segment columns/rows) +#endif i &= 0xFFFF; if (i >= virtualLength() || i<0) return; // if pixel would fall out of segment just exit @@ -952,7 +959,9 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa) uint32_t Segment::getPixelColor(int i) { +#ifndef WLED_DISABLE_2D int vStrip = i>>16; +#endif i &= 0xFFFF; #ifndef WLED_DISABLE_2D @@ -1040,15 +1049,34 @@ uint8_t Segment::differs(Segment& b) const { void Segment::refreshLightCapabilities() { uint8_t capabilities = 0; + uint16_t segStartIdx = 0xFFFFU; + uint16_t segStopIdx = 0; + + if (start < Segment::maxWidth * Segment::maxHeight) { + // we are withing 2D matrix (includes 1D segments) + for (int y = startY; y < stopY; y++) for (int x = start; x < stop; x++) { + uint16_t index = x + Segment::maxWidth * y; + if (index < strip.customMappingSize) index = strip.customMappingTable[index]; // convert logical address to physical + if (index < 0xFFFFU) { + if (segStartIdx > index) segStartIdx = index; + if (segStopIdx < index) segStopIdx = index; + } + if (segStartIdx == segStopIdx) segStopIdx++; // we only have 1 pixel segment + } + } else { + // we are on the strip located after the matrix + segStartIdx = start; + segStopIdx = stop; + } for (uint8_t b = 0; b < busses.getNumBusses(); b++) { Bus *bus = busses.getBus(b); if (bus == nullptr || bus->getLength()==0) break; if (!bus->isOk()) continue; - if (bus->getStart() >= stop) continue; - if (bus->getStart() + bus->getLength() <= start) continue; + if (bus->getStart() >= segStopIdx) continue; + if (bus->getStart() + bus->getLength() <= segStartIdx) continue; - uint8_t type = bus->getType(); + //uint8_t type = bus->getType(); if (bus->hasRGB() || (cctFromRgb && bus->hasCCT())) capabilities |= SEG_CAPABILITY_RGB; if (!cctFromRgb && bus->hasCCT()) capabilities |= SEG_CAPABILITY_CCT; if (correctWB && (bus->hasRGB() || bus->hasCCT())) capabilities |= SEG_CAPABILITY_CCT; //white balance correction (CCT slider) @@ -1287,14 +1315,50 @@ uint8_t * Segment::getAudioPalette(int pal) { // WS2812FX class implementation /////////////////////////////////////////////////////////////////////////////// -//WLEDMM from +//WLEDMM from util.cpp +// enumerate all ledmapX.json files on FS and extract ledmap names if existing void WS2812FX::enumerateLedmaps() { ledMaps = 1; for (size_t i=1; i<10; i++) { - char fileName[16]; + char fileName[33]; sprintf_P(fileName, PSTR("/ledmap%d.json"), i); bool isFile = WLED_FS.exists(fileName); - if (isFile) ledMaps |= 1 << i; + + #ifndef ESP8266 + if (ledmapNames[i-1]) { //clear old name + delete[] ledmapNames[i-1]; + ledmapNames[i-1] = nullptr; + } + #endif + + if (isFile) { + ledMaps |= 1 << i; + + #ifndef ESP8266 + if (requestJSONBufferLock(21)) { + if (readObjectFromFile(fileName, nullptr, &doc)) { + size_t len = 0; + if (!doc["n"].isNull()) { + // name field exists + const char *name = doc["n"].as(); + if (name != nullptr) len = strlen(name); + if (len > 0 && len < 33) { + ledmapNames[i-1] = new char[len+1]; + if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], name, 33); + } + } + if (!ledmapNames[i-1]) { + char tmp[33]; + snprintf_P(tmp, 32, PSTR("ledmap%d.json"), i); + len = strlen(tmp); + ledmapNames[i-1] = new char[len+1]; + if (ledmapNames[i-1]) strlcpy(ledmapNames[i-1], tmp, 33); + } + } + releaseJSONBufferLock(); + } + #endif + } } //WLEDMM add segment names to be used as ledmap names uint8_t segment_index = 0; @@ -1364,10 +1428,11 @@ void WS2812FX::finalizeInit(void) #endif } - if (!isMatrix) { // if 2D then max values defined in setUpMatrix() using panel set-up + if (isMatrix) setUpMatrix(); + else { Segment::maxWidth = _length; Segment::maxHeight = 1; - } + } //initialize leds array. TBD: realloc if nr of leds change if (Segment::_globalLeds) { @@ -1376,17 +1441,20 @@ void WS2812FX::finalizeInit(void) Segment::_globalLeds = nullptr; } if (useLedsArray) { + size_t arrSize = sizeof(CRGB) * getLengthTotal(); #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM) if (psramFound()) - Segment::_globalLeds = (CRGB*) ps_malloc(sizeof(CRGB) * _length); + Segment::_globalLeds = (CRGB*) ps_malloc(arrSize); else #endif - Segment::_globalLeds = (CRGB*) malloc(sizeof(CRGB) * _length); - memset(Segment::_globalLeds, 0, sizeof(CRGB) * _length); + Segment::_globalLeds = (CRGB*) malloc(arrSize); + memset(Segment::_globalLeds, 0, arrSize); } //segments are created in makeAutoSegments(); + DEBUG_PRINTLN(F("Loading custom palettes")); loadCustomPalettes(); // (re)load all custom palettes + DEBUG_PRINTLN(F("Loading custom ledmaps")); deserializeMap(); // (re)load default ledmap } @@ -1447,15 +1515,15 @@ void WS2812FX::service() { void IRAM_ATTR WS2812FX::setPixelColor(int i, uint32_t col) { - if (i >= _length) return; if (i < customMappingSize) i = customMappingTable[i]; + if (i >= _length) return; busses.setPixelColor(i, col); } uint32_t WS2812FX::getPixelColor(uint16_t i) { - if (i >= _length) return 0; if (i < customMappingSize) i = customMappingTable[i]; + if (i >= _length) return 0; return busses.getPixelColor(i); } @@ -1668,6 +1736,12 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) { return c; } +uint16_t WS2812FX::getLengthTotal(void) { + uint16_t len = Segment::maxWidth * Segment::maxHeight; // will be _length for 1D (see finalizeInit()) but should cover whole matrix for 2D + if (isMatrix && _length > len) len = _length; // for 2D with trailing strip + return len; +} + uint16_t WS2812FX::getLengthPhysical(void) { uint16_t len = 0; for (size_t b = 0; b < busses.getNumBusses(); b++) { @@ -1710,7 +1784,6 @@ void WS2812FX::purgeSegments(bool force) { if (_segments.size() <= 1) return; for (size_t i = _segments.size()-1; i > 0; i--) if (_segments[i].stop == 0 || force) { - DEBUG_PRINT(F("Purging segment segment: ")); DEBUG_PRINTLN(i); deleted++; _segments.erase(_segments.begin() + i); } @@ -1760,45 +1833,31 @@ void WS2812FX::resetSegments(bool boundsOnly) { //WLEDMM add boundsonly } void WS2812FX::makeAutoSegments(bool forceReset) { - if (isMatrix) { - #ifndef WLED_DISABLE_2D - // only create 1 2D segment - if (forceReset || getSegmentsNum() == 0) resetSegments(); // initialises 1 segment - else if (getActiveSegmentsNum() == 1) { - size_t i = getLastActiveSegmentId(); - _segments[i].start = 0; - _segments[i].stop = Segment::maxWidth; - _segments[i].startY = 0; - _segments[i].stopY = Segment::maxHeight; - _segments[i].grouping = 1; - _segments[i].spacing = 0; - _mainSegment = i; - } - // do we have LEDs after the matrix? (ignore buses) - if (autoSegments && _length > Segment::maxWidth*Segment::maxHeight /*&& getActiveSegmentsNum() == 2*/) { - if (_segments.size() == getLastActiveSegmentId()+1) - _segments.push_back(Segment(Segment::maxWidth*Segment::maxHeight, _length)); - else { - size_t i = getLastActiveSegmentId() + 1; - _segments[i].start = Segment::maxWidth*Segment::maxHeight; - _segments[i].stop = _length; - _segments[i].startY = 0; - _segments[i].stopY = 1; - _segments[i].grouping = 1; - _segments[i].spacing = 0; - } - } - #endif - } else if (autoSegments) { //make one segment per bus + if (autoSegments) { //make one segment per bus uint16_t segStarts[MAX_NUM_SEGMENTS] = {0}; uint16_t segStops [MAX_NUM_SEGMENTS] = {0}; - uint8_t s = 0; - for (uint8_t i = 0; i < busses.getNumBusses(); i++) { + size_t s = 0; + + #ifndef WLED_DISABLE_2D + // 2D segment is the 1st one using entire matrix + if (isMatrix) { + segStarts[0] = 0; + segStops[0] = Segment::maxWidth*Segment::maxHeight; + s++; + } + #endif + + for (size_t i = s; i < busses.getNumBusses(); i++) { Bus* b = busses.getBus(i); segStarts[s] = b->getStart(); segStops[s] = segStarts[s] + b->getLength(); + #ifndef WLED_DISABLE_2D + if (isMatrix && segStops[s] < Segment::maxWidth*Segment::maxHeight) continue; // ignore buses comprising matrix + if (isMatrix && segStarts[s] < Segment::maxWidth*Segment::maxHeight) segStarts[s] = Segment::maxWidth*Segment::maxHeight; + #endif + //check for overlap with previous segments for (size_t j = 0; j < s; j++) { if (segStops[j] > segStarts[s] && segStarts[j] < segStops[s]) { @@ -1810,24 +1869,40 @@ void WS2812FX::makeAutoSegments(bool forceReset) { } s++; } + _segments.clear(); _segments.reserve(s); // prevent reallocations - for (size_t i = 0; i < s; i++) { - Segment seg = Segment(segStarts[i], segStops[i]); - seg.selected = true; - _segments.push_back(seg); + // there is always at least one segment (but we need to differentiate between 1D and 2D) + #ifndef WLED_DISABLE_2D + if (isMatrix) + _segments.push_back(Segment(0, Segment::maxWidth, 0, Segment::maxHeight)); + else + #endif + _segments.push_back(Segment(segStarts[0], segStops[0])); + for (size_t i = 1; i < s; i++) { + _segments.push_back(Segment(segStarts[i], segStops[i])); } - _mainSegment = 0; + } else { + if (forceReset || getSegmentsNum() == 0) resetSegments(); //expand the main seg to the entire length, but only if there are no other segments, or reset is forced else if (getActiveSegmentsNum() == 1) { size_t i = getLastActiveSegmentId(); + #ifndef WLED_DISABLE_2D + _segments[i].start = 0; + _segments[i].stop = Segment::maxWidth; + _segments[i].startY = 0; + _segments[i].stopY = Segment::maxHeight; + _segments[i].grouping = 1; + _segments[i].spacing = 0; + #else _segments[i].start = 0; _segments[i].stop = _length; - _mainSegment = 0; + #endif } } + _mainSegment = 0; fixInvalidSegments(); } @@ -1835,14 +1910,30 @@ void WS2812FX::makeAutoSegments(bool forceReset) { void WS2812FX::fixInvalidSegments() { //make sure no segment is longer than total (sanity check) for (size_t i = getSegmentsNum()-1; i > 0; i--) { - if (_segments[i].start >= _length) { _segments.erase(_segments.begin()+i); continue; } - if (_segments[i].stop > _length) _segments[i].stop = _length; - // this is always called as the last step after finalizeInit(), update covered bus types - _segments[i].refreshLightCapabilities(); + if (isMatrix) { + #ifndef WLED_DISABLE_2D + if (_segments[i].start >= Segment::maxWidth * Segment::maxHeight) { + // 1D segment at the end of matrix + if (_segments[i].start >= _length || _segments[i].startY > 0 || _segments[i].stopY > 1) { _segments.erase(_segments.begin()+i); continue; } + if (_segments[i].stop > _length) _segments[i].stop = _length; + continue; + } + if (_segments[i].start >= Segment::maxWidth || _segments[i].startY >= Segment::maxHeight) { _segments.erase(_segments.begin()+i); continue; } + if (_segments[i].stop > Segment::maxWidth) _segments[i].stop = Segment::maxWidth; + if (_segments[i].stopY > Segment::maxHeight) _segments[i].stopY = Segment::maxHeight; + #endif + } else { + if (_segments[i].start >= _length) { _segments.erase(_segments.begin()+i); continue; } + if (_segments[i].stop > _length) _segments[i].stop = _length; + } } + // this is always called as the last step after finalizeInit(), update covered bus types + for (segment &seg : _segments) + seg.refreshLightCapabilities(); } //true if all segments align with a bus, or if a segment covers the total length +//irrelevant in 2D set-up bool WS2812FX::checkSegmentAlignment() { bool aligned = false; for (segment &seg : _segments) { @@ -1890,7 +1981,8 @@ void WS2812FX::printSize() { DEBUG_PRINTF("Modes: %d*%d=%uB\n", sizeof(mode_ptr), _mode.size(), (_mode.capacity()*sizeof(mode_ptr))); DEBUG_PRINTF("Data: %d*%d=%uB\n", sizeof(const char *), _modeData.size(), (_modeData.capacity()*sizeof(const char *))); DEBUG_PRINTF("Map: %d*%d=%uB\n", sizeof(uint16_t), (int)customMappingSize, customMappingSize*sizeof(uint16_t)); - if (useLedsArray) DEBUG_PRINTF("Buffer: %d*%d=%uB\n", sizeof(CRGB), (int)_length, _length*sizeof(CRGB)); + size = getLengthTotal(); + if (useLedsArray) DEBUG_PRINTF("Buffer: %d*%u=%uB\n", sizeof(CRGB), size, size*sizeof(CRGB)); } #endif @@ -1942,22 +2034,22 @@ void WS2812FX::loadCustomPalettes() { } //load custom mapping table from JSON file (called from finalizeInit() or deserializeState()) -void WS2812FX::deserializeMap(uint8_t n) { - // WLEDMM: also supports isMatrix +bool WS2812FX::deserializeMap(uint8_t n) { + // 2D support creates its own ledmap (on the fly) if a ledmap.json exists it will overwrite built one. char fileName[32]; //WLEDMM: als support segment name ledmaps bool isFile = false;; if (n<10) { strcpy_P(fileName, PSTR("/ledmap")); - if (n) sprintf(fileName +7, "%d", n); + if (n) sprintf(fileName +7, "%d", n); //WLEDMM: trick to not include 0 in ledmap.json strcat(fileName, ".json"); isFile = WLED_FS.exists(fileName); } else { //WLEDM add segment name as ledmap.name uint8_t segment_index = 0; for (segment &seg : _segments) { if (n == 10 + segment_index && !isFile && seg.name != nullptr) { - sprintf_P(fileName, PSTR("/lm%s.json"), seg.name); + sprintf_P(fileName, PSTR("/%s.json"), seg.name); isFile = WLED_FS.exists(fileName); } if (isFile) break; @@ -1966,31 +2058,27 @@ void WS2812FX::deserializeMap(uint8_t n) { } if (!isFile) { - // erase custom mapping if selecting nonexistent ledmap.json (n==0) //WLEDM always erase if nonexistant - if (customMappingTable != nullptr) { - //WLEDMM: if isMatrix then not erase but back to matrix default - if (isMatrix) - setUpMatrix(true); - else { - customMappingSize = 0; - delete[] customMappingTable; - customMappingTable = nullptr; - loadedLedmap = 0; - } + // erase custom mapping if selecting nonexistent ledmap.json (n==0) + //WLEDM: doubt this is necessary as return false causes setupMatrix to deal with this + if (!isMatrix && !n && customMappingTable != nullptr) { + customMappingSize = 0; + delete[] customMappingTable; + customMappingTable = nullptr; + loadedLedmap = 0; //WLEDMM } - return; + return false; } - if (!requestJSONBufferLock(7)) return; - - USER_PRINT(F("Reading LED map from ")); //WLEDMM use USER_PRINT - USER_PRINTLN(fileName); + if (!requestJSONBufferLock(7)) return false; if (!readObjectFromFile(fileName, nullptr, &doc)) { releaseJSONBufferLock(); - return; //if file does not exist just exit + return false; //if file does not exist just exit } + USER_PRINT(F("Reading LED map from ")); //WLEDMM use USER_PRINT + USER_PRINTLN(fileName); + // erase old custom ledmap if (customMappingTable != nullptr) { customMappingSize = 0; @@ -2001,16 +2089,20 @@ void WS2812FX::deserializeMap(uint8_t n) { JsonArray map = doc[F("map")]; if (!map.isNull() && map.size()) { // not an empty map - //WLEDMM: if isMatrix then customMap size is whole matrix -#ifndef WLED_DISABLE_2D - if (isMatrix) - customMappingSize = Segment::maxWidth * Segment::maxHeight; //as whole matrix will be stored in setUpMatrix - else -#endif - customMappingSize = map.size(); + + //WLEDMM: support ledmap file properties width and height + if (doc[F("width")]>0 && doc[F("height")]>0) { + Segment::maxWidth = doc[F("width")];; + Segment::maxHeight = doc[F("height")];; + resetSegments(true); //WLEDMM not makeAutoSegments() as we only want to change bounds + } + + customMappingSize = map.size(); customMappingTable = new uint16_t[customMappingSize]; - for (uint16_t i=0; i HSB convert here - Blynk.virtualWrite(V3, bri? 1:0); - Blynk.virtualWrite(V4, effectCurrent); - Blynk.virtualWrite(V5, effectSpeed); - Blynk.virtualWrite(V6, effectIntensity); - Blynk.virtualWrite(V7, nightlightActive); - Blynk.virtualWrite(V8, notifyDirect); - #endif -} - -#ifndef WLED_DISABLE_BLYNK -BLYNK_WRITE(V0) -{ - bri = param.asInt();//bri - stateUpdated(CALL_MODE_BLYNK); -} - -BLYNK_WRITE(V1) -{ - blHue = param.asInt();//hue - colorHStoRGB(blHue*10,blSat,col); - colorUpdated(CALL_MODE_BLYNK); -} - -BLYNK_WRITE(V2) -{ - blSat = param.asInt();//sat - colorHStoRGB(blHue*10,blSat,col); - colorUpdated(CALL_MODE_BLYNK); -} - -BLYNK_WRITE(V3) -{ - bool on = (param.asInt()>0); - if (!on != !bri) {toggleOnOff(); stateUpdated(CALL_MODE_BLYNK);} -} - -BLYNK_WRITE(V4) -{ - effectCurrent = param.asInt()-1;//fx - colorUpdated(CALL_MODE_BLYNK); -} - -BLYNK_WRITE(V5) -{ - effectSpeed = param.asInt();//sx - colorUpdated(CALL_MODE_BLYNK); -} - -BLYNK_WRITE(V6) -{ - effectIntensity = param.asInt();//ix - colorUpdated(CALL_MODE_BLYNK); -} - -BLYNK_WRITE(V7) -{ - nightlightActive = (param.asInt()>0); -} - -BLYNK_WRITE(V8) -{ - notifyDirect = (param.asInt()>0); //send notifications -} -#endif diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 91692b5b..08bb5128 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -18,6 +18,7 @@ void colorRGBtoRGBW(byte* rgb); uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false); // enable additional debug output +//WLEDMM: #define DEBUGOUT(x) netDebugEnabled?NetDebug.print(x):Serial.print(x) not supported in this file as netDebugEnabled not in scope #if defined(WLED_DEBUG_HOST) #include "net_debug.h" #define DEBUGOUT NetDebug @@ -361,7 +362,7 @@ void BusOnOff::setPixelColor(uint16_t pix, uint32_t c) { uint8_t b = B(c); uint8_t w = W(c); - _data = bool((r+g+b+w) && _bri) ? 0xFF : 0; + _data = bool(r|g|b|w) && bool(_bri) ? 0xFF : 0; } uint32_t BusOnOff::getPixelColor(uint16_t pix) { @@ -387,19 +388,15 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) { case TYPE_NET_ARTNET_RGB: _rgbw = false; _UDPtype = 2; - break; + break; case TYPE_NET_E131_RGB: _rgbw = false; _UDPtype = 1; - break; - case TYPE_NET_DDP_RGB: - _rgbw = false; - _UDPtype = 0; - break; + break; default: // TYPE_NET_DDP_RGB / TYPE_NET_DDP_RGBW _rgbw = bc.type == TYPE_NET_DDP_RGBW; _UDPtype = 0; - break; + break; } _UDPchannels = _rgbw ? 4 : 3; _data = (byte *)malloc(bc.count * _UDPchannels); @@ -563,4 +560,4 @@ uint16_t BusManager::getTotalLength() { // Bus static member definition int16_t Bus::_cct = -1; uint8_t Bus::_cctBlend = 0; -uint8_t Bus::_gAWM = 255; \ No newline at end of file +uint8_t Bus::_gAWM = 255; diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 7b9bc6e4..ffb3bd14 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -140,16 +140,16 @@ class Bus { static void setCCT(uint16_t cct) { _cct = cct; } - static void setCCTBlend(uint8_t b) { - if (b > 100) b = 100; - _cctBlend = (b * 127) / 100; - //compile-time limiter for hardware that can't power both white channels at max - #ifdef WLED_MAX_CCT_BLEND - if (_cctBlend > WLED_MAX_CCT_BLEND) _cctBlend = WLED_MAX_CCT_BLEND; - #endif - } - inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; } - inline uint8_t getAutoWhiteMode() { return _autoWhiteMode; } + static void setCCTBlend(uint8_t b) { + if (b > 100) b = 100; + _cctBlend = (b * 127) / 100; + //compile-time limiter for hardware that can't power both white channels at max + #ifdef WLED_MAX_CCT_BLEND + if (_cctBlend > WLED_MAX_CCT_BLEND) _cctBlend = WLED_MAX_CCT_BLEND; + #endif + } + inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; } + inline uint8_t getAutoWhiteMode() { return _autoWhiteMode; } inline static void setGlobalAWMode(uint8_t m) { if (m < 5) _gAWM = m; else _gAWM = AW_GLOBAL_DISABLED; } inline static uint8_t getGlobalAWMode() { return _gAWM; } diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index ac2a996a..bbf38d2e 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -182,7 +182,12 @@ #endif //APA102 -#define B_HS_DOT_3 NeoPixelBrightnessBus //hardware SPI +#ifdef WLED_USE_ETHERNET +// fix for #2542 (by @BlackBird77) +#define B_HS_DOT_3 NeoPixelBrightnessBus //hardware HSPI with DMA (ESP32 only) +#else +#define B_HS_DOT_3 NeoPixelBrightnessBus //hardware HSPI +#endif #define B_SS_DOT_3 NeoPixelBrightnessBus //soft SPI //LPD8806 diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index ae9cee77..3f0f2347 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -17,6 +17,10 @@ void getStringFromJson(char* dest, const char* src, size_t len) { } bool deserializeConfig(JsonObject doc, bool fromFS) { + + //WLEDMM add USER_PRINT + USER_PRINTF("deserializeConfig\n"); + bool needsSave = false; //int rev_major = doc["rev"][0]; // 1 //int rev_minor = doc["rev"][1]; // 0 @@ -100,18 +104,20 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { JsonObject matrix = hw_led[F("matrix")]; if (!matrix.isNull()) { strip.isMatrix = true; + + //WLEDMM: keep storing basic 2d setup CJSON(strip.panels, matrix[F("mpc")]); CJSON(strip.bOrA, matrix["ba"]); //WLEDMM basic or advanced - CJSON(strip.panelsV, matrix[F("mpv")]); //WLEDMM needs to be stored as well - CJSON(strip.panelsH, matrix[F("mph")]); //WLEDMM needs to be stored as well + CJSON(strip.panelsV, matrix[F("mpv")]); + CJSON(strip.panelsH, matrix[F("mph")]); CJSON(strip.matrix.bottomStart, matrix[F("pb")]); CJSON(strip.matrix.rightStart, matrix[F("pr")]); CJSON(strip.matrix.vertical, matrix[F("pv")]); CJSON(strip.matrix.serpentine, matrix["ps"]); - CJSON(strip.panelO.bottomStart, matrix[F("pbl")]); //WLEDMM - CJSON(strip.panelO.rightStart, matrix[F("prl")]); //WLEDMM - CJSON(strip.panelO.vertical, matrix[F("pvl")]); //WLEDMM - CJSON(strip.panelO.serpentine, matrix["psl"]); //WLEDMM + CJSON(strip.panelO.bottomStart, matrix[F("pbl")]); + CJSON(strip.panelO.rightStart, matrix[F("prl")]); + CJSON(strip.panelO.vertical, matrix[F("pvl")]); + CJSON(strip.panelO.serpentine, matrix["psl"]); strip.panel.clear(); JsonArray panels = matrix[F("panels")]; @@ -140,8 +146,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { p.options = 0; strip.panel.push_back(p); } - - strip.setUpMatrix(); + // cannot call strip.setUpMatrix() here due to already locked JSON buffer } #endif @@ -342,12 +347,20 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(strip.paletteBlend, light[F("pal-mode")]); CJSON(autoSegments, light[F("aseg")]); + CJSON(gammaCorrectVal, light["gc"]["val"]); // default 2.8 float light_gc_bri = light["gc"]["bri"]; - float light_gc_col = light["gc"]["col"]; // 2.8 - if (light_gc_bri > 1.5) gammaCorrectBri = true; - else if (light_gc_bri > 0.5) gammaCorrectBri = false; - if (light_gc_col > 1.5) gammaCorrectCol = true; - else if (light_gc_col > 0.5) gammaCorrectCol = false; + float light_gc_col = light["gc"]["col"]; + if (light_gc_bri > 1.0f) gammaCorrectBri = true; + else gammaCorrectBri = false; + if (light_gc_col > 1.0f) gammaCorrectCol = true; + else gammaCorrectCol = false; + if (gammaCorrectVal > 1.0f && gammaCorrectVal <= 3) { + if (gammaCorrectVal != 2.8f) calcGammaTable(gammaCorrectVal); + } else { + gammaCorrectVal = 1.0f; // no gamma correction + gammaCorrectBri = false; + gammaCorrectCol = false; + } JsonObject light_tr = light["tr"]; CJSON(fadeTransition, light_tr["mode"]); @@ -415,6 +428,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (!DMXAddress || DMXAddress > 510) DMXAddress = 1; CJSON(DMXSegmentSpacing, if_live_dmx[F("dss")]); if (DMXSegmentSpacing > 150) DMXSegmentSpacing = 0; + CJSON(e131Priority, if_live_dmx[F("e131prio")]); + if (e131Priority > 200) e131Priority = 200; CJSON(DMXMode, if_live_dmx["mode"]); tdd = if_live[F("timeout")] | -1; @@ -430,17 +445,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(alexaNumPresets, interfaces["va"]["p"]); -#ifndef WLED_DISABLE_BLYNK - const char* apikey = interfaces["blynk"][F("token")] | "Hidden"; - tdd = strnlen(apikey, 36); - if (tdd > 20 || tdd == 0) - getStringFromJson(blynkApiKey, apikey, 36); //normally not present due to security - - JsonObject if_blynk = interfaces["blynk"]; - getStringFromJson(blynkHost, if_blynk[F("host")], 33); - CJSON(blynkPort, if_blynk["port"]); -#endif - #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces["mqtt"]; CJSON(mqttEnabled, if_mqtt["en"]); @@ -472,6 +476,16 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(hueIP[i], if_hue_ip[i]); #endif +//WLEDMM: add netdebug variables +#ifdef WLED_DEBUG_HOST + JsonObject if_ndb = interfaces["ndb"]; + JsonArray if_ndb_ip = if_ndb["ip"]; + for (byte i = 0; i < 4; i++) + CJSON(netDebugPrintIP[i], if_ndb_ip[i]); + CJSON(netDebugPrintPort, if_ndb["port"]); + CJSON(netDebugEnabled, if_ndb["enabled"]); +#endif + JsonObject if_ntp = interfaces[F("ntp")]; CJSON(ntpEnabled, if_ntp["en"]); getStringFromJson(ntpServerName, if_ntp[F("host")], 33); // "1.wled.pool.ntp.org" @@ -717,9 +731,11 @@ void serializeConfig() { if (strip.isMatrix) { JsonObject matrix = hw_led.createNestedObject(F("matrix")); matrix[F("mpc")] = strip.panels; + + //WLEDMM: keep storing basic 2d setup matrix[F("ba")] = strip.bOrA; //WLEDMM basic or advanced - matrix[F("mph")] = strip.panelsH; //WLEDMM needs to be stored as well - matrix[F("mpv")] = strip.panelsV; //WLEDMM needs to be stored as well + matrix[F("mph")] = strip.panelsH; + matrix[F("mpv")] = strip.panelsV; matrix[F("pb")] = strip.matrix.bottomStart; matrix[F("pr")] = strip.matrix.rightStart; matrix[F("pv")] = strip.matrix.vertical; @@ -822,8 +838,9 @@ void serializeConfig() { light[F("aseg")] = autoSegments; JsonObject light_gc = light.createNestedObject("gc"); - light_gc["bri"] = (gammaCorrectBri) ? 2.8 : 1.0; - light_gc["col"] = (gammaCorrectCol) ? 2.8 : 1.0; + light_gc["bri"] = (gammaCorrectBri) ? gammaCorrectVal : 1.0f; // keep compatibility + light_gc["col"] = (gammaCorrectCol) ? gammaCorrectVal : 1.0f; // keep compatibility + light_gc["val"] = gammaCorrectVal; JsonObject light_tr = light.createNestedObject("tr"); light_tr["mode"] = fadeTransition; @@ -877,6 +894,7 @@ void serializeConfig() { JsonObject if_live_dmx = if_live.createNestedObject("dmx"); if_live_dmx[F("uni")] = e131Universe; if_live_dmx[F("seqskip")] = e131SkipOutOfSequence; + if_live_dmx[F("e131prio")] = e131Priority; if_live_dmx[F("addr")] = DMXAddress; if_live_dmx[F("dss")] = DMXSegmentSpacing; if_live_dmx["mode"] = DMXMode; @@ -895,13 +913,6 @@ void serializeConfig() { if_va["p"] = alexaNumPresets; -#ifndef WLED_DISABLE_BLYNK - JsonObject if_blynk = interfaces.createNestedObject("blynk"); - if_blynk[F("token")] = strlen(blynkApiKey) ? "Hidden":""; - if_blynk[F("host")] = blynkHost; - if_blynk["port"] = blynkPort; -#endif - #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces.createNestedObject("mqtt"); if_mqtt["en"] = mqttEnabled; @@ -933,6 +944,17 @@ void serializeConfig() { } #endif +//WLEDMM: add netdebug variables +#ifdef WLED_DEBUG_HOST + JsonObject if_ndb = interfaces.createNestedObject("ndb"); + JsonArray if_ndb_ip = if_ndb.createNestedArray("ip"); + for (byte i = 0; i < 4; i++) { + if_ndb_ip.add(netDebugPrintIP[i]); + } + if_ndb["port"] = netDebugPrintPort; + if_ndb["enabled"] = netDebugEnabled; +#endif + JsonObject if_ntp = interfaces.createNestedObject("ntp"); if_ntp["en"] = ntpEnabled; if_ntp[F("host")] = ntpServerName; @@ -1004,6 +1026,9 @@ void serializeConfig() { JsonObject usermods_settings = doc.createNestedObject("um"); usermods.addToConfig(usermods_settings); + //WLEDMM add USER_PRINT + USER_PRINTF("serializeConfig\n"); + File f = WLED_FS.open("/cfg.json", "w"); if (f) serializeJson(doc, f); f.close(); @@ -1032,13 +1057,6 @@ bool deserializeConfigSec() { JsonObject interfaces = doc["if"]; -#ifndef WLED_DISABLE_BLYNK - const char* apikey = interfaces["blynk"][F("token")] | "Hidden"; - int tdd = strnlen(apikey, 36); - if (tdd > 20 || tdd == 0) - getStringFromJson(blynkApiKey, apikey, 36); -#endif - #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces["mqtt"]; getStringFromJson(mqttPass, if_mqtt["psk"], 65); @@ -1077,10 +1095,6 @@ void serializeConfigSec() { ap["psk"] = apPass; JsonObject interfaces = doc.createNestedObject("if"); -#ifndef WLED_DISABLE_BLYNK - JsonObject if_blynk = interfaces.createNestedObject("blynk"); - if_blynk[F("token")] = blynkApiKey; -#endif #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces.createNestedObject("mqtt"); if_mqtt["psk"] = mqttPass; diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 3cba87d2..8a4a4ebd 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -57,39 +57,42 @@ void setRandomColor(byte* rgb) void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb { - float h = ((float)hue)/65535.0; - float s = ((float)sat)/255.0; - byte i = floor(h*6); - float f = h * 6-i; - float p = 255 * (1-s); - float q = 255 * (1-f*s); - float t = 255 * (1-(1-f)*s); + float h = ((float)hue)/65535.0f; + float s = ((float)sat)/255.0f; + int i = floorf(h*6); + float f = h * 6.0f - i; + int p = int(255.0f * (1.0f-s)); + int q = int(255.0f * (1.0f-f*s)); + int t = int(255.0f * (1.0f-(1.0f-f)*s)); + p = constrain(p, 0, 255); + q = constrain(q, 0, 255); + t = constrain(t, 0, 255); switch (i%6) { - case 0: rgb[0]=255,rgb[1]=t,rgb[2]=p;break; - case 1: rgb[0]=q,rgb[1]=255,rgb[2]=p;break; - case 2: rgb[0]=p,rgb[1]=255,rgb[2]=t;break; - case 3: rgb[0]=p,rgb[1]=q,rgb[2]=255;break; - case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break; - case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q; + case 0: rgb[0]=255,rgb[1]=t, rgb[2]=p; break; + case 1: rgb[0]=q, rgb[1]=255,rgb[2]=p; break; + case 2: rgb[0]=p, rgb[1]=255,rgb[2]=t; break; + case 3: rgb[0]=p, rgb[1]=q, rgb[2]=255;break; + case 4: rgb[0]=t, rgb[1]=p, rgb[2]=255;break; + case 5: rgb[0]=255,rgb[1]=p, rgb[2]=q; break; } } //get RGB values from color temperature in K (https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html) void colorKtoRGB(uint16_t kelvin, byte* rgb) //white spectrum to rgb, calc { - float r = 0, g = 0, b = 0; - float temp = kelvin / 100; - if (temp <= 66) { + int r = 0, g = 0, b = 0; + float temp = kelvin / 100.0f; + if (temp <= 66.0f) { r = 255; - g = round(99.4708025861 * log(temp) - 161.1195681661); - if (temp <= 19) { + g = roundf(99.4708025861f * logf(temp) - 161.1195681661f); + if (temp <= 19.0f) { b = 0; } else { - b = round(138.5177312231 * log((temp - 10)) - 305.0447927307); + b = roundf(138.5177312231f * logf((temp - 10.0f)) - 305.0447927307f); } } else { - r = round(329.698727446 * pow((temp - 60), -0.1332047592)); - g = round(288.1221695283 * pow((temp - 60), -0.0755148492)); + r = roundf(329.698727446f * powf((temp - 60.0f), -0.1332047592f)); + g = roundf(288.1221695283f * powf((temp - 60.0f), -0.0755148492f)); b = 255; } //g += 12; //mod by Aircoookie, a bit less accurate but visibly less pinkish @@ -147,9 +150,9 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www b = 1.0f; } // Apply gamma correction - r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f; - g = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * pow(g, (1.0f / 2.4f)) - 0.055f; - b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f; + r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * powf(r, (1.0f / 2.4f)) - 0.055f; + g = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * powf(g, (1.0f / 2.4f)) - 0.055f; + b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * powf(b, (1.0f / 2.4f)) - 0.055f; if (r > b && r > g) { // red is biggest @@ -173,9 +176,9 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www b = 1.0f; } } - rgb[0] = 255.0*r; - rgb[1] = 255.0*g; - rgb[2] = 255.0*b; + rgb[0] = byte(255.0f*r); + rgb[1] = byte(255.0f*g); + rgb[2] = byte(255.0f*b); } void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy) @@ -242,35 +245,13 @@ float maxf (float v, float w) return v; } -/* -uint32_t colorRGBtoRGBW(uint32_t c) -{ - byte rgb[4]; - rgb[0] = R(c); - rgb[1] = G(c); - rgb[2] = B(c); - rgb[3] = W(c); - colorRGBtoRGBW(rgb); - return RGBW32(rgb[0], rgb[1], rgb[2], rgb[3]); -} - -void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) -{ - float low = minf(rgb[0],minf(rgb[1],rgb[2])); - float high = maxf(rgb[0],maxf(rgb[1],rgb[2])); - if (high < 0.1f) return; - float sat = 100.0f * ((high - low) / high); // maximum saturation is 100 (corrected from 255) - rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3); -} -*/ - -byte correctionRGB[4] = {0,0,0,0}; -uint16_t lastKelvin = 0; - // adjust RGB values based on color temperature in K (range [2800-10200]) (https://en.wikipedia.org/wiki/Color_balance) +// called from bus manager when color correction is enabled! uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb) { //remember so that slow colorKtoRGB() doesn't have to run for every setPixelColor() + static byte correctionRGB[4] = {0,0,0,0}; + static uint16_t lastKelvin = 0; if (lastKelvin != kelvin) colorKtoRGB(kelvin, correctionRGB); // convert Kelvin to RGB lastKelvin = kelvin; byte rgbw[4]; diff --git a/wled00/const.h b/wled00/const.h index 9ddc2b5b..368dbab2 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -79,6 +79,17 @@ #define WLED_MAX_COLOR_ORDER_MAPPINGS 10 #endif +#if defined(WLED_MAX_LEDMAPS) && (WLED_MAX_LEDMAPS > 32 || WLED_MAX_LEDMAPS < 10) + #undef WLED_MAX_LEDMAPS +#endif +#ifndef WLED_MAX_LEDMAPS + #ifdef ESP8266 + #define WLED_MAX_LEDMAPS 10 + #else + #define WLED_MAX_LEDMAPS 16 + #endif +#endif + //Usermod IDs #define USERMOD_ID_RESERVED 0 //Unused. Might indicate no usermod present #define USERMOD_ID_UNSPECIFIED 1 //Default value for a general user mod that does not specify a custom ID @@ -120,6 +131,7 @@ #define USERMOD_ID_SD_CARD 37 //Usermod "usermod_sd_card.h" #define USERMOD_ID_PWM_OUTPUTS 38 //Usermod "usermod_pwm_outputs.h #define USERMOD_ID_SHT 39 //Usermod "usermod_sht.h +#define USERMOD_ID_KLIPPER 40 // Usermod Klipper percentage //WLEDMM #define USERMOD_ID_CUSTOMEFFECTS 90 //Usermod "usermod_v2_customeffects.h" #define USERMOD_ID_WEATHER 91 //Usermod "usermod_v2_weather.h" @@ -141,7 +153,7 @@ #define CALL_MODE_FX_CHANGED 6 //no longer used #define CALL_MODE_HUE 7 #define CALL_MODE_PRESET_CYCLE 8 -#define CALL_MODE_BLYNK 9 +#define CALL_MODE_BLYNK 9 //no longer used #define CALL_MODE_ALEXA 10 #define CALL_MODE_WS_SEND 11 //special call mode, not for notifier, updates websocket only #define CALL_MODE_BUTTON_PRESET 12 //button/IR JSON preset/macro @@ -352,11 +364,11 @@ #define MAX_LEDS_PER_BUS 2048 // may not be enough for fast LEDs (i.e. APA102) #endif -// string temp buffer (now stored in stack locally) +// string temp buffer (now stored in stack locally) // WLEDMM ...which is actually not the greatest design choice on ESP32 #ifdef ESP8266 #define SETTINGS_STACK_BUF_SIZE 2048 #else -#define SETTINGS_STACK_BUF_SIZE 3096 +#define SETTINGS_STACK_BUF_SIZE 3712 // WLEDMM added 512 bytes of margin (was 3096) #endif #ifdef WLED_USE_ETHERNET @@ -397,8 +409,8 @@ #define JSON_BUFFER_SIZE 24576 #endif -//#define MIN_HEAP_SIZE (MAX_LED_MEMORY+2048) -#define MIN_HEAP_SIZE (8192) +//#define MIN_HEAP_SIZE (8k for AsyncWebServer) +#define MIN_HEAP_SIZE 8192 // Maximum size of node map (list of other WLED instances) #ifdef ESP8266 diff --git a/wled00/data/index.css b/wled00/data/index.css index 913cd360..b676a7de 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -392,12 +392,16 @@ button { } .slider { - background-color: var(--c-2); max-width: 300px; - min-width: 280px; + min-width: 260px; margin: 0 auto; /* add 5px; if you want some vertical space but looks ugly */ border-radius: 24px; position: relative; + padding-bottom: 2px; +} + +#sliders .slider, #info .slider { + background-color: var(--c-2); } .filter, .option { @@ -425,14 +429,14 @@ button { box-shadow: 4px 4px 10px 4px var(--c-1); color: var(--c-f); text-align: center; - padding: 5px 10px; + padding: 4px 8px; border-radius: 6px; /* Position the tooltip text */ width: 160px; position: absolute; z-index: 1; - bottom: 100%; + bottom: 80%; left: 50%; margin-left: -92px; @@ -647,7 +651,7 @@ img { #wbal .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #cbdbff); } /* wrapper divs hidden by default */ -#rgbwrap, #kwrap, #wwrap, #wbal, #qcs-w, #hexw { +#rgbwrap, #swrap, #hwrap, #kwrap, #wwrap, #wbal, #qcs-w, #hexw { display: none; } @@ -731,7 +735,11 @@ input[type=range]::-moz-range-thumb { #Colors .sliderwrap { width: 260px; - margin: 10px 0 0; + margin: 4px 0 0; +} + +#Colors { + padding-top: 18px; } /* Dynamically hide brightness slider label */ @@ -744,13 +752,14 @@ input[type=range]::-moz-range-thumb { margin-top: var(--bmt); } -#picker, #rgbwrap, #kwrap, #wwrap, #wbal, #vwrap, #qcs-w, #hexw, #pall, #ledmap { +#picker, #qcs-w, #hexw, #pall, #ledmap { margin: 0 auto; width: 260px; + /*background-color: unset;*/ } #picker { - margin-top: 10px; + margin-top: -10px !important; } /* buttons */ @@ -1409,6 +1418,9 @@ TD .checkmark, TD .radiomark { .expanded { display: inline-block !important; } +.expanded .segin.hide, .expanded .presin.hide, .expanded .sbs.hide { + display: none !important; +} .m6 { margin: 6px 0; diff --git a/wled00/data/index.htm b/wled00/data/index.htm index c975522d..47751fda 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -90,68 +90,73 @@
-
- +
-

+
+ Hue
-
- +
-

+
+ Saturation
-
- +
-

+
+ Value/Brightness
-
- +
+ Kelvin/Temperature
-

RGB color

-
+ +
+ Red channel
-
+
+ Green channel
-
+
+ Blue channel
-
-

White channel

+
+
+ White channel
-
-

White balance

+
+
+ White balance
@@ -304,6 +309,16 @@
+ +
+

Peek ☾

+
+

Segment view ☾

+
+
+
+
+
Loading...
@@ -312,14 +327,7 @@
- -
-
-
-
-
-
-

Transition:  s

+

Transition:  s

@@ -366,7 +374,8 @@

- Made with ❤︎ by Aircoookie and the WLED community + WLED made with ❤︎ by Aircoookie and the WLED community
+ WLED MM made with ❤︎ by Softhack007 & Ewowi and the WLED 2D & Audio Dev community