From c2d429c3f7f3f023208954853c7abcc897533e45 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Fri, 21 Aug 2020 07:49:36 +0200 Subject: [PATCH] * AUTOCAL is available for each ADJUST menu page. With cursor on THR or MAX bar, press UP and DOWN buttons at the same time (and keep off the sensors being calibrated). AUTOCAL will be displayed for two seconds, then updated settings will be shown. [removed for now - needs work] * Experimental breath controlled harmonic series (BRTH HARM and BR HM SEL settings). Like the lip sensor harmonics function, this shifts the fingered note up the harmonic series. For improved switching speed, try turning down the key deglitch time. (If this function is to be kept, I will probably need to tweak it quite a bit. Tongueing into higher notes and releasing them does not work well currently.) --- NuEVI/NuEVI.ino | 28 +- NuEVI/adjustmenu.cpp | 125 + NuEVI/config.h | 2 +- NuEVI/globals.h | 4 +- NuEVI/hardware.h | 2 +- NuEVI/menu.cpp | 32 +- NuEVI/settings.cpp | 11 +- NuEVI/settings.h | 8 +- uploadable hex files/NuEVI-v15b3.ino.hex | 5418 +++++++++++++++++++++ uploadable hex files/NuRAD-v15b3.ino.hex | 5531 ++++++++++++++++++++++ 10 files changed, 11142 insertions(+), 19 deletions(-) create mode 100644 uploadable hex files/NuEVI-v15b3.ino.hex create mode 100644 uploadable hex files/NuRAD-v15b3.ino.hex diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index e500075..c2ce486 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -95,7 +95,9 @@ unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) unsigned short batteryType; // 0-2 ALK,NIM,LIP unsigned short harmSetting; // 0-7 -unsigned short harmSelect; // 0-4 +unsigned short harmSelect; // 0-5 +unsigned short brHarmSetting; // 0-7 +unsigned short brHarmSelect; // 0-3 unsigned short polySelect; // OFF, MGR, MGD, MND, MNH, FWC, RTA, RTB or RTC unsigned short fwcType; // 6, m6, 7, m7 unsigned short fwcLockH; // OFF:ON @@ -221,6 +223,7 @@ int oldextrac=0; int oldextrac2=0; int harmonics = 0; +int brHarmonics = 0; int pitchBend=8192; int oldpb=8192; @@ -428,11 +431,18 @@ const int minHipHmz[12][3] = {{ -5, -9, -10 }, // C or key base { -4, -6, -9 }}; // B or base +11 -const int harmonicResult[5][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HRM +const int harmonicResult[6][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1 + { 0, 7, 12, 16, 19, 22, 24 }, //HM2 (7th harmonic not excluded) { 0, 7, 12, 19, 24, 31, 36 }, //5TH { 0, 12, 24, 36, 48, 60, 72 }, //OCT { 0, -5, -12, -17, -24, -29, -36 }, //5DN { 0, -12, -24, -36, -48, -60, -72 }}; //ODN + + +const int brHarmonicResult[4][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1 + { 0, 7, 12, 16, 19, 22, 24 }, //HM2 (7th harmonic not excluded) + { 0, 7, 12, 19, 24, 31, 36 }, //5TH + { 0, 12, 24, 36, 48, 60, 72 }}; //OCT const int rollerHarmonic[2][7] = {{ 0, 7, 12, 16, 19, 24, 26 }, //F horn 2,3,4,5,6,8,9 hrm { 7, 12, 16, 19, 24, 26, 31 }}; //Bb horn 3,4,5,6,8,9,12 hrm @@ -1448,11 +1458,11 @@ void breath() { breathCCval = (breathCCvalHires >> 7) & 0x007F; breathCCvalFine = breathCCvalHires & 0x007F; breathCC2val = constrain(breathCCval*breathCC2Rise,0,127); - + if (brHarmSetting) brHarmonics = map(constrain(breathLevel, breathThrVal, breathMaxVal), breathThrVal, breathMaxVal, 0, brHarmSetting); else brHarmonics = 0; if (breathCCval != oldbreath) { // only send midi data if breath has changed from previous value if (breathCC) { // send midi cc - midiSendControlChange(ccList[breathCC], breathCCval); + midiSendControlChange(ccList[breathCC], breathCCval); } if (breathAT) { // send aftertouch @@ -1895,12 +1905,12 @@ void autoCal() { writeSetting(PITCHB_MAX_ADDR, pitchbMaxVal); // Lever calRead = 3000-touchRead(vibratoPin); - leverThrVal = constrain(calRead+70, leverLoLimit, leverHiLimit); - leverMaxVal = constrain(calRead+150, leverLoLimit, leverHiLimit); + leverThrVal = constrain(calRead+60, leverLoLimit, leverHiLimit); + leverMaxVal = constrain(calRead+120, leverLoLimit, leverHiLimit); writeSetting(LEVER_THR_ADDR, leverThrVal); writeSetting(LEVER_MAX_ADDR, leverMaxVal); #if defined(NURAD) // NuRAD sensor calibration - // Pressure sensor + // Bite Pressure sensor calRead = analogRead(bitePressurePin); portamThrVal = constrain(calRead+300, portamLoLimit, portamHiLimit); portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); @@ -2093,7 +2103,7 @@ void readSwitches() { + (6-octaveR)*12; //Octave rollers, reversed } - int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics]; //lip sensor harmonics + int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor and breath harmonics if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered @@ -2171,7 +2181,7 @@ void readSwitches() { if (4 == trill3_interval) fingeredNoteUntransposed+=2; else fingeredNoteUntransposed+=4; } - int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics]; //lip sensor harmonics + int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor harmonics pcCombo1 = (K1 && K5 && !K2 && !K3); pcCombo2 = (K2 && K6 && !K1 && !K3); diff --git a/NuEVI/adjustmenu.cpp b/NuEVI/adjustmenu.cpp index c4bd7e7..dc1a938 100644 --- a/NuEVI/adjustmenu.cpp +++ b/NuEVI/adjustmenu.cpp @@ -142,6 +142,114 @@ static const int numAdjustEntries = ARR_LEN(adjustMenuEntries); //*********************************************************** + + +void autoCalSelected() { + int calRead; + int calReadNext; +// NuRAD/NuEVI sensor calibration + // Extra Controller + if(adjustOption == 3) { + calRead = touchRead(extraPin); + extracThrVal = constrain(calRead+200, extracLoLimit, extracHiLimit); + extracMaxVal = constrain(extracThrVal+600, extracLoLimit, extracHiLimit); + writeSetting(EXTRAC_THR_ADDR, extracThrVal); + writeSetting(EXTRAC_MAX_ADDR, extracMaxVal); + } + // Breath sensor + if(adjustOption == 0) { + calRead = analogRead(breathSensorPin); + breathThrVal = constrain(calRead+200, breathLoLimit, breathHiLimit); + breathMaxVal = constrain(breathThrVal+2000, breathLoLimit, breathHiLimit); + writeSetting(BREATH_THR_ADDR, breathThrVal); + writeSetting(BREATH_MAX_ADDR, breathMaxVal); + } + // Pitch Bend + if(adjustOption == 2) { + calRead = touchRead(pbUpPin); + calReadNext = touchRead(pbDnPin); + if (calReadNext > calRead) calRead = calReadNext; //use highest value + pitchbThrVal = constrain(calRead+200, pitchbLoLimit, pitchbHiLimit); + pitchbMaxVal = constrain(pitchbThrVal+800, pitchbLoLimit, pitchbHiLimit); + writeSetting(PITCHB_THR_ADDR, pitchbThrVal); + writeSetting(PITCHB_MAX_ADDR, pitchbMaxVal); + } + // Lever + if(adjustOption == 5) { + calRead = 3000-touchRead(vibratoPin); + leverThrVal = constrain(calRead+60, leverLoLimit, leverHiLimit); + leverMaxVal = constrain(calRead+120, leverLoLimit, leverHiLimit); + writeSetting(LEVER_THR_ADDR, leverThrVal); + writeSetting(LEVER_MAX_ADDR, leverMaxVal); + } +#if defined(NURAD) // NuRAD sensor calibration + // Bite Pressure sensor + if(adjustOption == 1) { + calRead = analogRead(bitePressurePin); + portamThrVal = constrain(calRead+300, portamLoLimit, portamHiLimit); + portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); + writeSetting(PORTAM_THR_ADDR, portamThrVal); + writeSetting(PORTAM_MAX_ADDR, portamMaxVal); + } + // Touch sensors + if(adjustOption == 4) { + calRead = ctouchHiLimit; + for (byte i = 0; i < 6; i++) { + calReadNext = touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300; + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + for (byte i = 0; i < 12; i++) { + calReadNext = touchSensorRH.filteredData(i) * (300-calOffsetRH[i])/300; + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + for (byte i = 0; i < 12; i++) { + calReadNext = touchSensorLH.filteredData(i) * (300-calOffsetLH[i])/300; + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + ctouchThrVal = constrain(calRead-20, ctouchLoLimit, ctouchHiLimit); + touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); + writeSetting(CTOUCH_THR_ADDR, ctouchThrVal); + } +#else // NuEVI sensor calibration + // Bite sensor + if(adjustOption == 1) { + if (digitalRead(biteJumperPin)){ //PBITE (if pulled low with jumper, pressure sensor is used instead of capacitive bite sensing) + // Capacitive sensor + calRead = touchRead(bitePin); + portamThrVal = constrain(calRead+200, portamLoLimit, portamHiLimit); + portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); + writeSetting(PORTAM_THR_ADDR, portamThrVal); + writeSetting(PORTAM_MAX_ADDR, portamMaxVal); + } else { + // Pressure sensor + calRead = analogRead(bitePressurePin); + portamThrVal = constrain(calRead+300, portamLoLimit, portamHiLimit); + portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); + writeSetting(PORTAM_THR_ADDR, portamThrVal); + writeSetting(PORTAM_MAX_ADDR, portamMaxVal); + } + } + // Touch sensors + if(adjustOption == 4) { + calRead = ctouchHiLimit; + for (byte i = 0; i < 12; i++) { + calReadNext = touchSensor.filteredData(i); + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + calReadNext=map(touchRead(halfPitchBendKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit); + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + calReadNext=map(touchRead(specialKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit); + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + ctouchThrVal = constrain(calRead-20, ctouchLoLimit, ctouchHiLimit); + touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); + writeSetting(CTOUCH_THR_ADDR, ctouchThrVal); + } +#endif +} + + +//*********************************************************** + static void drawAdjCursor(byte color) { display.drawTriangle(16,4,20,4,18,1,color); display.drawTriangle(16,6,20,6,18,9,color); @@ -322,6 +430,7 @@ static bool drawAdjustBar(uint16_t buttons, int row, const AdjustValue* entry, u val -= step; updated = true; break; + } if(updated) { *entry->value = constrain(val, entry->limitLow, entry->limitHigh); @@ -346,7 +455,23 @@ static bool updateAdjustCursor(uint32_t timeNow) { static bool handleInput(const AdjustMenuEntry *currentMenu, uint32_t timeNow, uint8_t buttons, uint16_t *xpos, int ypos, int index) { if (buttons) { + if (buttons == BTN_DOWN+BTN_UP){ + display.fillRect(26,35,90,7,BLACK); + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(53,35); + display.println("AUTOCAL"); + display.display(); + delay(2000); + autoCalSelected(); + display.fillRect(26,35,90,7,BLACK); + display.display(); + drawAdjustMenu(currentMenu); + forcePix = 1; + plotSensorPixels(); + } else drawAdjustBar( buttons, ypos, ¤tMenu->entries[index], xpos ); + int last = adjustCurrent; if(buttons == BTN_ENTER) adjustCurrent += 1; else if( buttons == BTN_MENU) adjustCurrent = 0; diff --git a/NuEVI/config.h b/NuEVI/config.h index d390f45..7b70176 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,7 +5,7 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.5b2" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< +#define FIRMWARE_VERSION "1.5b3" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< #define ON_Delay 20 // Set Delay after ON threshold before velocity is checked (wait for tounging peak) #define CCN_Port 5 // Controller number for portamento level diff --git a/NuEVI/globals.h b/NuEVI/globals.h index e77bb24..ee7f5a5 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -103,7 +103,9 @@ extern unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR extern unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) extern unsigned short batteryType; // 0-2 ALK,NIM,LIP extern unsigned short harmSetting; // 0-7 -extern unsigned short harmSelect; // 0-4 +extern unsigned short harmSelect; // 0-5 +extern unsigned short brHarmSetting; // 0-7 +extern unsigned short brHarmSelect; // 0-3 extern unsigned short polySelect; // OFF, MGR, MGD, MND, MNH, FWC, RTA, RTB or RTC extern unsigned short fwcType; // 6, m6, 7, m7 extern unsigned short fwcLockH; // OFF:ON diff --git a/NuEVI/hardware.h b/NuEVI/hardware.h index a704660..e777da1 100644 --- a/NuEVI/hardware.h +++ b/NuEVI/hardware.h @@ -2,7 +2,7 @@ #define __HARDWARE_H #define REVB -#define NURAD +//#define NURAD #if defined(NURAD) //NuRAD <<<<<<<<<<<<<<<<<<<<<<< diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index c90a432..cea21d1 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -1182,6 +1182,30 @@ const MenuEntrySub breathATMenu = { , nullptr }; +const MenuEntrySub brHarmonicsMenu = { + MenuType::ESub, "BRTH HARM", "HARM RANGE", &brHarmSetting, 0, 6, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + if(brHarmSetting) numToString(brHarmSetting, out); + else strncpy(out, "OFF", 4); + }, +[](const MenuEntrySub & __unused sub) { writeSetting(BRHARMSET_ADDR,brHarmSetting); } + , nullptr +}; + +const MenuEntrySub brHarmSelectMenu = { + MenuType::ESub, "BR HM SEL", "SERIES", &brHarmSelect, 0, 3, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + const char* brHarmSelectMenuLabels[] = { "HM1", "HM2", "5TH", "OCT" }; + strncpy(out, brHarmSelectMenuLabels[brHarmSelect], 4); + }, + [](const MenuEntrySub & __unused sub){ + if (readSetting(BRHARMSEL_ADDR) != brHarmSelect) { + writeSetting(BRHARMSEL_ADDR,brHarmSelect); + } + } + , nullptr +}; + const MenuEntrySub velocityMenu = { MenuType::ESub, "VELOCITY", "VELOCITY", &velocity, 0, 127, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { @@ -1254,7 +1278,9 @@ const MenuEntry* breathMenuEntries[] = { (MenuEntry*)&velocityMenu, (MenuEntry*)&curveMenu, (MenuEntry*)&velSmpDlMenu, - (MenuEntry*)&velBiasMenu, + (MenuEntry*)&velBiasMenu, + //(MenuEntry*)&brHarmonicsMenu, + //(MenuEntry*)&brHarmSelectMenu, (MenuEntry*)&breathIntervalMenu }; @@ -1334,9 +1360,9 @@ const MenuEntrySub harmonicsMenu = { }; const MenuEntrySub harmSelectMenu = { - MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 4, MenuEntryFlags::EMenuEntryWrap, + MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 5, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { - const char* harmSelectMenuLabels[] = { "HRM", "5TH", "OCT", "5DN", "ODN" }; + const char* harmSelectMenuLabels[] = { "HM1", "HM2", "5TH", "OCT", "5DN", "ODN" }; strncpy(out, harmSelectMenuLabels[harmSelect], 4); }, [](const MenuEntrySub & __unused sub){ diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 2acad39..06453f0 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -157,6 +157,11 @@ void readEEPROM(const bool factoryReset) { writeSetting(LEVER_THR_ADDR, LEVER_THR_FACTORY); writeSetting(LEVER_MAX_ADDR, LEVER_MAX_FACTORY); } + + if(settingsVersion < 41) { + writeSetting(BRHARMSET_ADDR, BRHARMSET_FACTORY); + writeSetting(BRHARMSEL_ADDR, BRHARMSEL_FACTORY); + } writeSetting(VERSION_ADDR, EEPROM_VERSION); @@ -224,7 +229,7 @@ void readEEPROM(const bool factoryReset) { lpinky3 = readSettingBounded(LPINKY3_ADDR, 0, 25, LPINKY3_FACTORY); batteryType = readSettingBounded(BATTYPE_ADDR, 0, 2, BATTYPE_FACTORY); harmSetting = readSettingBounded(HARMSET_ADDR, 0, 6, HARMSET_FACTORY); - harmSelect = readSettingBounded(HARMSEL_ADDR, 0, 4, HARMSEL_FACTORY); + harmSelect = readSettingBounded(HARMSEL_ADDR, 0, 5, HARMSEL_FACTORY); polySelect = readSettingBounded(POLYSEL_ADDR, 0, 10, POLYSEL_FACTORY); fwcType = readSettingBounded(FWCTYPE_ADDR, 0, 4, FWCTYPE_FACTORY); fwcLockH = readSettingBounded(FWCLCH_ADDR, 0, 1, FWCLCH_FACTORY); @@ -246,7 +251,9 @@ void readEEPROM(const bool factoryReset) { portLimit = readSettingBounded(PORTLIMIT_ADDR, 1, 127, PORTLIMIT_FACTORY); leverThrVal = readSettingBounded(LEVER_THR_ADDR, leverLoLimit, leverHiLimit, LEVER_THR_FACTORY); leverMaxVal = readSettingBounded(LEVER_MAX_ADDR, leverLoLimit, leverHiLimit, LEVER_MAX_FACTORY); - + brHarmSetting = readSettingBounded(BRHARMSET_ADDR, 0, 6, BRHARMSET_FACTORY); + brHarmSelect = readSettingBounded(BRHARMSEL_ADDR, 0, 3, BRHARMSEL_FACTORY); + //Flags stored in bit field fastBoot = (dipSwBits & (1<