From 597991c9686c0294c3a99518ccf49e55f0ee81a6 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Thu, 18 Jul 2019 13:58:28 +0200 Subject: [PATCH] Added possibility to use bite sensor for vibrato. --- NuEVI/NuEVI.ino | 107 +++++++++++++++++++++++++++++++++++------------ NuEVI/globals.h | 6 +++ NuEVI/menu.cpp | 57 +++++++++++++++++++------ NuEVI/settings.h | 8 +++- 4 files changed, 138 insertions(+), 40 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 5eb6ee2..854856c 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -72,8 +72,11 @@ unsigned short priority; // mono priority for rotator chords unsigned short vibSens = 2; // vibrato sensitivity unsigned short vibRetn = 2; // vibrato return speed -unsigned short vibSquelch = 15; //vibrato signal squelch +unsigned short vibSquelch = 12; //vibrato signal squelch unsigned short vibDirection = DNWD; //direction of first vibrato wave UPWD or DNWD +unsigned short vibSensBite = 2; // vibrato sensitivity (bite) +unsigned short vibSquelchBite = 12; //vibrato signal squelch (bite) +unsigned short vibControl = 0; unsigned short fastPatch[7] = {0,0,0,0,0,0,0}; @@ -184,6 +187,9 @@ const unsigned short* const curves[] = { int vibThr; // this gets auto calibrated in setup int vibThrLo; int vibZero; +int vibZeroBite; +int vibThrBite; +int vibThrBiteLo; int fingeredNote; // note calculated from fingering (switches), transpose and octave settings @@ -309,6 +315,9 @@ void setup() { writeSetting(VIB_DIRECTION_ADDR,VIB_DIRECTION_FACTORY); writeSetting(BREATH_CC2_ADDR,BREATH_CC2_FACTORY); writeSetting(BREATH_CC2_RISE_ADDR,BREATH_CC2_RISE_FACTORY); + writeSetting(VIB_SENS_BITE_ADDR,VIB_SENS_BITE_FACTORY); + writeSetting(VIB_SQUELCH_BITE_ADDR,VIB_SQUELCH_BITE_FACTORY); + writeSetting(VIB_CONTROL_ADDR,VIB_CONTROL_FACTORY); } // read settings from EEPROM breathThrVal = readSetting(BREATH_THR_ADDR); @@ -355,7 +364,10 @@ void setup() { vibSquelch = readSetting(VIB_SQUELCH_ADDR); vibDirection = readSetting(VIB_DIRECTION_ADDR); breathCC2 = readSetting(BREATH_CC2_ADDR); - breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR); + breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR); + vibSensBite = readSetting(VIB_SENS_BITE_ADDR); + vibSquelchBite = readSetting(VIB_SQUELCH_BITE_ADDR); + vibControl = readSetting(VIB_CONTROL_ADDR); legacy = dipSwBits & (1<<1); legacyBrAct = dipSwBits & (1<<2); @@ -380,19 +392,23 @@ void setup() { } //auto-calibrate the vibrato threshold while showing splash screen - vibZero = breathCalZero = 0; + vibZero = vibZeroBite = breathCalZero = 0; const int sampleCount = 4; for(int i = 1 ; i <= sampleCount; ++i) { vibZero += touchRead(vibratoPin); breathCalZero += analogRead(breathSensorPin); + if (biteJumper) vibZeroBite += analogRead(A7); else vibZeroBite += touchRead(bitePin); digitalWrite( statusLedPin, i&1 ); delay(250); } vibZero /= sampleCount; breathCalZero /= sampleCount; + vibZeroBite /= sampleCount; vibThr = vibZero - vibSquelch; vibThrLo = vibZero + vibSquelch; + vibThrBite = vibZeroBite - vibSquelchBite; + vibThrBiteLo = vibZeroBite + vibSquelchBite; digitalWrite(statusLedPin, LOW); delay(250); @@ -948,49 +964,84 @@ void pitch_bend() { int vibMax; int calculatedPBdepth; byte pbTouched = 0; + int vibRead; + int vibReadBite; pbUp = touchRead(pbUpPin); // SENSOR PIN 23 - PCB PIN "Pu" pbDn = touchRead(pbDnPin); // SENSOR PIN 22 - PCB PIN "Pd" halfPitchBendKey = (pinkySetting == PBD) && (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" - hold for 1/2 pitchbend value - int vibRead = touchRead(vibratoPin); // SENSOR PIN 15 - built in var cap + calculatedPBdepth = pbDepthList[PBdepth]; if (halfPitchBendKey) calculatedPBdepth = calculatedPBdepth * 0.5; + vibMax = vibMaxList[vibSens - 1]; - if (vibRead < vibThr) { - if (UPWD == vibDirection) { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); - } else { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + if (vibControl){ //bite vibrato + if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) + vibReadBite = analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE + } else { + vibReadBite = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) } - } else if (vibRead > vibThrLo) { - if (UPWD == vibDirection) { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + if (vibReadBite < vibThrBite) { + if (UPWD == vibDirection) { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMax), vibThrBite), vibThrBite, (vibZeroBite - vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + } else { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMax), vibThrBite), vibThrBite, (vibZeroBite - vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + } + } else if (vibReadBite > vibThrBiteLo) { + if (UPWD == vibDirection) { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMax)), vibThrBiteLo, (vibZeroBite + vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + } else { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMax)), vibThrBiteLo, (vibZeroBite + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + } } else { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + vibSignal = vibSignal * 0.5; + } + } else { //lever vibrato + vibRead = touchRead(vibratoPin); // SENSOR PIN 15 - built in var cap + if (vibRead < vibThr) { + if (UPWD == vibDirection) { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + } else { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + } + } else if (vibRead > vibThrLo) { + if (UPWD == vibDirection) { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + } else { + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + } + } else { + vibSignal = vibSignal * 0.5; } - } else { - vibSignal = vibSignal * 0.5; } + + switch (vibRetn) { // moving baseline case 0: //keep vibZero value break; case 1: vibZero = vibZero * 0.95 + vibRead * 0.05; + vibZeroBite = vibZeroBite * 0.95 + vibReadBite * 0.05; break; case 2: vibZero = vibZero * 0.9 + vibRead * 0.1; + vibZeroBite = vibZeroBite * 0.9 + vibReadBite * 0.1; break; case 3: vibZero = vibZero * 0.8 + vibRead * 0.2; + vibZeroBite = vibZeroBite * 0.8 + vibReadBite * 0.2; break; case 4: vibZero = vibZero * 0.6 + vibRead * 0.4; + vibZeroBite = vibZeroBite * 0.6 + vibReadBite * 0.4; } vibThr = vibZero - vibSquelch; vibThrLo = vibZero + vibSquelch; + vibThrBite = vibZeroBite - vibSquelchBite; + vibThrBiteLo = vibZeroBite + vibSquelchBite; int pbPos = map(constrain(pbUp, pitchbThrVal, pitchbMaxVal), pitchbThrVal, pitchbMaxVal, 0, calculatedPBdepth); int pbNeg = map(constrain(pbDn, pitchbThrVal, pitchbMaxVal), pitchbThrVal, pitchbMaxVal, 0, calculatedPBdepth); int pbSum = 8193 + pbPos - pbNeg; @@ -1132,19 +1183,21 @@ void extraController() { //*********************************************************** void portamento_() { - // Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece - if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) - biteSensor=analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE - } else { - biteSensor = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) - } - if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento - if (!portIsOn) { - portOn(); + if (!vibControl){ + // Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece + if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) + biteSensor=analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE + } else { + biteSensor = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) + } + if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento + if (!portIsOn) { + portOn(); + } + port(); + } else if (portIsOn) { // we have just gone below threshold, so send zero value + portOff(); } - port(); - } else if (portIsOn) { // we have just gone below threshold, so send zero value - portOff(); } } diff --git a/NuEVI/globals.h b/NuEVI/globals.h index b61882b..a9b0f0d 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -62,6 +62,9 @@ extern unsigned short vibSens; // vibrato sensitivity extern unsigned short vibRetn; // vibrato return speed extern unsigned short vibSquelch; //vibrato signal squelch extern unsigned short vibDirection; //direction of first vibrato wave UPWD or DNWD +extern unsigned short vibSensBite; // vibrato sensitivity (bite) +extern unsigned short vibSquelchBite; //vibrato signal squelch (bite) +extern unsigned short vibControl; extern unsigned short fastPatch[7]; extern uint16_t gateOpenEnable; extern uint16_t specialKeyEnable; @@ -103,6 +106,9 @@ extern byte oldpkey; extern int vibThr; // this gets auto calibrated in setup extern int vibThrLo; extern int vibZero; +extern int vibZeroBite; +extern int vibThrBite; +extern int vibThrBiteLo; // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed extern byte K1; // Valve 1 (pitch change -2) diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index b826176..d2793ac 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -871,15 +871,6 @@ const MenuEntrySub vibDepthMenu = { nullptr }; -const MenuEntrySub vibSenseMenu = { - MenuType::ESub, "SENSE", "LEVEL", &vibSens, 1, 12, MenuEntryFlags::ENone, - [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { - numToString(vibSens, textBuffer); - }, - [](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_ADDR,vibSens); } - , nullptr -}; - const MenuEntrySub vibRetnMenu = { MenuType::ESub, "RETURN", "LEVEL", &vibRetn, 0, 4, MenuEntryFlags::ENone, [](SubMenuRef __unused, char* textBuffer, const char** __unused unit) { @@ -889,8 +880,17 @@ const MenuEntrySub vibRetnMenu = { , nullptr }; +const MenuEntrySub vibSenseMenu = { + MenuType::ESub, "SENSE LVR", "LEVEL", &vibSens, 1, 12, MenuEntryFlags::ENone, + [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { + numToString(vibSens, textBuffer); + }, + [](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_ADDR,vibSens); } + , nullptr +}; + const MenuEntrySub vibSquelchMenu = { - MenuType::ESub, "SQUELCH", "LEVEL", &vibSquelch, 1, 30, MenuEntryFlags::ENone, + MenuType::ESub, "SQUELCH L", "LEVEL", &vibSquelch, 1, 30, MenuEntryFlags::ENone, [](SubMenuRef __unused, char* textBuffer, const char** __unused unit) { numToString(vibSquelch, textBuffer); }, @@ -898,6 +898,36 @@ const MenuEntrySub vibSquelchMenu = { , nullptr }; +const MenuEntrySub vibSenseBiteMenu = { + MenuType::ESub, "SENSE BTE", "LEVEL", &vibSensBite, 1, 12, MenuEntryFlags::ENone, + [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { + numToString(vibSensBite, textBuffer); + }, + [](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_BITE_ADDR,vibSensBite); } + , nullptr +}; + +const MenuEntrySub vibSquelchBiteMenu = { + MenuType::ESub, "SQUELCH B", "LEVEL", &vibSquelchBite, 1, 30, MenuEntryFlags::ENone, + [](SubMenuRef __unused, char* textBuffer, const char** __unused unit) { + numToString(vibSquelchBite, textBuffer); + }, + [](const MenuEntrySub & __unused sub) { writeSetting(VIB_SQUELCH_BITE_ADDR,vibSquelchBite); } + , nullptr +}; + +const MenuEntrySub vibControlMenu = { + MenuType::ESub, "CONTROL", "CONTROL", &vibControl , 0, 1, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + if (vibControl) + strncpy(out, "BIT", 4); + else + strncpy(out, "LVR", 4); + }, + [](const MenuEntrySub & __unused sub) { writeSetting(VIB_CONTROL_ADDR,vibControl); } + , nullptr +}; + const MenuEntrySub vibDirMenu = { MenuType::ESub, "DIRECTION", "DIRECTION", &vibDirection , 0, 1, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { @@ -911,11 +941,14 @@ const MenuEntrySub vibDirMenu = { }; const MenuEntry* vibratorMenuEntries[] = { + (MenuEntry*)&vibControlMenu, (MenuEntry*)&vibDepthMenu, - (MenuEntry*)&vibSenseMenu, (MenuEntry*)&vibRetnMenu, + (MenuEntry*)&vibDirMenu, + (MenuEntry*)&vibSenseMenu, (MenuEntry*)&vibSquelchMenu, - (MenuEntry*)&vibDirMenu + (MenuEntry*)&vibSenseBiteMenu, + (MenuEntry*)&vibSquelchBiteMenu, }; const MenuPage vibratoMenuPage = { diff --git a/NuEVI/settings.h b/NuEVI/settings.h index 3305715..32167dd 100644 --- a/NuEVI/settings.h +++ b/NuEVI/settings.h @@ -51,6 +51,9 @@ #define VIB_DIRECTION_ADDR 86 #define BREATH_CC2_ADDR 88 #define BREATH_CC2_RISE_ADDR 90 +#define VIB_SENS_BITE_ADDR 92 +#define VIB_SQUELCH_BITE_ADDR 94 +#define VIB_CONTROL_ADDR 96 //"factory" values for settings #define VERSION 32 @@ -90,9 +93,12 @@ #define PRIO_FACTORY 0 // Mono priority 0 - BAS(e note), 1 - ROT(ating note) #define VIB_SENS_FACTORY 6 // 1 least sensitive, higher more sensitive #define VIB_RETN_FACTORY 2 // 0, no return, 1 slow return, higher faster return -#define VIB_SQUELCH_FACTORY 15 // 0 to 30, vib signal squelch +#define VIB_SQUELCH_FACTORY 12 // 0 to 30, vib signal squelch #define VIB_DIRECTION_FACTORY 0 #define BREATH_CC2_FACTORY 0 //OFF,1-127 #define BREATH_CC2_RISE_FACTORY 1 +#define VIB_SENS_BITE_FACTORY 6 +#define VIB_SQUELCH_BITE_FACTORY 12 +#define VIB_CONTROL_FACTORY 0 #endif