From 14b8b742df442e24b2a400ad70595a2d77624561 Mon Sep 17 00:00:00 2001 From: Ewoud Date: Fri, 8 Nov 2024 23:26:02 +0100 Subject: [PATCH] set/getValue to Variable. ESPLiveScript 1.2.0 pio.ini - add STARBASE_USERMOD_MIDI (not active yet) - update LiveScript t0 main/1.2.0 - rename esp32_wrover to esp-wrover-kit main.cpp - add STARBASE_USERMOD_MIDI (not active yet) SysModModel - setValueJV, setValueF, getValue, setValue -> Variable - mdl->setValue(variable.var, -> variable.setValue( - mdl->getValue(variable.var, -> variable.getValue( --- platformio.ini | 15 +++- src/Sys/SysModFiles.cpp | 2 +- src/Sys/SysModInstances.h | 34 ++++---- src/Sys/SysModModel.cpp | 48 +++++++++++ src/Sys/SysModModel.h | 165 ++++++++++++++------------------------ src/Sys/SysModNetwork.cpp | 12 +-- src/Sys/SysModPins.cpp | 6 +- src/Sys/SysModPrint.cpp | 2 +- src/Sys/SysModSystem.cpp | 19 ++--- src/Sys/SysModUI.cpp | 6 +- src/Sys/SysModUI.h | 8 +- src/Sys/SysModWeb.cpp | 18 ++--- src/User/UserModE131.h | 8 +- src/User/UserModLive.cpp | 16 ++-- src/User/UserModMPU6050.h | 4 +- src/User/UserModMidi.h | 45 +++++++++++ src/main.cpp | 10 +++ 17 files changed, 244 insertions(+), 174 deletions(-) create mode 100644 src/User/UserModMidi.h diff --git a/platformio.ini b/platformio.ini index 4248499..3e9319c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,13 +66,20 @@ build_flags = lib_deps = ElectronicCats/MPU6050 @ 1.3.0 +[STARBASE_USERMOD_MIDI] +build_flags = + -D STARBASE_USERMOD_MIDI +lib_deps = + ; https://github.com/marcel-licence/esp32_usb_midi + ; https://github.com/felis/USB_Host_Shield_2.0 + ;asmParser Ā© https://github.com/hpwit/ASMParser [STARBASE_USERMOD_LIVE] build_flags = -D STARBASE_USERMOD_LIVE + -D EXTPRINTF=ppf lib_deps = - ; https://github.com/hpwit/ESPLiveScript.git#17b4bb7 ;v2.9.3 @ 20241030 15:39 - https://github.com/ewowi/ESPLiveScript.git#v2.9.3 ;ewowi repo adds some proposed PR's and makes sure we don't have unexpected updates + https://github.com/ewowi/ESPLiveScript.git#main ;1.2.0. ewowi repo adds some proposed PR's and makes sure we don't have unexpected updates [STARBASE] build_flags = @@ -88,6 +95,7 @@ build_flags = -D STARBASE_ETHERNET ; +41.876 bytes (2.2%) ${STARBASE_USERMOD_E131.build_flags} ;+11.416 bytes 0.6% ${STARBASE_USERMOD_MPU6050.build_flags} ;+35.308 bytes 1.8% + ; ${STARBASE_USERMOD_MIDI.build_flags} ;+5%... ; ${STARBASE_USERMOD_HA.build_flags} ${STARBASE_USERMOD_LIVE.build_flags} ;+222.204 bytes 11.7% lib_deps = @@ -97,6 +105,7 @@ lib_deps = ;optional: ${STARBASE_USERMOD_E131.lib_deps} ${STARBASE_USERMOD_MPU6050.lib_deps} + ; ${STARBASE_USERMOD_MIDI.lib_deps} ; ${STARBASE_USERMOD_HA.lib_deps} ${STARBASE_USERMOD_LIVE.lib_deps} @@ -148,7 +157,7 @@ lib_deps = ; https://github.com/platformio/platform-espressif32/issues/1360 ; https://community.platformio.org/t/support-esp32-wrover-module/17717 ; note: flasghing to new board goes wrong, try first without ICVD then with and without etc until it works (witchcraft) -[env:esp32_wrover] +[env:esp-wrover-kit] board = esp-wrover-kit ; esp-wrover-kit ;https://github.com/platformio/platform-espressif32/blob/develop/boards/esp-wrover-kit.json ; recommended to pin to a platform version, see https://github.com/platformio/platform-espressif32/releases platform = espressif32@6.5.0 ;using platformio/framework-arduinoespressif32 @ ~3.20014.0 / framework-arduinoespressif32 @ 3.20014.231204 (2.0.14) diff --git a/src/Sys/SysModFiles.cpp b/src/Sys/SysModFiles.cpp index 452e245..9b315f8 100644 --- a/src/Sys/SysModFiles.cpp +++ b/src/Sys/SysModFiles.cpp @@ -63,7 +63,7 @@ void SysModFiles::setup() { // for (size_t rowNr = 0; rowNr < fileList.size(); rowNr++) { // char urlString[32] = "file/"; // strlcat(urlString, fileList[rowNr].name, sizeof(urlString)); - // mdl->setValue(variable.var, JsonString(urlString, JsonString::Copied), rowNr); + // variable.setValue(JsonString(urlString, JsonString::Copied), rowNr); // } // return true; // default: return false; diff --git a/src/Sys/SysModInstances.h b/src/Sys/SysModInstances.h index 84cec6f..67e982a 100644 --- a/src/Sys/SysModInstances.h +++ b/src/Sys/SysModInstances.h @@ -119,12 +119,12 @@ class SysModInstances:public SysModule { ui->initText(tableVar, "name", nullptr, 32, false, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, JsonString(instances[rowNrL].name, JsonString::Copied), rowNrL); + variable.setValue(JsonString(instances[rowNrL].name, JsonString::Copied), rowNrL); return true; // comment this out for the time being as causes corrupted instance names // case onChange: - // strlcpy(instances[rowNr].name, mdl->getValue(variable.var, rowNr), sizeof(instances[rowNr].name)); - // sendMessageUDP(instances[rowNr].ip, "name", mdl->getValue(variable.var, rowNr)); + // strlcpy(instances[rowNr].name, variable.getValue(rowNr), sizeof(instances[rowNr].name)); + // sendMessageUDP(instances[rowNr].ip, "name", variable.getValue(rowNr)); // return true; default: return false; }}); @@ -134,7 +134,7 @@ class SysModInstances:public SysModule { for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) { char urlString[32] = "http://"; strlcat(urlString, instances[rowNrL].ip.toString().c_str(), sizeof(urlString)); - mdl->setValue(variable.var, JsonString(urlString, JsonString::Copied), rowNrL); + variable.setValue(JsonString(urlString, JsonString::Copied), rowNrL); } return true; default: return false; @@ -143,7 +143,7 @@ class SysModInstances:public SysModule { ui->initNumber(tableVar, "link", UINT16_MAX, 0, UINT16_MAX, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, calcGroup(instances[rowNrL].name), rowNrL); + variable.setValue(calcGroup(instances[rowNrL].name), rowNrL); return true; default: return false; }}); @@ -151,7 +151,7 @@ class SysModInstances:public SysModule { ui->initText(tableVar, "IP", nullptr, 16, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, JsonString(instances[rowNrL].ip.toString().c_str(), JsonString::Copied), rowNrL); + variable.setValue(JsonString(instances[rowNrL].ip.toString().c_str(), JsonString::Copied), rowNrL); return true; default: return false; }}); @@ -160,7 +160,7 @@ class SysModInstances:public SysModule { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) { byte type = instances[rowNrL].sysData.type; - mdl->setValue(variable.var, (type==0)?"WLED":(type==1)?"StarBase":(type==2)?"StarLight":(type==3)?"StarLedsLive":"StarFork", rowNrL); + variable.setValue((type==0)?"WLED":(type==1)?"StarBase":(type==2)?"StarLight":(type==3)?"StarLedsLive":"StarFork", rowNrL); } return true; default: return false; @@ -169,7 +169,7 @@ class SysModInstances:public SysModule { ui->initNumber(tableVar, "version", UINT16_MAX, 0, (unsigned long)-1, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, instances[rowNrL].version, rowNrL); + variable.setValue(instances[rowNrL].version, rowNrL); return true; default: return false; }}); @@ -177,14 +177,14 @@ class SysModInstances:public SysModule { ui->initNumber(tableVar, "uptime", UINT16_MAX, 0, (unsigned long)-1, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, instances[rowNrL].sysData.uptime, rowNrL); + variable.setValue(instances[rowNrL].sysData.uptime, rowNrL); return true; default: return false; }}); ui->initNumber(tableVar, "now", UINT16_MAX, 0, (unsigned long)-1, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, instances[rowNrL].sysData.now / 1000, rowNrL); + variable.setValue(instances[rowNrL].sysData.now / 1000, rowNrL); return true; default: return false; }}); @@ -192,7 +192,7 @@ class SysModInstances:public SysModule { ui->initNumber(tableVar, "timestamp", UINT16_MAX, 0, (unsigned long)-1, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, instances[rowNrL].sysData.timeSource, rowNrL); + variable.setValue(instances[rowNrL].sysData.timeSource, rowNrL); return true; default: return false; }}); @@ -200,7 +200,7 @@ class SysModInstances:public SysModule { ui->initNumber(tableVar, "time", UINT16_MAX, 0, (unsigned long)-1, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, instances[rowNrL].sysData.tokiTime, rowNrL); + variable.setValue(instances[rowNrL].sysData.tokiTime, rowNrL); return true; default: return false; }}); @@ -208,7 +208,7 @@ class SysModInstances:public SysModule { ui->initNumber(tableVar, "ms", UINT16_MAX, 0, (unsigned long)-1, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNrL = 0; rowNrL < instances.size() && (rowNr == UINT8_MAX || rowNrL == rowNr); rowNrL++) - mdl->setValue(variable.var, instances[rowNrL].sysData.tokiMs, rowNrL); + variable.setValue(instances[rowNrL].sysData.tokiMs, rowNrL); return true; default: return false; }}); @@ -248,9 +248,9 @@ class SysModInstances:public SysModule { if (rowNr != UINT8_MAX) { //if this instance update directly, otherwise send over network if (instances[rowNr].ip == net->localIP()) { - mdl->setValue(var, mdl->getValue(insVariable.var, rowNr).as()); //this will call sendDataWS (tbd...), do not set for rowNr + Variable(var).setValue(insVariable.getValue(rowNr).as()); //this will call sendDataWS (tbd...), do not set for rowNr } else { - sendMessageUDP(instances[rowNr].ip, var, mdl->getValue(insVariable.var, rowNr)); + sendMessageUDP(instances[rowNr].ip, var, insVariable.getValue(rowNr)); } } // print->printJson(" ", var); @@ -499,7 +499,7 @@ class SysModInstances:public SysModule { if (!message["id"].isNull() && !message["value"].isNull()) { ppf("handleNotifications i:%d json message %.*s l:%d\n", instanceUDP.remoteIP()[3], packetSize, buffer, packetSize); - mdl->setValueJV(mdl->findVar(message["pid"].as(), message["id"].as()), message["value"]); + Variable(mdl->findVar(message["pid"].as(), message["id"].as())).setValueJV(message["value"]); } } } @@ -774,7 +774,7 @@ class SysModInstances:public SysModule { id = strtok(NULL, "."); //the rest after . } - mdl->setValueJV(mdl->findVar(pid, id), pair.value()); + Variable(mdl->findVar(pid, id)).setValueJV(pair.value()); } instance.jsonData = newData; // deepcopy: https://github.com/bblanchon/ArduinoJson/issues/1023 // ppf("updateInstance json ip:%d", instance.ip[3]); diff --git a/src/Sys/SysModModel.cpp b/src/Sys/SysModModel.cpp index 682772c..e20243c 100644 --- a/src/Sys/SysModModel.cpp +++ b/src/Sys/SysModModel.cpp @@ -385,6 +385,54 @@ return false; } + JsonObject Variable::setValueJV(JsonVariant value, uint8_t rowNr) { + if (value.is()) { + uint8_t rowNr = 0; + // ppf(" %s is Array\n", value.as().c_str); + JsonObject var; + for (JsonVariant el: value.as()) { + var = setValueJV(el, rowNr++); + } + return var; + } + else if (value.is()) + return setValue(JsonString(value, JsonString::Copied), rowNr); + else if (value.is()) //otherwise it will be treated as JsonObject and toJson / fromJson will not be triggered!!! + return setValue(value.as(), rowNr); + else + return setValue(value, rowNr); + } + + //Set value with argument list + JsonObject Variable::setValueF(const char * format, ...) { + va_list args; + va_start(args, format); + + char value[128]; + vsnprintf(value, sizeof(value)-1, format, args); + + va_end(args); + + return setValue(JsonString(value, JsonString::Copied)); + } + + JsonVariant Variable::getValue(uint8_t rowNr) { + if (var["value"].is()) { + JsonArray valueArray = valArray(); + if (rowNr == UINT8_MAX) rowNr = mdl->getValueRowNr; + if (rowNr != UINT8_MAX && rowNr < valueArray.size()) + return valueArray[rowNr]; + else if (valueArray.size()) + return valueArray[0]; //return the first element + else { + ppf("dev getValue no array or rownr wrong %s.%s %s %d\n", pid(), id(), valueString().c_str(), rowNr); + return JsonVariant(); // return null + } + } + else + return var["value"]; + } + SysModModel::SysModModel() :SysModule("Model") { model = new JsonDocument(&allocator); diff --git a/src/Sys/SysModModel.h b/src/Sys/SysModModel.h index 244a547..ac2f503 100644 --- a/src/Sys/SysModModel.h +++ b/src/Sys/SysModModel.h @@ -260,90 +260,29 @@ class Variable { // (groupName and optionName as pointers? String is already a pointer?) bool findOptionsTextRec(JsonVariant options, uint8_t * startValue, uint8_t value, JsonString *groupName, JsonString *optionName, JsonString parentGroup = JsonString()); -}; //class Variable - -#define EventArguments Variable variable, uint8_t rowNr, uint8_t eventType - -// https://stackoverflow.com/questions/59111610/how-do-you-declare-a-lambda-function-using-typedef-and-then-use-it-by-passing-to -typedef std::function VarEvent; - -class SysModModel:public SysModule { - -public: - - RAM_Allocator allocator; - JsonDocument *model = nullptr; - - bool doWriteModel = false; - - uint8_t setValueRowNr = UINT8_MAX; - uint8_t getValueRowNr = UINT8_MAX; - int varCounter = 1; //start with 1 so it can be negative, see var["o"] - - std::vector varEvents; - - SysModModel(); - void setup(); - void loop20ms(); - void loop1s(); - - //scan all vars in the model and remove vars where var["o"] is negative or positive, if ro then remove ro values - void cleanUpModel(JsonObject parent = JsonObject(), bool oPos = true, bool ro = false); - //setValue for JsonVariants (extract the StarMod supported types) - JsonObject setValueJV(JsonObject var, JsonVariant value, uint8_t rowNr = UINT8_MAX) { - if (value.is()) { - uint8_t rowNr = 0; - // ppf(" %s is Array\n", value.as().c_str); - JsonObject var; - for (JsonVariant el: value.as()) { - var = setValueJV(var, el, rowNr++); - } - return var; - } - else if (value.is()) - return setValue(var, JsonString(value, JsonString::Copied), rowNr); - else if (value.is()) //otherwise it will be treated as JsonObject and toJson / fromJson will not be triggered!!! - return setValue(var, value.as(), rowNr); - else - return setValue(var, value, rowNr); - } - - //sets the value of var with id - template - JsonObject setValue(const char * pid, const char * id, Type value, uint8_t rowNr = UINT8_MAX) { - JsonObject var = findVar(pid, id); - if (!var.isNull()) { - return setValue(var, value, rowNr); - } - else { - ppf("setValue var %s.%s not found\n", pid, id); - return JsonObject(); - } - } + JsonObject setValueJV(JsonVariant value, uint8_t rowNr = UINT8_MAX); template - JsonObject setValue(JsonObject var, Type value, uint8_t rowNr = UINT8_MAX) { - Variable variable = Variable(var); - + JsonObject setValue(Type value, uint8_t rowNr = UINT8_MAX) { bool changed = false; if (rowNr == UINT8_MAX) { //normal situation - if (variable.value().isNull() || variable.value().as() != value) { //const char * will be JsonString so comparison works - if (!variable.value().isNull() && !variable.readOnly()) var["oldValue"] = variable.value(); + if (var["value"].isNull() || var["value"].as() != value) { //const char * will be JsonString so comparison works + if (!var["value"].isNull() && !readOnly()) var["oldValue"] = var["value"]; var["value"] = value; //trick to remove null values - if (variable.value().isNull() || variable.value().as() == UINT16_MAX) { + if (var["value"].isNull() || var["value"].as() == UINT16_MAX) { var.remove("value"); - // ppf("dev setValue value removed %s %s\n", variable.id(), var["oldValue"].as().c_str()); + // ppf("dev setValue value removed %s %s\n", id(), var["oldValue"].as().c_str()); } else { //only print if ! read only - // if (!variable.readOnly()) - // ppf("setValue changed %s.%s %s -> %s\n", variable.pid(), variable.id(), var["oldValue"].as().c_str(), variable.valueString().c_str()); + // if (!readOnly()) + // ppf("setValue changed %s.%s %s -> %s\n", pid(), id(), var["oldValue"].as().c_str(), valueString().c_str()); // else - // ppf("setValue changed %s %s\n", variable.id(), variable.value().as().c_str()); - web->addResponse(variable.var, "value", variable.value()); + // ppf("setValue changed %s %s\n", id(), var["value"].as().c_str()); + web->addResponse(var, "value", var["value"]); changed = true; } } @@ -351,13 +290,13 @@ class SysModModel:public SysModule { else { //if we deal with multiple rows, value should be an array, if not we create one - if (variable.value().isNull() || !variable.value().is()) { - // ppf("setValue var %s[%d] value %s not array, creating\n", variable.id(), rowNr, variable.value().as().c_str()); + if (var["value"].isNull() || !var["value"].is()) { + // ppf("setValue var %s[%d] value %s not array, creating\n", id(), rowNr, var["value"].as().c_str()); var["value"].to(); } - if (variable.value().is()) { - JsonArray valueArray = variable.valArray(); + if (var["value"].is()) { + JsonArray valueArray = valArray(); //set the right value in the array (if array did not contain values yet, all values before rownr are set to false) bool notSame = true; //rowNr >= size @@ -369,60 +308,78 @@ class SysModModel:public SysModule { // ppf("notSame %d %d\n", rowNr, valueArray.size()); valueArray[rowNr] = value; //if valueArray[().c_str()); - web->addResponse(variable.var, "value", variable.value()); //send the whole array to UI as response is in format value: !! + web->addResponse(var, "value", var["value"]); //send the whole array to UI as response is in format value: !! changed = true; } } else { - ppf("setValue %s.%s could not create value array\n", variable.pid(), variable.id()); + ppf("setValue %s.%s could not create value array\n", pid(), id()); } } - if (changed) variable.triggerEvent(onChange, rowNr); + if (changed) triggerEvent(onChange, rowNr); - return var; + return var; } //Set value with argument list - JsonObject setValue(JsonObject var, const char * format = nullptr, ...) { - va_list args; - va_start(args, format); + JsonObject setValueF(const char * format = nullptr, ...); + + JsonVariant getValue(uint8_t rowNr = UINT8_MAX); + +}; //class Variable + +#define EventArguments Variable variable, uint8_t rowNr, uint8_t eventType + +// https://stackoverflow.com/questions/59111610/how-do-you-declare-a-lambda-function-using-typedef-and-then-use-it-by-passing-to +typedef std::function VarEvent; + +class SysModModel:public SysModule { + +public: + + RAM_Allocator allocator; + JsonDocument *model = nullptr; + + bool doWriteModel = false; + + uint8_t setValueRowNr = UINT8_MAX; + uint8_t getValueRowNr = UINT8_MAX; + int varCounter = 1; //start with 1 so it can be negative, see var["o"] - char value[128]; - vsnprintf(value, sizeof(value)-1, format, args); + std::vector varEvents; - va_end(args); + SysModModel(); + void setup(); + void loop20ms(); + void loop1s(); + + //scan all vars in the model and remove vars where var["o"] is negative or positive, if ro then remove ro values + void cleanUpModel(JsonObject parent = JsonObject(), bool oPos = true, bool ro = false); - return setValue(var, JsonString(value, JsonString::Copied)); + //sets the value of var with id + template + JsonObject setValue(const char * pid, const char * id, Type value, uint8_t rowNr = UINT8_MAX) { + JsonObject var = findVar(pid, id); + if (!var.isNull()) { + return Variable(var).setValue(value, rowNr); + } + else { + ppf("setValue var %s.%s not found\n", pid, id); + return JsonObject(); + } } JsonVariant getValue(const char * pid, const char * id, uint8_t rowNr = UINT8_MAX) { JsonObject var = findVar(pid, id); if (!var.isNull()) { - return getValue(var, rowNr); + return Variable(var).getValue(rowNr); } else { // ppf("getValue: Var %s does not exist!!\n", id); return JsonVariant(); } } - JsonVariant getValue(JsonObject var, uint8_t rowNr = UINT8_MAX) { - Variable variable = Variable(var); - if (variable.value().is()) { - JsonArray valueArray = variable.valArray(); - if (rowNr == UINT8_MAX) rowNr = getValueRowNr; - if (rowNr != UINT8_MAX && rowNr < valueArray.size()) - return valueArray[rowNr]; - else if (valueArray.size()) - return valueArray[0]; //return the first element - else { - ppf("dev getValue no array or rownr wrong %s %s %d\n", variable.id(), variable.valueString().c_str(), rowNr); - return JsonVariant(); // return null - } - } - else - return variable.value(); - } //returns the var defined by id (parent to recursively call findVar) bool walkThroughModel(std::function fun, JsonObject parent = JsonObject()); diff --git a/src/Sys/SysModNetwork.cpp b/src/Sys/SysModNetwork.cpp index 3423739..22913ac 100644 --- a/src/Sys/SysModNetwork.cpp +++ b/src/Sys/SysModNetwork.cpp @@ -69,14 +69,14 @@ void SysModNetwork::setup() { ui->initText(currentVar, "rssi", nullptr, 32, true, [](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "%d dBm", WiFi.RSSI(), 0); //0 is to force format overload used + variable.setValueF("%d dBm", WiFi.RSSI(), 0); //0 is to force format overload used return true; default: return false; }}); ui->initText(currentVar, "status", nullptr, 32, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "%s %s (s:%d)", wfActive?WiFi.localIP()[0]?"šŸŸ¢":"šŸŸ ":"šŸ›‘", wfActive?WiFi.localIP().toString().c_str():"inactive", WiFi.status()); + variable.setValueF("%s %s (s:%d)", wfActive?WiFi.localIP()[0]?"šŸŸ¢":"šŸŸ ":"šŸ›‘", wfActive?WiFi.localIP().toString().c_str():"inactive", WiFi.status()); return true; default: return false; }}); @@ -86,7 +86,7 @@ void SysModNetwork::setup() { currentVar = ui->initCheckBox(parentVar, "ethernet", false, false, [this](EventArguments) { switch (eventType) { case onLoop1s: //initEthernet not done in onChange as initEthernet needs a bit of a delay - if (!ethActive && mdl->getValue(variable.var).as()) + if (!ethActive && variable.getValue().as()) initEthernet(); default: return false; }}); @@ -174,7 +174,7 @@ void SysModNetwork::setup() { ui->initText(currentVar, "status", nullptr, 32, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "%s %s", ethActive?ETH.localIP()[0]?"šŸŸ¢":"šŸŸ ":"šŸ›‘", ethActive?ETH.localIP().toString().c_str():"inactive"); + variable.setValueF("%s %s", ethActive?ETH.localIP()[0]?"šŸŸ¢":"šŸŸ ":"šŸ›‘", ethActive?ETH.localIP().toString().c_str():"inactive"); return true; default: return false; }}); @@ -189,7 +189,7 @@ void SysModNetwork::setup() { stopAP(); return true; // case onLoop1s: - // if (!apActive && mdl->getValue(var).as()) { + // if (!apActive && variable.getValue().as()) { // stopAP(); // initAP(); // } @@ -198,7 +198,7 @@ void SysModNetwork::setup() { }}); ui->initText(currentVar, "status", nullptr, 32, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "%s %s", apActive?WiFi.softAPIP()[0]?"šŸŸ¢":"šŸŸ ":"šŸ›‘", apActive?WiFi.softAPIP().toString().c_str():"inactive"); + variable.setValueF("%s %s", apActive?WiFi.softAPIP()[0]?"šŸŸ¢":"šŸŸ ":"šŸ›‘", apActive?WiFi.softAPIP().toString().c_str():"inactive"); return true; default: return false; }}); diff --git a/src/Sys/SysModPins.cpp b/src/Sys/SysModPins.cpp index 32fd829..575baee 100644 --- a/src/Sys/SysModPins.cpp +++ b/src/Sys/SysModPins.cpp @@ -38,7 +38,7 @@ void SysModPins::setup() { variable.var.remove("value"); ppf("pin onSetValue %s %d\n", variable.valueString().c_str(), getNrOfAllocatedPins()); for (uint8_t rowNr = 0; rowNr < getNrOfAllocatedPins(); rowNr++) - mdl->setValue(variable.var, getPinNr(rowNr), rowNr); + variable.setValue(getPinNr(rowNr), rowNr); return true; default: return false; }}); @@ -47,7 +47,7 @@ void SysModPins::setup() { case onSetValue: variable.var.remove("value"); for (uint8_t rowNr = 0; rowNr < getNrOfAllocatedPins(); rowNr++) - mdl->setValue(variable.var, JsonString(getNthAllocatedPinObject(rowNr).owner, JsonString::Copied), rowNr); + variable.setValue(JsonString(getNthAllocatedPinObject(rowNr).owner, JsonString::Copied), rowNr); return true; default: return false; }}); @@ -57,7 +57,7 @@ void SysModPins::setup() { variable.var.remove("value"); for (uint8_t rowNr = 0; rowNr < getNrOfAllocatedPins(); rowNr++) { // ppf("details[%d] d:%s\n", rowNr, getNthAllocatedPinObject(rowNr).details); - mdl->setValue(variable.var, JsonString(getNthAllocatedPinObject(rowNr).details, JsonString::Copied), rowNr); + variable.setValue(JsonString(getNthAllocatedPinObject(rowNr).details, JsonString::Copied), rowNr); } return true; default: return false; diff --git a/src/Sys/SysModPrint.cpp b/src/Sys/SysModPrint.cpp index 367c219..79cef7f 100644 --- a/src/Sys/SysModPrint.cpp +++ b/src/Sys/SysModPrint.cpp @@ -102,7 +102,7 @@ void SysModPrint::printf(const char * format, ...) { else responseObject["Print.log"]["value"] = responseObject["Print.log"]["value"].as() + String(buffer); // web->addResponse(variable.var, "value", JsonString(buffer, JsonString::Copied)); //setValue not necessary - // mdl->setValue(variable.var, "%s", buffer); + // variable.setValueF("%s", buffer); } else if (output == 3) { //tbd diff --git a/src/Sys/SysModSystem.cpp b/src/Sys/SysModSystem.cpp index 12b1332..512e271 100644 --- a/src/Sys/SysModSystem.cpp +++ b/src/Sys/SysModSystem.cpp @@ -49,7 +49,7 @@ void SysModSystem::setup() { char name[24]; removeInvalidCharacters(name, variable.value()); ppf("instance name stripped %s\n", name); - mdl->setValue(variable.var, JsonString(name, JsonString::Copied)); //update with stripped name + variable.setValue(JsonString(name, JsonString::Copied)); //update with stripped name mdns->resetMDNS(); // set the new name for mdns return true; default: return false; @@ -60,7 +60,7 @@ void SysModSystem::setup() { variable.setComment("s. Uptime of board"); return true; case onLoop1s: - mdl->setValue(variable.var, millis()/1000); + variable.setValue(millis()/1000); return true; default: return false; }}); @@ -70,7 +70,7 @@ void SysModSystem::setup() { variable.setComment("s"); return true; case onLoop1s: - mdl->setValue(variable.var, now/1000); + variable.setValue(now/1000); return true; default: return false; }}); @@ -80,7 +80,7 @@ void SysModSystem::setup() { variable.setComment("s"); return true; case onLoop1s: - mdl->setValue(variable.var, (nowsetValue(variable.var, loopCounter); + variable.setValue(loopCounter); loopCounter = 0; return true; default: return false; @@ -119,9 +119,10 @@ void SysModSystem::setup() { variable.var["max"] = ESP.getHeapSize()/1000; //makes sense? web->addResponse(variable.var, "comment", "f:%d / t:%d (l:%d) B [%d %d]", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getMaxAllocHeap(), esp_get_free_heap_size(), esp_get_free_internal_heap_size()); //temporary add esp_get_free_heap_size(), esp_get_free_internal_heap_size() to see if/how it differs + //esp_get_free_heap_size can be bigger in case of heap return true; case onLoop1s: - mdl->setValue(variable.var, (ESP.getHeapSize()-ESP.getFreeHeap()) / 1000); + variable.setValue((ESP.getHeapSize()-ESP.getFreeHeap()) / 1000); return true; default: return false; }}); @@ -133,7 +134,7 @@ void SysModSystem::setup() { web->addResponse(variable.var, "comment", "%d / %d (%d) B", ESP.getFreePsram(), ESP.getPsramSize(), ESP.getMinFreePsram()); return true; case onLoop1s: - mdl->setValue(variable.var, (ESP.getPsramSize()-ESP.getFreePsram()) / 1000); + variable.setValue((ESP.getPsramSize()-ESP.getFreePsram()) / 1000); return true; default: return false; }}); @@ -145,7 +146,7 @@ void SysModSystem::setup() { web->addResponse(variable.var, "comment", "%d of %d B", sysTools_get_arduino_maxStackUsage(), getArduinoLoopTaskStackSize()); return true; case onLoop1s: - mdl->setValue(variable.var, sysTools_get_arduino_maxStackUsage()); + variable.setValue(sysTools_get_arduino_maxStackUsage()); return true; default: return false; }}); @@ -155,7 +156,7 @@ void SysModSystem::setup() { web->addResponse(variable.var, "comment", "%d of %d B", sysTools_get_webserver_maxStackUsage(), CONFIG_ASYNC_TCP_STACK_SIZE); return true; case onLoop1s: - mdl->setValue(variable.var, sysTools_get_webserver_maxStackUsage()); + variable.setValue(sysTools_get_webserver_maxStackUsage()); return true; default: return false; }}); diff --git a/src/Sys/SysModUI.cpp b/src/Sys/SysModUI.cpp index 5e9a461..cd531aa 100644 --- a/src/Sys/SysModUI.cpp +++ b/src/Sys/SysModUI.cpp @@ -32,7 +32,7 @@ void SysModUI::setup() { initText(tableVar, "variable", nullptr, 32, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNr = 0; rowNr < loopFunctions.size(); rowNr++) - mdl->setValue(variable.var, JsonString(loopFunctions[rowNr].var["id"], JsonString::Copied), rowNr); + variable.setValue(JsonString(loopFunctions[rowNr].var["id"], JsonString::Copied), rowNr); return true; default: return false; }}); @@ -40,7 +40,7 @@ void SysModUI::setup() { initNumber(tableVar, "#loops", UINT16_MAX, 0, 999, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNr = 0; rowNr < loopFunctions.size(); rowNr++) - mdl->setValue(variable.var, loopFunctions[rowNr].counter, rowNr); + variable.setValue(loopFunctions[rowNr].counter, rowNr); return true; case onLoop1s: variable.triggerEvent(onSetValue); //set the value (WIP) @@ -248,7 +248,7 @@ void SysModUI::processJson(JsonVariant json) { if (rowNr != UINT8_MAX) web->getResponseObject()[pidid]["rowNr"] = rowNr; } else { - mdl->setValueJV(var, newValue, rowNr); + Variable(var).setValueJV(newValue, rowNr); //we do need the response! to update multiple clients and also things within a client (e.g. systemName) // json.remove(key); //key / var["id"] processed we don't need the key in the response // print->printJson("setValueJV", web->getResponseObject()); diff --git a/src/Sys/SysModUI.h b/src/Sys/SysModUI.h index 01ac694..6e9439f 100644 --- a/src/Sys/SysModUI.h +++ b/src/Sys/SysModUI.h @@ -171,7 +171,7 @@ class SysModUI: public SysModule { JsonObject var = initVar(parent, id, type, readOnly, varEvent); if (initValue(var, min, max, 0)) { //no pointer - mdl->setValue(var, value, mdl->setValueRowNr); //does onChange if needed, if var in table, update the table row + Variable(var).setValue(value, mdl->setValueRowNr); //does onChange if needed, if var in table, update the table row } return var; @@ -183,7 +183,7 @@ class SysModUI: public SysModule { JsonObject var = initVar(parent, id, type, readOnly, varEvent); if (initValue(var, min, max, int(value))) { - mdl->setValue(var, *value, mdl->setValueRowNr); //does onChange if needed, if var in table, update the table row + Variable(var).setValue(*value, mdl->setValueRowNr); //does onChange if needed, if var in table, update the table row } return var; @@ -202,7 +202,7 @@ class SysModUI: public SysModule { if (initValue(var, min, max, (int)values)) { uint8_t rowNrL = 0; for (Type value: *values) { //loop over vector - mdl->setValue(var, value, rowNrL); //does onChange if needed, if var in table, update the table row + Variable(var).setValue(value, rowNrL); //does onChange if needed, if var in table, update the table row rowNrL++; } } @@ -222,7 +222,7 @@ class SysModUI: public SysModule { if (initValue(var, min, max, (int)values)) { uint8_t rowNrL = 0; for (VectorString value: *values) { //loop over vector - mdl->setValue(var, JsonString(value.s, JsonString::Copied), rowNrL); //does onChange if needed, if var in table, update the table row + Variable(var).setValue(JsonString(value.s, JsonString::Copied), rowNrL); //does onChange if needed, if var in table, update the table row rowNrL++; } } diff --git a/src/Sys/SysModWeb.cpp b/src/Sys/SysModWeb.cpp index 4410a61..31c992c 100644 --- a/src/Sys/SysModWeb.cpp +++ b/src/Sys/SysModWeb.cpp @@ -57,7 +57,7 @@ void SysModWeb::setup() { ui->initNumber(tableVar, "nr", UINT16_MAX, 0, 999, true, [this](EventArguments) { switch (eventType) { case onSetValue: { uint8_t rowNr = 0; for (auto &client:ws.getClients()) - mdl->setValue(variable.var, client->id(), rowNr++); + variable.setValue(client->id(), rowNr++); return true; } default: return false; }}); @@ -65,7 +65,7 @@ void SysModWeb::setup() { ui->initText(tableVar, "ip", nullptr, 16, true, [this](EventArguments) { switch (eventType) { case onSetValue: { uint8_t rowNr = 0; for (auto &client:ws.getClients()) - mdl->setValue(variable.var, JsonString(client->remoteIP().toString().c_str(), JsonString::Copied), rowNr++); + variable.setValue(JsonString(client->remoteIP().toString().c_str(), JsonString::Copied), rowNr++); return true; } default: return false; }}); @@ -74,7 +74,7 @@ void SysModWeb::setup() { ui->initCheckBox(tableVar, "full", UINT8_MAX, true, [this](EventArguments) { switch (eventType) { case onSetValue: { uint8_t rowNr = 0; for (auto &client:ws.getClients()) - mdl->setValue(variable.var, client->queueIsFull(), rowNr++); + variable.setValue(client->queueIsFull(), rowNr++); return true; } default: return false; }}); @@ -82,7 +82,7 @@ void SysModWeb::setup() { ui->initSelect(tableVar, "status", UINT8_MAX, true, [this](EventArguments) { switch (eventType) { case onSetValue: { uint8_t rowNr = 0; for (auto &client:ws.getClients()) - mdl->setValue(variable.var, client->status(), rowNr++); + variable.setValue(client->status(), rowNr++); return true; } case onUI: { @@ -99,7 +99,7 @@ void SysModWeb::setup() { ui->initNumber(tableVar, "length", UINT16_MAX, 0, WS_MAX_QUEUED_MESSAGES, true, [this](EventArguments) { switch (eventType) { case onSetValue: { uint8_t rowNr = 0; for (auto &client:ws.getClients()) - mdl->setValue(variable.var, client->queueLen(), rowNr++); + variable.setValue(client->queueLen(), rowNr++); return true; } default: return false; }}); @@ -108,7 +108,7 @@ void SysModWeb::setup() { ui->initText(parentVar, "WSSend", nullptr, 16, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "#: %d /s T: %d B/s B:%d B/s", sendWsCounter, sendWsTBytes, sendWsBBytes); + variable.setValueF("#: %d /s T: %d B/s B:%d B/s", sendWsCounter, sendWsTBytes, sendWsBBytes); sendWsCounter = 0; sendWsTBytes = 0; sendWsBBytes = 0; @@ -117,7 +117,7 @@ void SysModWeb::setup() { ui->initText(parentVar, "WSRecv", nullptr, 16, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "#: %d /s %d B/s", recvWsCounter, recvWsBytes); + variable.setValueF("#: %d /s %d B/s", recvWsCounter, recvWsBytes); recvWsCounter = 0; recvWsBytes = 0; return true; @@ -126,7 +126,7 @@ void SysModWeb::setup() { ui->initText(parentVar, "UDPSend", nullptr, 16, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "#: %d /s %d B/s", sendUDPCounter, sendUDPBytes); + variable.setValueF("#: %d /s %d B/s", sendUDPCounter, sendUDPBytes); sendUDPCounter = 0; sendUDPBytes = 0; return true; @@ -135,7 +135,7 @@ void SysModWeb::setup() { ui->initText(parentVar, "UDPRecv", nullptr, 16, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "#: %d /s %d B/s", recvUDPCounter, recvUDPBytes); + variable.setValueF("#: %d /s %d B/s", recvUDPCounter, recvUDPBytes); recvUDPCounter = 0; recvUDPBytes = 0; default: return false; diff --git a/src/User/UserModE131.h b/src/User/UserModE131.h index 39ef064..4650b5d 100644 --- a/src/User/UserModE131.h +++ b/src/User/UserModE131.h @@ -51,7 +51,7 @@ class UserModE131:public SysModule { ui->initNumber(tableVar, "channel", UINT16_MAX, 1, 512, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNr = 0; rowNr < varsToWatch.size(); rowNr++) - mdl->setValue(variable.var, channel + varsToWatch[rowNr].channelOffset, rowNr); + variable.setValue(channel + varsToWatch[rowNr].channelOffset, rowNr); return true; default: return false; }}); @@ -59,7 +59,7 @@ class UserModE131:public SysModule { ui->initText(tableVar, "variable", nullptr, 32, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNr = 0; rowNr < varsToWatch.size(); rowNr++) - mdl->setValue(variable.var, varsToWatch[rowNr].id, rowNr); + variable.setValue(varsToWatch[rowNr].id, rowNr); return true; default: return false; }}); @@ -67,7 +67,7 @@ class UserModE131:public SysModule { ui->initNumber(tableVar, "max", UINT16_MAX, 0, UINT16_MAX, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNr = 0; rowNr < varsToWatch.size(); rowNr++) - mdl->setValue(variable.var, varsToWatch[rowNr].max, rowNr); + variable.setValue(varsToWatch[rowNr].max, rowNr); return true; default: return false; }}); @@ -75,7 +75,7 @@ class UserModE131:public SysModule { ui->initNumber(tableVar, "value", UINT16_MAX, 0, 255, true, [this](EventArguments) { switch (eventType) { case onSetValue: for (size_t rowNr = 0; rowNr < varsToWatch.size(); rowNr++) - mdl->setValue(variable.var, varsToWatch[rowNr].savedValue, rowNr); + variable.setValue(varsToWatch[rowNr].savedValue, rowNr); return true; default: return false; }}); diff --git a/src/User/UserModLive.cpp b/src/User/UserModLive.cpp index faddaf9..f50b6cd 100644 --- a/src/User/UserModLive.cpp +++ b/src/User/UserModLive.cpp @@ -167,13 +167,13 @@ static float _time(float j) { ui->initText(parentVar, "fps1", nullptr, 10, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "%.0f /s", fps, 0); //0 is to force format overload used + variable.setValueF("%.0f /s", fps, 0); //0 is to force format overload used return true; default: return false; }}); ui->initText(parentVar, "fps2", nullptr, 10, true, [this](EventArguments) { switch (eventType) { case onLoop1s: - mdl->setValue(variable.var, "%d /s", frameCounter, 0); //0 is to force format overload used + variable.setValueF("%d /s", frameCounter, 0); //0 is to force format overload used frameCounter = 0; return true; default: return false; @@ -187,7 +187,7 @@ static float _time(float j) { rowNr = 0; for (Executable &exec: scriptRuntime._scExecutables) { const char *name = exec.name.c_str(); - mdl->setValue(variable.var, JsonString(exec.name.c_str(), JsonString::Copied), rowNr++); + variable.setValue(JsonString(exec.name.c_str(), JsonString::Copied), rowNr++); } return true; default: return false; @@ -198,7 +198,7 @@ static float _time(float j) { variable.var["value"].to(); web->addResponse(variable.var, "value", variable.value()); // empty the value rowNr = 0; for (Executable &exec: scriptRuntime._scExecutables) { - mdl->setValue(variable.var, exec.isRunning(), rowNr++); + variable.setValue(exec.isRunning(), rowNr++); } return true; default: return false; @@ -209,7 +209,7 @@ static float _time(float j) { variable.var["value"].to(); web->addResponse(variable.var, "value", variable.value()); // empty the value rowNr = 0; for (Executable &exec: scriptRuntime._scExecutables) { - mdl->setValue(variable.var, exec.isHalted, rowNr++); + variable.setValue(exec.isHalted, rowNr++); } return true; default: return false; @@ -220,7 +220,7 @@ static float _time(float j) { variable.var["value"].to(); web->addResponse(variable.var, "value", variable.value()); // empty the value rowNr = 0; for (Executable &exec: scriptRuntime._scExecutables) { - mdl->setValue(variable.var, exec.exeExist, rowNr++); + variable.setValue(exec.exeExist, rowNr++); } return true; default: return false; @@ -231,7 +231,7 @@ static float _time(float j) { variable.var["value"].to(); web->addResponse(variable.var, "value", variable.value()); // empty the value rowNr = 0; for (Executable &exec: scriptRuntime._scExecutables) { - mdl->setValue(variable.var, exec.__run_handle_index, rowNr++); + variable.setValue(exec.__run_handle_index, rowNr++); } return true; default: return false; @@ -245,7 +245,7 @@ static float _time(float j) { exe_info exeInfo = scriptRuntime.getExecutableInfo(exec.name); char text[30]; print->fFormat(text, sizeof(text), "%d+%d=%d B", exeInfo.binary_size, exeInfo.data_size, exeInfo.total_size); - mdl->setValue(variable.var, JsonString(text, JsonString::Copied), rowNr++); + variable.setValue(JsonString(text, JsonString::Copied), rowNr++); } return true; default: return false; diff --git a/src/User/UserModMPU6050.h b/src/User/UserModMPU6050.h index 0e5025f..632bfbc 100644 --- a/src/User/UserModMPU6050.h +++ b/src/User/UserModMPU6050.h @@ -48,7 +48,7 @@ class UserModMPU6050: public SysModule { variable.setComment("in degrees"); return true; case onLoop1s: - mdl->setValue(variable.var, gyro); //automatic as var is referenced??? + variable.setValue(gyro); //automatic as var is referenced??? return true; default: return false; }}); @@ -58,7 +58,7 @@ class UserModMPU6050: public SysModule { variable.setComment("in m/sĀ²"); return true; case onLoop1s: - mdl->setValue(variable.var, accell); //automatic as var is referenced??? + variable.setValue(accell); //automatic as var is referenced??? return true; default: return false; }}); diff --git a/src/User/UserModMidi.h b/src/User/UserModMidi.h new file mode 100644 index 0000000..1d7d5ac --- /dev/null +++ b/src/User/UserModMidi.h @@ -0,0 +1,45 @@ +/* + @title StarBase + @file UserModMidi.h + @date 20241105 + @repo https://github.com/ewowi/StarBase, submit changes to this file as PRs to ewowi/StarBase + @Authors https://github.com/ewowi/StarBase/commits/main + @Copyright Ā© 2024 Github StarBase Commit Authors + @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com +*/ + +// #include + +class UserModMidi:public SysModule { + +public: + + UserModMidi() :SysModule("Midi") { + }; + + void setup() { + SysModule::setup(); + + // UsbMidi_Setup(); + // esp32_usb_midi.begin(); // Initialize USB MIDI + + } + + void onOffChanged() { + if (mdls->isConnected && isEnabled) { + + + } else { + } + } + + void loop() { + // if (esp32_usb_midi.available()) { + // esp32_usb_midi.read(); // Read MIDI data + // } + } + +}; + +extern UserModMidi *midi; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 300625b..6d864a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,6 +48,10 @@ AppModDemo *appModDemo; #include "User/UserModMPU6050.h" UserModMPU6050 *mpu6050; #endif +#ifdef STARBASE_USERMOD_MIDI + #include "User/UserModMidi.h" + UserModMidi *midi; +#endif #ifdef STARBASE_USERMOD_LIVE #include "User/UserModLive.h" UserModLive *liveM; @@ -77,6 +81,9 @@ void setup() { #ifdef STARBASE_USERMOD_MPU6050 mpu6050 = new UserModMPU6050(); #endif + #ifdef STARBASE_USERMOD_MIDI + midi = new UserModMidi(); + #endif #ifdef STARBASE_USERMOD_LIVE liveM = new UserModLive(); #endif @@ -102,6 +109,9 @@ void setup() { #ifdef STARBASE_USERMOD_MPU6050 mdls->add(mpu6050); #endif + #ifdef STARBASE_USERMOD_MIDI + mdls->add(midi); + #endif mdls->add(mdl); mdls->add(ui); mdls->add(mdns); //no ui