Merge pull request #367 from biveraxe/ver4dev

Добавили поддержку кнопок и ледов для tm1638
This commit is contained in:
2023-12-27 11:57:35 +03:00
committed by GitHub
4 changed files with 177 additions and 115 deletions

View File

@@ -4,19 +4,103 @@
#include <TM1637.h>
#include <TM1638.h>
#include <TM16xxDisplay.h>
#include <TM16xxbuttons.h>
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<IoTItem*>::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<String> _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<IoTValue>& 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;
}

View File

@@ -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"
]
}
}

View File

@@ -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() {

View File

@@ -2,6 +2,7 @@
"menuSection": "sensors",
"configItem": [
{
"global": 0,
"name": "(S8) Cенсор качества воздуха",
"num": 3,
"type": "Reading",