From b80f9247a22216268f9211b35cd76ce4d221f315 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Fri, 4 Sep 2020 11:32:40 +0200 Subject: [PATCH] Added compile option to include a MPR121 board adress scanning function for troubleshooting (MENU button at startup). Changed the destination setup for bite and lever to be less confusing and more powerful (custom CCs now possible). The VIB CTL item in the VIBRATO menu is now removed, and in SETUP CTL menu you will find BITE CTL, BITE CC, LEVER CTL and LEVER CC. BITE CTL and LEVER CTL can both be set to any of these destinations: OFF - no destination active for this controller VIB - vibrato GLD - glide/portamento (defined by GLIDE MOD and GLIDE LMT settings) CC - custom CC output (defined in GLIDE CC and LEVER CC settings) Settings in GLIDE CC and LEVER CC are only used when corresponding control is set to CC in its CTL setting as described above. --- NuEVI/NuEVI.ino | 161 +- NuEVI/config.h | 2 +- NuEVI/globals.h | 7 +- NuEVI/hardware.h | 2 + NuEVI/menu.cpp | 91 +- NuEVI/menu.h | 1 + NuEVI/settings.cpp | 11 + NuEVI/settings.h | 12 +- uploadable hex files/NuEVI-v15b4.ino.hex | 5501 ++++++++++++++++ uploadable hex files/NuRAD-v15b4.ino.hex | 5614 +++++++++++++++++ user guides/notes 1.5b4.txt | 50 + .../poly play user guide section otfkey.txt | 68 - user guides/poly play user guide section.txt | 6 +- 13 files changed, 11443 insertions(+), 83 deletions(-) mode change 100755 => 100644 NuEVI/menu.h create mode 100644 uploadable hex files/NuEVI-v15b4.ino.hex create mode 100644 uploadable hex files/NuRAD-v15b4.ino.hex create mode 100644 user guides/notes 1.5b4.txt delete mode 100644 user guides/poly play user guide section otfkey.txt diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index c2ce486..4227d67 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -114,6 +114,10 @@ unsigned short vibDirection = DNWD; //direction of first vibrato wave UPWD or DN unsigned short vibSensBite = 2; // vibrato sensitivity (bite) unsigned short vibSquelchBite = 12; //vibrato signal squelch (bite) unsigned short vibControl = 0; +unsigned short biteControl = 0; // OFF, VIB, GLD, CC +unsigned short leverControl = 0; // OFF, VIB, GLD, CC +unsigned short biteCC = 0; // 0 - 127 +unsigned short leverCC = 0; // 0 -127 unsigned short fastPatch[7] = {0,0,0,0,0,0,0}; @@ -209,9 +213,13 @@ int leverPortRead; int biteSensor=0; // capacitance data from bite sensor, for midi cc and threshold checks byte portIsOn=0; // keep track and make sure we send CC with 0 value when off threshold +byte biteIsOn=0; // keep track and make sure we send CC with 0 value when off threshold +byte leverIsOn=0; // keep track and make sure we send CC with 0 value when off threshold int oldport=0; int lastBite=0; byte biteJumper=0; +int oldbitecc=0; +int oldlevercc=0; int cvPitch; int targetPitch; @@ -542,6 +550,7 @@ FilterOnePole breathFilter; IntervalTimer cvTimer; bool configManagementMode = false; +bool i2cScan = false; //_______________________________________________________________________________________________ SETUP @@ -563,6 +572,8 @@ void cvUpdate(){ #endif } + + void setup() { analogReadResolution(12); // set resolution of ADCs to 12 bit @@ -592,7 +603,8 @@ void setup() { bool factoryReset = !digitalRead(ePin) && !digitalRead(mPin); configManagementMode = !factoryReset && !digitalRead(uPin) && !digitalRead(dPin); - + i2cScan = !factoryReset && !digitalRead(mPin); + initDisplay(); //Start up display and show logo //If going into config management mode, stop here before we even touch the EEPROM. @@ -601,6 +613,14 @@ void setup() { return; } + #if defined(I2CSCANNER) + if(i2cScan){ + delay(2000); + i2cScanDisplay(); + } + #endif + + //Read eeprom data into global vars readEEPROM(factoryReset); @@ -1335,6 +1355,8 @@ void loop() { // deal with Pitch Bend, Modulation, etc. pitch_bend(); extraController(); + biteCC_(); + leverCC_(); ccSendTime = currentTime; } if (currentTime - ccSendTime2 > CC_INTERVAL2) { @@ -1507,7 +1529,7 @@ void pitch_bend() { vibMax = vibMaxList[vibSens - 1]; vibMaxBite = vibMaxBiteList[vibSensBite - 1]; - if (vibControl){ //bite vibrato + if (1 == biteControl){ //bite vibrato if (biteJumper){ //PBITE (if pulled low with jumper, or NuRAD compile, use pressure sensor instead of capacitive bite sensor) vibReadBite = analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE } else { @@ -1529,7 +1551,7 @@ void pitch_bend() { vibSignal = vibSignal / 2; } } - if (vibControl != 1) { //lever vibrato + if (1 == leverControl) { //lever vibrato vibRead = touchRead(vibratoPin); // SENSOR PIN 15 - built in var cap if (vibRead < vibThr) { if (UPWD == vibDirection) { @@ -1788,7 +1810,8 @@ void extraController() { //*********************************************************** -void portamento_() { +/* +void portamento_() { //old version 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 { @@ -1831,6 +1854,7 @@ void portamento_() { } } + //*********************************************************** void portOn() { @@ -1878,6 +1902,135 @@ void portOff() { } //*********************************************************** +*/ + + +void portamento_() { + int portSumCC = 0; + if (pinkySetting == GLD){ + if (portamento && pinkyKey){ + portSumCC += portLimit; + } + } + if (2 == biteControl) { + // Portamento is controlled with the bite sensor in the mouthpiece + if (biteJumper) { //PBITE (if pulled low with jumper or if on a NuRAD, 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 + portSumCC += map(constrain(biteSensor, portamThrVal, portamMaxVal), portamThrVal, portamMaxVal, 0, portLimit); + } + } + if (2 == leverControl) { + // Portamento is controlled with thumb lever + leverPortRead = touchRead(vibratoPin); + if (portamento && ((3000-leverPortRead) >= leverThrVal)) { // if we are enabled and over the threshold, send portamento + portSumCC += map(constrain((3000-leverPortRead), leverThrVal, leverMaxVal), leverThrVal, leverMaxVal, 0, portLimit); + } + } + portSumCC = constrain(portSumCC, 0, portLimit); // Total output glide rate limited to glide max setting + if (portSumCC) { // there is a portamento level, so go for it + if (!portIsOn) { + portOn(); + } + port(portSumCC); + }else if (portIsOn) { + portOff(); + } +} + +//*********************************************************** + +void portOn() { + if ((portamento == 2) || (portamento == 5)) { // if portamento midi switching is enabled + midiSendControlChange(CCN_PortOnOff, 127); + } else if (portamento == 3) { // if portamento midi switching is enabled - SE02 OFF/LIN + midiSendControlChange(CCN_PortSE02, 64); + } else if (portamento == 4) { // if portamento midi switching is enabled - SE02 OFF/EXP + midiSendControlChange(CCN_PortSE02, 127); + } + portIsOn = 1; +} + +//*********************************************************** + +void port(int portCC) { + if ((portamento != 5) && (portCC != oldport)) { // portamento setting 5 is switch only, do not transmit glide rate + midiSendControlChange(CCN_Port, portCC); + } + oldport = portCC; +} + +//*********************************************************** + +void portOff() { + if ((portamento != 5) && (oldport != 0)) { //did a zero get sent? if not, then send one (unless portamento is switch only) + midiSendControlChange(CCN_Port, 0); + } + if ((portamento == 2) || (portamento == 5)) { // if portamento midi switching is enabled + midiSendControlChange(CCN_PortOnOff, 0); + } else if (portamento == 3) { // if portamento midi switching is enabled - SE02 OFF/LIN + midiSendControlChange(CCN_PortSE02, 0); + } else if (portamento == 4) { // if portamento midi switching is enabled - SE02 OFF/EXP + midiSendControlChange(CCN_PortSE02, 0); + } + portIsOn = 0; + oldport = 0; +} + +//*********************************************************** + +void biteCC_() { + int biteCClevel = 0; + if (3 == biteControl){ + if (biteJumper) { //PBITE (if pulled low with jumper or if on a NuRAD, 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 (biteSensor >= portamThrVal) { // we are over the threshold, calculate CC value + biteCClevel = map(constrain(biteSensor, portamThrVal, portamMaxVal), portamThrVal, portamMaxVal, 0, 127); + } + if (biteCClevel) { // there is a bite CC level, so go for it + if (!biteIsOn) { + biteIsOn = 1; + } + if (biteCClevel != oldbitecc) { + midiSendControlChange(biteCC, biteCClevel); + } + oldbitecc = biteCClevel; + } else if (biteIsOn) { + midiSendControlChange(biteCC, 0); + biteIsOn = 0; + oldbitecc = 0; + } + } +} + +void leverCC_() { + int leverCClevel = 0; + if (3 == leverControl){ + leverPortRead = touchRead(vibratoPin); + if (((3000-leverPortRead) >= leverThrVal)) { // we are over the threshold, calculate CC value + leverCClevel = map(constrain((3000-leverPortRead), leverThrVal, leverMaxVal), leverThrVal, leverMaxVal, 0, 127); + } + if (leverCClevel) { // there is a lever CC level, so go for it + if (!leverIsOn) { + leverIsOn = 1; + } + if (leverCClevel != oldlevercc) { + midiSendControlChange(leverCC, leverCClevel); + } + oldlevercc = leverCClevel; + } else if (leverIsOn) { + midiSendControlChange(leverCC, 0); + leverIsOn = 0; + oldlevercc = 0; + } + } +} void autoCal() { int calRead; diff --git a/NuEVI/config.h b/NuEVI/config.h index 7b70176..bbc359e 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,7 +5,7 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.5b3" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< +#define FIRMWARE_VERSION "1.5b4" // 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 ee7f5a5..673c5cd 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -18,7 +18,7 @@ #define NOTE_ON 3 -//Magic value where pinky button means "pitch bend" +//Magic values #define PBD 12 #define EC2 25 #define ECSW 26 @@ -41,7 +41,6 @@ #define MOD 13 - //Vibrato direction #define UPWD 1 #define DNWD 0 @@ -114,6 +113,10 @@ extern unsigned short hmzKey; // 0-11 (0 is C) extern unsigned short hmzLimit; // 2-5 extern unsigned short otfKey; //OFF:ON extern unsigned short breathInterval; // 3-15 +extern unsigned short biteControl; // OFF, VIB, GLD, CC +extern unsigned short leverControl; // OFF, VIB, GLD, CC +extern unsigned short biteCC; // 0 - 127 +extern unsigned short leverCC; // 0 -127 extern uint16_t gateOpenEnable; extern uint16_t specialKeyEnable; extern byte rotatorOn; diff --git a/NuEVI/hardware.h b/NuEVI/hardware.h index e777da1..9dac779 100644 --- a/NuEVI/hardware.h +++ b/NuEVI/hardware.h @@ -4,6 +4,8 @@ #define REVB //#define NURAD +#define I2CSCANNER + #if defined(NURAD) //NuRAD <<<<<<<<<<<<<<<<<<<<<<< // Pin definitions diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index cea21d1..99a3bd3 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -258,6 +258,40 @@ void showVersion() { display.display(); } +void i2cScanDisplay(){ + uint8_t target; // slave addr + byte error; + while(1){ + display.clearDisplay(); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(0,0); + display.println("MPR121 board scan"); + display.display(); + for(target = 0x5A; target <= 0x5D; target++) // sweep addr + { + Wire.beginTransmission(target); // slave addr + error = Wire.endTransmission(); + delay(500); + display.print("Addr 0x"); + display.print(target,HEX); + if (error) + display.print(" N\n"); + else + display.print(" Y\n"); + display.display(); + } + delay(1000); + display.println(); + display.println("MENU to rescan"); + display.println("Power off to exit"); + display.display(); + while (digitalRead(mPin)){ + delay(100); + } + } +} + // Assumes dest points to a buffer of atleast 7 bytes. static const char* numToString(int16_t value, char* dest, bool plusSign = false) { char* ptr = dest; @@ -1294,8 +1328,47 @@ const MenuPage breathMenuPage = { //*********************************************************** // Control menu + +const MenuEntrySub biteCtlMenu = { + MenuType::ESub, "BITE CTL", "BITE DEST", &biteControl, 0, 3, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused,char* out, const char ** __unused unit) { + const char* labs[] = { "OFF", "VIB", "GLD", "CC" }; + strncpy(out, labs[biteControl], 4); + }, + [](SubMenuRef __unused sub) { writeSetting(BITECTL_ADDR,biteControl); } + , nullptr +}; + +const MenuEntrySub biteCCMenu = { + MenuType::ESub, "BITE CC", "CC NUMBER", &biteCC, 0, 127, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + numToString(biteCC, out); + }, +[](const MenuEntrySub & __unused sub) { writeSetting(BITECC_ADDR,biteCC); } + , nullptr +}; + +const MenuEntrySub leverCtlMenu = { + MenuType::ESub, "LEVER CTL", "LEVER DEST", &leverControl, 0, 3, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused,char* out, const char ** __unused unit) { + const char* labs[] = { "OFF", "VIB", "GLD", "CC" }; + strncpy(out, labs[leverControl], 4); + }, + [](SubMenuRef __unused sub) { writeSetting(LEVERCTL_ADDR,leverControl); } + , nullptr +}; + +const MenuEntrySub leverCCMenu = { + MenuType::ESub, "LEVER CC", "CC NUMBER", &leverCC, 0, 127, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + numToString(leverCC, out); + }, +[](const MenuEntrySub & __unused sub) { writeSetting(LEVERCC_ADDR,leverCC); } + , nullptr +}; + const MenuEntrySub portMenu = { - MenuType::ESub, "GLIDE CTL", "PORT/GLD", &portamento, 0, 5, MenuEntryFlags::EMenuEntryWrap, + MenuType::ESub, "GLIDE MOD", "PORT/GLD", &portamento, 0, 5, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused,char* out, const char ** __unused unit) { const char* labs[] = { "OFF", "ON", "SW", "SEL", "SEE", "SWO" }; strncpy(out, labs[portamento], 4); @@ -1451,7 +1524,7 @@ const MenuEntrySub fingeringMenu = { const MenuEntrySub lpinky3Menu = { - MenuType::ESub, "EXTRA PKEY", "EXTRA PKEY", &lpinky3, 0, 25, MenuEntryFlags::ENone, + MenuType::ESub, "EXTRA KEY", "EXTRA PKEY", &lpinky3, 0, 25, MenuEntryFlags::ENone, [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { if (lpinky3 == 0) strncpy(textBuffer, "OFF", 4); @@ -1466,13 +1539,17 @@ const MenuEntrySub lpinky3Menu = { #if defined(NURAD) const MenuEntry* controlMenuEntries[] = { + (MenuEntry*)&biteCtlMenu, + (MenuEntry*)&biteCCMenu, + (MenuEntry*)&leverCtlMenu, + (MenuEntry*)&leverCCMenu, (MenuEntry*)&portMenu, (MenuEntry*)&portLimitMenu, + (MenuEntry*)&vibratoSubMenu, (MenuEntry*)&extraMenu, (MenuEntry*)&extraCC2Menu, (MenuEntry*)&harmonicsMenu, (MenuEntry*)&harmSelectMenu, - (MenuEntry*)&vibratoSubMenu, (MenuEntry*)°litchMenu, (MenuEntry*)&pinkyMenu, (MenuEntry*)&lvlCtrlCCMenu, @@ -1482,13 +1559,17 @@ const MenuEntry* controlMenuEntries[] = { }; #else const MenuEntry* controlMenuEntries[] = { + (MenuEntry*)&biteCtlMenu, + (MenuEntry*)&biteCCMenu, + (MenuEntry*)&leverCtlMenu, + (MenuEntry*)&leverCCMenu, (MenuEntry*)&portMenu, (MenuEntry*)&portLimitMenu, + (MenuEntry*)&vibratoSubMenu, (MenuEntry*)&extraMenu, (MenuEntry*)&extraCC2Menu, (MenuEntry*)&harmonicsMenu, (MenuEntry*)&harmSelectMenu, - (MenuEntry*)&vibratoSubMenu, (MenuEntry*)°litchMenu, (MenuEntry*)&pinkyMenu, (MenuEntry*)&lvlCtrlCCMenu, @@ -1600,7 +1681,7 @@ const MenuEntrySub vibDirMenu = { }; const MenuEntry* vibratorMenuEntries[] = { - (MenuEntry*)&vibControlMenu, + //(MenuEntry*)&vibControlMenu, (MenuEntry*)&vibDepthMenu, (MenuEntry*)&vibRetnMenu, (MenuEntry*)&vibDirMenu, diff --git a/NuEVI/menu.h b/NuEVI/menu.h old mode 100755 new mode 100644 index 8fd4016..e65cc3e --- a/NuEVI/menu.h +++ b/NuEVI/menu.h @@ -41,6 +41,7 @@ void initDisplay(); void showVersion(); void menu(); void drawSensorPixels(); +void i2cScanDisplay(); int updateAdjustMenu(uint32_t timeNow, KeyState &input, bool firstRun, bool drawSensor); bool adjustPageUpdate(KeyState &input, uint32_t timeNow); diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 06453f0..407ce9d 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -162,6 +162,13 @@ void readEEPROM(const bool factoryReset) { writeSetting(BRHARMSET_ADDR, BRHARMSET_FACTORY); writeSetting(BRHARMSEL_ADDR, BRHARMSEL_FACTORY); } + + if(settingsVersion < 42) { + writeSetting(BITECTL_ADDR, BITECTL_FACTORY); + writeSetting(BITECC_ADDR, BITECC_FACTORY); + writeSetting(LEVERCTL_ADDR, LEVERCTL_FACTORY); + writeSetting(LEVERCC_ADDR, LEVERCC_FACTORY); + } writeSetting(VERSION_ADDR, EEPROM_VERSION); @@ -253,6 +260,10 @@ void readEEPROM(const bool factoryReset) { 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); + biteControl = readSettingBounded(BITECTL_ADDR, 0, 3, BITECTL_FACTORY); + leverControl = readSettingBounded(LEVERCTL_ADDR, 0, 3, LEVERCTL_FACTORY); + biteCC = readSettingBounded(BITECC_ADDR, 0, 127, BITECC_FACTORY); + leverCC = readSettingBounded(LEVERCC_ADDR, 0, 127, LEVERCC_FACTORY); //Flags stored in bit field fastBoot = (dipSwBits & (1<