diff --git a/data_svelte/items.json b/data_svelte/items.json index 7ec9b010..4275b34b 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -652,5 +652,24 @@ "coord": "0,0", "id2show": "id датчика", "num": 48 + }, + { + "name": "49. Strip ws2812b", + "type": "Reading", + "subtype": "Ws2812b", + "id": "strip", + "widget": "range", + "page": "Кнопки", + "descr": "Лента", + "int": 15, + "needSave": 0, + "pin": "4", + "numLeds": "8", + "brightness": "100", + "mode": "1", + "min": "15", + "max": "30", + "idshow": "t", + "num": 49 } ] \ No newline at end of file diff --git a/myProfile.json b/myProfile.json index 3c0ddde3..695b2faf 100644 --- a/myProfile.json +++ b/myProfile.json @@ -198,6 +198,10 @@ { "path": "src/modules/display/Lcd2004", "active": true + }, + { + "path": "src/modules/display/Ws2812b", + "active": true } ] } diff --git a/platformio.ini b/platformio.ini index 311b037d..fc750421 100644 --- a/platformio.ini +++ b/platformio.ini @@ -156,6 +156,7 @@ lib_deps = dfrobot/DFRobotDFPlayerMini @ ^1.0.5 adafruit/Adafruit BusIO @ ^1.13.2 marcoschwartz/LiquidCrystal_I2C@^1.1.4 + adafruit/Adafruit NeoPixel@^1.10.6 build_src_filter = + + @@ -187,6 +188,7 @@ build_src_filter = + + + + + [env:esp32_4mb_fromitems] lib_deps = diff --git a/src/modules/API.cpp b/src/modules/API.cpp index ab864765..7523aff7 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -30,6 +30,7 @@ void* getAPI_Pcf8574(String subtype, String params); void* getAPI_Pwm8266(String subtype, String params); void* getAPI_TelegramLT(String subtype, String params); void* getAPI_Lcd2004(String subtype, String params); +void* getAPI_Ws2812b(String subtype, String params); void* getAPI(String subtype, String params) { void* tmpAPI; @@ -63,5 +64,6 @@ if ((tmpAPI = getAPI_Pcf8574(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_TelegramLT(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI; +if ((tmpAPI = getAPI_Ws2812b(subtype, params)) != nullptr) return tmpAPI; return nullptr; } \ No newline at end of file diff --git a/src/modules/display/Ws2812b/Ws2181b.cpp b/src/modules/display/Ws2812b/Ws2181b.cpp new file mode 100644 index 00000000..8cd90a29 --- /dev/null +++ b/src/modules/display/Ws2812b/Ws2181b.cpp @@ -0,0 +1,198 @@ +#include "Global.h" +#include "classes/IoTItem.h" +#include "ESPConfiguration.h" +#include + + +class Ws2812b : public IoTItem +{ +private: + Adafruit_NeoPixel *_strip; + int _pin; + int _numLeds; + int _brightness; + int correctLed; + int _min = 0; + int _max = 100; + int PrevValidShow = 0; + int FlagFN = 1; + int PreFlagFN = 1; + String idshow; + +public: + Ws2812b(String parameters) : IoTItem(parameters) { + jsonRead(parameters, F("pin"), _pin); + jsonRead(parameters, F("numLeds"), _numLeds); + jsonRead(parameters, F("idshow"), idshow); + jsonRead(parameters, F("brightness"), _brightness); + jsonRead(parameters, F("min"), _min); + jsonRead(parameters, F("max"), _max); + + + _strip = new Adafruit_NeoPixel(_numLeds, _pin, NEO_GRB + NEO_KHZ800); + if (_strip != nullptr) { + _strip->begin(); + SerialPrint("E", "Strip Ws2812b:" + _id, "begin"); + correctLed = correctPixel(_numLeds); + _strip->setBrightness(_brightness); + _strip->clear(); + } + } + + // void loop() { + // if (enableDoByInt) { + // currentMillis = millis(); + // difference = currentMillis - prevMillis; + // if (difference >= interval || PreFlagFN != FlagFN) { + // prevMillis = millis(); + // this->doByInterval(); + // } + // } + // } + + void doByInterval() { + if (!_strip) return; + + if (!isItemExist(idshow)) { + SerialPrint("E", F("Ws2812b"), "'" + idshow + "' detector object not exist"); + }else if (getItemValue(idshow) == ""){ + SerialPrint("E", F("Ws2812b"), "'" + idshow + "' detector value is empty"); + }else if (_min >= _max){ + SerialPrint("E", F("Ws2812b"), " the minimum (" + String(_min) + ") value must be greater than the maximum (" + String(_max) + ")"); + }else if(isItemExist(idshow) && getItemValue(idshow) != "" && _min < _max && FlagFN == 1){ + SerialPrint("E", "Ws2812b:" + String(correctLed), " work"); + String value = getItemValue(idshow); + if(PrevValidShow == 0 || PrevValidShow > value.toInt() ){ + noShow(); + } + int t = map(value.toInt(), _min, _max, 0, _numLeds); + for(uint16_t L = 0; LsetPixelColor(L,wheel(((205+(L*correctLed)) & 255))); + } + PrevValidShow = value.toInt(); + _strip->show(); + } + } + + int correctPixel(int _numLeds){ + if(_numLeds <= 65 && _numLeds > 60){ + correctLed = 0; + }else if(_numLeds <= 60 && _numLeds > 55){ + correctLed = 1; + }else if(_numLeds <= 55 && _numLeds > 50){ + correctLed = 2; + }else if(_numLeds <= 50 && _numLeds > 40){ + correctLed = 3; + }else if(_numLeds <= 40 && _numLeds > 35){ + correctLed = 4; + }else if(_numLeds <= 35 && _numLeds > 24){ + correctLed = 5; + }else if(_numLeds <= 24 && _numLeds > 16){ + correctLed = 6; + }else if(_numLeds <= 16 && _numLeds > 12){ + correctLed = 8; + }else if(_numLeds <= 12 && _numLeds > 8){ + correctLed = 12; + }else if(_numLeds <= 8 && _numLeds > 4){ + correctLed = 16; + }else{ + correctLed = 0; + } + return correctLed; + } + + uint32_t wheel(byte WheelPos) { + if(WheelPos < 85) { + return _strip->Color(WheelPos * 3, 255 - WheelPos * 3, 0); + } + else if(WheelPos < 205) { + WheelPos -= 85; + return _strip->Color(255 - WheelPos * 3, 0, WheelPos * 3); + } + else { + WheelPos -= 205; + return _strip->Color(0, WheelPos * 3, 255 - WheelPos * 3); + } + } + + void noShow(){ + if (!_strip) return; + + _strip->clear(); + for(int i=0; i<_numLeds; i++) { + _strip->setPixelColor(i, _strip->Color(0, 0, 0)); + _strip->show(); + } + } + + IoTValue execute(String command, std::vector ¶m) { + if (!_strip) return {}; + + if (command == "test") { + for(int i=0; i<_numLeds; i++) { + _strip->setPixelColor(i, _strip->Color(20+(i*2), 20+(i*2), 20+(i*2))); + _strip->show(); + } + SerialPrint("E", "Strip Ws2812b", "demo"); + } else if (command == "noShow"){ + noShow(); + SerialPrint("E", "Strip Ws2812b", "noShow"); + } else if(command == "noShowOne"){ + if (param.size() == 1) { + _strip->setPixelColor(param[0].valD, _strip->Color(0, 0, 0)); + _strip->show(); + SerialPrint("E", "Strip Ws2812b", "noShowOne"); + } + } else if (command == "showLed"){ + if (param.size() == 4) { + _strip->setPixelColor( param[0].valD, _strip->Color(param[1].valD, param[2].valD, param[3].valD)); + _strip->show(); + SerialPrint("E", "Strip Ws2812b", "showLed:" + param[0].valS + " red:" + param[1].valS + " green:" + param[2].valS + " blue:" + param[3].valS); + } + } else if (command == "showLedAll"){ + if (param.size() == 3) { + for(int i=0; i<_numLeds; i++) { + _strip->setPixelColor(i, _strip->Color(param[0].valD, param[1].valD, param[2].valD)); + _strip->show(); + } + SerialPrint("E", "Strip Ws2812b", "showLedAll - red:" + param[0].valS + " green:" + param[1].valS + " blue:" + param[2].valS); + } + } else if (command == "disableIndication"){ + FlagFN = 0; + PreFlagFN = 1; + SerialPrint("E", "Strip Ws2812b", "disableIndication"); + } else if (command == "enableIndication"){ + FlagFN = 1; + PreFlagFN = 0; + doByInterval(); + SerialPrint("E", "Strip Ws2812b", "enableIndication"); + } + doByInterval(); + return {}; + } + + void setValue(IoTValue Value, bool generateEvent = true){ + if (!_strip) return; + + value = Value; + int b = map(value.valD, 1,1024,1,255); + _strip->setBrightness(b); + _strip->show(); + regEvent(value.valD, "Ws2812b"); + } + + ~Ws2812b(){}; +}; + +void *getAPI_Ws2812b(String subtype, String param) +{ + if (subtype == F("Ws2812b")) { + return new Ws2812b(param); + } else { + return nullptr; + } +} + + + + diff --git a/src/modules/display/Ws2812b/modinfo.json b/src/modules/display/Ws2812b/modinfo.json new file mode 100644 index 00000000..280d3e26 --- /dev/null +++ b/src/modules/display/Ws2812b/modinfo.json @@ -0,0 +1,96 @@ +{ + "menuSection": "Экраны", + "configItem": [ + { + "name": "Strip ws2812b", + "type": "Reading", + "subtype": "Ws2812b", + "id": "strip", + "widget": "range", + "page": "Кнопки", + "descr": "Лента", + "int": 15, + "needSave": 0, + "pin": "4", + "numLeds": "8", + "brightness": "100", + "mode": "1", + "min": "15", + "max": "30", + "idshow": "t" + }], + + "about": { + "authorName": "Yuriy Kuneev", + "authorContact": "https://t.me/Kuneev07", + "authorGit": "", + "exampleURL": "https://iotmanager.org/wiki", + "specialThanks": "", + "moduleName": "Ws2812b", + "moduleVersion": "1.0.1", + "moduleDesc": "Позволяет визуализировать наполнение бака или температуру нагрева. В зависимост от показаний которые везуализируем нужно редактировать min и max.", + "propInfo": { + "int": "Период времени в секундах обновления.", + "pin": "Пин к которому подключена лента.", + "numLeds": "Количество пикселей в ленте.", + "needSave": "Запись яркости в энергонезависимую память", + "brightness": "Яркость ленты можно менять из сценария.", + "min": "Минимальный порог индикатора на который реагировать.", + "max": "Максимальный порог индикатора на который реагировать.", + "idshow": "id элемента конфигурации который нужно повесить индикацию." + }, + "funcInfo": [ + { + "name": "noShow", + "descr": "Выключить ленту", + "params": ["номер пикселя"] + }, + { + "name": "noShowOne", + "descr": "Выключить один светодиод на ленте", + "params": [] + }, + { + "name": "test", + "descr": "для проверки всех светодиодов ленты", + "params": [] + }, + { + "name": "showLed", + "descr": "Зажечь один диод", + "params": ["номер пикселя","цвет 255,255,255 или red,green"] + }, + { + "name": "showLedAll", + "descr": "Зажечь все диоды", + "params": ["Цвет красного светодиода от 0 до 255","Цвет зеленого светодиода от 0 до 255","Цвет синего светодиода от 0 до 255"] + }, + { + "name": "Brightness", + "descr": "Устанавливает общую яркость ленты от 0 до 255", + "params": ["яркость от 0 до 255"] + }, + { + "name": "enableIndication", + "descr": "Включает работу индикации по idshow по дэфолту включено всегда", + "params": [] + }, + { + "name": "disableIndication", + "descr": "Выключает работу индикации по idshow", + "params": [] + } + ] + }, + + "defActive": true, + + "usedLibs": { + "esp32_4mb": [ + "adafruit/Adafruit NeoPixel@^1.10.6" + ], + "esp8266_4mb": [ + "adafruit/Adafruit NeoPixel@^1.10.6" + ] + } +} \ No newline at end of file