diff --git a/src/modules/display/TM16XX/TM16XX.cpp b/src/modules/display/TM16XX/TM16XX.cpp index 7a8a1b3d..10199d38 100644 --- a/src/modules/display/TM16XX/TM16XX.cpp +++ b/src/modules/display/TM16XX/TM16XX.cpp @@ -4,19 +4,103 @@ #include #include #include +#include +TM16xxButtons* buttons = nullptr; // указатель на объект управления кнопками для TM1638 иначе nullptr +IoTItem* iotItemObj = nullptr; // указатель на объект конфигурации для доступа из функций calback + +void setIotItemValue(int buttonNum, int state) { + if (iotItemObj) { + String id = iotItemObj->getID() + "_" + String(buttonNum); + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->getID() == id) { + IoTValue value; + value.valD = state; + (*it)->setValue(value); + //value.valD = 0; // сбрасываем состояние в нулевое если статус конечный (т.к. библиотека отрабатывает события не по порядку) + //if (state == 1 || state == 5 || state == 2) (*it)->setValue(value, false); + break; + } + } + } +} + +// The Release function will be called when a button was released. +// It can be used for fast actions when no click or double click needs to be detected. +void fnRelease(byte nButton) { + // using isPressed or is LongPressed a shift-key can be implemented + if(buttons->isLongPressed(0)) + Serial.print(F("Button 0 still longpressed. ")); + else if(buttons->isPressed(0)) + Serial.print(F("Button 0 still pressed. ")); + + Serial.print(F("Button ")); + Serial.print(nButton); + Serial.println(F(" release.")); + + setIotItemValue(nButton, 0); +} // release + + +// This function will be called when a button was pressed 1 time (without a second press). +void fnClick(byte nButton) { + Serial.print(F("Button ")); + Serial.print(nButton); + Serial.println(F(" click.")); + + setIotItemValue(nButton, 1); +} // click + + +// This function will be called when a button was pressed 2 times in a short timeframe. +void fnDoubleclick(byte nButton) { + Serial.print(F("Button ")); + Serial.print(nButton); + Serial.println(F(" doubleclick.")); + + setIotItemValue(nButton, 2); +} // doubleclick + + +// This function will be called once, when a button is pressed for a long time. +void fnLongPressStart(byte nButton) { + Serial.print(F("Button ")); + Serial.print(nButton); + Serial.println(F(" longPress start")); + + setIotItemValue(nButton, 3); +} // longPressStart + + +// This function will be called often, while a button is pressed for a long time. +void fnLongPress(byte nButton) { + Serial.print(F("Button ")); + Serial.print(nButton); + Serial.println(F(" longPress...")); + + setIotItemValue(nButton, 4); +} // longPress + + +// This function will be called once, when a button is released after beeing pressed for a long time. +void fnLongPressStop(byte nButton) { + Serial.print(F("Button ")); + Serial.print(nButton); + Serial.println(F(" longPress stop")); + + setIotItemValue(nButton, 5); +} // longPressStop + class TM16XX : public IoTItem { private: TM16xxDisplay *_display = nullptr; TM16xx *_module = nullptr; - std::vector _ids2show; + String _id2show; public: TM16XX(String parameters) : IoTItem(parameters) { - //jsonRead(parameters, "id2show", _id2show); - int DIO, CLK, STB, chip, numDigits, intensity; bool onoff; String id2show; @@ -28,58 +112,97 @@ class TM16XX : public IoTItem { jsonRead(parameters, "intensity", intensity); jsonRead(parameters, "on", onoff); - jsonRead(parameters, "id2show", id2show); - if (id2show != "") _ids2show = splitStr(id2show, ","); + jsonRead(parameters, "id2show", _id2show); if (chip == 1637) { _module = new TM1637(DIO, CLK, numDigits); } else if (chip == 1638) { _module = new TM1638(DIO, CLK, STB, numDigits); + buttons = new TM16xxButtons(_module); + buttons->attachRelease(fnRelease); + buttons->attachClick(fnClick); + buttons->attachDoubleClick(fnDoubleclick); + buttons->attachLongPressStart(fnLongPressStart); + buttons->attachLongPressStop(fnLongPressStop); + buttons->attachDuringLongPress(fnLongPress); } _module->setupDisplay(onoff, intensity); _display = new TM16xxDisplay(_module, numDigits); + _display->println(getValue()); } - void doByInterval() { - + byte btLeds=0; + byte btPosition=0; + void loop() { + if(buttons) buttons->tick(); } void setValue(const IoTValue& Value, bool genEvent = true) { if (_display == nullptr) return; value = Value; - _display->println(getValue()); + //_display->println(getValue()); + _display->printf("%4s\n", getValue()); IoTItem::setValue(Value, genEvent); } void onRegEvent(IoTItem* eventItem) { if (_display == nullptr) return; - if (!eventItem || _ids2show.size() == 0) return; + if (!eventItem || _id2show == "") return; + + //_display->println(eventItem->getValue()); + if (_id2show == eventItem->getID()) { + setValue(eventItem->value, false); + } + // } else { + // _display->println(); + // for (int i = 0; i < _ids2show.size(); i++) { + // IoTItem* item = findIoTItem(_ids2show[i]); + // if (item) { + // _display->print(item->getValue()); + // } + // } + // } + } - if (strInVector(eventItem->getID(), _ids2show)) { - if (_ids2show.size() == 1) { - _display->println(eventItem->getValue()); - } else { - _display->println(); - for (int i = 0; i < _ids2show.size(); i++) { - IoTItem* item = findIoTItem(_ids2show[i]); - if (item) { - _display->print(item->getValue()); - } - } + IoTValue execute(String command, std::vector& param) { + if (command == "setLEDs") { + if (param.size() == 1) { + ((TM1638*)_module)->setLEDs(param[0].valD); + } + } else if (command == "onLED") { + if (param.size() == 1) { + ((TM1638*)_module)->setLED(TM1638_COLOR_RED, param[0].valD - 1); + } + } else if (command == "offLED") { + if (param.size() == 1) { + ((TM1638*)_module)->setLED(TM1638_COLOR_GREEN, param[0].valD - 1); + } + } else if (command == "setParamLED") { + if (param.size() == 2) { + _module->setupDisplay(param[0].valD, param[1].valD); + } + } else if (command == "id2show") { + if (param.size() == 1) { + _id2show = param[0].valS; } } + + return {}; } ~TM16XX() { - delete _display; - delete _module; + if (_display) delete _display; + if (_module) delete _module; + if (buttons) delete buttons; + iotItemObj = nullptr; + buttons = nullptr; }; }; void *getAPI_TM16XX(String subtype, String param) { if (subtype == F("TM16XX")) { - return new TM16XX(param); + return iotItemObj = new TM16XX(param); } else { return nullptr; } diff --git a/src/modules/display/TM16XX/modinfo.json b/src/modules/display/TM16XX/modinfo.json index a7c8c82f..bbbed517 100644 --- a/src/modules/display/TM16XX/modinfo.json +++ b/src/modules/display/TM16XX/modinfo.json @@ -15,7 +15,7 @@ "numDigits": 4, "DIO": "13", "CLK": "14", - "STB": "12", + "STB": "21", "intensity": "5", "on": "1", "id2show": "" @@ -33,6 +33,7 @@ "esp8266_4mb": 15 }, "moduleDesc": "Позволяет выводить на 7 сегментный экран серии TM16XX (TM1637, TM1638). Может быть расширен до поддержки TM1616, TM1620, TM1628, TM1630, TM1637, TM1638, TM1640, TM1650, TM1652 и TM1668", + "retInfo": "Если не установлен ИД для отслеживания значения, то внутренняя переменная будет использоваться как источник для информации", "propInfo": { "int": "Период времени в секундах обновления информации на экране по конкретному элементу.", "chip": "Номер чипа TM1637 или TM1638", @@ -42,54 +43,28 @@ "intensity": "Яркость 0-7", "on": "Вкл/выкл при старте 1/0", "STB": "Номер пина стекового сигнала - не используется на определенных моделях", - "id2show": "id элемента конфигурации для отображения. Если пустая строка, то дисплей использует свою переменную. Если указать несколько значений через запятую, то все данные будут последовательно выводиться в строку." + "id2show": "id элемента конфигурации для отображения. Если пустая строка, то дисплей использует свою переменную." }, "funcInfo": [ { - "name": "noBacklight", - "descr": "Выключить подсветку", - "params": [] + "name": "setLEDs", + "descr": "Зажигает верхние светодиоды через установку байта, где каждый разряд соответствует диоду. От 0 до 255", + "params": ["Значение байта"] }, { - "name": "backlight", - "descr": "Включить подсветку", - "params": [] + "name": "onLED", + "descr": "Включить один диод", + "params": ["Номер диода"] }, { - "name": "noDisplay", - "descr": "Спрятать все данные", - "params": [] + "name": "offLED", + "descr": "Выключить один диод", + "params": ["Номер диода"] }, { - "name": "display", - "descr": "Показать данные на экране", - "params": [] - }, - { - "name": "toggle", - "descr": "Переключает видимость значений на экране", - "params": [] - }, - { - "name": "x", - "descr": "Устанавливает первую координату", - "params": [ - "Номер строки первого символа" - ] - }, - { - "name": "y", - "descr": "Устанавливает вторую координату", - "params": [ - "Номер столбца первого символа" - ] - }, - { - "name": "descr", - "descr": "Задает приставку слева от значения", - "params": [ - "Строка" - ] + "name": "setParamLED", + "descr": "Включить/выключить (1/0) и установить яркость от 0 до 7 дисплея", + "params": ["Вкл/Выкл", "Яркость"] }, { "name": "id2show", @@ -100,57 +75,13 @@ } ] }, - "defActive": true, + "defActive": false, "usedLibs": { - "esp32_4mb": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" + "esp32*": [ + "https://github.com/maxint-rd/TM16xx" ], - "esp32_4mb3f": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp32cam_4mb": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8266_4mb": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8266_1mb": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8266_1mb_ota": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8285_1mb": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8285_1mb_ota": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8266_2mb": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" - ], - "esp8266_2mb_ota": [ - "https://github.com/maxint-rd/TM16xx", - "adafruit/Adafruit GFX Library @ ^1.11.5", - "adafruit/Adafruit BusIO @ ^1.13.2" + "esp82*": [ + "https://github.com/maxint-rd/TM16xx" ] } } \ No newline at end of file diff --git a/src/modules/sensors/S8/S8.cpp b/src/modules/sensors/S8/S8.cpp index ce721103..c600809a 100644 --- a/src/modules/sensors/S8/S8.cpp +++ b/src/modules/sensors/S8/S8.cpp @@ -6,12 +6,14 @@ #define R_LEN 7 #define C_LEN 8 -byte cmd_s8[8] = {0xFE, 0x04, 0x00, 0x03, 0x00, 0x01, 0xD5, 0xC5}; -//byte abc_s8[8] = {0xFE, 0x03, 0x00, 0x1F, 0x00, 0x01, 0xA1, 0xC3}; + class S8co : public IoTItem { private: + byte cmd_s8[8] = {0xFE, 0x04, 0x00, 0x03, 0x00, 0x01, 0xD5, 0xC5}; + //byte abc_s8[8] = {0xFE, 0x03, 0x00, 0x1F, 0x00, 0x01, 0xA1, 0xC3}; + SoftwareSerial* s8Serial; unsigned int _s8_co2; @@ -24,6 +26,11 @@ class S8co : public IoTItem { byte _response_s8[7] = {0, 0, 0, 0, 0, 0, 0}; void s8Request(byte cmd[]) { + if (!s8Serial) { + SerialPrint("E", "Sensor S8_uart", "Serial not found!"); + return; + } + while(!s8Serial->available()) { s8Serial->write(cmd, C_LEN); delay(50); @@ -45,7 +52,7 @@ class S8co : public IoTItem { _response_s8[i] = s8Serial->read(); } - s8Serial->end(); + //s8Serial->end(); } void co2_measure() { diff --git a/src/modules/sensors/S8/modinfo.json b/src/modules/sensors/S8/modinfo.json index c4ac2fe9..5874fca9 100644 --- a/src/modules/sensors/S8/modinfo.json +++ b/src/modules/sensors/S8/modinfo.json @@ -2,6 +2,7 @@ "menuSection": "sensors", "configItem": [ { + "global": 0, "name": "(S8) Cенсор качества воздуха", "num": 3, "type": "Reading",