From 2b44eb392a000fa9a4a259f6f884cf8833eee808 Mon Sep 17 00:00:00 2001 From: alf45tar <35426671+alf45tar@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:03:42 +0200 Subject: [PATCH] Version 3.5.0 --- data/blueboard4.cfg | 1 + data/css/bootstrap.min.css.gz | Bin 31139 -> 31136 bytes data/js/Sortable.min.js.gz | Bin 14832 -> 14847 bytes data/js/bootstrap.bundle.min.js.gz | Bin 23802 -> 23823 bytes data/schema.json | 4 +- esp32_platform_version.py | 16 ++ platformio.ini | 85 ++++---- src/Config.h | 123 +++++++----- src/Controller.h | 311 +++++++++++++++++++++-------- src/DisplayOLED.h | 14 +- src/DisplayTFT.h | 50 ++++- src/Pedalino.h | 55 +++-- src/PedalinoMini.cpp | 121 +++++++---- src/USBMidiIn.h | 12 +- src/Version.h | 4 +- src/WebConfigAsync.h | 149 +++++++++++--- 16 files changed, 660 insertions(+), 285 deletions(-) create mode 100644 data/blueboard4.cfg create mode 100644 esp32_platform_version.py diff --git a/data/blueboard4.cfg b/data/blueboard4.cfg new file mode 100644 index 0000000..13bb029 --- /dev/null +++ b/data/blueboard4.cfg @@ -0,0 +1 @@ +{"Pedals":[{"Pedal":1,"Mode":"Momentary 1","InvertPolarity":false,"PressMode":"1","LatchEmulation":true,"AnalogResponse":"Linear","Min":0,"Max":127,"Easing":0.001,"ActivityThreshold":32,"AutoSensing":false},{"Pedal":2,"Mode":"Momentary 1","InvertPolarity":false,"PressMode":"1","LatchEmulation":true,"AnalogResponse":"Linear","Min":0,"Max":127,"Easing":0.001,"ActivityThreshold":32,"AutoSensing":false},{"Pedal":3,"Mode":"Momentary 1","InvertPolarity":false,"PressMode":"1","LatchEmulation":true,"AnalogResponse":"Linear","Min":0,"Max":127,"Easing":0.001,"ActivityThreshold":32,"AutoSensing":false},{"Pedal":4,"Mode":"Momentary 1","InvertPolarity":false,"PressMode":"1","LatchEmulation":true,"AnalogResponse":"Linear","Min":0,"Max":127,"Easing":0.001,"ActivityThreshold":32,"AutoSensing":false},{"Pedal":5,"Mode":"None","InvertPolarity":false,"PressMode":"None","LatchEmulation":false,"AnalogResponse":"Linear","Min":0,"Max":1023,"Easing":0.001,"ActivityThreshold":2,"AutoSensing":false},{"Pedal":6,"Mode":"None","InvertPolarity":false,"PressMode":"None","LatchEmulation":false,"AnalogResponse":"Linear","Min":1023,"Max":0,"Easing":0.01,"ActivityThreshold":8,"AutoSensing":true},{"Pedal":7,"Mode":"Momentary 1","InvertPolarity":false,"PressMode":"1","LatchEmulation":false,"AnalogResponse":"Linear","Min":0,"Max":127,"Easing":0.001,"ActivityThreshold":32,"AutoSensing":false},{"Pedal":8,"Mode":"Momentary 1","InvertPolarity":false,"PressMode":"12L","LatchEmulation":false,"AnalogResponse":"Linear","Min":0,"Max":127,"Easing":0.001,"ActivityThreshold":32,"AutoSensing":false}],"Controls":[{"Control":1,"Pedal1":1,"Button1":1,"Pedal2":0,"Button2":0,"Led":7},{"Control":2,"Pedal1":2,"Button1":1,"Pedal2":0,"Button2":0,"Led":5},{"Control":3,"Pedal1":3,"Button1":1,"Pedal2":0,"Button2":0,"Led":3},{"Control":4,"Pedal1":4,"Button1":1,"Pedal2":0,"Button2":0,"Led":1},{"Control":5,"Pedal1":5,"Button1":1,"Pedal2":0,"Button2":0,"Led":7},{"Control":6,"Pedal1":6,"Button1":1,"Pedal2":0,"Button2":0,"Led":8},{"Control":37,"Pedal1":7,"Button1":1,"Pedal2":0,"Button2":0,"Led":0},{"Control":38,"Pedal1":8,"Button1":1,"Pedal2":0,"Button2":0,"Led":0}],"BankNames":[{"Bank":0,"Name":"Global"},{"Bank":1,"Name":":Mode 1"},{"Bank":2,"Name":":Mode 2"},{"Bank":3,"Name":""},{"Bank":4,"Name":""},{"Bank":5,"Name":""},{"Bank":6,"Name":""},{"Bank":7,"Name":""},{"Bank":8,"Name":""},{"Bank":9,"Name":""},{"Bank":10,"Name":""},{"Bank":11,"Name":""},{"Bank":12,"Name":""},{"Bank":13,"Name":""},{"Bank":14,"Name":""},{"Bank":15,"Name":""},{"Bank":16,"Name":""},{"Bank":17,"Name":""},{"Bank":18,"Name":""},{"Bank":19,"Name":""},{"Bank":20,"Name":""}],"Actions":[{"Bank":0,"Control":37,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"","NameOn":"","Slot":0,"Event":"Press","Message":"Bank+","Channel":1,"Code":0,"Value1":1,"Value2":2,"OSCAddress":""},{"Bank":0,"Control":38,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"","NameOn":"","Slot":0,"Event":"Click","Message":"Profile+","Channel":1,"Code":0,"Value1":1,"Value2":3,"OSCAddress":""},{"Bank":0,"Control":38,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"","NameOn":"","Slot":0,"Event":"Double Click","Message":"Power On/Off","Channel":1,"Code":0,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":0,"Control":38,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"","NameOn":"","Slot":0,"Event":"Long Press","Message":"Device Info","Channel":1,"Code":0,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":1,"Control":1,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ A ]","Slot":0,"Event":"Press","Message":"Note On","Channel":1,"Code":60,"Value1":0,"Value2":100,"OSCAddress":""},{"Bank":1,"Control":1,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> A <","NameOn":"","Slot":0,"Event":"Release","Message":"Note Off","Channel":1,"Code":60,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":1,"Control":2,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ B ]","Slot":2,"Event":"Press","Message":"Note On","Channel":1,"Code":62,"Value1":0,"Value2":100,"OSCAddress":""},{"Bank":1,"Control":2,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> B <","NameOn":"","Slot":2,"Event":"Release","Message":"Note Off","Channel":1,"Code":62,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":1,"Control":3,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ C ]","Slot":3,"Event":"Press","Message":"Note On","Channel":1,"Code":64,"Value1":0,"Value2":100,"OSCAddress":""},{"Bank":1,"Control":3,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> C <","NameOn":"","Slot":3,"Event":"Release","Message":"Note Off","Channel":1,"Code":64,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":1,"Control":4,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ D ]","Slot":5,"Event":"Press","Message":"Note On","Channel":1,"Code":65,"Value1":0,"Value2":100,"OSCAddress":""},{"Bank":1,"Control":4,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> D <","NameOn":"","Slot":5,"Event":"Release","Message":"Note Off","Channel":1,"Code":65,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":2,"Control":1,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ A ]","Slot":0,"Event":"Press","Message":"Control Change","Channel":1,"Code":20,"Value1":0,"Value2":127,"OSCAddress":""},{"Bank":2,"Control":1,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> A <","NameOn":"","Slot":0,"Event":"Release","Message":"Control Change","Channel":1,"Code":20,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":2,"Control":2,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ B ]","Slot":2,"Event":"Press","Message":"Control Change","Channel":1,"Code":21,"Value1":0,"Value2":127,"OSCAddress":""},{"Bank":2,"Control":2,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> B <","NameOn":"","Slot":2,"Event":"Release","Message":"Control Change","Channel":1,"Code":21,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":2,"Control":3,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ C ]","Slot":3,"Event":"Press","Message":"Control Change","Channel":1,"Code":22,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":2,"Control":3,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> C <","NameOn":"","Slot":3,"Event":"Release","Message":"Control Change","Channel":1,"Code":22,"Value1":127,"Value2":0,"OSCAddress":""},{"Bank":2,"Control":4,"Led":255,"Color0":"#000000","Color1":"#0433ff","NameOff":"","NameOn":"[ D ]","Slot":5,"Event":"Press","Message":"Control Change","Channel":1,"Code":23,"Value1":0,"Value2":0,"OSCAddress":""},{"Bank":2,"Control":4,"Led":255,"Color0":"#000000","Color1":"#000000","NameOff":"> D <","NameOn":"","Slot":5,"Event":"Release","Message":"Control Change","Channel":1,"Code":23,"Value1":127,"Value2":0,"OSCAddress":""}]} \ No newline at end of file diff --git a/data/css/bootstrap.min.css.gz b/data/css/bootstrap.min.css.gz index cc414b52df56b60ae9da9457b6450ce435b19d30..07c2e9b598c96ba1fb3ab188cb11af41737a30f8 100644 GIT binary patch literal 31136 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 U#Hq`@+ZR6Sky=TMcxZ_K2Y&*>RR910 literal 31139 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

khFKqy`!{{eEQ~{gCVj|GZ9Ec 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 Z&PNafd~Xus=J$sj<|<_8CJ7$q{{!Vto74aR diff --git a/data/js/Sortable.min.js.gz b/data/js/Sortable.min.js.gz index a2320936d4ff15997a9f410fa499ce87cb3f480b..b5ea6f4fee0a84069c64b4890c7491eb295f82c3 100644 GIT binary patch literal 14847 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

jr5!+F${4UdOpAZK7z{${SdhyI4mC!(!326+YvQ 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 ZCEg_H&7&Bjzs$qM{{h;+ks(n#0RRqPz?c94 delta 21784 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 +SpiRamAllocator allocator; #endif bool control_not_defined (unsigned int c) { @@ -276,20 +281,15 @@ void spiffs_remove_profile(byte profile) { void spiffs_save_config(const String& filename, bool saveActions = true, bool savePedals = true, bool saveControls = true, bool saveInterfaces = true, bool saveSequences = true, bool saveOptions = true) { - uint32_t allocated; - #ifdef BOARD_HAS_PSRAM - allocated = 256*1024; - SpiRamJsonDocument jdoc(allocated); + JsonDocument jdoc(&allocator); #else - allocated = ESP.getMaxAllocHeap(); - DynamicJsonDocument jdoc(ESP.getMaxAllocHeap()); + JsonDocument jdoc; #endif - DPRINT("Memory allocated for JSON document: %d bytes\n", allocated); if (saveOptions) { - JsonArray jglobals = jdoc.createNestedArray("Globals"); - JsonObject jo = jglobals.createNestedObject(); + JsonArray jglobals = jdoc["Globals"].to(); + JsonObject jo = jglobals.add(); jo["Hostname"] = host; jo["BootMode"] = bootMode; jo["BLEServer"] = bleServer; @@ -339,18 +339,18 @@ void spiffs_save_config(const String& filename, bool saveActions = true, bool sa jo["OSCLocalPort"] = oscLocalPort; jo["OSCRemoteHost"] = oscRemoteHost; jo["OSCRemotePort"] = oscRemotePort; - JsonArray jladder = jdoc.createNestedArray("Ladder"); + JsonArray jladder = jdoc["Ladder"].to(); for (byte s = 0; s < LADDER_STEPS + 1; s++) { - JsonObject jo = jladder.createNestedObject(); + JsonObject jo = jladder.add(); jo["Step"] = s + 1; jo["Level"] = ladderLevels[s]; } } if (savePedals) { - JsonArray jpedals = jdoc.createNestedArray("Pedals"); + JsonArray jpedals = jdoc["Pedals"].to(); for (byte p = 0; p < PEDALS; p++) { - JsonObject jo = jpedals.createNestedObject(); + JsonObject jo = jpedals.add(); jo["Pedal"] = p + 1; jo["Mode"] = pedalModeName[pedals[p].mode]; jo["InvertPolarity"] = (pedals[p].invertPolarity == PED_ENABLE); @@ -366,10 +366,10 @@ void spiffs_save_config(const String& filename, bool saveActions = true, bool sa } if (saveControls) { - JsonArray jpedals = jdoc.createNestedArray("Controls"); + JsonArray jpedals = jdoc["Controls"].to(); for (byte c = 0; c < CONTROLS; c++) { if (control_not_defined(c)) continue; - JsonObject jo = jpedals.createNestedObject(); + JsonObject jo = jpedals.add(); jo["Control"] = c + 1; jo["Pedal1"] = (controls[c].pedal1 == PEDALS ? 0 : controls[c].pedal1 + 1); jo["Button1"] = (controls[c].button1 == LADDER_STEPS ? 0 : controls[c].button1 + 1); @@ -380,20 +380,20 @@ void spiffs_save_config(const String& filename, bool saveActions = true, bool sa } if (saveActions) { - JsonArray jbnames = jdoc.createNestedArray("BankNames"); + JsonArray jbnames = jdoc["BankNames"].to(); for (byte b = 0; b < BANKS; b++) { - JsonObject jo = jbnames.createNestedObject(); + JsonObject jo = jbnames.add(); jo["Bank"] = b; jo["Name"] = banknames[b]; } - JsonArray jactions = jdoc.createNestedArray("Actions"); + JsonArray jactions = jdoc["Actions"].to(); for (byte b = 0; b < BANKS; b++) { action *act = actions[b]; while (act != nullptr) { char color[8]; - JsonObject jo = jactions.createNestedObject(); + JsonObject jo = jactions.add(); jo["Bank"] = b; jo["Control"] = act->control + 1; jo["Led"] = (act->led == LEDS ? 0 : (act->led == 255 ? 255 : act->led + 1)); @@ -417,9 +417,9 @@ void spiffs_save_config(const String& filename, bool saveActions = true, bool sa } if (saveInterfaces) { - JsonArray jinterfaces = jdoc.createNestedArray("Interfaces"); + JsonArray jinterfaces = jdoc["Interfaces"].to(); for (byte i = 0; i < INTERFACES; i++) { - JsonObject jo = jinterfaces.createNestedObject(); + JsonObject jo = jinterfaces.add(); jo["Interface"] = i + 1; jo["Name"] = interfaces[i].name; jo["In"] = (IS_INTERFACE_ENABLED(interfaces[i].midiIn)); @@ -432,14 +432,21 @@ void spiffs_save_config(const String& filename, bool saveActions = true, bool sa } if (saveSequences) { - JsonArray jsequences = jdoc.createNestedArray("Sequences"); + JsonArray jsequences = jdoc["Sequences"].to(); for (byte s = 0; s < SEQUENCES; s++) { for (byte t = 0; t < STEPS; t++) { - JsonObject jo = jsequences.createNestedObject(); + JsonObject jo = jsequences.add(); jo["Sequence"] = s + 1; jo["Step"] = t + 1; jo["Message"] = ActionEnumToString(sequences[s][t].midiMessage); - jo["Channel"] = sequences[s][t].midiChannel; + switch (sequences[s][t].midiMessage) { + case PED_SEQUENCE: + jo["Channel"] = sequences[s][t].midiChannel + 1; + break; + default: + jo["Channel"] = sequences[s][t].midiChannel; + break; + } jo["Code"] = sequences[s][t].midiCode; jo["Value"] = sequences[s][t].midiValue; jo["Led"] = (sequences[s][t].led == LEDS ? 0 : (sequences[s][t].led == 255 ? 255 : sequences[s][t].led + 1)); @@ -516,16 +523,11 @@ void spiffs_save_profile(byte profile) { void spiffs_load_config(const String& filename, bool loadActions = true, bool loadPedals = true, bool loadControls = true, bool loadInterfaces = true, bool loadSequences = true, bool loadOptions = true, bool append = false) { - uint32_t allocated; - #ifdef BOARD_HAS_PSRAM - allocated = 256*1024; - SpiRamJsonDocument jdoc(allocated); + JsonDocument jdoc(&allocator); #else - allocated = ESP.getMaxAllocHeap(); - DynamicJsonDocument jdoc(ESP.getMaxAllocHeap()); + JsonDocument jdoc; #endif - DPRINT("Memory allocated for JSON document: %d bytes\n", allocated); DPRINT("Reading %s from SPIFFS ... ", filename.c_str()); File file = SPIFFS.open(filename, FILE_READ); @@ -543,11 +545,6 @@ void spiffs_load_config(const String& filename, bool loadActions = true, bool lo file.close(); DPRINT("done\n"); -#ifndef BOARD_HAS_PSRAM - jdoc.shrinkToFit(); - DPRINT("Memory used by JSON document: %d bytes\n", jdoc.memoryUsage()); -#endif - #ifdef DEBUG_ESP_PORT serializeJson(jdoc, SERIALDEBUG); #endif @@ -786,7 +783,14 @@ void spiffs_load_config(const String& filename, bool loadActions = true, bool lo t = constrain(t, 0, STEPS - 1); sequences[s][t].midiMessage = ActionStringToEnum(jo["Message"]); sequences[s][t].midiChannel = jo["Channel"]; - sequences[s][t].midiChannel = constrain(sequences[s][t].midiChannel, 0, 17); + switch (sequences[s][t].midiMessage) { + case PED_SEQUENCE: + sequences[s][t].midiChannel = constrain(sequences[s][t].midiChannel - 1, 0, SEQUENCES - 1); + break; + default: + sequences[s][t].midiChannel = constrain(sequences[s][t].midiChannel, 0, 17); + break; + } sequences[s][t].midiCode = jo["Code"]; sequences[s][t].midiCode = constrain(sequences[s][t].midiCode, 0, MIDI_RESOLUTION - 1); sequences[s][t].midiValue = jo["Value"]; @@ -840,8 +844,8 @@ void load_factory_default() wifiPassword = ""; ssidSoftAP = String("Pedalino-") + getChipId(); passwordSoftAP = getChipId(); - httpUsername = "admin"; - httpPassword = getChipId(); + httpUsername = ""; + httpPassword = ""; theme = "bootstrap"; currentBank = 1; currentProfile = 0; @@ -889,6 +893,8 @@ void load_factory_default() nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr }; } @@ -985,6 +991,8 @@ void load_factory_default() nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr }; pedals[PEDALS-1].pressMode = PED_PRESS_1_2_L; @@ -1079,6 +1087,8 @@ void load_factory_default() nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr }; action *act; @@ -1194,12 +1204,12 @@ void load_factory_default() } // TC-Helicon Switch 6 - ladderLevels[0] = 352; - ladderLevels[1] = 533; - ladderLevels[2] = 640; - ladderLevels[3] = 723; - ladderLevels[4] = 806; - ladderLevels[5] = 908; + ladderLevels[0] = 352/2; + ladderLevels[1] = 533/2; + ladderLevels[2] = 640/2; + ladderLevels[3] = 723/2; + ladderLevels[4] = 806/2; + ladderLevels[5] = 908/2; ladderLevels[6] = ADC_RESOLUTION - 1; } @@ -1283,7 +1293,7 @@ void eeprom_update_ap_wifi_credentials(const String& ssid = String("Pedalino-") #endif } -void eeprom_update_login_credentials(const String& username = "admin", const String& password = getChipId()) +void eeprom_update_login_credentials(const String& username = "", const String& password = "") { #ifdef NVS DPRINT("Updating NVS ... "); @@ -1537,9 +1547,12 @@ void eeprom_update_profile(byte profile = currentProfile) pedals_copy[i].pedalValue[1] = 0; pedals_copy[i].lastUpdate[0] = 0; pedals_copy[i].lastUpdate[1] = 0; - pedals_copy[i].analogPedal = nullptr; + for (byte j = 0; j < ADC_INPUTS; j++) + pedals_copy[i].analogPedal[j] = nullptr; pedals_copy[i].jogwheel = nullptr; pedals_copy[i].buttonConfig = nullptr; + for (byte a = 0; a < 4; a++) + pedals_copy[i].ads[a] = nullptr; for (byte s = 0; s < LADDER_STEPS; s++) { pedals_copy[i].latchStatus[s] = 0; pedals_copy[i].button[s] = nullptr; @@ -1689,8 +1702,8 @@ void eeprom_read_global() void eeprom_read_profile(byte profile = currentProfile) { #ifdef NVS - controller_delete(); delete_actions(); + controller_delete(); DPRINT("Reading NVS Profile "); switch (profile) { case 0: @@ -1714,7 +1727,8 @@ void eeprom_read_profile(byte profile = currentProfile) pedals[i].pedalValue[1] = 0; pedals[i].lastUpdate[0] = 0; pedals[i].lastUpdate[1] = 0; - pedals[i].analogPedal = nullptr; + for (byte j = 0; j < ADC_INPUTS; j++) + pedals[i].analogPedal[j] = nullptr; pedals[i].analogPad = nullptr; pedals[i].jogwheel = nullptr; pedals[i].buttonConfig = nullptr; @@ -1756,12 +1770,13 @@ void eeprom_read_profile(byte profile = currentProfile) } } } + create_banks(); preferences.end(); DPRINT("done\n"); #else - controller_delete(); delete_actions(); + delete_controller(); spiffs_load_profile(profile); create_banks(); #endif diff --git a/src/Controller.h b/src/Controller.h index 736ad2e..38bee10 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -118,7 +118,8 @@ void leds_update_single(byte e, action *act, byte value, byte bank = currentBank case PED_PROGRAM_CHANGE_DEC: if (e == PED_EVENT_NONE) { - set_last_led_color(bank, led_control(act->control, act->led), act->color0, ledsOffBrightness); + set_last_led_color(bank, led_control(act->control, act->led), act->color0, ledsOffBrightness); + set_last_led_color(currentBank, led_control(act->control, act->led), act->color0, ledsOffBrightness); leds_refresh(led_control(act->control, act->led)); return; } @@ -774,7 +775,6 @@ void midi_send(byte message, byte code, byte value, byte channel, bool on_off, b { code = constrain(code, 0, MIDI_RESOLUTION - 1); value = constrain(value, 0, MIDI_RESOLUTION - 1); - channel = constrain(channel, 0, 17); bool channelMessage = (message == PED_NOTE_ON ) || (message == PED_NOTE_OFF ) || @@ -786,6 +786,8 @@ void midi_send(byte message, byte code, byte value, byte channel, bool on_off, b (message == PED_PITCH_BEND ) || (message == PED_CHANNEL_PRESSURE ); + if (channelMessage) channel = constrain(channel, 0, SEQUENCES); + if (channel == 0 && channelMessage) { switch (message) { @@ -1027,20 +1029,21 @@ void midi_send(byte message, byte code, byte value, byte channel, bool on_off, b case PED_SEQUENCE: - channel = constrain(channel, 1, SEQUENCES); + channel = constrain(channel, 0, SEQUENCES - 1); + DPRINT("\n"); DPRINT("=======================================================\n"); - DPRINT("SEQUENCE.....Number %2d\n", channel); + DPRINT("SEQUENCE.....Number %2d\n", channel + 1); DPRINT("-------------------------------------------------------\n"); for (byte s = 0; s < STEPS; s++) { - if (sequences[channel-1][s].midiMessage == PED_EMPTY) continue; - if (sequences[channel-1][s].midiMessage != PED_ACTION_LED_COLOR) { - midi_send(sequences[channel-1][s].midiMessage, sequences[channel-1][s].midiCode, sequences[channel-1][s].midiValue, sequences[channel-1][s].midiChannel, on_off, 0, MIDI_RESOLUTION - 1, bank, pedal, button, led); + if (sequences[channel][s].midiMessage == PED_EMPTY) continue; + if (sequences[channel][s].midiMessage != PED_ACTION_LED_COLOR) { + midi_send(sequences[channel][s].midiMessage, sequences[channel][s].midiCode, sequences[channel][s].midiValue, sequences[channel][s].midiChannel, on_off, 0, MIDI_RESOLUTION - 1, bank, pedal, button, led); } - byte l = (sequences[channel-1][s].led == 255 ? led : sequences[channel-1][s].led); + byte l = (sequences[channel][s].led == 255 ? led : sequences[channel][s].led); l = constrain(l, 0, LEDS); - fastleds[l] = sequences[channel-1][s].color; + fastleds[l] = sequences[channel][s].color; fastleds[l].nscale8(ledsOnBrightness); - if (sequences[channel-1][s].led != LEDS) { DPRINT("LED COLOR.....Led %2d......RGB Color #%02x%02x%02x\n", l + 1, fastleds[l].red, fastleds[l].green, fastleds[l].blue); } + if (sequences[channel][s].led != LEDS) { DPRINT("LED COLOR.....Led %2d......RGB Color #%02x%02x%02x\n", l + 1, fastleds[l].red, fastleds[l].green, fastleds[l].blue); } fastleds[l] = swap_rgb_order(fastleds[l], rgbOrder); FastLED.show(); lastLedColor[currentBank][l] = fastleds[l]; @@ -1053,21 +1056,21 @@ void midi_send(byte message, byte code, byte value, byte channel, bool on_off, b case PED_SEQUENCE_STEP_BY_STEP_FWD: case PED_SEQUENCE_STEP_BY_STEP_REV: - channel = constrain(channel, 1, SEQUENCES); - byte step = constrain(code, 1, STEPS); - DPRINT("SEQUENCE.....Number %2d.....Step %2d\n", channel, step); - midi_send(sequences[channel-1][step-1].midiMessage, sequences[channel-1][step-1].midiCode, sequences[channel-1][step-1].midiValue, sequences[channel-1][step-1].midiChannel, on_off, 0, MIDI_RESOLUTION - 1, bank, pedal, button, led); - byte l = (sequences[channel-1][step-1].led == 255 ? led : sequences[channel-1][step-1].led); + channel = constrain(channel, 0, SEQUENCES - 1); + byte step = constrain(code, 0, STEPS - 1); + DPRINT("SEQUENCE.....Number %2d.....Step %2d\n", channel + 1, step + 1); + midi_send(sequences[channel][step].midiMessage, sequences[channel][step].midiCode, sequences[channel][step].midiValue, sequences[channel][step].midiChannel, on_off, 0, MIDI_RESOLUTION - 1, bank, pedal, button, led); + byte l = (sequences[channel][step].led == 255 ? led : sequences[channel][step].led); l = constrain(l, 0, LEDS); - fastleds[l] = sequences[channel-1][step-1].color; + fastleds[l] = sequences[channel][step].color; fastleds[l].nscale8(ledsOnBrightness); - if (sequences[channel-1][step-1].led != LEDS) { DPRINT("LED COLOR.....Led %2d......RGB Color #%02x%02x%02x\n", l + 1, fastleds[l].red, fastleds[l].green, fastleds[l].blue); } + if (sequences[channel][step].led != LEDS) { DPRINT("LED COLOR.....Led %2d......RGB Color #%02x%02x%02x\n", l + 1, fastleds[l].red, fastleds[l].green, fastleds[l].blue); } fastleds[l] = swap_rgb_order(fastleds[l], rgbOrder); FastLED.show(); lastLedColor[currentBank][l] = fastleds[l]; DPRINT("--------------------------------------------------\n"); - currentMIDIValue[bank][pedal][button] = channel; - lastMIDIMessage[currentBank] = {(byte)(message == PED_SEQUENCE_STEP_BY_STEP_FWD ? PED_SEQUENCE_STEP_BY_STEP_FWD : PED_SEQUENCE_STEP_BY_STEP_REV), code, value, channel}; + //currentMIDIValue[bank][pedal][button] = channel; + //lastMIDIMessage[currentBank] = {(byte)(message == PED_SEQUENCE_STEP_BY_STEP_FWD ? PED_SEQUENCE_STEP_BY_STEP_FWD : PED_SEQUENCE_STEP_BY_STEP_REV), code, value, channel}; break; } } @@ -1087,34 +1090,36 @@ void fire_action(action* act, byte p, byte i, byte e) case PED_MIDI_START: case PED_MIDI_STOP: case PED_MIDI_CONTINUE: - case PED_SEQUENCE: midi_send(act->midiMessage, act->midiCode, act->midiValue1, act->midiChannel, true, act->midiValue1, act->midiValue2, currentBank, p, i); break; + case PED_SEQUENCE: + midi_send(act->midiMessage, act->midiCode, act->midiValue1, act->midiChannel - 1, true, act->midiValue1, act->midiValue2, currentBank, p, i); + break; + case PED_SEQUENCE_STEP_BY_STEP_FWD: case PED_SEQUENCE_STEP_BY_STEP_REV: act->midiChannel = constrain(act->midiChannel, 1, SEQUENCES); - act->midiCode = constrain(act->midiCode, 0, STEPS); + act->midiCode = constrain(act->midiCode, 0, STEPS - 1); + act->midiCode = (sequences[act->midiChannel - 1][act->midiCode].midiMessage == PED_EMPTY) ? 0 : act->midiCode; + if (sequences[act->midiChannel - 1][0].midiMessage == PED_EMPTY) break; + midi_send(act->midiMessage, act->midiCode, act->midiValue1, act->midiChannel - 1, true, act->midiValue1, act->midiValue2, currentBank, p, i, led_control(act->control, act->led)); switch (act->midiMessage) { case PED_SEQUENCE_STEP_BY_STEP_FWD: - act->midiCode = act->midiCode % STEPS + 1; - act->midiCode = (sequences[act->midiChannel-1][act->midiCode-1].midiMessage == PED_EMPTY ? 1 : act->midiCode); + act->midiCode = (act->midiCode + 1 ) % STEPS; + act->midiCode = (sequences[act->midiChannel - 1][act->midiCode].midiMessage == PED_EMPTY ? 0 : act->midiCode); break; case PED_SEQUENCE_STEP_BY_STEP_REV: - if (act->midiCode <= 1) { - for (byte s = 0; s < STEPS; s++) { - if (sequences[act->midiChannel-1][s].midiMessage == PED_EMPTY) { - act->midiCode = s; - break; - } - if (s == (STEPS - 1)) act->midiCode = STEPS; + if (act->midiCode == 0) { + byte s; + for (s = 0; s < STEPS; s++) { + if (sequences[act->midiChannel - 1][s].midiMessage == PED_EMPTY) break; } + if (s > 0) act->midiCode = s - 1; } - else - act->midiCode = act->midiCode % (STEPS + 1) - 1; + else if (act->midiCode > 0) act->midiCode--; break; } - midi_send(act->midiMessage, act->midiCode, act->midiValue1, act->midiChannel, true, act->midiValue1, act->midiValue2, currentBank, p, i, led_control(act->control, act->led)); for (byte b = 0; b < BANKS; b++) { action *a = actions[b]; while ( a != nullptr) { @@ -1402,7 +1407,8 @@ void fire_action(action* act, byte p, byte i, byte e) #ifdef WIFI esp_wifi_stop(); #endif - adc_power_off(); + //adc_power_off(); + adc_power_release(); delay(200); rtc_gpio_pullup_en((gpio_num_t)PIN_D(p)); rtc_gpio_pulldown_dis((gpio_num_t)PIN_D(p)); @@ -1495,12 +1501,13 @@ void process_backlog() (controls[act->control].pedal2 == e->pedal) && (controls[act->control].button2 == e->button) ) ) && - (((act->event == e->event) || // Events match or - (act->event == PED_EVENT_PRESS_RELEASE) && ((e->event == PED_EVENT_PRESS) || (e->event == PED_EVENT_RELEASE)) // PRESS_RELEASE matches with PRESS or RELEASE - ) && - ((act->event == f->event) || // Events match or - (act->event == PED_EVENT_PRESS_RELEASE) && ((f->event == PED_EVENT_PRESS) || (f->event == PED_EVENT_RELEASE)) // PRESS_RELEASE matches with PRESS or RELEASE - ) + (((act->event == e->event) || // Events match or + (act->event == PED_EVENT_PRESS_RELEASE) && ((e->event == PED_EVENT_PRESS) || (e->event == PED_EVENT_RELEASE)) // PRESS_RELEASE matches with PRESS or RELEASE + ) && + ((act->event == f->event) || // Events match or + (act->event == PED_EVENT_PRESS_RELEASE) && ((f->event == PED_EVENT_PRESS) || (f->event == PED_EVENT_RELEASE)) // PRESS_RELEASE matches with PRESS or RELEASE + ) && + (e->event == f->event) ) ) { fire_action(act, e->pedal, e->button, e->event); @@ -1517,7 +1524,8 @@ void process_backlog() } } } - backlog.clear(); + for (std::list::iterator e = backlog.begin(); e != backlog.end(); ) + e->processed ? e = backlog.erase(e) : e++; } // @@ -1633,12 +1641,12 @@ void controller_event_handler_button(AceButton* button, uint8_t eventType, uint8 // // Trigger Actions on Analog Events // -void controller_event_handler_analog(byte pedal, int value) +void controller_event_handler_analog(byte pedal, byte button, int value) { bool global = actions[0] != nullptr; action *act = actions[0] == nullptr ? actions[currentBank] : actions[0]; while (act != nullptr) { - if (controls[act->control].pedal1 == pedal && (act->event == PED_EVENT_MOVE || act->event == PED_EVENT_SHOT)) { + if (controls[act->control].pedal1 == pedal && controls[act->control].button1 == button && (act->event == PED_EVENT_MOVE || act->event == PED_EVENT_SHOT)) { if (act->midiMessage == PED_ACTION_REPEAT) { value = map2(value, // map from [0, ADC_RESOLUTION-1] to [0, 127] MIDI value 0, @@ -1688,7 +1696,7 @@ void controller_event_handler_analog(byte pedal, int value) break; case PED_SEQUENCE: - midi_send(act->midiMessage, act->midiCode, value, act->midiChannel, true, act->midiValue1, act->midiValue2, currentBank, pedal); + midi_send(act->midiMessage, act->midiCode, value, act->midiChannel - 1, true, act->midiValue1, act->midiValue2, currentBank, pedal); set_led_color(led_control(act->control, act->led), act->color0, ledsOffBrightness, act->color1, ledsOnBrightness, value); FastLED.show(); lastLedColor[currentBank][led_control(act->control, act->led)] = fastleds[led_control(act->control, act->led)]; @@ -1767,29 +1775,67 @@ void refresh_analog(byte i, bool send) int input; int value; - static int direction = 0; - if (pedals[i].analogPedal == nullptr) return; // sanity check + if (pedals[i].analogPedal[0] == nullptr) return; // sanity check input = analogRead(PIN_A(i)); // read the raw analog input value if (pedals[i].autoSensing) { // continuos calibration if (pedals[i].expZero > (input + SAFE_ZONE)) { + pedals[i].expZero = constrain(input + SAFE_ZONE, SAFE_ZONE, ADC_RESOLUTION - 1 - SAFE_ZONE); + pedals[i].expMax = constrain(pedals[i].expMax, pedals[i].expZero, ADC_RESOLUTION - 1 - SAFE_ZONE); DPRINT("Pedal %2d calibration min %d\n", i + 1, input); } if (pedals[i].expMax < (input - SAFE_ZONE)) { + pedals[i].expMax = constrain(input - SAFE_ZONE, SAFE_ZONE, ADC_RESOLUTION - 1 - SAFE_ZONE); + pedals[i].expZero = constrain(pedals[i].expZero, SAFE_ZONE, pedals[i].expMax); DPRINT("Pedal %2d calibration max %d\n", i + 1, input); } - pedals[i].expZero = _min(pedals[i].expZero, input + SAFE_ZONE); - pedals[i].expMax = _max(pedals[i].expMax, input - SAFE_ZONE); - //DPRINT("%d -> [%d, %d]\n", input, pedals[i].expZero, pedals[i].expMax); } value = map_analog(i, input); // expand to [0, ADC_RESOLUTION-1] and apply the map function - pedals[i].analogPedal->update(value); // update the responsive analog average - if (pedals[i].analogPedal->hasChanged()) { // if the value changed since last time - value = pedals[i].analogPedal->getValue(); // get the responsive analog average value + pedals[i].analogPedal[0]->update(value); // update the responsive analog average + if (pedals[i].analogPedal[0]->hasChanged()) { // if the value changed since last time + value = pedals[i].analogPedal[0]->getValue(); // get the responsive analog average value double velocity = (1000.0 * (value - pedals[i].pedalValue[0])) / (micros() - pedals[i].lastUpdate[0]); DPRINT("Pedal %2d input %d output %d velocity %.2f\n", i + 1, input, value, velocity); - if (send) controller_event_handler_analog(i, value); + if (send) controller_event_handler_analog(i, 0, value); + pedals[i].pedalValue[0] = value; + pedals[i].lastUpdate[0] = micros(); + if (scannerActivated) { + scanPedal = i; + scanIndex = (scanIndex + 1) % POINTS; + scan[scanIndex] = input; + scanProcessed[scanIndex] = value; + } + } +} + +void refresh_analog4(int input, byte i, byte j, bool send) +{ + const int SAFE_ZONE = ADC_RESOLUTION / 20; // 5% of margin at both end of the scale + + int value; + + if (pedals[i].analogPedal[j] == nullptr) return; // sanity check + + if (pedals[i].autoSensing) { // continuos calibration + if (pedals[i].expZero > (input + SAFE_ZONE)) { + pedals[i].expZero = constrain(input + SAFE_ZONE, SAFE_ZONE, ADC_RESOLUTION - 1 - SAFE_ZONE); + pedals[i].expMax = constrain(pedals[i].expMax, pedals[i].expZero, ADC_RESOLUTION - 1 - SAFE_ZONE); + DPRINT("Pedal %2d/%2d calibration min %d\n", i + 1, j + 1, input); + } + if (pedals[i].expMax < (input - SAFE_ZONE)) { + pedals[i].expMax = constrain(input - SAFE_ZONE, SAFE_ZONE, ADC_RESOLUTION - 1 - SAFE_ZONE); + pedals[i].expZero = constrain(pedals[i].expZero, SAFE_ZONE, pedals[i].expMax); + DPRINT("Pedal %2d/%2d calibration max %d\n", i + 1, j + 1, input); + } + } + value = map_analog(i, input); // expand to [0, ADC_RESOLUTION-1] and apply the map function + pedals[i].analogPedal[j]->update(value); // update the responsive analog average + if (pedals[i].analogPedal[j]->hasChanged()) { // if the value changed since last time + value = pedals[i].analogPedal[j]->getValue(); // get the responsive analog average value + double velocity = (1000.0 * (value - pedals[i].pedalValue[j])) / (micros() - pedals[i].lastUpdate[j]); + DPRINT("Pedal %2d Button %2d input %d output %d velocity %.2f\n", i + 1, j + 1, input, value, velocity); + if (send) controller_event_handler_analog(i, j, value); pedals[i].pedalValue[0] = value; pedals[i].lastUpdate[0] = micros(); if (scannerActivated) { @@ -1831,12 +1877,12 @@ void refresh_ultrasonic(bool send) */ value = map_analog(i, input); // expand to [0, ADC_RESOLUTION-1] and apply the map function - pedals[i].analogPedal->update(value); // update the responsive analog average - if (pedals[i].analogPedal->hasChanged()) { // if the value changed since last time - value = pedals[i].analogPedal->getValue(); // get the responsive analog average value + pedals[i].analogPedal[0]->update(value); // update the responsive analog average + if (pedals[i].analogPedal[0]->hasChanged()) { // if the value changed since last time + value = pedals[i].analogPedal[0]->getValue(); // get the responsive analog average value double velocity = (1000.0 * (value - pedals[i].pedalValue[0])) / (micros() - pedals[i].lastUpdate[0]); DPRINT("Pedal %2d input %d output %d velocity %.2f\n", i + 1, input, value, velocity); - if (send) controller_event_handler_analog(i, value); + if (send) controller_event_handler_analog(i, 0, value); pedals[i].pedalValue[0] = value; pedals[i].lastUpdate[0] = micros(); if (scannerActivated) { @@ -1856,7 +1902,7 @@ void refresh_ultrasonic(bool send) void onAnalogPad(int id, int pressure) { pressure = map_analog(id, pressure); // expand to [0, ADC_RESOLUTION-1] and apply the map function - controller_event_handler_analog(id, pressure); + controller_event_handler_analog(id, 0, pressure); } @@ -1867,25 +1913,32 @@ void controller_setup(); // void controller_delete() { - for (byte i = 0; i < PEDALS; i++) { - if (pedals[i].analogPedal != nullptr) { - delete pedals[i].analogPedal; - pedals[i].analogPedal = nullptr; + for (byte i = 0; i < PEDALS; i++) + for (byte j = 0; j < ADC_INPUTS; j++) { + if (pedals[i].analogPedal[j] != nullptr) { + delete pedals[i].analogPedal[j]; + pedals[i].analogPedal[j] = nullptr; } - if (pedals[i].analogPad != nullptr) { + for (byte a = 0; a < 4; a++) { + if (pedals[i].ads[a] != nullptr) { + delete pedals[i].ads[a]; + pedals[i].ads[a] = nullptr; + } + } + if (pedals[i].analogPad != nullptr) { delete pedals[i].analogPad; pedals[i].analogPad = nullptr; } - if (pedals[i].jogwheel != nullptr) { + if (pedals[i].jogwheel != nullptr) { delete pedals[i].jogwheel; pedals[i].jogwheel = nullptr; } - if (pedals[i].buttonConfig != nullptr) { + if (pedals[i].buttonConfig != nullptr) { delete pedals[i].buttonConfig; pedals[i].buttonConfig = nullptr; } for (byte s = 0; s < LADDER_STEPS; s++) - if (pedals[i].button[s] != nullptr) { + if (pedals[i].button[s] != nullptr) { delete pedals[i].button[s]; pedals[i].button[s] = nullptr; } @@ -1899,10 +1952,16 @@ void controller_delete() // void controller_run(bool send = true) { + static byte adsChannel[ADC_BOARDS] = {0, 0, 0, 0}; + + while (controllerRunning) vTaskDelay(1/portTICK_PERIOD_MS); // wait for fist task to complete + controllerRunning = true; // block second tasks to run + if (saveProfile && send) { saveProfile = false; DPRINT("Saving profile ...\n"); eeprom_update_current_profile(currentProfile); + controllerRunning = false; return; } @@ -1939,6 +1998,7 @@ void controller_run(bool send = true) //OscControllerUpdate(); #endif DPRINT("... profile %d loaded.\n", currentProfile); + controllerRunning = false; return; } @@ -1952,6 +2012,7 @@ void controller_run(bool send = true) OscControllerUpdate(); #endif DPRINT("... configuration loaded.\n"); + controllerRunning = false; return; } @@ -1979,6 +2040,41 @@ void controller_run(bool send = true) refresh_analog(i, send); break; + case PED_ANALOG4: + for (byte a = 0; a < ADC_BOARDS; a++) { + + if (!ads1115Found[a]) continue; + + if (pedals[i].ads[a]->conversionComplete()) { // The ADS1115 provide 16 bits of data in binary two's complement format + int16_t result = pedals[i].ads[a]->getLastConversionResults(); // It returns value range from 0000h to 7FFFh when input is between 0V to positive Full Scale + // It returns value range from 8000h to FFFFh when input is between negative Full Scale to 0V + result = result < 0 ? 0 : result>>6; // The ADS1115 can still output negative values in case input is close to 0V + // Convert from 16 bits to 10 bits in case of positive values + refresh_analog4(result, i, adsChannel[a] * (a + 1), send); + // The ADS1115 contains an input multiplexer to connect signals to the internal ADC. + // Either four single-ended or two differential signals can be measured. + // When single-ended signals are measured, the negative input of the ADC is internally connected to GND by a switch within the multiplexer. + // Only one signal can be converted at time. + // Non-blocking start conversion function + adsChannel[a] = (adsChannel[a] + 1) % 4; + switch (adsChannel[a]) { + case 0: + pedals[i].ads[a]->startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_0, false); + break; + case 1: + pedals[i].ads[a]->startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_1, false); + break; + case 2: + pedals[i].ads[a]->startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_2, false); + break; + case 3: + pedals[i].ads[a]->startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_3, false); + break; + } + } + } + break; + case PED_ANALOG_PAD: if (pedals[i].analogPad != nullptr) { //int v = analogRead(PIN_A(i)); @@ -1986,7 +2082,7 @@ void controller_run(bool send = true) pedals[i].analogPad->singlePiezo(pedals[i].gain, pedals[i].expZero, pedals[i].scanCycles, pedals[i].holdCycles); //(sensitivity, threshold, scantime, masktime) if (pedals[i].analogPad->hit) { int pressure = map_analog(i, pedals[i].analogPad->velocity); // expand to [0, ADC_RESOLUTION-1] and apply the map function - controller_event_handler_analog(i, pressure); + controller_event_handler_analog(i, 0, pressure); } if (scannerActivated) { int v = analogRead(PIN_A(i)); @@ -2114,6 +2210,8 @@ void controller_run(bool send = true) if (backlog.size() > 0) process_backlog(); refresh_ultrasonic(send); + + controllerRunning = false; } @@ -2134,12 +2232,13 @@ void controller_setup() lastUsed = 0xFF; lastSlot = SLOTS; memset(lastPedalName, 0, MAXACTIONNAME+1); + controller_delete(); analogReadResolution(ADC_RESOLUTION_BITS); analogSetAttenuation(ADC_11db); - DPRINT("Bank %2d\n", currentBank + 1); + DPRINT("Bank %2d\n", currentBank); // Build new MIDI controllers setup for (byte i = 0; i < PEDALS; i++) { @@ -2151,6 +2250,7 @@ void controller_setup() case PED_LATCH1: DPRINT("LATCH1 "); break; case PED_LATCH2: DPRINT("LATCH2 "); break; case PED_ANALOG: DPRINT("ANALOG "); break; + case PED_ANALOG4: DPRINT("ANALOG4 "); break; case PED_ANALOG_PAD: DPRINT("ANALOG PAD "); break; case PED_JOG_WHEEL: DPRINT("JOG_WHEEL "); break; case PED_LADDER: DPRINT("LADDER "); break; @@ -2308,11 +2408,11 @@ void controller_setup() case PED_ANALOG: pinMode(PIN_D(i), OUTPUT); digitalWrite(PIN_D(i), HIGH); - pedals[i].analogPedal = new ResponsiveAnalogRead(PIN_A(i), true); - pedals[i].analogPedal->setAnalogResolution(ADC_RESOLUTION); - pedals[i].analogPedal->enableEdgeSnap(); - pedals[i].analogPedal->setSnapMultiplier(pedals[i].snapMultiplier); - pedals[i].analogPedal->setActivityThreshold(pedals[i].activityThreshold); + pedals[i].analogPedal[0] = new ResponsiveAnalogRead(PIN_A(i), true); + pedals[i].analogPedal[0]->setAnalogResolution(ADC_RESOLUTION); + pedals[i].analogPedal[0]->enableEdgeSnap(); + pedals[i].analogPedal[0]->setSnapMultiplier(pedals[i].snapMultiplier); + pedals[i].analogPedal[0]->setActivityThreshold(pedals[i].activityThreshold); if (lastUsedPedal == 0xFF) { lastUsedPedal = i; lastUsed = i; @@ -2322,6 +2422,45 @@ void controller_setup() DPRINT(" Pin A%d D%d", PIN_A(i), PIN_D(i)); break; + case PED_ANALOG4: + for (byte j = 0; j < ADC_INPUTS; j++) { + pedals[i].analogPedal[j] = new ResponsiveAnalogRead(PIN_A(i), true); + pedals[i].analogPedal[j]->setAnalogResolution(ADC_RESOLUTION); + pedals[i].analogPedal[j]->enableEdgeSnap(); + pedals[i].analogPedal[j]->setSnapMultiplier(pedals[i].snapMultiplier); + pedals[i].analogPedal[j]->setActivityThreshold(pedals[i].activityThreshold); + } + // The I2C bus operates at one of three speeds. Standard mode allows a clock frequency of up to 100 kHz; fast mode permits a clock frequency of up to 400 kHz; + // and high-speed mode (also called Hs mode) allows a clock frequency of up to 3.4 MHz. The ADS1115 are fully compatible with all three modes. + // ESP32 and ESP32-S3 supports only I2C standard and fast modes which can go up to 100kHz and 400kHz respectively. + // ESP32 and ESP32-S3 has 2 I2C controllers, responsible for handling communication on the I2C bus. A single I2C controller can be a master or a slave. + // Using 2nd I2C bus at 100kHz (default) as master + for (byte a = 0; a < ADC_BOARDS; a++) { + + pedals[i].ads[a] = new Adafruit_ADS1115(); + // Sets the gain to 1 for an input range of +/-4.096V + pedals[i].ads[a]->setGain(GAIN_ONE); + // Set data rate to 128 samples per second (default) + pedals[i].ads[a]->setDataRate(RATE_ADS1115_128SPS); + // Initialize the ADC for operation +#ifdef WIRE_HAS_END + Wire1.end(); +#endif + Wire1.setPins(PIN_D(i), PIN_A(i)); + ads1115Found[a] = pedals[i].ads[a]->begin(ADS1X15_ADDRESS + a, &Wire1); + // Non-blocking start conversion function + if (ads1115Found[a]) pedals[i].ads[a]->startADCReading(ADS1X15_REG_CONFIG_MUX_SINGLE_0, false); + } + if (lastUsedPedal == 0xFF) { + lastUsedPedal = i; + lastUsed = i; + lastSlot = SLOTS; + strlcpy(lastPedalName, banks[currentBank][i].pedalName, MAXACTIONNAME+1); + } + DPRINT(" I2C"); + for (byte a = 0; a < ADC_BOARDS; a++) ads1115Found[a] ? DPRINT(" %#04x", ADS1X15_ADDRESS + a) : DPRINT(" ----"); + break; + case PED_ANALOG_PAD: pinMode(PIN_A(i), INPUT); /* @@ -2376,22 +2515,22 @@ void controller_setup() case PED_ULTRASONIC: ultrasonicEcho.push_back(PIN_A(i)); if (ultrasonicTrigger == 0) ultrasonicTrigger = PIN_D(i); - pedals[i].analogPedal = new ResponsiveAnalogRead(); - pedals[i].analogPedal->setAnalogResolution(ADC_RESOLUTION); - pedals[i].analogPedal->enableSleep(); - pedals[i].analogPedal->enableEdgeSnap(); - pedals[i].analogPedal->setSnapMultiplier(pedals[i].snapMultiplier); - pedals[i].analogPedal->setActivityThreshold(pedals[i].activityThreshold); + pedals[i].analogPedal[0] = new ResponsiveAnalogRead(); + pedals[i].analogPedal[0]->setAnalogResolution(ADC_RESOLUTION); + pedals[i].analogPedal[0]->enableSleep(); + pedals[i].analogPedal[0]->enableEdgeSnap(); + pedals[i].analogPedal[0]->setSnapMultiplier(pedals[i].snapMultiplier); + pedals[i].analogPedal[0]->setActivityThreshold(pedals[i].activityThreshold); DPRINT(" Pin A%d (ECHO) D%d (TRIG)", PIN_A(i), PIN_D(i)); break; case PED_ANALOG_MOMENTARY: case PED_ANALOG_LATCH: - pedals[i].analogPedal = new ResponsiveAnalogRead(PIN_A(i), true); - pedals[i].analogPedal->setAnalogResolution(ADC_RESOLUTION); - pedals[i].analogPedal->enableEdgeSnap(); - pedals[i].analogPedal->setSnapMultiplier(pedals[i].snapMultiplier); - pedals[i].analogPedal->setActivityThreshold(pedals[i].activityThreshold); + pedals[i].analogPedal[0] = new ResponsiveAnalogRead(PIN_A(i), true); + pedals[i].analogPedal[0]->setAnalogResolution(ADC_RESOLUTION); + pedals[i].analogPedal[0]->enableEdgeSnap(); + pedals[i].analogPedal[0]->setSnapMultiplier(pedals[i].snapMultiplier); + pedals[i].analogPedal[0]->setActivityThreshold(pedals[i].activityThreshold); if (lastUsedPedal == 0xFF) { lastUsedPedal = i; lastUsed = i; @@ -2427,10 +2566,10 @@ void controller_setup() } if (ultrasonicTrigger) HCSR04.begin(ultrasonicTrigger, ultrasonicEcho.data(), ultrasonicEcho.size()); - +/* for (int i = 0; i < 100; i++) { controller_run(false); // to avoid spurious readings } - +*/ set_initial_led_color(); } \ No newline at end of file diff --git a/src/DisplayOLED.h b/src/DisplayOLED.h index 48e0083..2ecc923 100644 --- a/src/DisplayOLED.h +++ b/src/DisplayOLED.h @@ -1093,16 +1093,19 @@ int frameCount = sizeof(frames) / sizeof(FrameCallback); OverlayCallback overlays[] = { topOverlay, bottomOverlay }; int overlaysCount = sizeof(overlays) / sizeof(OverlayCallback); -void display_init() +void display_boot() { display.init(); display.setContrast(255); + if (flipScreen) display.flipScreenVertically(); + #ifdef WIFI if (wifiEnabled) { display.clear(); display.drawXbm((display.getWidth() - WIFI_LOGO_WIDTH) / 2, (display.getHeight() - WIFI_LOGO_HEIGHT) / 2, WIFI_LOGO_WIDTH, WIFI_LOGO_HEIGHT, WiFiLogo); display.display(); + delay(1000); } #endif @@ -1111,14 +1114,19 @@ void display_init() display.clear(); display.drawXbm((display.getWidth() - BLUETOOTH_LOGO_WIDTH) / 2, (display.getHeight() - BLUETOOTH_LOGO_HEIGHT) / 2, BLUETOOTH_LOGO_WIDTH, BLUETOOTH_LOGO_HEIGHT, BluetoothLogo); display.display(); - + delay(1000); } #endif + display.clear(); + display.display(); +} +void display_init() +{ // The ESP is capable of rendering 60fps in 80Mhz mode // but that won't give you much time for anything else // run it in 160Mhz mode or just set it to 30 fps - ui.setTargetFPS(60); + ui.setTargetFPS(30); // Customize the active and inactive symbol ui.setActiveSymbol(activeSymbol); diff --git a/src/DisplayTFT.h b/src/DisplayTFT.h index 726a7da..deaf0b0 100644 --- a/src/DisplayTFT.h +++ b/src/DisplayTFT.h @@ -1046,6 +1046,8 @@ void drawFrame1(int16_t x, int16_t y) for (uint16_t i = 0; i < POINTS; i++) { uint16_t h = (historyStart + i) % POINTS; uint16_t h1 = (h + 1) % POINTS; + if (scanLoopHistory[h] != 0 && scanLoopHistory[h1] != 0) sprite.drawLine(i, map2(scanLoopHistory[h], 100, 0, 3, sprite.height() - 3), i + 1, map2(scanLoopHistory[h1], 100, 0, 3, sprite.height() - 3), TFT_INDEX_MAGENTA); + if (serviceLoopHistory[h] != 0 && serviceLoopHistory[h1] != 0) sprite.drawLine(i, map2(serviceLoopHistory[h], 100, 0, 3, sprite.height() - 3), i + 1, map2(serviceLoopHistory[h1], 100, 0, 3, sprite.height() - 3), TFT_INDEX_CYAN); if (memoryHistory[h] != 0 && memoryHistory[h1] != 0) sprite.drawLine(i, map2(memoryHistory[h], 100, 0, 3, sprite.height() - 3), i + 1, map2(memoryHistory[h1], 100, 0, 3, sprite.height() - 3), TFT_INDEX_RED); if (fragmentationHistory[h] != 0 && fragmentationHistory[h1] != 0) sprite.drawLine(i, map2(fragmentationHistory[h], 100, 0, 3, sprite.height() - 3), i + 1, map2(fragmentationHistory[h1], 100, 0, 3, sprite.height() - 3), TFT_INDEX_YELLOW); if (wifiHistory[h] != 0 && wifiHistory[h1] != 0) sprite.drawLine(i, map2(wifiHistory[h], 100, 0, 3, sprite.height() - 3), i + 1, map2(wifiHistory[h1], 100, 0, 3, sprite.height() - 3), TFT_INDEX_BLUE); @@ -1060,13 +1062,31 @@ void drawFrame1(int16_t x, int16_t y) sprite.drawString("-50dB", 0, sprite.height() / 2); sprite.setTextDatum(ML_DATUM); sprite.drawString("-90dB", 0, sprite.height() / 2 + (sprite.height() - 8) / 2); + + sprite.setTextColor(TFT_INDEX_MAGENTA, TFT_INDEX_BLACK); + sprite.setTextDatum(MC_DATUM); + sprite.drawString("10ms", sprite.width() / 4, sprite.height() / 2 - (sprite.height() - 8) / 2); + sprite.setTextDatum(MC_DATUM); + sprite.drawString("5ms", sprite.width() / 4, sprite.height() / 2); + sprite.setTextDatum(MC_DATUM); + sprite.drawString("0ms", sprite.width() / 4, sprite.height() / 2 + (sprite.height() - 8) / 2); + sprite.setTextColor(TFT_INDEX_RED, TFT_INDEX_BLACK); sprite.setTextDatum(MC_DATUM); - sprite.drawString("200Kb", sprite.width() / 2, sprite.height() / 2 - (sprite.height() - 8) / 2); + sprite.drawString("120Kb", sprite.width() / 2, sprite.height() / 2 - (sprite.height() - 8) / 2); sprite.setTextDatum(MC_DATUM); - sprite.drawString("100Kb", sprite.width() / 2, sprite.height() / 2); + sprite.drawString("60Kb", sprite.width() / 2, sprite.height() / 2); sprite.setTextDatum(MC_DATUM); sprite.drawString("0Kb", sprite.width() / 2, sprite.height() / 2 + (sprite.height() - 8) / 2); + + sprite.setTextColor(TFT_INDEX_CYAN, TFT_INDEX_BLACK); + sprite.setTextDatum(MC_DATUM); + sprite.drawString("10ms", 3 * sprite.width() / 4, sprite.height() / 2 - (sprite.height() - 8) / 2); + sprite.setTextDatum(MC_DATUM); + sprite.drawString("5ms", 3 * sprite.width() / 4, sprite.height() / 2); + sprite.setTextDatum(MC_DATUM); + sprite.drawString("0ms", 3 * sprite.width() / 4, sprite.height() / 2 + (sprite.height() - 8) / 2); + sprite.setTextColor(TFT_INDEX_GREEN, TFT_INDEX_BLACK); sprite.setTextDatum(MR_DATUM); sprite.drawString("5.0V", sprite.width() - 1, sprite.height() / 2 - (sprite.height() - 8) / 2); @@ -1074,6 +1094,7 @@ void drawFrame1(int16_t x, int16_t y) sprite.drawString("4.0V", sprite.width() - 1, sprite.height() / 2); sprite.setTextDatum(MR_DATUM); sprite.drawString("3.0V", sprite.width() - 1, sprite.height() / 2 + (sprite.height() - 8) / 2); + sprite.pushSprite(0, 27); sprite.deleteSprite(); #endif @@ -1383,18 +1404,20 @@ void drawFrame3(int16_t x, int16_t y) } -void display_init() +void display_boot() { +#ifdef ARDUINO_LILYGO_T_DISPLAY_S3 + // When T-Display-S3 is powered by battery, GPIO15 must be set to HIGH to turn on the backlight. + pinMode(15, OUTPUT); + digitalWrite(15, HIGH); + if (TFT_BL > 0) { // TFT_BL has been set in the TFT_eSPI library in the User Setup file ARDUINO_LILYGO_T_DISPLAY.h + pinMode(TFT_BL, OUTPUT); // Set backlight pin GPIO38 to output mode + digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); // Turn backlight on. TFT_BACKLIGHT_ON has been set in the TFT_eSPI library in the User Setup file ARDUINO_LILYGO_T_DISPLAY.h + } +#endif display.init(); flipScreen ? display.setRotation(3) : display.setRotation(1); display.fillScreen(TFT_BLACK); - /* - if (TFT_BL > 0) { // TFT_BL has been set in the TFT_eSPI library in the User Setup file ARDUINO_LILYGO_T_DISPLAY.h - pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode - digitalWrite(TFT_BL, TFT_BACKLIGHT_ON); // Turn backlight on. TFT_BACKLIGHT_ON has been set in the TFT_eSPI library in the User Setup file ARDUINO_LILYGO_T_DISPLAY.h - } - */ - display.fillScreen(TFT_WHITE); display.setSwapBytes(true); display.pushImage((display.width() - PEDALINO_LOGO_WIDTH) / 2, (display.height() - PEDALINO_LOGO_HEIGHT) / 2, PEDALINO_LOGO_WIDTH, PEDALINO_LOGO_HEIGHT, PedalinoLogo); @@ -1419,7 +1442,12 @@ void display_init() #endif display.fillScreen(TFT_BLACK); - displayInit = false; +} + +void display_init() +{ + flipScreen ? display.setRotation(3) : display.setRotation(1); + displayInit = false; } void display_ui_update_disable() diff --git a/src/Pedalino.h b/src/Pedalino.h index 65b613d..eb53bfa 100644 --- a/src/Pedalino.h +++ b/src/Pedalino.h @@ -24,9 +24,12 @@ __________ .___ .__ .__ _____ .__ .__ #define BANKS 21 // 20 banks + 1 bank for global actions #define PEDALS 6 // real number of pedals is board specific (see below) #define CONTROLS 100 -#define SEQUENCES 16 +#define SEQUENCES 20 #define STEPS 10 // number of steps for each sequence #define LADDER_STEPS 6 // max number of controls in a resistor ladder +#define ADC_BOARDS 4 // +#define ADC_INPUTS 4 // ADS1115 number of analog inputs +#define ADC_CHANNELS (ADC_BOARDS * ADC_INPUTS) #define LEDS 10 // number of WS2812B leds (254 max) #define LED_RGB_ORDER RGB // do not change it, RGB order is managed by program because FastLED library does not support changing RGB order at runtime #define SLOTS_ROWS 2 @@ -85,7 +88,7 @@ const byte pinA[] = {GPIO_NUM_36, GPIO_NUM_39, GPIO_NUM_34, GPIO_NUM_35, GPIO_NU #undef PEDALS #define PEDALS 9 // https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/gpio.html -// Strapping pins: 1, 3, 45, 46 +// Strapping pins: 0, 3, 45, 46 // ADC1: 1-10 // ADC2: 11-20 (19=D- 20=D+) (ADC2 module is also used by the Wi-Fi) // SPI0/1: 26-32 (usually used for SPI flash and PSRAM) @@ -105,18 +108,24 @@ const byte pinA[] = {GPIO_NUM_4, GPIO_NUM_5, GPIO_NUM_6, GPIO_NUM_7, GPIO_NU #undef PEDALS #define PEDALS 8 // https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/gpio.html -// Strapping pins: 1, 3, 45, 46 +// Strapping pins: 0, 3, 45, 46 // ADC1: 1-10 // ADC2: 11-20 (19=D- 20=D+) (ADC2 module is also used by the Wi-Fi) // SPI0/1: 26-32 (usually used for SPI flash and PSRAM) // SPI0/1: 33-37 (board with ESP32-S3R8 chip not recommended for other uses) -const byte pinD[] = {GPIO_NUM_10, GPIO_NUM_2, GPIO_NUM_43, GPIO_NUM_44, GPIO_NUM_21, GPIO_NUM_1, GPIO_NUM_14, GPIO_NUM_0}; -const byte pinA[] = {GPIO_NUM_11, GPIO_NUM_12, GPIO_NUM_13, GPIO_NUM_16, GPIO_NUM_17, GPIO_NUM_18, GPIO_NUM_14, GPIO_NUM_0}; +//const byte pinD[] = {GPIO_NUM_10, GPIO_NUM_2, GPIO_NUM_43, GPIO_NUM_44, GPIO_NUM_21, GPIO_NUM_1, GPIO_NUM_14, GPIO_NUM_0}; +//const byte pinA[] = {GPIO_NUM_11, GPIO_NUM_12, GPIO_NUM_13, GPIO_NUM_16, GPIO_NUM_17, GPIO_NUM_18, GPIO_NUM_14, GPIO_NUM_0}; +// Analog pedals are supported only on pedal 4, 5 and 6 because there are not enough available GPIO on ADC1 +//const byte pinD[] = {GPIO_NUM_11, GPIO_NUM_12, GPIO_NUM_13, GPIO_NUM_16, GPIO_NUM_17, GPIO_NUM_18, GPIO_NUM_14, GPIO_NUM_0}; +//const byte pinA[] = {GPIO_NUM_44, GPIO_NUM_43, GPIO_NUM_21, GPIO_NUM_10, GPIO_NUM_2, GPIO_NUM_1, GPIO_NUM_14, GPIO_NUM_0}; +// Analog pedals are not supported on pedal 1 and 2 because there are only 4 available GPIOs on ADC1 +const byte pinD[] = {GPIO_NUM_11, GPIO_NUM_12, GPIO_NUM_13, GPIO_NUM_16, GPIO_NUM_17, GPIO_NUM_18, GPIO_NUM_14, GPIO_NUM_0}; +const byte pinA[] = {GPIO_NUM_44, GPIO_NUM_43, GPIO_NUM_10, GPIO_NUM_3, GPIO_NUM_2, GPIO_NUM_1, GPIO_NUM_14, GPIO_NUM_0}; #define FACTORY_DEFAULT_PIN GPIO_NUM_0 // Button BOOT #define DIN_MIDI_IN_PIN GPIO_NUM_1 -#define DIN_MIDI_OUT_PIN GPIO_NUM_3 +#define DIN_MIDI_OUT_PIN GPIO_NUM_1 #define BATTERY_PIN GPIO_NUM_4 // Pin connected to BAT (BAT is not VBAT) -#define FASTLEDS_DATA_PIN GPIO_NUM_3 +#define FASTLEDS_DATA_PIN GPIO_NUM_21 #else #undef PEDALS #define PEDALS 7 @@ -134,6 +143,7 @@ const byte pinA[] = {GPIO_NUM_36, GPIO_NUM_39, GPIO_NUM_34, GPIO_NUM_35, GPIO_NU #define PIN_D(x) pinD[x] #define PIN_A(x) pinA[x] +#define FASTLED_RMT_MAX_TICKS_FOR_GTX_SEM (2000/portTICK_PERIOD_MS) // https://github.com/davidlmorris/FastLED_Hang_Fix_Demo #include // https://github.com/FastLED/FastLED CRGB fastleds[LEDS+1]; // fastleds[LEDS] not used EOrder rgbOrder = RGB; @@ -145,6 +155,7 @@ typedef uint8_t byte; #include // https://github.com/MajicDesigns/MD_REncoder #include // https://github.com/bxparks/AceButton #include // https://github.com/RyoKosaka/HelloDrum-arduino-Library +#include // https://github.com/adafruit/Adafruit_ADS1X15 //#include "AnalogPad.h" using namespace ace_button; @@ -230,8 +241,9 @@ using namespace ace_button; #define PED_ANALOG_LATCH 12 #define PED_ANALOG_PAD 13 // Piezo #define PED_ANALOG_PAD_MOMENTARY 14 // Piezo + switch +#define PED_ANALOG4 15 // ADS1115 -const char *pedalModeName[] = {"", "None", "Momentary 1", "Latch", "Analog", "Jog Wheel", "Momentary 2", "Momentary 3", "Latch 2", "Ladder", "Ultrasonic", "Analog+Momentary", "Analog+Latch", "Analog Pad", "Analog Pad+Momentary"}; +const char *pedalModeName[] = {"", "None", "Momentary 1", "Latch", "Analog", "Jog Wheel", "Momentary 2", "Momentary 3", "Latch 2", "Ladder", "Ultrasonic", "Analog+Momentary", "Analog+Latch", "Analog Pad", "Analog Pad+Momentary", "Analog 4"}; #define PED_PRESS_1 1 #define PED_PRESS_2 2 @@ -314,9 +326,9 @@ const char *pedalAnalogResponse[] = {"Linear", "Log", "Antilog"}; #define PED_TIMESIGNATURE_LAST 7 #define MIDI_RESOLUTION 128 // MIDI 7-bit CC resolution -#define ADC_RESOLUTION 1024 -#define ADC_RESOLUTION_BITS 10 // hardware 9 to 12-bit ADC converter resolution +#define ADC_RESOLUTION_BITS 9 // hardware 9 to 12-bit ADC converter resolution // software 1 to 16-bit resolution +#define ADC_RESOLUTION (1 << ADC_RESOLUTION_BITS) struct action { char tag0[MAXACTIONNAME+1]; @@ -330,7 +342,7 @@ struct action { uint32_t color1; byte event; byte midiMessage; - byte midiChannel; /* MIDI channel 1-16 */ + byte midiChannel; /* MIDI channel 1-16, 0 = None, 17 = All or sequence 1-20 */ byte midiCode; /* Program Change, Control Code, Note or Pitch Bend value to send */ byte midiValue1; byte midiValue2; @@ -394,7 +406,8 @@ struct pedal { AceButton *button[LADDER_STEPS]; ButtonConfig *buttonConfig; MD_REncoder *jogwheel; - ResponsiveAnalogRead *analogPedal; + ResponsiveAnalogRead *analogPedal[ADC_CHANNELS]; + Adafruit_ADS1115 *ads[ADC_BOARDS]; //AnalogPad *analogPad; HelloDrum *analogPad; }; @@ -452,6 +465,8 @@ AceButton bootButton; ButtonConfig bootButtonConfig; uint16_t ladderLevels[LADDER_STEPS+1] = {497, 660, 752, 816, 876, 945, ADC_RESOLUTION - 1}; // TC-Helicon Switch 6 +bool ads1115Found[ADC_BOARDS]; + char slots[SLOTS_ROWS][SLOTS_COLS][MAXBANKNAME+1]; bool tapDanceMode = false; @@ -465,12 +480,15 @@ unsigned long displayOffCountdownStart = 0; unsigned long screenSaverTimeout = 1000*60*60; // 1 hour volatile byte currentProfile = 0; +volatile bool controllerRunning = false; volatile bool reloadProfile = true; volatile bool saveProfile = false; volatile bool loadConfig = false; volatile bool scrollingMode = false; // Display scrolling mode -volatile bool displayInit = false; +volatile bool displayInit = true; volatile bool startWebServer = false; +volatile unsigned long scanLoop = 0; +volatile unsigned long serviceLoop = 0; byte currentBank = 1; byte currentPedal = 0; @@ -537,10 +555,13 @@ uint16_t batteryVoltage = 4200; // mV #define GRAPH_DURATION_QUARTER_MIN GRAPH_DURATION_QUARTER_SEC / 60 #define GRAPH_DURATION_QUARTER_HOUR GRAPH_DURATION_QUARTER_MIN / 60 RTC_DATA_ATTR uint16_t historyStart = 0; -RTC_DATA_ATTR byte memoryHistory[POINTS]; // 0% = 0Kb 100% = 200Kb -RTC_DATA_ATTR byte fragmentationHistory[POINTS]; // 0% = 0Kb 100% = 200Kb -RTC_DATA_ATTR byte wifiHistory[POINTS]; // 0% = -90dB 100% = -10dB -RTC_DATA_ATTR byte batteryHistory[POINTS]; // 0% = 3.0V 100% = 5.0V +RTC_DATA_ATTR byte memoryHistory[POINTS]; // 0% = 0Kb 100% = 120Kb +RTC_DATA_ATTR byte fragmentationHistory[POINTS]; // 0% = 0Kb 100% = 120Kb +RTC_DATA_ATTR byte wifiHistory[POINTS]; // 0% = -90dB 100% = -10dB +RTC_DATA_ATTR byte batteryHistory[POINTS]; // 0% = 3.0V 100% = 5.0V +RTC_DATA_ATTR byte scanLoopHistory[POINTS]; // 0% = 0us 100% = 10ms +RTC_DATA_ATTR byte serviceLoopHistory[POINTS]; // 0% = 0ms 100% = 10ms + #endif // DIAGNOSTIC uint16_t scan[POINTS]; diff --git a/src/PedalinoMini.cpp b/src/PedalinoMini.cpp index 7579d2a..4d00451 100644 --- a/src/PedalinoMini.cpp +++ b/src/PedalinoMini.cpp @@ -84,9 +84,10 @@ __________ .___ .__ .__ _____ .__ .__ #include #endif -TaskHandle_t loopCore0; // loop() on core 0 +TaskHandle_t loopCore0; // loop0() on core 0 +TaskHandle_t loopCore1; // loop1() on core 1 void loop0(void * pvParameters); - +void loop1(void * pvParameters); void verbose_print_reset_reason(int reason) { @@ -135,15 +136,13 @@ void wifi_and_battery_level() { digitalWrite(BATTERY_ADC_EN, HIGH); delay(10); #endif // BATTERY_ADC_EN - uint16_t v = analogRead(BATTERY_PIN); + //analogReadResolution(12); + uint16_t voltage = analogReadMilliVolts(BATTERY_PIN) * 2; // Read the ADC voltage using the built in factory calibration, no conversion needed. + // Battery voltage is measured using a voltage divider + //analogReadResolution(ADC_RESOLUTION_BITS); #ifdef BATTERY_ADC_EN digitalWrite(BATTERY_ADC_EN, LOW); #endif // BATTERY_ADC_EN -#ifdef ARDUINO_BPI_LEAF_S3 - uint16_t voltage = ((uint32_t)v * 2 * 37 * vref) / 10240; // float voltage = ((float)v / 1024.0) * 2.0 * 3.3 * (vref / 1000.0); -#else - uint16_t voltage = ((uint32_t)v * 2 * 33 * vref) / 10240; // float voltage = ((float)v / 1024.0) * 2.0 * 3.3 * (vref / 1000.0); -#endif // ARDUINO_BPI_LEAF_S3 uint16_t difference = abs(voltage - batteryVoltage); //DPRINT("%d %d %d %d\n", voltage, batteryVoltage, difference, map2(constrain(batteryVoltage, 3000, 5000), 3000, 5000, 0, 100)); if (difference > 100) @@ -156,10 +155,12 @@ void wifi_and_battery_level() { static byte sec = 0; if (sec == 0) { - memoryHistory[historyStart] = map2(freeMemory, 0, 200*1024, 0, 100); - fragmentationHistory[historyStart] = map2(maxAllocation, 0, 200*1024, 0, 100); - wifiHistory[historyStart] = map2(constrain(wifiLevel, -90, -10), -90, -10, 0, 100); - batteryHistory[historyStart] = map2(constrain(batteryVoltage, 3000, 5000), 3000, 5000, 0, 100); + memoryHistory[historyStart] = map2(freeMemory, 0, 120*1024, 0, 100); + fragmentationHistory[historyStart] = map2(maxAllocation, 0, 120*1024, 0, 100); + wifiHistory[historyStart] = map2(constrain(wifiLevel, -90, -10), -90, -10, 0, 100); + batteryHistory[historyStart] = map2(constrain(batteryVoltage, 3000, 5000), 3000, 5000, 0, 100); + scanLoopHistory[historyStart] = map2(constrain(scanLoop, 0, 10000), 0, 10000, 0, 100); + serviceLoopHistory[historyStart] = map2(constrain(serviceLoop, 0, 10000), 0, 10000, 0, 100); historyStart = (historyStart + 1) % POINTS; } sec = (sec + 1) % SECONDS_BETWEEN_SAMPLES; @@ -203,6 +204,8 @@ void setup() DPRINT("Internal Total Heap %d, Internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap()); DPRINT("PSRAM Total Heap %d, PSRAM Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram()); + adc_power_acquire(); + // Reset the pin used for power off // If the specified GPIO is a valid RTC GPIO, init as digital GPIO for (byte p = 0; p < PEDALS; p++) { @@ -211,7 +214,7 @@ void setup() #ifdef BATTERY_PIN //Check type of calibration value used to characterize ADC for BATTERY_PIN - esp_adc_cal_characteristics_t adc_chars; + esp_adc_cal_characteristics_t adc_chars = {}; #if defined ARDUINO_LILYGO_T_DISPLAY // GPIO34 esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars); @@ -265,11 +268,6 @@ void setup() DPRINT("Internal Total Heap %d, Internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap()); DPRINT("PSRAM Total Heap %d, PSRAM Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram()); - sketchSize = ESP.getSketchSize(); - sketchMD5 = ESP.getSketchMD5(); - - DPRINT("Sketch Size %d bytes, Firmware Hash %s\n", sketchSize, sketchMD5.c_str()); - if (!SPIFFS.begin()) { DPRINT("SPIFFS mount FAILED\n"); } @@ -280,6 +278,13 @@ void setup() eeprom_init_or_erase(); eeprom_read_global(); + display_boot(); + + sketchSize = ESP.getSketchSize(); + sketchMD5 = ESP.getSketchMD5(); + + DPRINT("Sketch Size %d bytes, Firmware Hash %s\n", sketchSize, sketchMD5.c_str()); + FastLED.addLeds(fastleds, LEDS); fill_solid(fastleds, LEDS, CRGB::Black); FastLED.show(); @@ -289,8 +294,6 @@ void setup() for (byte l = 0; l < LEDS; l++) lastLedColor[b][l] = CRGB::Black; - display_init(); - // Reset to factory default if BOOT key is pressed and hold for alt least 15 seconds at power on pinMode(FACTORY_DEFAULT_PIN, INPUT_PULLUP); @@ -504,9 +507,18 @@ void setup() set_initial_led_color(); + xTaskCreatePinnedToCore( + loop1, /* Task function. */ + "loopTask1", /* name of task. */ + 8192, /* Stack size of task */ + NULL, /* parameter of the task */ + 1, /* priority of the task */ + &loopCore1, /* Task handle to keep track of created task */ + 1); /* pin task to core 1 */ + xTaskCreatePinnedToCore( loop0, /* Task function. */ - "loopTask", /* name of task. */ + "loopTask0", /* name of task. */ 8192, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ @@ -521,17 +533,44 @@ void loop() { // High priority activities run on Core 1 + unsigned long startClock = micros(); + // Check whether the input has changed since last time, if so, send the new value over MIDI controller_run(); // Send MTC or MIDI CLock MTC.loop(); + + // It is not a priority task but it only works on the same core where FastLED init run + // https://github.com/davidlmorris/FastLED_Hang_Fix_Demo + // It has no effect when not in diagnostic screen + + if (scrollingMode && !displayOff) { + switch (currentProfile) { + case 0: + //blendwave(); + ease2(); + break; + case 1: + pacifica_loop(); + break; + case 2: + pride(); + break; + } + FastLED.show(); + } + + scanLoop = micros() - startClock; } -void loop0(void * pvParameters) +void loop1(void * pvParameters) { - // Low priority activities run on Core 0 within WiFi and Bluetooth + // High priority activities run on Core 1 + + unsigned long startClock = micros(); + unsigned long endClock; for(;;) { @@ -562,6 +601,26 @@ void loop0(void * pvParameters) if (interfaces[PED_IPMIDI].midiIn && IP_MIDI.read()) DPRINTMIDI("IP MIDI", IP_MIDI.getType(), IP_MIDI.getChannel(), IP_MIDI.getData1(), IP_MIDI.getData2()); } + } +#endif // WIFI + + endClock = micros(); + serviceLoop = endClock - startClock; + startClock = endClock; + } +} + +void loop0(void * pvParameters) +{ + // Low priority activities run on Core 0 within WiFi and Bluetooth + + for(;;) { + + // Feed the watchdog of FreeRTOS + vTaskDelay(10); + +#ifdef WIFI + if (wifiEnabled) { http_run(); @@ -586,22 +645,6 @@ void loop0(void * pvParameters) // Update display display_update(); - if (scrollingMode && !displayOff) { - switch (currentProfile) { - case 0: - //blendwave(); - ease2(); - break; - case 1: - pacifica_loop(); - break; - case 2: - pride(); - break; - } - FastLED.show(); - } - switch (firmwareUpdate) { case PED_UPDATE_ARDUINO_OTA: case PED_UPDATE_HTTP: diff --git a/src/USBMidiIn.h b/src/USBMidiIn.h index 15248e8..7db3ea4 100644 --- a/src/USBMidiIn.h +++ b/src/USBMidiIn.h @@ -252,12 +252,20 @@ void usb_midi_connect() #if defined(ARDUINO_BPI_LEAF_S3) || defined(ARDUINO_LILYGO_T_DISPLAY_S3) //usb_midi.setStringDescriptor("PedalinoMini USB MIDI"); TinyUSBDevice.setManufacturerDescriptor("Pedalino"); - TinyUSBDevice.setProductDescriptor("PedalinoMini USB MIDI"); - usb_midi.setCableName(1, "PedalinoMini"); + TinyUSBDevice.setProductDescriptor("PedalinoMiniā„¢"); + usb_midi.setCableName(1, "USB MIDI"); #endif // Initiate USB MIDI communications, listen to all channels USB_MIDI.begin(MIDI_CHANNEL_OMNI); +#if defined(ARDUINO_BPI_LEAF_S3) || defined(ARDUINO_LILYGO_T_DISPLAY_S3) + // If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration + if (TinyUSBDevice.mounted()) { + TinyUSBDevice.detach(); + delay(10); + TinyUSBDevice.attach(); + } +#endif // Enable/disable MIDI Thru interfaces[PED_USBMIDI].midiThru ? USB_MIDI.turnThruOn() : USB_MIDI.turnThruOff(); diff --git a/src/Version.h b/src/Version.h index 66c41e1..e3f15d8 100644 --- a/src/Version.h +++ b/src/Version.h @@ -18,9 +18,9 @@ extern "C" { /** Major version number (X.x.x) */ #define PEDALINO_VERSION_MAJOR 3 /** Minor version number (x.X.x) */ -#define PEDALINO_VERSION_MINOR 2 +#define PEDALINO_VERSION_MINOR 5 /** Patch version number (x.x.X) */ -#define PEDALINO_VERSION_PATCH 2 +#define PEDALINO_VERSION_PATCH 0 #define xstr(s) sstr(s) // stringize the result of expansion of a macro argument #define sstr(s) #s diff --git a/src/WebConfigAsync.h b/src/WebConfigAsync.h index ab7920e..5e53fc1 100644 --- a/src/WebConfigAsync.h +++ b/src/WebConfigAsync.h @@ -10,8 +10,8 @@ __________ .___ .__ .__ _____ .__ .__ */ String theme = "bootstrap"; -String httpUsername = "admin"; -String httpPassword = getChipId(); +String httpUsername = ""; +String httpPassword = ""; bool authenticated = false; #ifdef NOWIFI @@ -116,7 +116,7 @@ bool get_top_page(int p, unsigned int start, unsigned int len) { page += F(" "); if ( theme == "bootstrap" ) { #ifdef BOOTSTRAP_LOCAL - page += F(""); + page += F(""); #else page += F(""); #endif @@ -125,7 +125,7 @@ bool get_top_page(int p, unsigned int start, unsigned int len) { page += theme; page += F("/bootstrap.min.css' rel='stylesheet' crossorigin='anonymous'>"); } - if (p == 2) page += F(""); + if (p == 2) page += F(""); page += F(""); page += F(""); @@ -363,7 +363,7 @@ void get_footer_page() { page += F(""); #ifdef BOOTSTRAP_LOCAL - page += F(""); + page += F(""); #else page += F(""); #endif @@ -462,6 +462,9 @@ void get_root_page(unsigned int start, unsigned int len) { break; } page += F(""); + page += F("

PlatformIO ESP32 Platform
"); + page += xstr(ESP32_PLATFORM_VERSION); + page += F("
"); page += F("
IDF Version
"); page += ESP_IDF_VERSION_MAJOR; page += F("."); @@ -484,6 +487,18 @@ void get_root_page(unsigned int start, unsigned int len) { page += F("
PlatformIO Build Env
"); page += xstr(PLATFORMIO_ENV); page += F("
"); + + page += F("
Bootstrap Version
"); + page += F(""); + page += F("
Firmware
"); page += PEDALINO_VERSION_MAJOR; page += F("."); @@ -491,7 +506,6 @@ void get_root_page(unsigned int start, unsigned int len) { page += F("."); page += PEDALINO_VERSION_PATCH; page += F("
"); - page += F("
Firmware Size
"); page += sketchSize; page += F(" bytes
"); @@ -499,7 +513,7 @@ void get_root_page(unsigned int start, unsigned int len) { page += sketchMD5; page += F(""); page += F(""); - + if (trim_page(start, len)) return; page += F("
"); @@ -1355,6 +1369,7 @@ void get_actions_page(unsigned int start, unsigned int len) { break; case PED_ANALOG: + case PED_ANALOG4: case PED_ULTRASONIC: page += F(""); + page += F(""); } page += F(""); @@ -2846,6 +2896,7 @@ void get_pedals_page(unsigned int start, unsigned int len) { " document.getElementById('threshold_' + i).style.display = 'block';" " break;" " case 'Analog':" + " case 'Analog 4':" " document.getElementById('polarityCheck_' + i).style.display = 'block';" " document.getElementById('mapSelect_' + i).style.display = 'block';" " document.getElementById('minInput_' + i).style.display = 'block';" @@ -3448,7 +3499,9 @@ void get_sequences_page(unsigned int start, unsigned int len) { if (trim_page(start, len)) return; page += F("
"); - page += F("
"); + page += F(""); page += F("
"); if (trim_page(start, len)) return; @@ -3648,6 +3726,8 @@ void get_sequences_page(unsigned int start, unsigned int len) { page += F("function init_line(i) {" " document.getElementById('channelLabel' + i).textContent = 'Channel';" + " document.getElementById('channelDiv' + i).removeAttribute('hidden');" + " document.getElementById('sequenceDiv' + i).setAttribute('hidden', 'hidden');" " document.getElementById('codeLabel' + i).textContent = 'Code';" " document.getElementById('valueLabel' + i).textContent = 'Value';" " document.getElementById('channelSelect' + i).disabled = false;" @@ -3675,7 +3755,6 @@ void get_sequences_page(unsigned int start, unsigned int len) { page += F(" case 'Bank Select+':" " case 'Bank Select-':" - " document.getElementById('channelLabel' + i).textContent = 'Channel';" " document.getElementById('codeLabel' + i).textContent = 'MSB';" " document.getElementById('valueLabel' + i).textContent = 'LSB';" " break;" @@ -3684,7 +3763,8 @@ void get_sequences_page(unsigned int start, unsigned int len) { " document.getElementById('codeInput' + i).disabled = true;" " break;" " case 'Sequence':" - " document.getElementById('channelLabel' + i).textContent = 'Sequence';" + " document.getElementById('channelDiv' + i).setAttribute('hidden', 'hidden');" + " document.getElementById('sequenceDiv' + i).removeAttribute('hidden');" " document.getElementById('codeInput' + i).disabled = true;" " document.getElementById('valueInput' + i).disabled = true;" " document.getElementById('ledSelect' + i).disabled = true;" @@ -5319,7 +5399,7 @@ void http_handle_login(AsyncWebServerRequest *request) { } else { authenticated = false; get_login_page(); - request->send(200, "text/html", page); + request->send(200, "text/html", page.c_str()); } } @@ -5333,7 +5413,7 @@ void http_handle_post_login(AsyncWebServerRequest *request) { } } get_login_page(); - request->send(200, "text/html", page); + request->send(200, "text/html", page.c_str()); } void http_handle_globals(AsyncWebServerRequest *request) { @@ -5375,9 +5455,9 @@ void http_handle_actions(AsyncWebServerRequest *request) { if (!httpUsername.isEmpty() && !request->authenticate(httpUsername.c_str(), httpPassword.c_str())) return request->requestAuthentication(); http_handle_globals(request); - if (request->hasArg("bank")) uibank = request->arg("bank"); - if (request->hasArg("control")) uicontrol = request->arg("control"); - if (request->hasArg("banksorder")) list = request->arg("banksorder"); + if (request->hasArg("bank")) uibank = request->arg("bank"); + if (request->hasArg("control")) uicontrol = request->arg("control"); + if (request->hasArg("banksorder")) list = request->arg("banksorder"); for (byte b = 0; b < BANKS; b++) { a[b] = actions[b]; @@ -5637,6 +5717,7 @@ void http_handle_post_actions(AsyncWebServerRequest *request) { case PED_SEQUENCE: case PED_SEQUENCE_STEP_BY_STEP_FWD: case PED_SEQUENCE_STEP_BY_STEP_REV: + act->midiChannel = constrain(request->arg(String("sequence") + String(i)).toInt(), 1, SEQUENCES); act->color0 = CRGB::Black; act->color1 = CRGB::Black; break; @@ -5853,7 +5934,7 @@ void http_handle_post_interfaces(AsyncWebServerRequest *request) { void http_handle_post_sequences(AsyncWebServerRequest *request) { String a; - const byte s = constrain(uisequence.toInt() - 1, 0, SEQUENCES); + const byte s = constrain(uisequence.toInt() - 1, 0, SEQUENCES - 1); unsigned int red, green, blue; for (unsigned int i = 0; i < STEPS; i++) { @@ -5864,6 +5945,13 @@ void http_handle_post_sequences(AsyncWebServerRequest *request) { a = request->arg(String("channel") + String(i+1)); sequences[s][i].midiChannel = constrain(a.toInt(), 0, 17); + switch (sequences[s][i].midiMessage) { + case PED_SEQUENCE: + a = request->arg(String("sequence") + String(i+1)); + sequences[s][i].midiChannel = constrain(a.toInt() - 1, 0, SEQUENCES - 1); + break; + } + a = request->arg(String("code") + String(i+1)); sequences[s][i].midiCode = constrain(a.toInt(), 0, MIDI_RESOLUTION - 1); @@ -6098,7 +6186,8 @@ void http_handle_post_options(AsyncWebServerRequest *request) { esp_bt_controller_disable(); #endif esp_wifi_stop(); - adc_power_off(); + //adc_power_off(); + adc_power_release(); delay(200); for (byte b = 0; b < BANKS; b++) { action *act = actions[b]; @@ -6156,7 +6245,6 @@ void http_handle_post_configurations(AsyncWebServerRequest *request) { } else if (request->arg("action").equals("apply") || request->arg("action").equals("append")) { String config = request->arg("filename"); - controller_delete(); spiffs_load_config(config, request->arg("actions2") == checked, request->arg("pedals2") == checked, @@ -6174,7 +6262,6 @@ void http_handle_post_configurations(AsyncWebServerRequest *request) { } else if (request->arg("action").equals("save") || request->arg("action").equals("appendsave")) { String config = request->arg("filename"); - controller_delete(); spiffs_load_config(config, request->arg("actions2") == checked, request->arg("pedals2") == checked, @@ -6556,12 +6643,12 @@ void http_setup() { httpServer.serveStatic("/schema.json", SPIFFS, "/schema.json").setDefaultFile("/schema.json").setCacheControl("max-age=600"); httpServer.serveStatic("/files", SPIFFS, "/").setDefaultFile("").setAuthentication(httpUsername.c_str(), httpPassword.c_str()); */ - httpServer.serveStatic("/favicon.ico", SPIFFS, "/favicon.ico"); - httpServer.serveStatic("/logo.png", SPIFFS, "/logo.png"); - httpServer.serveStatic("/css/bootstrap.min.css", SPIFFS, "/css/bootstrap.min.css"); - httpServer.serveStatic("/js/bootstrap.bundle.min.js", SPIFFS, "/js/bootstrap.bundle.min.js"); - httpServer.serveStatic("/js/Sortable.min.js", SPIFFS, "/js/Sortable.min.js"); - httpServer.serveStatic("/schema.json", SPIFFS, "/schema.json"); + httpServer.serveStatic("/favicon.ico", SPIFFS, "/favicon.ico").setCacheControl("max-age=600"); + httpServer.serveStatic("/logo.png", SPIFFS, "/logo.png").setCacheControl("max-age=600"); + httpServer.serveStatic("/css/bootstrap.min.css", SPIFFS, "/css/bootstrap.min.css").setCacheControl("max-age=600"); + httpServer.serveStatic("/js/bootstrap.bundle.min.js", SPIFFS, "/js/bootstrap.bundle.min.js").setCacheControl("max-age=600"); + httpServer.serveStatic("/js/Sortable.min.js", SPIFFS, "/js/Sortable.min.js").setCacheControl("max-age=600"); + httpServer.serveStatic("/schema.json", SPIFFS, "/schema.json").setCacheControl("max-age=600"); httpServer.serveStatic("/files", SPIFFS, "/").setDefaultFile("").setAuthentication(httpUsername.c_str(), httpPassword.c_str()); httpServer.on("/", http_handle_root);