From 4decdf1d725311d2130dedaffe986fcaadebf8a3 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Wed, 11 Dec 2019 16:12:01 +0100 Subject: [PATCH] Now it's also NuRAD firmware! Set define for compile option NURAD in hardware.h to switch. Added a new little thing for NuEVI too: releasing the rollers leaves octave in current one instead of going to bottom octave unless coming down from first roller. This is helpful against bass hum from filter leak when setting the EVI aside, using pitch CV from NuEVI and synth with no VCA in use or gate open (drone mode). --- NuEVI/NuEVI.ino | 208 ++++++++++++++++++++++++++++++++++++++++--- NuEVI/adjustmenu.cpp | 32 +++++++ NuEVI/config.h | 2 +- NuEVI/globals.h | 6 ++ NuEVI/hardware.h | 76 ++++++++++++++++ NuEVI/menu.cpp | 104 ++++++++++++++++++++-- NuEVI/name.c | 5 +- NuEVI/settings.cpp | 5 ++ 8 files changed, 418 insertions(+), 20 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 798e612..1d53d0d 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -24,6 +24,21 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath */ +/* +but hey, it's also... + +NAME: NuRAD +WRITTEN BY: JOHAN BERGLUND +DATE: 2019-08-09 +FILE SAVED AS: n/a +FOR: PJRC Teensy 3.2 and three MPR121 capactive touch sensor boards. + Uses an SSD1306 controlled OLED display communicating over I2C. +PROGRAMME FUNCTION: EWI Wind Controller using the Freescale MP3V5004GP breath sensor + and capacitive touch keys. Output to both USB MIDI and DIN MIDI. + +...if you just uncomment the #define NURAD in hardware.h +*/ + //Make sure compiler is set to the appropriate platform #ifndef __MK20DX256__ @@ -105,6 +120,11 @@ byte ccList[11] = {0,1,2,7,11,1,2,7,11,74,20}; // OFF, Modulation, Breath, Volu int pbDepthList[13] = {8192,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683}; +#if defined(NURAD) +int calOffsetRollers[6] = {16,10,8,21,24,41}; +int calOffsetRH[12] = {-88,-68,-31,13,4,120,121,-68,-85,-34,23,87}; +int calOffsetLH[12] = {90,-13,-33,-93,-82,115,118,2,4,-40,-75,-94}; +#endif // the following variables are unsigned longs because the time, measured in // milliseconds, will quickly become a bigger number than can be stored in an int. @@ -150,7 +170,11 @@ byte velocitySend; // remapped midi velocity from breath sensor (or set to sta int breathCalZero; int leverPortZero; +#if defined(NURAD) +int leverPortThr = 40; +#else int leverPortThr = 50; +#endif int leverPortRead; @@ -176,6 +200,8 @@ int pbDn=0; byte vibLedOff = 0; byte oldpkey = 0; +byte lap = 0; + static const float vibDepth[10] = {0,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.40,0.45}; // max pitch bend values (+/-) for the vibrato settings static const short vibMaxBiteList[17] = {1600,1400,1200,1000,900,800,700,600,500,400,300,250,200,150,100,50,25}; static const short vibMaxList[12] = {300,275,250,225,200,175,150,125,100,75,50,25}; @@ -219,6 +245,34 @@ int slurBase; // first note in slur sustain chord int slurInterval[9] = {-5,0,0,0,0,0,0,0,0}; byte addedIntervals = 1; +#if defined(NURAD) + // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed +byte LHs; +byte LH1; // Left Hand key 1 (pitch change -2) +byte LHb; // Left Hand bis key (pitch change -1 unless both LH1 and LH2 are pressed) +byte LH2; // Left Hand key 2 (with LH1 also pressed pitch change is -2, otherwise -1) +byte LH3; // Left Hand key 3 (pitch change -2) +byte LHp1; // Left Hand pinky key 1 (pitch change +1) +byte LHp2; // Left Hand pinky key 2 (pitch change -1) +byte LHp3; +byte RHs; // Right Hand side key (pitch change -2 unless LHp1 is pressed) +byte RH1; // Right Hand key 1 (with LH3 also pressed pitch change is -2, otherwise -1) +byte RH2; // Right Hand key 2 (pitch change -1) +byte RH3; // Right Hand key 3 (pitch change -2) +byte RHp1; // Right Hand pinky key 1 (pitch change +1) +byte RHp2; // Right Hand pinky key 2 (pitch change -1) +byte RHp3; // Right Hand pinky key 3 (pitch change -2) +byte Tr1; // Trill key 1 (pitch change +2) (EVI fingering) +byte Tr2; // Trill key 2 (pitch change +1) +byte Tr3; // Trill key 3 (pitch change +4) +byte K1; // Valve 1 (pitch change -2) +byte K2; // Valve 2 (pitch change -1) +byte K3; // Valve 3 (pitch change -3) +byte K4; // Left Hand index finger (pitch change -5) +byte K5; // Trill key 1 (pitch change +2) +byte K6; // Trill key 2 (pitch change +1) +byte K7; // Trill key 3 (pitch change +4) +#else // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed byte K1; // Valve 1 (pitch change -2) byte K2; // Valve 2 (pitch change -1) @@ -227,7 +281,7 @@ byte K4; // Left Hand index finger (pitch change -5) byte K5; // Trill key 1 (pitch change +2) byte K6; // Trill key 2 (pitch change +1) byte K7; // Trill key 3 (pitch change +4) - +#endif byte R1; byte R2; byte R3; @@ -254,7 +308,13 @@ byte slurSustain = 0; byte parallelChord = 0; byte subOctaveDouble = 0; +#if defined(NURAD) +Adafruit_MPR121 touchSensorRollers = Adafruit_MPR121(); +Adafruit_MPR121 touchSensorRH = Adafruit_MPR121(); +Adafruit_MPR121 touchSensorLH = Adafruit_MPR121(); +#else Adafruit_MPR121 touchSensor = Adafruit_MPR121(); // This is the 12-input touch sensor +#endif FilterOnePole breathFilter; IntervalTimer cvTimer; @@ -266,11 +326,18 @@ bool configManagementMode = false; //Update CV output pin, run from timer. void cvUpdate(){ int cvPressure = analogRead(breathSensorPin); + #if defined(NURAD) + analogWrite(pwmDacPin,map(constrain(cvPressure,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095)); + if(dacMode == DAC_MODE_BREATH){ + analogWrite(dacPin,map(constrain(cvPressure,breathThrVal,4095),breathThrVal,4095,0,4095)); + } + #else if(dacMode == DAC_MODE_PITCH){ analogWrite(pwmDacPin,cvPressure); } else { //DAC_MODE_BREATH analogWrite(dacPin,map(constrain(cvPressure,breathThrVal,4095),breathThrVal,4095,0,4095)); } + #endif } void setup() { @@ -291,9 +358,14 @@ void setup() { pinMode(dacPin, OUTPUT); //DAC output for analog signal pinMode(pwmDacPin, OUTPUT); //PWMed DAC output for analog signal + #if defined(NURAD) + pinMode(eLedPin, OUTPUT); // breath indicator LED + pinMode(sLedPin, OUTPUT); // portam indicator LED + #else pinMode(biteJumperPin, INPUT_PULLUP); //PBITE pinMode(biteJumperGndPin, OUTPUT); //PBITE digitalWrite(biteJumperGndPin, LOW); //PBITE + #endif bool factoryReset = !digitalRead(ePin) && !digitalRead(mPin); configManagementMode = !factoryReset && !digitalRead(uPin) && !digitalRead(dPin); @@ -308,21 +380,39 @@ void setup() { //Read eeprom data into global vars readEEPROM(factoryReset); - - activePatch = patch; - + touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); - + + activePatch = patch; + + #if defined(NURAD) + digitalWrite(statusLedPin,HIGH); + if (!touchSensorRollers.begin(0x5D)) { + while (1); // Touch sensor initialization failed - stop doing stuff + } + if (!touchSensorLH.begin(0x5C)) { + while (1); // Touch sensor initialization failed - stop doing stuff + } + if (!touchSensorRH.begin(0x5B)) { + while (1); // Touch sensor initialization failed - stop doing stuff + } + digitalWrite(statusLedPin,LOW); + #else if (!touchSensor.begin(0x5A)) { while (1); // Touch sensor initialization failed - stop doing stuff } + #endif breathFilter.setFilter(LOWPASS, filterFreq, 0.0); // create a one pole (RC) lowpass filter + #if defined(NURAD) + biteJumper = true; + #else biteJumper = !digitalRead(biteJumperPin); if (biteJumper){ pinMode(bitePin, INPUT); } + #endif //auto-calibrate the vibrato threshold while showing splash screen vibZero = vibZeroBite = breathCalZero = 0; @@ -330,7 +420,7 @@ void setup() { for(int i = 1 ; i <= sampleCount; ++i) { vibZero += touchRead(vibratoPin); breathCalZero += analogRead(breathSensorPin); - if (biteJumper) vibZeroBite += analogRead(A7); else vibZeroBite += touchRead(bitePin); + if (biteJumper) vibZeroBite += analogRead(bitePressurePin); else vibZeroBite += touchRead(bitePin); statusLed(i&1); delay(fastBoot?75:250); //Shorter delay for fastboot } @@ -538,7 +628,10 @@ void loop() { } if (analogRead(breathSensorPin) > (breathCalZero - 850)) programonce = false; + #if defined(NURAD) + #else specialKey = (touchRead(specialKeyPin) > touch_Thr); //S2 on pcb + #endif if (specialKeyEnable) { if (lastSpecialKey != specialKey) { if (specialKey) { @@ -800,7 +893,10 @@ void loop() { ccSendTime2 = currentTime; } if (currentTime - ccSendTime3 > CC_INTERVAL3) { + #if defined(NURAD) + #else if (gateOpenEnable || gateOpen) doorKnobCheck(); + #endif if (((pinkySetting == LVL) || (pinkySetting == LVLP) || (pinkySetting == GLD)) && pinkyKey && (mainState == NOTE_OFF)){ // show LVL indication } else updateSensorLEDs(); @@ -941,9 +1037,9 @@ void pitch_bend() { byte pbTouched = 0; int vibRead = 0; int vibReadBite = 0; - 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 + pbUp = touchRead(pbUpPin); // PCB PIN "Pu" + pbDn = touchRead(pbDnPin); // PCB PIN "Pd" + halfPitchBendKey = (pinkySetting == PBD) && pinkyKey; // hold pinky key for 1/2 pitchbend value calculatedPBdepth = pbDepthList[PBdepth]; if (halfPitchBendKey) calculatedPBdepth = calculatedPBdepth * 0.5; @@ -953,11 +1049,11 @@ void pitch_bend() { vibMaxBite = vibMaxBiteList[vibSensBite - 1]; if (vibControl){ //bite vibrato - if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) + 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 { vibReadBite = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) - } + } if (vibReadBite < vibThrBite) { if (UPWD == vibDirection) { vibSignal = (vibSignal + map(constrain(vibReadBite, (vibZeroBite - vibMaxBite), vibThrBite), vibThrBite, (vibZeroBite - vibMaxBite), 0, calculatedPBdepth * vibDepth[vibrato]))/2; @@ -1189,7 +1285,6 @@ void extraController() { //*********************************************************** void portamento_() { - 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 { @@ -1274,6 +1369,90 @@ void portOff() { void readSwitches() { +#if defined(NURAD) + + switch (lap){ + case 0: + // Octave rollers + int touchValueRollers[12]; + for (byte i=0; i<6; i++){ + touchValueRollers[i]=touchSensorRollers.filteredData(i) - calOffsetRollers[i]; + } + // 6-pin version + octaveR = 0; + if (touchValueRollers[rPin6] < ctouchThrVal) octaveR = 6; //R6 + else if (touchValueRollers[rPin5] < ctouchThrVal) octaveR = 5; //R5 + else if (touchValueRollers[rPin4] < ctouchThrVal) octaveR = 4; //R4 + else if (touchValueRollers[rPin3] < ctouchThrVal) octaveR = 3; //R3 + else if (touchValueRollers[rPin2] < ctouchThrVal) octaveR = 2; //R2 + else if (touchValueRollers[rPin1] < ctouchThrVal) octaveR = 1; //R1 + /* + //5-pin version + octaveR = 0; + if ((touchValueRollers[rPin5] < ctouchThrVal) && (touchValueRollers[rPin3] < ctouchThrVal)) octaveR = 6; //R6 + else if (touchValueRollers[rPin5] < ctouchThrVal) octaveR = 5; //R5 + else if (touchValueRollers[rPin4] < ctouchThrVal) octaveR = 4; //R4 + else if (touchValueRollers[rPin3] < ctouchThrVal) octaveR = 3; //R3 + else if (touchValueRollers[rPin2] < ctouchThrVal) octaveR = 2; //R2 + else if (touchValueRollers[rPin1] < ctouchThrVal) octaveR = 1; //R1 + */ + break; + case 1: + // RH keys + int touchValueRH[12]; + for (byte i=0; i<12; i++){ + touchValueRH[i]=touchSensorRH.filteredData(i) - calOffsetRH[i]; + } + RHs=(touchValueRH[RHsPin] < ctouchThrVal); + RH1=(touchValueRH[RH1Pin] < ctouchThrVal); + RH2=(touchValueRH[RH2Pin] < ctouchThrVal); + RH3=(touchValueRH[RH3Pin] < ctouchThrVal); + RHp1=(touchValueRH[RHp1Pin] < ctouchThrVal); + RHp2=(touchValueRH[RHp2Pin] < ctouchThrVal); + RHp3=(touchValueRH[RHp3Pin] < ctouchThrVal); + specialKey=(touchValueRH[spec1Pin] < ctouchThrVal) && (touchValueRH[spec2Pin] < ctouchThrVal); + break; + case 2: + // LH keys + int touchValueLH[12]; + for (byte i=0; i<12; i++){ + touchValueLH[i]=touchSensorLH.filteredData(i) - calOffsetLH[i]; + } + LHs=(touchValueLH[LHsPin] < ctouchThrVal); + LHb=(touchValueLH[LHbPin] < ctouchThrVal); + LH1=(touchValueLH[LH1Pin] < ctouchThrVal); + LH2=(touchValueLH[LH2Pin] < ctouchThrVal); + LH3=(touchValueLH[LH3Pin] < ctouchThrVal); + LHp1=(touchValueLH[LHp1Pin] < ctouchThrVal); + LHp2=(touchValueLH[LHp2Pin] < ctouchThrVal); + LHp3=(touchValueLH[LHp3Pin] < ctouchThrVal); + } + if (lap<2) lap++; else lap=0; + + K1=RHp2; + K2=LHp2; + K3=LHp3; + K4=LHp1; + K5=RHp1; + K6=RHp2; + K7=RHp3; + + pinkyKey = LHs; + + int qTransp = (pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0; + + + // Calculate midi note number from pressed keys + + //fingeredNote=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12+(octave-3)*12+transpose-12+qTransp; + + fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12; + int fingeredNoteRead = fingeredNoteUntransposed + transpose - 12 + qTransp; + + if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered + +#else //NuEVI + // Read touch pads (MPR121), compare against threshold value bool touchKeys[12]; for (byte i = 0; i < 12; i++) { @@ -1295,6 +1474,9 @@ void readSwitches() { else if (R3 && lastOctaveR) octaveR = 3; //R3 else if (R2) octaveR = 2; //R2 else if (R1) octaveR = 1; //R1 + else if (lastOctaveR > 1) octaveR = lastOctaveR; + //if rollers are released and we are not coming down from roller 1, stay at the higher octave + //CV filter leak prevention when putting NuEVI aside lastOctaveR = octaveR; @@ -1331,6 +1513,8 @@ void readSwitches() { if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered +#endif + if (fingeredNoteRead != lastFingering) { // // reset the debouncing timer lastDeglitchTime = millis(); diff --git a/NuEVI/adjustmenu.cpp b/NuEVI/adjustmenu.cpp index f136cd2..aedb414 100644 --- a/NuEVI/adjustmenu.cpp +++ b/NuEVI/adjustmenu.cpp @@ -12,8 +12,19 @@ //*********************************************************** extern Adafruit_SSD1306 display; +#if defined(NURAD) +extern Adafruit_MPR121 touchSensorRH; +extern Adafruit_MPR121 touchSensorLH; +extern Adafruit_MPR121 touchSensorRollers; +#else extern Adafruit_MPR121 touchSensor; +#endif extern byte cursorNow; +#if defined(NURAD) +extern int calOffsetRollers[6]; +extern int calOffsetRH[12]; +extern int calOffsetLH[12]; +#endif //*********************************************************** // Variables used for the adjust menu @@ -225,6 +236,26 @@ void plotSensorPixels(){ int pos = map(constrain(exSensor, extracLoLimit, extracHiLimit), extracLoLimit, extracHiLimit, 28, 118); redraw = updateSensorPixel(pos, -1); } + #if defined(NURAD) + else if(adjustOption == 4) { + display.drawLine(28,37,118,37,BLACK); + for (byte i=0; i<12; i++){ + int pos = map(constrain(touchSensorRH.filteredData(i) - calOffsetRH[i], ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118); + display.drawPixel(pos, 37, WHITE); + } + display.drawLine(28,38,118,38,BLACK); + for (byte i=0; i<12; i++){ + int pos = map(constrain(touchSensorLH.filteredData(i) - calOffsetLH[i], ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118); + display.drawPixel(pos, 38, WHITE); + } + display.drawLine(28,39,118,39,BLACK); + for (byte i=0; i<6; i++){ + int pos = map(constrain(touchSensorRollers.filteredData(i) - calOffsetRollers[i], ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118); + display.drawPixel(pos, 39, WHITE); + } + redraw = 1; + } + #else //NuEVI else if(adjustOption == 4) { display.drawLine(28,39,118,39,BLACK); for (byte i=0; i<12; i++){ @@ -242,6 +273,7 @@ void plotSensorPixels(){ redraw = 1; } + #endif if (redraw){ display.display(); } diff --git a/NuEVI/config.h b/NuEVI/config.h index ef3a2e0..69607b9 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,7 +5,7 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.4.3" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< +#define FIRMWARE_VERSION "1.4.4" // 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 28ba100..617c4b3 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -34,6 +34,12 @@ extern const unsigned short* const curves[]; extern const unsigned short curveIn[]; +#if defined(NURAD) +extern int calOffsetRollers[6]; +extern int calOffsetRH[12]; +extern int calOffsetLH[12]; +#endif + extern unsigned short breathThrVal; extern unsigned short breathMaxVal; extern unsigned short portamThrVal; diff --git a/NuEVI/hardware.h b/NuEVI/hardware.h index 53c456f..e777da1 100644 --- a/NuEVI/hardware.h +++ b/NuEVI/hardware.h @@ -2,6 +2,81 @@ #define __HARDWARE_H #define REVB +//#define NURAD + +#if defined(NURAD) //NuRAD <<<<<<<<<<<<<<<<<<<<<<< + +// Pin definitions + +// Teensy pins + +//Capacitive sensor pins (on-board teensy) +#define bitePin 17 +#define extraPin 16 +#define pbUpPin 1 +#define pbDnPin 0 +#define vibratoPin 15 + +//Analog pressure sensors. Breath and optional bite +#define breathSensorPin A0 +#define bitePressurePin A7 + +//Digital pins for menu buttons +#define dPin 3 +#define ePin 4 +#define uPin 5 +#define mPin 6 + +//Output pins for LEDs (breath, power, status) +#define bLedPin 10 +#define pLedPin 9 +#define eLedPin 22 +#define sLedPin 23 +#define statusLedPin 13 + +//Analog input for measuring voltage +#define vMeterPin A11 + +//DAC outputs for analog and pwm +#define dacPin A14 +#define pwmDacPin A6 + +//Which serial port to use for MIDI +#define MIDI_SERIAL Serial3 + +// MPR121 Rollers 0x5D + +#define rPin1 0 +#define rPin2 1 +#define rPin3 2 +#define rPin4 3 +#define rPin5 4 +#define rPin6 5 + +// MPR121 RH 0x5C + +#define RHsPin 3 +#define RH1Pin 4 +#define RH2Pin 2 +#define RH3Pin 1 +#define RHp1Pin 0 +#define RHp2Pin 8 +#define RHp3Pin 7 +#define spec1Pin 10 +#define spec2Pin 9 + +// MPR121 LH 0x5B + +#define LHsPin 8 +#define LH1Pin 7 +#define LHbPin 1 +#define LH2Pin 9 +#define LH3Pin 10 +#define LHp1Pin 11 +#define LHp2Pin 3 +#define LHp3Pin 4 + +#else //NuEVI <<<<<<<<<<<<<<<<<<<<<<< // Pin definitions @@ -102,6 +177,7 @@ */ #endif //REVB +#endif //NURAD #endif diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index caaec70..31686d1 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -54,9 +54,77 @@ static byte stateFirstRun = 1; // The status led was update when the Squelch menu was open. byte subVibSquelch = 0; //extern - // 'NuEVI' logo + // 'NuEVI' or 'NuRAD' logo #define LOGO16_GLCD_WIDTH 128 #define LOGO16_GLCD_HEIGHT 64 +#if defined(NURAD) +static const unsigned char PROGMEM nurad_logo_bmp[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x03, 0xf9, 0xff, 0xff, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x07, 0xf9, 0xff, 0xff, 0xfe, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x0e, 0x19, 0x80, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xfc, 0xc0, 0x00, 0x1d, 0xd9, 0xbf, 0xff, 0xf3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xfe, 0xc0, 0x00, 0x3b, 0xd9, 0xbf, 0xff, 0xfb, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x00, 0x77, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x00, 0xee, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x01, 0xdc, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x03, 0xb8, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x6f, 0xff, 0xfe, 0xc0, 0x07, 0x7f, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x6f, 0xff, 0xfc, 0xc0, 0x0e, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0xc0, 0x18, 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x1c, 0x00, 0x19, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0xc0, 0x38, 0x00, 0x00, 0x6f, 0xfb, 0xff, 0x80, 0x3b, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x00, 0xc0, 0x30, 0x00, 0x00, 0x6f, 0xfd, 0xff, 0x00, 0x77, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x01, 0xe0, 0x30, 0x00, 0x00, 0x6c, 0x0e, 0xe0, 0x00, 0xee, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x01, 0xe0, 0x30, 0x00, 0x00, 0x6c, 0x07, 0x70, 0x01, 0xdc, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x01, 0xb0, 0x30, 0x00, 0x00, 0x6c, 0x03, 0xb8, 0x03, 0xb8, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x01, 0xb0, 0x30, 0x00, 0x00, 0x6c, 0x01, 0xdc, 0x07, 0x70, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x01, 0x98, 0x20, 0xc0, 0x40, 0x6c, 0x00, 0xee, 0x0e, 0xe0, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, + 0x03, 0x0c, 0x20, 0xc0, 0xc0, 0x6c, 0x00, 0x77, 0x1d, 0xc0, 0x00, 0xd9, 0xbf, 0xff, 0xfb, 0x00, + 0x03, 0x0c, 0x20, 0xc0, 0xc0, 0x6c, 0x00, 0x3b, 0xbb, 0x80, 0x00, 0xd9, 0xbf, 0xff, 0xf3, 0x00, + 0x03, 0x06, 0x20, 0xc1, 0xc0, 0x6c, 0x00, 0x1d, 0xf7, 0x00, 0x00, 0xd9, 0x80, 0x00, 0x07, 0x00, + 0x03, 0x03, 0x20, 0x83, 0x80, 0x6c, 0x00, 0x0e, 0xee, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xfe, 0x00, + 0x03, 0x03, 0xb1, 0x83, 0x80, 0x6c, 0x00, 0x07, 0x5c, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xfc, 0x00, + 0x03, 0x01, 0xf1, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0xf1, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x71, 0xb9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x31, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#else static const unsigned char PROGMEM nuevi_logo_bmp[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -123,7 +191,7 @@ static const unsigned char PROGMEM nuevi_logo_bmp[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - +#endif extern void readSwitches(void); extern Adafruit_MPR121 touchSensor; @@ -144,7 +212,11 @@ void initDisplay() { // internally, this will display the splashscreen. display.clearDisplay(); + #if defined(NURAD) + display.drawBitmap(0,0,nurad_logo_bmp,LOGO16_GLCD_WIDTH,LOGO16_GLCD_HEIGHT,1); + #else display.drawBitmap(0,0,nuevi_logo_bmp,LOGO16_GLCD_WIDTH,LOGO16_GLCD_HEIGHT,1); + #endif display.display(); memset(cursors, 0, sizeof(cursors)); @@ -529,7 +601,17 @@ const MenuEntrySub wlChannelMenu = { , nullptr }; - +#if defined(NURAD) +const MenuEntry* extrasMenuEntries[] = { + (MenuEntry*)&legacyPBMenu, + (MenuEntry*)&legacyBRMenu, + (MenuEntry*)&specialKeyMenu, + (MenuEntry*)&dacModeMenu, + (MenuEntry*)&fastBootMenu, + (MenuEntry*)&wlPowerMenu, + (MenuEntry*)&wlChannelMenu, +}; +#else const MenuEntry* extrasMenuEntries[] = { (MenuEntry*)&legacyPBMenu, (MenuEntry*)&legacyBRMenu, @@ -542,6 +624,7 @@ const MenuEntry* extrasMenuEntries[] = { (MenuEntry*)&wlPowerMenu, (MenuEntry*)&wlChannelMenu, }; +#endif const MenuPage extrasMenuPage = { "EXTRAS", @@ -865,9 +948,15 @@ const MenuEntrySub deglitchMenu = { , nullptr }; +#if defined(NURAD) +const MenuEntrySub pinkyMenu = { + MenuType::ESub, "MOD KEY", "MOD KEY", &pinkySetting, 0, 29, MenuEntryFlags::ENone, + [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { +#else const MenuEntrySub pinkyMenu = { MenuType::ESub, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 29, MenuEntryFlags::ENone, [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { +#endif if (pinkySetting == PBD) strncpy(textBuffer, "PBD", 4); else if (pinkySetting == EC2) @@ -1044,8 +1133,11 @@ const MenuPageCustom aboutMenuPage = { nullptr, EMenuPageCustom, display.setCursor(49,0); display.setTextColor(WHITE); display.setTextSize(0); + #if defined(NURAD) + display.println("NuRAD"); + #else display.println("NuEVI"); - + #endif display.setCursor(16,12); display.print("firmware v."); display.println(FIRMWARE_VERSION); @@ -1411,12 +1503,12 @@ static bool idlePageUpdate(KeyState& __unused input, uint32_t __unused timeNow) break; case BTN_MENU: - if (pinkyKey && (exSensor >= ((extracThrVal+extracMaxVal)/2))) { // switch breath activated legacy settings on/off + if (pinkyKey && (exSensor >= ((extracThrVal+extracMaxVal)/2)) && !specialKey) { // switch breath activated legacy settings on/off legacyBrAct = !legacyBrAct; dipSwBits = dipSwBits ^ (1<<2); writeSetting(DIPSW_BITS_ADDR,dipSwBits); statusLedBlink(); - } else if ((exSensor >= ((extracThrVal+extracMaxVal)/2))) { // switch pb pad activated legacy settings control on/off + } else if ((exSensor >= ((extracThrVal+extracMaxVal)/2)) && !specialKey) { // switch pb pad activated legacy settings control on/off legacy = !legacy; dipSwBits = dipSwBits ^ (1<<1); writeSetting(DIPSW_BITS_ADDR,dipSwBits); diff --git a/NuEVI/name.c b/NuEVI/name.c index 1e9a706..a90b580 100644 --- a/NuEVI/name.c +++ b/NuEVI/name.c @@ -6,8 +6,11 @@ // Edit these lines to create your own name. The length must // match the number of characters in your custom name. - +#if defined(NURAD) +#define MIDI_NAME {'N','u','R','A','D',' ','M','I','D','I'} +#else #define MIDI_NAME {'N','u','E','V','I',' ','M','I','D','I'} +#endif #define MIDI_NAME_LEN 10 // Do not change this part. This exact format is required by USB. diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 5c42a1a..9e2b0d9 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -28,6 +28,10 @@ void readEEPROM(const bool factoryReset) { if(settingsVersion < 24) { //Oldest version from which any settings are recognized writeSetting(BREATH_THR_ADDR, BREATH_THR_FACTORY); writeSetting(BREATH_MAX_ADDR, BREATH_MAX_FACTORY); + #if defined(NURAD) + writeSetting(PORTAM_THR_ADDR, PORTPR_THR_FACTORY); + writeSetting(PORTAM_MAX_ADDR, PORTPR_MAX_FACTORY); + #else if (digitalRead(biteJumperPin)){ //PBITE (if pulled low with jumper, pressure sensor is used instead of capacitive bite sensing) writeSetting(PORTAM_THR_ADDR, PORTAM_THR_FACTORY); writeSetting(PORTAM_MAX_ADDR, PORTAM_MAX_FACTORY); @@ -35,6 +39,7 @@ void readEEPROM(const bool factoryReset) { writeSetting(PORTAM_THR_ADDR, PORTPR_THR_FACTORY); writeSetting(PORTAM_MAX_ADDR, PORTPR_MAX_FACTORY); } + #endif writeSetting(PITCHB_THR_ADDR, PITCHB_THR_FACTORY); writeSetting(PITCHB_MAX_ADDR, PITCHB_MAX_FACTORY); writeSetting(EXTRAC_THR_ADDR, EXTRAC_THR_FACTORY);