diff --git a/src/modules/sensors/Ina219/Ina219.cpp b/src/modules/sensors/Ina219/Ina219.cpp index b81843f0..60269a1a 100644 --- a/src/modules/sensors/Ina219/Ina219.cpp +++ b/src/modules/sensors/Ina219/Ina219.cpp @@ -1,68 +1,60 @@ /****************************************************************** - Used Adafruit INA219 Current Sensor - Support for INA219 - https://github.com/adafruit/Adafruit_INA219 + Used GyverINA Current Sensor + Support for INA219 INA226 + https://github.com/GyverLibs/GyverINA - adapted for version 4dev @Serghei63 + adapted for version 4dev @Mit4bmw ******************************************************************/ #include "Global.h" #include "classes/IoTItem.h" #include -#include +#include #include -// Adafruit_INA219 ina219; -// Структура для хранения данных с датчика + + +// Структура для хранения настроек датчика struct Ina219Value { - float shuntvoltage = 0; - float busvoltage = 0; + float shunt = 0; + float maxV = 0; }; -// глобальные списки необходимы для хранения данных, полученных разными датчиками из модуля. Ключ - адрес -std::map ina219ValueArray; + +// глобальные списки необходимы для хранения Модуля Настроек. Ключ - адрес +std::map ina219SettingArray; // глобальные списки необходимы для хранения объектов используемых разными датчиками из модуля. Ключ - адрес -std::map ina219Array; +std::map ina219Array; // Функция инициализации библиотечного класса, возвращает Единстрвенный указать на библиотеку -Adafruit_INA219 *instanceIna219(uint8_t ADDR) +INA219 *instanceIna219(uint8_t ADDR) { /** default I2C address **/ if (ADDR == 0) - ADDR = INA219_ADDRESS; // 1000000 (A0+A1=GND) + ADDR = 0x40; // 1000000 (A0+A1=GND) // учитываем, что библиотека может работать с несколькими линиями на разных пинах, поэтому инициируем библиотеку, если линия ранее не использовалась if (ina219Array.find(ADDR) == ina219Array.end()) { - ina219Array[ADDR] = new Adafruit_INA219((uint8_t)ADDR); + if (ina219SettingArray.find(ADDR) == ina219SettingArray.end()) + ina219Array[ADDR] = new INA219(ina219SettingArray[ADDR]->shunt, ina219SettingArray[ADDR]->maxV, (uint8_t)ADDR); + else + ina219Array[ADDR] = new INA219(0.1f, 3.2f, (uint8_t)ADDR); // Стандартные значения для модуля INA219 (0.1 Ом, 3.2А, адрес 0x40) ina219Array[ADDR]->begin(); - ina219ValueArray[ADDR] = new Ina219Value; + // ina219ValueArray[ADDR] = new Ina219Value; } return ina219Array[ADDR]; } -/* -float shuntvoltage = 0; -float busvoltage = 0; -float current_mA = 0; -float loadvoltage = 0; -float power_mW = 0; -*/ -// shuntvoltage = ina219.getShuntVoltage_mV(); // Получение напряжение на шунте -// busvoltage = ina219.getBusVoltage_V(); // Получение значение напряжения V -// current_mA = ina219.getCurrent_mA(); // Получение значение тока в мА -// power_mW = ina219.getPower_mW(); // Получение значение мощности -// loadvoltage = busvoltage + (shuntvoltage / 1000); // Расчет напряжение на нагрузки - -class Ina219loadvoltage : public IoTItem +class Ina219voltage : public IoTItem { private: uint8_t _addr = 0; public: - Ina219loadvoltage(String parameters) : IoTItem(parameters) + Ina219voltage(String parameters) : IoTItem(parameters) { String sAddr; jsonRead(parameters, "addr", sAddr); @@ -74,37 +66,11 @@ public: void doByInterval() { - value.valD = ina219ValueArray[_addr]->busvoltage + (ina219ValueArray[_addr]->shuntvoltage / 1000); - regEvent(value.valD, "Ina219loadvoltage"); + value.valD = instanceIna219(_addr)->getVoltage(); + regEvent(value.valD, "Ina219voltage"); } - ~Ina219loadvoltage(){}; -}; - -class Ina219busvoltage : public IoTItem -{ -private: - uint8_t _addr = 0; - -public: - Ina219busvoltage(String parameters) : IoTItem(parameters) - { - String sAddr; - jsonRead(parameters, "addr", sAddr); - if (sAddr == "") - scanI2C(); - else - _addr = hexStringToUint8(sAddr); - } - - void doByInterval() - { - ina219ValueArray[_addr]->busvoltage = instanceIna219(_addr)->getBusVoltage_V(); - value.valD = ina219ValueArray[_addr]->busvoltage; - regEvent(value.valD, "Ina219busvoltage"); - } - - ~Ina219busvoltage(){}; + ~Ina219voltage(){}; }; class Ina219shuntvoltage : public IoTItem @@ -124,8 +90,7 @@ public: } void doByInterval() { - ina219ValueArray[_addr]->shuntvoltage = instanceIna219(_addr)->getShuntVoltage_mV(); - value.valD = ina219ValueArray[_addr]->shuntvoltage; + value.valD = instanceIna219(_addr)->getShuntVoltage(); regEvent(value.valD, "Ina219shuntvoltage"); } @@ -149,20 +114,20 @@ public: } void doByInterval() { - value.valD = instanceIna219(_addr)->getCurrent_mA(); + value.valD = instanceIna219(_addr)->getCurrent(); regEvent(value.valD, "Ina219curr"); } ~Ina219curr(){}; }; -class Ina219Power_mW : public IoTItem +class Ina219Power : public IoTItem { private: uint8_t _addr = 0; public: - Ina219Power_mW(String parameters) : IoTItem(parameters) + Ina219Power(String parameters) : IoTItem(parameters) { String sAddr; jsonRead(parameters, "addr", sAddr); @@ -173,12 +138,82 @@ public: } void doByInterval() { - value.valD = instanceIna219(_addr)->getPower_mW(); + value.valD = instanceIna219(_addr)->getPower(); regEvent(value.valD, "Ina219power"); // TODO: найти способ понимания ошибки получения данных } - ~Ina219Power_mW(){}; + ~Ina219Power(){}; }; + +class Ina219Setting : public IoTItem +{ +private: + uint8_t _addr = 0; + int adjClbr = 0; + int resol = 1; + + +public: + Ina219Setting(String parameters) : IoTItem(parameters) + { + String sAddr; + jsonRead(parameters, "addr", sAddr); + jsonRead(parameters, "adjClbr", adjClbr); + jsonRead(parameters, "resol", resol); + + + if (sAddr == "") + scanI2C(); + else + _addr = hexStringToUint8(sAddr); + + ina219SettingArray[_addr] = new Ina219Value; + jsonRead(parameters, "shunt", ina219SettingArray[_addr]->shunt); + jsonRead(parameters, "maxV", ina219SettingArray[_addr]->maxV); + + instanceIna219(_addr)->adjCalibration(adjClbr); + if (resol == 1) + resol = 0b0011; + else + resol += 0b0111; + + instanceIna219(_addr)->setResolution(INA219_VBUS, resol); // Напряжение в 12ти битном режиме + instanceIna219(_addr)->setResolution(INA219_VSHUNT, resol); // Ток в 12ти битном режиме + } + + void onModuleOrder(String &key, String &value) + { + if (key == "getClbr") + { + SerialPrint("i", F("Ina219"), "addr: " + String(_addr) + ", Value Calibration:" + instanceIna219(_addr)->getCalibration()); + } + } + + IoTValue execute(String command, std::vector ¶m) + { + if (command == "sleep") + { + if (param.size() == 1) + { + if (param[0].valD == 0) + instanceIna219(_addr)->sleep(false); + if (param[0].valD == 1) + instanceIna219(_addr)->sleep(true); + return {}; + } + } + /* + else if (command == "getCalibration") + { + SerialPrint("i", F("Ina219"), "addr: " + String(_addr) + ", Value Calibration:" + instanceIna219(_addr)->getCalibration()); + return {}; + }*/ + return {}; + } + + ~Ina219Setting(){}; +}; + void *getAPI_Ina219(String subtype, String param) { if (subtype == F("Ina219curr")) @@ -189,17 +224,20 @@ void *getAPI_Ina219(String subtype, String param) { return new Ina219shuntvoltage(param); } - else if (subtype == F("Ina219power_mW")) + else if (subtype == F("Ina219power")) { - return new Ina219Power_mW(param); + return new Ina219Power(param); } - else if (subtype == F("Ina219busvoltage")) + else if (subtype == F("Ina219voltage")) { - return new Ina219busvoltage(param); + return new Ina219voltage(param); } - else if (subtype == F("Ina219loadvoltage")) + else if (subtype == F("Ina219setting")) { - return new Ina219loadvoltage(param); + return new Ina219Setting(param); + // Ina219Setting *ptr = new Ina219Setting(param); + // ina219SettingArray[ptr->getAddr()] = ptr; + // return ptr; } else { diff --git a/src/modules/sensors/Ina219/modinfo.json b/src/modules/sensors/Ina219/modinfo.json index f29a1e57..c89e95b2 100644 --- a/src/modules/sensors/Ina219/modinfo.json +++ b/src/modules/sensors/Ina219/modinfo.json @@ -6,10 +6,10 @@ "name": "INA219 Tок", "type": "Reading", "subtype": "Ina219curr", - "id": "Ina219current", - "widget": "anydatamAmp", + "id": "ina219_A", + "widget": "anydataAmp", "page": "INA 219", - "descr": "219 Датчик тока", + "descr": "Сила тока", "addr": "0x40", "plus": 0, "multiply": 1, @@ -20,11 +20,11 @@ "global": 0, "name": "INA219 Напряжение", "type": "Reading", - "subtype": "Ina219busvoltage", - "id": "Ina219busvoltage", + "subtype": "Ina219voltage", + "id": "ina219_V", "widget": "anydataVlt", "page": "INA 219", - "descr": "219 Датчик напряжения", + "descr": "Напряжения", "addr": "0x40", "plus": 0, "multiply": 1, @@ -35,26 +35,11 @@ "global": 0, "name": "INA219 Мощность", "type": "Reading", - "subtype": "Ina219power_mW", - "id": "Ina219power", - "widget": "anydatamWt", + "subtype": "Ina219power", + "id": "ina219_W", + "widget": "anydataWt", "page": "INA 219", - "descr": "219 Мощность", - "addr": "0x40", - "plus": 0, - "multiply": 1, - "round": 3, - "int": 10 - }, - { - "global": 0, - "name": "INA219 Напряжение нагрузки", - "type": "Reading", - "subtype": "Ina219loadvoltage", - "id": "Ina219loadvoltage", - "widget": "anydataVlt", - "page": "INA 219", - "descr": "219 Напряжение нагрузки", + "descr": "Мощность", "addr": "0x40", "plus": 0, "multiply": 1, @@ -66,15 +51,31 @@ "name": "INA219 Шунт", "type": "Reading", "subtype": "Ina219shuntvoltage", - "id": "Ina219shuntvoltage", - "widget": "anydatamVlt", + "id": "ina219_Vsh", + "widget": "anydataVlt", "page": "INA 219", - "descr": "219 Напряжение шунта", + "descr": "Напряжение шунта", "addr": "0x40", "plus": 0, "multiply": 1, "round": 3, "int": 10 + }, + { + "global": 0, + "name": "INA219 Настройки", + "type": "Reading", + "subtype": "Ina219setting", + "id": "ina219_set", + "widget": "nil", + "page": "", + "descr": "", + "addr": "0x40", + "shunt": 0.1, + "maxV": 3.2, + "adjClbr": 0, + "resol": 4, + "btn-getClbr":"nil" }], "about": { @@ -90,31 +91,46 @@ }, "subTypes": [ "Ina219curr", - "Ina219busvoltage", - "Ina219power_mW", - "Ina219loadvoltage", - "Ina219shuntvoltage" + "Ina219voltage", + "Ina219power", + "Ina219shuntvoltage", + "Ina219setting" ], "title": "Милливатметр постоянного тока", - "moduleDesc": "Измеряет постоянный ток до 3.2 ампера, напряжение до 26 вольт и мощность на нагрузке. Для расчета Наряжения нагрузки, необходимы Напряжение шунта и Датчик Напряжения", + "moduleDesc": "Измеряет постоянный ток до 3.2 ампера, напряжение до 26 вольт и мощность на нагрузке. Модуль INA219 Настройки - для изменении настроек нужен постоянно в конфигурации, должен стоять перед рдугими модулями с тем же адресом, без него работает на значенях по умолчанию", "propInfo": { "int": "Количество секунд между опросами датчика.", - "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40" - } + "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40", + "shunt": "Сопротивление шунта, штатно 0.1Ом. Изменить если его перепаяли", + "maxV": "Максимальный ожидаемый ток, штатно 3.2А, для указаного шунта", + "adjClbr": "Задать смещение (подкрутить) калибровочное значение на указанное значение. -20 = Уменьшить калибровочное значение на 20", + "resol": "Установка режима усреднения для измерения напряжения и тока, рекомендуется для повышения стабильности показаний на шумной нагрузке. Варианты 1(без усреднения),2,4,8,16,32,64,128", + "btn-getClbr": "Кнопка запроса текущей калибровки, выводится в лог" + }, + "funcInfo": [ + { + "name": "sleep", + "descr": "INA219 Настройки. Установка / снятие режима сна датчика INA219", + "params": ["1- вкл сна/ 0-выкл сна"] + } + ] }, "defActive": false, "usedLibs": { "esp32_4mb": [ - "https://github.com/adafruit/Adafruit_INA219.git" + "https://github.com/GyverLibs/GyverINA" ], "esp32s2_4mb": [ - "https://github.com/adafruit/Adafruit_INA219.git" + "https://github.com/GyverLibs/GyverINA" ], "esp8266_4mb": [ - "https://github.com/adafruit/Adafruit_INA219.git" + "https://github.com/GyverLibs/GyverINA" + ], + "esp8266_16mb": [ + "https://github.com/GyverLibs/GyverINA" ] } diff --git a/src/modules/sensors/Ina226/Ina226.cpp b/src/modules/sensors/Ina226/Ina226.cpp new file mode 100644 index 00000000..74b614f6 --- /dev/null +++ b/src/modules/sensors/Ina226/Ina226.cpp @@ -0,0 +1,241 @@ +/****************************************************************** + Used GyverINA Current Sensor + Support for INA219 INA226 + https://github.com/GyverLibs/GyverINA + + adapted for version 4dev @Mit4bmw + ******************************************************************/ + +#include "Global.h" +#include "classes/IoTItem.h" + +#include +#include +#include + + + +// Структура для хранения настроек датчика +struct Ina226Value +{ + float shunt = 0; + float maxV = 0; +}; + +// глобальные списки необходимы для хранения Модуля Настроек. Ключ - адрес +std::map ina226SettingArray; + +// глобальные списки необходимы для хранения объектов используемых разными датчиками из модуля. Ключ - адрес +std::map ina226Array; + +// Функция инициализации библиотечного класса, возвращает Единстрвенный указать на библиотеку +INA226 *instanceIna226(uint8_t ADDR) +{ + /** default I2C address **/ + if (ADDR == 0) + ADDR = 0x40; // 1000000 (A0+A1=GND) + + // учитываем, что библиотека может работать с несколькими линиями на разных пинах, поэтому инициируем библиотеку, если линия ранее не использовалась + if (ina226Array.find(ADDR) == ina226Array.end()) + { + if (ina226SettingArray.find(ADDR) == ina226SettingArray.end()) + ina226Array[ADDR] = new INA226(ina226SettingArray[ADDR]->shunt, ina226SettingArray[ADDR]->maxV, (uint8_t)ADDR); + else + ina226Array[ADDR] = new INA226(0.1f, 0.8f, (uint8_t)ADDR); // Стандартные значения для модуля INA226 (0.1 Ом, 0.8А, адрес 0x40) + ina226Array[ADDR]->begin(); + // ina226ValueArray[ADDR] = new Ina226Value; + } + return ina226Array[ADDR]; +} + +class Ina226voltage : public IoTItem +{ +private: + uint8_t _addr = 0; + +public: + Ina226voltage(String parameters) : IoTItem(parameters) + { + String sAddr; + jsonRead(parameters, "addr", sAddr); + if (sAddr == "") + scanI2C(); + else + _addr = hexStringToUint8(sAddr); + } + + void doByInterval() + { + value.valD = instanceIna226(_addr)->getVoltage(); + regEvent(value.valD, "Ina226voltage"); + } + + ~Ina226voltage(){}; +}; + +class Ina226shuntvoltage : public IoTItem +{ +private: + uint8_t _addr = 0; + +public: + Ina226shuntvoltage(String parameters) : IoTItem(parameters) + { + String sAddr; + jsonRead(parameters, "addr", sAddr); + if (sAddr == "") + scanI2C(); + else + _addr = hexStringToUint8(sAddr); + } + void doByInterval() + { + value.valD = instanceIna226(_addr)->getShuntVoltage(); + regEvent(value.valD, "Ina226shuntvoltage"); + } + + ~Ina226shuntvoltage(){}; +}; + +class Ina226curr : public IoTItem +{ +private: + uint8_t _addr = 0; + +public: + Ina226curr(String parameters) : IoTItem(parameters) + { + String sAddr; + jsonRead(parameters, "addr", sAddr); + if (sAddr == "") + scanI2C(); + else + _addr = hexStringToUint8(sAddr); + } + void doByInterval() + { + value.valD = instanceIna226(_addr)->getCurrent(); + regEvent(value.valD, "Ina226curr"); + } + + ~Ina226curr(){}; +}; + +class Ina226Power : public IoTItem +{ +private: + uint8_t _addr = 0; + +public: + Ina226Power(String parameters) : IoTItem(parameters) + { + String sAddr; + jsonRead(parameters, "addr", sAddr); + if (sAddr == "") + scanI2C(); + else + _addr = hexStringToUint8(sAddr); + } + void doByInterval() + { + value.valD = instanceIna226(_addr)->getPower(); + regEvent(value.valD, "Ina226power"); // TODO: найти способ понимания ошибки получения данных + } + + ~Ina226Power(){}; +}; + +class Ina226Setting : public IoTItem +{ +private: + uint8_t _addr = 0; + int adjClbr = 0; + int resol = 1; + + +public: + Ina226Setting(String parameters) : IoTItem(parameters) + { + String sAddr; + jsonRead(parameters, "addr", sAddr); + jsonRead(parameters, "adjClbr", adjClbr); + jsonRead(parameters, "resol", resol); + + + if (sAddr == "") + scanI2C(); + else + _addr = hexStringToUint8(sAddr); + + ina226SettingArray[_addr] = new Ina226Value; + jsonRead(parameters, "shunt", ina226SettingArray[_addr]->shunt); + jsonRead(parameters, "maxV", ina226SettingArray[_addr]->maxV); + + instanceIna226(_addr)->adjCalibration(adjClbr); + + instanceIna226(_addr)->setAveraging(resol); // Напряжение в 12ти битном режиме + } + + void onModuleOrder(String &key, String &value) + { + if (key == "getClbr") + { + SerialPrint("i", F("Ina226"), "addr: " + String(_addr) + ", Value Calibration:" + instanceIna226(_addr)->getCalibration()); + } + } + + IoTValue execute(String command, std::vector ¶m) + { + if (command == "sleep") + { + if (param.size() == 1) + { + if (param[0].valD == 0) + instanceIna226(_addr)->sleep(false); + if (param[0].valD == 1) + instanceIna226(_addr)->sleep(true); + return {}; + } + } + /* + else if (command == "getCalibration") + { + SerialPrint("i", F("Ina226"), "addr: " + String(_addr) + ", Value Calibration:" + instanceIna226(_addr)->getCalibration()); + return {}; + }*/ + return {}; + } + + ~Ina226Setting(){}; +}; + +void *getAPI_Ina226(String subtype, String param) +{ + if (subtype == F("Ina226curr")) + { + return new Ina226curr(param); + } + else if (subtype == F("Ina226shuntvoltage")) + { + return new Ina226shuntvoltage(param); + } + else if (subtype == F("Ina226power")) + { + return new Ina226Power(param); + } + else if (subtype == F("Ina226voltage")) + { + return new Ina226voltage(param); + } + else if (subtype == F("Ina226setting")) + { + return new Ina226Setting(param); + // Ina226Setting *ptr = new Ina226Setting(param); + // ina226SettingArray[ptr->getAddr()] = ptr; + // return ptr; + } + else + { + return nullptr; + } +} diff --git a/src/modules/sensors/Ina226/modinfo.json b/src/modules/sensors/Ina226/modinfo.json new file mode 100644 index 00000000..a2f00e1c --- /dev/null +++ b/src/modules/sensors/Ina226/modinfo.json @@ -0,0 +1,139 @@ +{ + "menuSection": "Сенсоры", + + "configItem": [{ + "global": 0, + "name": "INA226 Tок", + "type": "Reading", + "subtype": "Ina226curr", + "id": "ina226_A", + "widget": "anydataAmp", + "page": "INA 226", + "descr": "Сила тока", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Напряжение", + "type": "Reading", + "subtype": "Ina226voltage", + "id": "ina226_V", + "widget": "anydataVlt", + "page": "INA 226", + "descr": "Напряжения", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Мощность", + "type": "Reading", + "subtype": "Ina226power", + "id": "ina226_W", + "widget": "anydataWt", + "page": "INA 226", + "descr": "Мощность", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Шунт", + "type": "Reading", + "subtype": "Ina226shuntvoltage", + "id": "ina226_Vsh", + "widget": "anydataVlt", + "page": "INA 226", + "descr": "Напряжение шунта", + "addr": "0x40", + "plus": 0, + "multiply": 1, + "round": 3, + "int": 10 + }, + { + "global": 0, + "name": "INA226 Настройки", + "type": "Reading", + "subtype": "Ina226setting", + "id": "ina226_set", + "widget": "nil", + "page": "", + "descr": "", + "addr": "0x40", + "shunt": 0.1, + "maxV": 3.2, + "adjClbr": 0, + "resol": 4, + "btn-getClbr":"nil" + }], + + "about": { + "authorName": "Serghei Crasnicov", + "authorContact": "https://t.me/Serghei63", + "authorGit": "https://github.com/Serghei63", + "specialThanks": "v2.0 - Mitchel @Mit4bmw", + "moduleName": "Ina226", + "moduleVersion": "2.0", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "subTypes": [ + "Ina226curr", + "Ina226voltage", + "Ina226power", + "Ina226shuntvoltage", + "Ina226setting" + ], + "title": "Милливатметр постоянного тока", + "moduleDesc": "Стандартные значения для модуля INA226 (Сопротивление шунта - 0.1 Ом, Максимальный ожидаемый ток - 0.8 А, Адрес на шине I2c - 0x40). Модуль INA226 Настройки - для изменении настроек нужен постоянно в конфигурации, должен стоять перед рдугими модулями с тем же адресом, без него работает на значенях по умолчанию", + "propInfo": { + "int": "Количество секунд между опросами датчика.", + "addr": "Адрес датчика на шине, обычно 0x40. Если оставить поле пустым, то запуститься сканер I2C и подключение к адресу 0x40", + "shunt": "Сопротивление шунта, штатно 0.1Ом. Изменить если его перепаяли", + "maxV": "Максимальный ожидаемый ток, штатно 0.8А, для указаного шунта", + "adjClbr": "Задать смещение (подкрутить) калибровочное значение на указанное значение. -20 = Уменьшить калибровочное значение на 20", + "resol": "Установка режима усреднения (колическва замеров) для измерения напряжения и тока, рекомендуется для повышения стабильности показаний на шумной нагрузке. Пропорционально увеличивает время оцифровки. Варианты 0(без усреднения), от 1 до 7 - соответстввует 4,16,64,128,256,512,1024", + "btn-getClbr": "Кнопка запроса текущей калибровки, выводится в лог" + }, + "funcInfo": [ + { + "name": "sleep", + "descr": "INA226 Настройки. Установка / снятие режима сна датчика INA226", + "params": ["1- вкл сна/ 0-выкл сна"] + } + ] + }, + + "defActive": false, + + "usedLibs": { + "esp32_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp32s2_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + + "esp8266_4mb": [ + "https://github.com/GyverLibs/GyverINA" + ], + "esp8266_16mb": [ + "https://github.com/GyverLibs/GyverINA" + ] + } + + } + + \ No newline at end of file