From c38adcd56c7cfaf9a66ae5293d11fe7a36dd5007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Wed, 24 Jul 2019 23:58:38 +0200 Subject: [PATCH 01/18] Move all EEPROM stuff into settings file Refactor version upgrade logic Add some new settings values --- NuEVI/NuEVI.ino | 114 +------------------------------ NuEVI/settings.cpp | 162 +++++++++++++++++++++++++++++++++++++++++++++ NuEVI/settings.h | 23 ++++++- 3 files changed, 184 insertions(+), 115 deletions(-) create mode 100644 NuEVI/settings.cpp diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 23b5ba2..8228e21 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -260,120 +260,10 @@ void setup() { pinMode(biteJumperGndPin, OUTPUT); //PBITE digitalWrite(biteJumperGndPin, LOW); //PBITE - // if stored settings are not for current version, or Enter+Menu are pressed at startup, they are replaced by factory settings - uint16_t settingsVersion = readSetting(VERSION_ADDR); + //Read eeprom data into global vars + readEEPROM(factoryReset); - if (((settingsVersion != VERSION) && (settingsVersion < 24)) || (!digitalRead(ePin) && !digitalRead(mPin)) || (settingsVersion == 0xffffu)) { - writeSetting(VERSION_ADDR,VERSION); - writeSetting(BREATH_THR_ADDR,BREATH_THR_FACTORY); - writeSetting(BREATH_MAX_ADDR,BREATH_MAX_FACTORY); - 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); - } else { - writeSetting(PORTAM_THR_ADDR,PORTPR_THR_FACTORY); - writeSetting(PORTAM_MAX_ADDR,PORTPR_MAX_FACTORY); - } - writeSetting(PITCHB_THR_ADDR,PITCHB_THR_FACTORY); - writeSetting(PITCHB_MAX_ADDR,PITCHB_MAX_FACTORY); - writeSetting(EXTRAC_THR_ADDR,EXTRAC_THR_FACTORY); - writeSetting(EXTRAC_MAX_ADDR,EXTRAC_MAX_FACTORY); - writeSetting(CTOUCH_THR_ADDR,CTOUCH_THR_FACTORY); - } - - if ((settingsVersion != VERSION) || (!digitalRead(ePin) && !digitalRead(mPin))) { - writeSetting(VERSION_ADDR,VERSION); - - writeSetting(TRANSP_ADDR,TRANSP_FACTORY); - writeSetting(MIDI_ADDR,MIDI_FACTORY); - writeSetting(BREATH_CC_ADDR,BREATH_CC_FACTORY); - writeSetting(BREATH_AT_ADDR,BREATH_AT_FACTORY); - writeSetting(VELOCITY_ADDR,VELOCITY_FACTORY); - writeSetting(PORTAM_ADDR,PORTAM_FACTORY); - writeSetting(PB_ADDR,PB_FACTORY); - writeSetting(EXTRA_ADDR,EXTRA_FACTORY); - writeSetting(VIBRATO_ADDR,VIBRATO_FACTORY); - writeSetting(DEGLITCH_ADDR,DEGLITCH_FACTORY); - writeSetting(PATCH_ADDR,PATCH_FACTORY); - writeSetting(OCTAVE_ADDR,OCTAVE_FACTORY); - writeSetting(BREATHCURVE_ADDR,BREATHCURVE_FACTORY); - writeSetting(VEL_SMP_DL_ADDR,VEL_SMP_DL_FACTORY); - writeSetting(VEL_BIAS_ADDR,VEL_BIAS_FACTORY); - writeSetting(PINKY_KEY_ADDR,PINKY_KEY_FACTORY); - writeSetting(FP1_ADDR,0); - writeSetting(FP2_ADDR,0); - writeSetting(FP3_ADDR,0); - writeSetting(FP4_ADDR,0); - writeSetting(FP5_ADDR,0); - writeSetting(FP6_ADDR,0); - writeSetting(FP7_ADDR,0); - writeSetting(DIPSW_BITS_ADDR,DIPSW_BITS_FACTORY); - writeSetting(PARAL_ADDR,PARAL_FACTORY); - writeSetting(ROTN1_ADDR,ROTN1_FACTORY); - writeSetting(ROTN2_ADDR,ROTN2_FACTORY); - writeSetting(ROTN3_ADDR,ROTN3_FACTORY); - writeSetting(ROTN4_ADDR,ROTN4_FACTORY); - writeSetting(PRIO_ADDR,PRIO_FACTORY); - writeSetting(VIB_SENS_ADDR,VIB_SENS_FACTORY); - writeSetting(VIB_RETN_ADDR,VIB_RETN_FACTORY); - writeSetting(VIB_SQUELCH_ADDR,VIB_SQUELCH_FACTORY); - 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); - breathMaxVal = readSetting(BREATH_MAX_ADDR); - portamThrVal = readSetting(PORTAM_THR_ADDR); - portamMaxVal = readSetting(PORTAM_MAX_ADDR); - pitchbThrVal = readSetting(PITCHB_THR_ADDR); - pitchbMaxVal = readSetting(PITCHB_MAX_ADDR); - transpose = readSetting(TRANSP_ADDR); - MIDIchannel = readSetting(MIDI_ADDR); - breathCC = readSetting(BREATH_CC_ADDR); - breathAT = readSetting(BREATH_AT_ADDR); - velocity = readSetting(VELOCITY_ADDR); - portamento = readSetting(PORTAM_ADDR); - PBdepth = readSetting(PB_ADDR); - extraCT = readSetting(EXTRA_ADDR); - vibrato = readSetting(VIBRATO_ADDR); - deglitch = readSetting(DEGLITCH_ADDR); - extracThrVal = readSetting(EXTRAC_THR_ADDR); - extracMaxVal = readSetting(EXTRAC_MAX_ADDR); - patch = readSetting(PATCH_ADDR); - octave = readSetting(OCTAVE_ADDR); - ctouchThrVal = readSetting(CTOUCH_THR_ADDR); - curve = readSetting(BREATHCURVE_ADDR); - velSmpDl = readSetting(VEL_SMP_DL_ADDR); - velBias = readSetting(VEL_BIAS_ADDR); - pinkySetting = readSetting(PINKY_KEY_ADDR); - fastPatch[0] = readSetting(FP1_ADDR); - fastPatch[1] = readSetting(FP2_ADDR); - fastPatch[2] = readSetting(FP3_ADDR); - fastPatch[3] = readSetting(FP4_ADDR); - fastPatch[4] = readSetting(FP5_ADDR); - fastPatch[5] = readSetting(FP6_ADDR); - fastPatch[6] = readSetting(FP7_ADDR); - dipSwBits = readSetting(DIPSW_BITS_ADDR); - parallel = readSetting(PARAL_ADDR); - rotations[0] = readSetting(ROTN1_ADDR); - rotations[1] = readSetting(ROTN2_ADDR); - rotations[2] = readSetting(ROTN3_ADDR); - rotations[3] = readSetting(ROTN4_ADDR); - priority = readSetting(PRIO_ADDR); - vibSens = readSetting(VIB_SENS_ADDR); - vibRetn = readSetting(VIB_RETN_ADDR); - vibSquelch = readSetting(VIB_SQUELCH_ADDR); - vibDirection = readSetting(VIB_DIRECTION_ADDR); - breathCC2 = readSetting(BREATH_CC2_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); diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp new file mode 100644 index 0000000..b924a8d --- /dev/null +++ b/NuEVI/settings.cpp @@ -0,0 +1,162 @@ +#include "settings.h" +#include "globals.h" +#include "menu.h" + +//Read settings from eeprom. Returns wether or not anything was written (due to factory reset or upgrade) +bool readEEPROM() { + bool factoryReset = !digitalRead(ePin) && !digitalRead(mPin); + bool hasWritten = false; + + // if stored settings are not for current version, or Enter+Menu are pressed at startup, they are replaced by factory settings + uint16_t settingsVersion = readSetting(VERSION_ADDR); + + // blank eeprom will be 0xFFFF. For a full reset, call it "version 0" so everything gets overwritten. + if (factoryReset || settingsVersion == 0xffffu) { + settingsVersion = 0; + } + + + if(settingsVersion != EEPROM_VERSION) { + + 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 (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); + } else { + writeSetting(PORTAM_THR_ADDR, PORTPR_THR_FACTORY); + writeSetting(PORTAM_MAX_ADDR, PORTPR_MAX_FACTORY); + } + writeSetting(PITCHB_THR_ADDR, PITCHB_THR_FACTORY); + writeSetting(PITCHB_MAX_ADDR, PITCHB_MAX_FACTORY); + writeSetting(EXTRAC_THR_ADDR, EXTRAC_THR_FACTORY); + writeSetting(EXTRAC_MAX_ADDR, EXTRAC_MAX_FACTORY); + writeSetting(CTOUCH_THR_ADDR, CTOUCH_THR_FACTORY); + + writeSetting(TRANSP_ADDR, TRANSP_FACTORY); + writeSetting(MIDI_ADDR, MIDI_FACTORY); + writeSetting(BREATH_CC_ADDR, BREATH_CC_FACTORY); + writeSetting(BREATH_AT_ADDR, BREATH_AT_FACTORY); + writeSetting(VELOCITY_ADDR, VELOCITY_FACTORY); + writeSetting(PORTAM_ADDR, PORTAM_FACTORY); + writeSetting(PB_ADDR, PB_FACTORY); + writeSetting(EXTRA_ADDR, EXTRA_FACTORY); + writeSetting(VIBRATO_ADDR, VIBRATO_FACTORY); + writeSetting(DEGLITCH_ADDR, DEGLITCH_FACTORY); + writeSetting(PATCH_ADDR, PATCH_FACTORY); + writeSetting(OCTAVE_ADDR, OCTAVE_FACTORY); + writeSetting(BREATHCURVE_ADDR, BREATHCURVE_FACTORY); + writeSetting(VEL_SMP_DL_ADDR, VEL_SMP_DL_FACTORY); + writeSetting(VEL_BIAS_ADDR, VEL_BIAS_FACTORY); + writeSetting(PINKY_KEY_ADDR, PINKY_KEY_FACTORY); + } + + if(settingsVersion < 26) { + writeSetting(FP1_ADDR, 0); + writeSetting(FP2_ADDR, 0); + writeSetting(FP3_ADDR, 0); + writeSetting(FP4_ADDR, 0); + writeSetting(FP5_ADDR, 0); + writeSetting(FP6_ADDR, 0); + writeSetting(FP7_ADDR, 0); + writeSetting(DIPSW_BITS_ADDR, DIPSW_BITS_FACTORY); + } + + if(settingsVersion < 28) { + writeSetting(PARAL_ADDR, PARAL_FACTORY); + writeSetting(ROTN1_ADDR, ROTN1_FACTORY); + writeSetting(ROTN2_ADDR, ROTN2_FACTORY); + writeSetting(ROTN3_ADDR, ROTN3_FACTORY); + writeSetting(ROTN4_ADDR, ROTN4_FACTORY); + writeSetting(PRIO_ADDR, PRIO_FACTORY); + } + + if(settingsVersion < 29) { + writeSetting(VIB_SENS_ADDR, VIB_SENS_FACTORY); + writeSetting(VIB_RETN_ADDR, VIB_RETN_FACTORY); + } + + if(settingsVersion < 31) { + writeSetting(VIB_SQUELCH_ADDR, VIB_SQUELCH_FACTORY); + writeSetting(VIB_DIRECTION_ADDR, VIB_DIRECTION_FACTORY); + } + + if(settingsVersion < 32) { + 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); + + writeSetting(TRILL3_INTERVAL_ADDR, TRILL3_INTERVAL_FACTORY); + writeSetting(BCAS_MODE_ADDR, BCAS_MODE_FACTORY); + writeSetting(DAC_MODE_ADDR, DAC_MODE_FACTORY); + writeSetting(FASTBOOT_ADDR, FASTBOOT_FACTORY); + } + + writeSetting(VERSION_ADDR, EEPROM_VERSION); + hasWritten = true; + } + + + // read all settings from EEPROM + breathThrVal = readSetting(BREATH_THR_ADDR); + breathMaxVal = readSetting(BREATH_MAX_ADDR); + portamThrVal = readSetting(PORTAM_THR_ADDR); + portamMaxVal = readSetting(PORTAM_MAX_ADDR); + pitchbThrVal = readSetting(PITCHB_THR_ADDR); + pitchbMaxVal = readSetting(PITCHB_MAX_ADDR); + transpose = readSetting(TRANSP_ADDR); + MIDIchannel = readSetting(MIDI_ADDR); + breathCC = readSetting(BREATH_CC_ADDR); + breathAT = readSetting(BREATH_AT_ADDR); + velocity = readSetting(VELOCITY_ADDR); + portamento = readSetting(PORTAM_ADDR); + PBdepth = readSetting(PB_ADDR); + extraCT = readSetting(EXTRA_ADDR); + vibrato = readSetting(VIBRATO_ADDR); + deglitch = readSetting(DEGLITCH_ADDR); + extracThrVal = readSetting(EXTRAC_THR_ADDR); + extracMaxVal = readSetting(EXTRAC_MAX_ADDR); + patch = readSetting(PATCH_ADDR); + octave = readSetting(OCTAVE_ADDR); + ctouchThrVal = readSetting(CTOUCH_THR_ADDR); + curve = readSetting(BREATHCURVE_ADDR); + velSmpDl = readSetting(VEL_SMP_DL_ADDR); + velBias = readSetting(VEL_BIAS_ADDR); + pinkySetting = readSetting(PINKY_KEY_ADDR); + fastPatch[0] = readSetting(FP1_ADDR); + fastPatch[1] = readSetting(FP2_ADDR); + fastPatch[2] = readSetting(FP3_ADDR); + fastPatch[3] = readSetting(FP4_ADDR); + fastPatch[4] = readSetting(FP5_ADDR); + fastPatch[5] = readSetting(FP6_ADDR); + fastPatch[6] = readSetting(FP7_ADDR); + dipSwBits = readSetting(DIPSW_BITS_ADDR); + parallel = readSetting(PARAL_ADDR); + rotations[0] = readSetting(ROTN1_ADDR); + rotations[1] = readSetting(ROTN2_ADDR); + rotations[2] = readSetting(ROTN3_ADDR); + rotations[3] = readSetting(ROTN4_ADDR); + priority = readSetting(PRIO_ADDR); + vibSens = readSetting(VIB_SENS_ADDR); + vibRetn = readSetting(VIB_RETN_ADDR); + vibSquelch = readSetting(VIB_SQUELCH_ADDR); + vibDirection = readSetting(VIB_DIRECTION_ADDR); + breathCC2 = readSetting(BREATH_CC2_ADDR); + breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR); + vibSensBite = readSetting(VIB_SENS_BITE_ADDR); + vibSquelchBite = readSetting(VIB_SQUELCH_BITE_ADDR); + vibControl = readSetting(VIB_CONTROL_ADDR); + + bcasMode = readSetting(BCAS_MODE_ADDR); + + trill3_interval = readSetting(TRILL3_INTERVAL_ADDR); + if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible bad values + + fastBoot = readSetting(FASTBOOT_ADDR); + dacMode = readSetting(DAC_MODE_ADDR); + + return hasWritten; +} \ No newline at end of file diff --git a/NuEVI/settings.h b/NuEVI/settings.h index bc155e8..06bea74 100644 --- a/NuEVI/settings.h +++ b/NuEVI/settings.h @@ -2,8 +2,6 @@ #ifndef __SETTINGS_H #define __SETTINGS_H - - // EEPROM addresses for settings #define VERSION_ADDR 0 #define BREATH_THR_ADDR 2 @@ -54,9 +52,19 @@ #define VIB_SENS_BITE_ADDR 92 #define VIB_SQUELCH_BITE_ADDR 94 #define VIB_CONTROL_ADDR 96 +#define TRILL3_INTERVAL_ADDR 98 +#define BCAS_MODE_ADDR 100 +#define DAC_MODE_ADDR 102 +#define FASTBOOT_ADDR 104 + + + +//DAC output modes +#define DAC_MODE_BREATH 0 +#define DAC_MODE_PITCH 1 //"factory" values for settings -#define VERSION 32 +#define EEPROM_VERSION 32 #define BREATH_THR_FACTORY 1400 #define BREATH_MAX_FACTORY 4000 #define PORTAM_THR_FACTORY 2600 @@ -101,4 +109,13 @@ #define VIB_SQUELCH_BITE_FACTORY 10 #define VIB_CONTROL_FACTORY 0 +#define TRILL3_INTERVAL_FACTORY 4 +#define BCAS_MODE_FACTORY 0 +#define DAC_MODE_FACTORY DAC_MODE_BREATH +#define FASTBOOT_FACTORY 0 + + +bool readEEPROM(); + + #endif From 7b179d43436c066c264b1ad345ae475791b73bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Thu, 25 Jul 2019 00:51:34 +0200 Subject: [PATCH 02/18] Add settings for fast boot, bcas mode, 3rd trill, dac out --- NuEVI/NuEVI.ino | 80 ++++++++++++++++++--------------------------- NuEVI/globals.h | 5 +++ NuEVI/menu.cpp | 73 ++++++++++++++++++++++++++++++++--------- NuEVI/settings.cpp | 10 ++---- NuEVI/settings.h | 6 +--- simulation/Makefile | 1 + 6 files changed, 99 insertions(+), 76 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 8228e21..fdabeef 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -80,6 +80,11 @@ unsigned short vibControl = 0; unsigned short fastPatch[7] = {0,0,0,0,0,0,0}; +uint16_t bcasMode; //Legacy CASSIDY compile flag +uint16_t trill3_interval; +uint16_t fastBoot; +uint16_t dacMode; + byte rotatorOn = 0; byte currentRotation = 0; uint16_t rotations[4]; // semitones { -5, -10, -7, -14 }; @@ -262,14 +267,16 @@ void setup() { //Read eeprom data into global vars - readEEPROM(factoryReset); - + readEEPROM(); + //Parse out flags from bit field + fastBoot = dipSwBits & (1<<0); legacy = dipSwBits & (1<<1); legacyBrAct = dipSwBits & (1<<2); slowMidi = dipSwBits & (1<<3); gateOpenEnable = dipSwBits & (1<<4); specialKeyEnable = dipSwBits & (1<<5); + bcasMode = dipSwBits & (1<<6); activePatch = patch; touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); @@ -295,8 +302,9 @@ void setup() { breathCalZero += analogRead(breathSensorPin); if (biteJumper) vibZeroBite += analogRead(A7); else vibZeroBite += touchRead(bitePin); digitalWrite( statusLedPin, i&1 ); - delay(250); + delay(fastBoot?75:250); //Shorter delay for fastboot } + vibZero /= sampleCount; breathCalZero /= sampleCount; vibZeroBite /= sampleCount; @@ -306,15 +314,17 @@ void setup() { vibThrBite = vibZeroBite - vibSquelchBite; vibThrBiteLo = vibZeroBite + vibSquelchBite; - digitalWrite(statusLedPin, LOW); - delay(250); - digitalWrite(statusLedPin,HIGH); - delay(250); - digitalWrite(statusLedPin,LOW); + if(!fastBoot) { + digitalWrite(statusLedPin, LOW); + delay(250); + digitalWrite(statusLedPin,HIGH); + delay(250); + digitalWrite(statusLedPin,LOW); - showVersion(); + showVersion(); - delay(1500); + delay(1500); + } mainState = NOTE_OFF; // initialize main state machine @@ -359,54 +369,37 @@ void loop() { mainState = RISE_WAIT; // Go to next state } if (legacy || legacyBrAct) { - #if defined(CASSIDY) - if (((pbUp > ((pitchbMaxVal + pitchbThrVal) / 2)) && (pbDn > ((pitchbMaxVal + pitchbThrVal) / 2)) && legacy) || - ((analogRead(breathSensorPin) < breathCalZero - 900) && legacyBrAct)) { // both pb pads touched or br suck - #else - if (((pbUp > ((pitchbMaxVal + pitchbThrVal) / 2)) && (pbDn > ((pitchbMaxVal + pitchbThrVal) / 2)) && legacy) || - ((analogRead(breathSensorPin) < breathCalZero - 800) && legacyBrAct && (pbUp > (pitchbMaxVal + pitchbThrVal) / 2) && (pbDn < (pitchbMaxVal + pitchbThrVal) / 2))) { // both pb pads touched or br suck - #endif + + bool bothPB = (pbUp > ((pitchbMaxVal + pitchbThrVal) / 2)) && (pbDn > ((pitchbMaxVal + pitchbThrVal) / 2)); + bool brSuck = analogRead(breathSensorPin) < (breathCalZero - (bcasMode?900:800)); + + if ( + (bothPB && legacy) || + (brSuck && legacyBrAct && (bothPB || bcasMode)) + ) { // both pb pads touched or br suck + + fingeredNoteUntransposed = patchLimit(fingeredNoteUntransposed + 1); if (exSensor >= ((extracThrVal + extracMaxVal) / 2)) { // instant midi setting if ((fingeredNoteUntransposed >= 73) && (fingeredNoteUntransposed <= 88)) { MIDIchannel = fingeredNoteUntransposed - 72; // Mid C and up - #if !defined(CASSIDY) - digitalWrite(statusLedPin, LOW); - delay(150); - digitalWrite(statusLedPin, HIGH); - #endif } } else { if (!pinkyKey) { // note number to patch number if (patch != fingeredNoteUntransposed) { patch = fingeredNoteUntransposed; doPatchUpdate = 1; - #if !defined(CASSIDY) - digitalWrite(statusLedPin, LOW); - delay(150); - digitalWrite(statusLedPin, HIGH); - #endif } } else { // hi and lo patch numbers if (fingeredNoteUntransposed > 75) { if (patch != patchLimit(fingeredNoteUntransposed + 24)) { patch = patchLimit(fingeredNoteUntransposed + 24); // add 24 to get high numbers 108 to 127 doPatchUpdate = 1; - #if !defined(CASSIDY) - digitalWrite(statusLedPin, LOW); - delay(150); - digitalWrite(statusLedPin, HIGH); - #endif } } else { if (patch != patchLimit(fingeredNoteUntransposed - 36)) { patch = patchLimit(fingeredNoteUntransposed - 36); // subtract 36 to get low numbers 0 to 36 doPatchUpdate = 1; - #if !defined(CASSIDY) - digitalWrite(statusLedPin, LOW); - delay(150); - digitalWrite(statusLedPin, HIGH); - #endif } } } @@ -1186,24 +1179,13 @@ void readSwitches() { } // Calculate midi note number from pressed keys - #if defined(CASSIDY) fingeredNoteUntransposed = startNote - 2*K1 - K2 - 3*K3 //"Trumpet valves" - 5*K4 //Fifth key - + 2*K5 + K6 + 3*K7 //Trill keys (different from standard) + + 2*K5 + K6 + trill3_interval*K7 //Trill keys. 3rd trill key interval controlled by setting + octaveR*12; //Octave rollers - #else - - fingeredNoteUntransposed = startNote - - 2*K1 - K2 - 3*K3 //"Trumpet valves" - - 5*K4 //Fifth key - + 2*K5 + K6 + 4*K7 //Trill keys - + octaveR*12; //Octave rollers - - #endif - int fingeredNoteRead = fingeredNoteUntransposed + transpose - 12 + qTransp; if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered diff --git a/NuEVI/globals.h b/NuEVI/globals.h index 56d0c41..5d1954a 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -73,6 +73,11 @@ extern byte currentRotation; extern uint16_t rotations[4]; extern uint16_t parallel; // semitones +extern uint16_t bcasMode; //Legacy CASSIDY compile flag +extern uint16_t trill3_interval; +extern uint16_t fastBoot; +extern uint16_t dacMode; + extern uint16_t wlPower; extern int touch_Thr; diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index a7c911b..286e4dd 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -156,10 +156,6 @@ void initDisplay() { void showVersion() { display.setTextColor(WHITE); display.setTextSize(1); - #if defined(CASSIDY) - display.setCursor(0,0); - display.print("BC"); - #endif #if defined(CVSCALEBOARD) display.setCursor(15,0); display.print("CV"); @@ -450,6 +446,10 @@ static void midiCustomDrawFunc(SubMenuRef __unused, char* __unused, const char** } } +//Poke at a certain bit in a bit field +void setBit(uint16_t &bitfield, const uint8_t pos, const uint8_t value) { + bitfield = (bitfield & ~(1< + //Read settings from eeprom. Returns wether or not anything was written (due to factory reset or upgrade) bool readEEPROM() { @@ -88,11 +91,8 @@ bool readEEPROM() { 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); - writeSetting(TRILL3_INTERVAL_ADDR, TRILL3_INTERVAL_FACTORY); - writeSetting(BCAS_MODE_ADDR, BCAS_MODE_FACTORY); writeSetting(DAC_MODE_ADDR, DAC_MODE_FACTORY); - writeSetting(FASTBOOT_ADDR, FASTBOOT_FACTORY); } writeSetting(VERSION_ADDR, EEPROM_VERSION); @@ -149,13 +149,9 @@ bool readEEPROM() { vibSensBite = readSetting(VIB_SENS_BITE_ADDR); vibSquelchBite = readSetting(VIB_SQUELCH_BITE_ADDR); vibControl = readSetting(VIB_CONTROL_ADDR); - - bcasMode = readSetting(BCAS_MODE_ADDR); trill3_interval = readSetting(TRILL3_INTERVAL_ADDR); if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible bad values - - fastBoot = readSetting(FASTBOOT_ADDR); dacMode = readSetting(DAC_MODE_ADDR); return hasWritten; diff --git a/NuEVI/settings.h b/NuEVI/settings.h index 06bea74..9da1886 100644 --- a/NuEVI/settings.h +++ b/NuEVI/settings.h @@ -53,9 +53,7 @@ #define VIB_SQUELCH_BITE_ADDR 94 #define VIB_CONTROL_ADDR 96 #define TRILL3_INTERVAL_ADDR 98 -#define BCAS_MODE_ADDR 100 -#define DAC_MODE_ADDR 102 -#define FASTBOOT_ADDR 104 +#define DAC_MODE_ADDR 100 @@ -110,9 +108,7 @@ #define VIB_CONTROL_FACTORY 0 #define TRILL3_INTERVAL_FACTORY 4 -#define BCAS_MODE_FACTORY 0 #define DAC_MODE_FACTORY DAC_MODE_BREATH -#define FASTBOOT_FACTORY 0 bool readEEPROM(); diff --git a/simulation/Makefile b/simulation/Makefile index 640a642..22f646f 100644 --- a/simulation/Makefile +++ b/simulation/Makefile @@ -36,6 +36,7 @@ CXXFILES= ../NuEVI/menu.cpp \ src/simusbmidi.cpp \ src/filters.cpp \ ../NuEVI/midi.cpp \ + ../NuEVI/settings.cpp \ src/Adafruit_GFX_sim.cpp \ src/Adafruit_SSD1306_sim.cpp \ src/Adafruit_MPR121_sim.cpp \ From 671dfe9b2c8d1a2e72c66069b786cc0fd07f901f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Thu, 25 Jul 2019 07:50:29 +0200 Subject: [PATCH 03/18] Define constant for "dipswitch" positions --- NuEVI/NuEVI.ino | 8 --- NuEVI/menu.cpp | 18 +++---- NuEVI/settings.cpp | 116 +++++++++++++++++++++++++------------------- NuEVI/settings.h | 13 ++++- simulation/Makefile | 4 +- 5 files changed, 87 insertions(+), 72 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index fdabeef..88dd235 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -269,14 +269,6 @@ void setup() { //Read eeprom data into global vars readEEPROM(); - //Parse out flags from bit field - fastBoot = dipSwBits & (1<<0); - legacy = dipSwBits & (1<<1); - legacyBrAct = dipSwBits & (1<<2); - slowMidi = dipSwBits & (1<<3); - gateOpenEnable = dipSwBits & (1<<4); - specialKeyEnable = dipSwBits & (1<<5); - bcasMode = dipSwBits & (1<<6); activePatch = patch; touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 286e4dd..a0e2808 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -446,11 +446,6 @@ static void midiCustomDrawFunc(SubMenuRef __unused, char* __unused, const char** } } -//Poke at a certain bit in a bit field -void setBit(uint16_t &bitfield, const uint8_t pos, const uint8_t value) { - bitfield = (bitfield & ~(1< + #include "settings.h" #include "globals.h" #include "menu.h" #include "hardware.h" -#include - //Read settings from eeprom. Returns wether or not anything was written (due to factory reset or upgrade) bool readEEPROM() { @@ -101,58 +101,76 @@ bool readEEPROM() { // read all settings from EEPROM - breathThrVal = readSetting(BREATH_THR_ADDR); - breathMaxVal = readSetting(BREATH_MAX_ADDR); - portamThrVal = readSetting(PORTAM_THR_ADDR); - portamMaxVal = readSetting(PORTAM_MAX_ADDR); - pitchbThrVal = readSetting(PITCHB_THR_ADDR); - pitchbMaxVal = readSetting(PITCHB_MAX_ADDR); - transpose = readSetting(TRANSP_ADDR); - MIDIchannel = readSetting(MIDI_ADDR); - breathCC = readSetting(BREATH_CC_ADDR); - breathAT = readSetting(BREATH_AT_ADDR); - velocity = readSetting(VELOCITY_ADDR); - portamento = readSetting(PORTAM_ADDR); - PBdepth = readSetting(PB_ADDR); - extraCT = readSetting(EXTRA_ADDR); - vibrato = readSetting(VIBRATO_ADDR); - deglitch = readSetting(DEGLITCH_ADDR); - extracThrVal = readSetting(EXTRAC_THR_ADDR); - extracMaxVal = readSetting(EXTRAC_MAX_ADDR); - patch = readSetting(PATCH_ADDR); - octave = readSetting(OCTAVE_ADDR); - ctouchThrVal = readSetting(CTOUCH_THR_ADDR); - curve = readSetting(BREATHCURVE_ADDR); - velSmpDl = readSetting(VEL_SMP_DL_ADDR); - velBias = readSetting(VEL_BIAS_ADDR); - pinkySetting = readSetting(PINKY_KEY_ADDR); - fastPatch[0] = readSetting(FP1_ADDR); - fastPatch[1] = readSetting(FP2_ADDR); - fastPatch[2] = readSetting(FP3_ADDR); - fastPatch[3] = readSetting(FP4_ADDR); - fastPatch[4] = readSetting(FP5_ADDR); - fastPatch[5] = readSetting(FP6_ADDR); - fastPatch[6] = readSetting(FP7_ADDR); - dipSwBits = readSetting(DIPSW_BITS_ADDR); - parallel = readSetting(PARAL_ADDR); - rotations[0] = readSetting(ROTN1_ADDR); - rotations[1] = readSetting(ROTN2_ADDR); - rotations[2] = readSetting(ROTN3_ADDR); - rotations[3] = readSetting(ROTN4_ADDR); - priority = readSetting(PRIO_ADDR); - vibSens = readSetting(VIB_SENS_ADDR); - vibRetn = readSetting(VIB_RETN_ADDR); - vibSquelch = readSetting(VIB_SQUELCH_ADDR); - vibDirection = readSetting(VIB_DIRECTION_ADDR); - breathCC2 = readSetting(BREATH_CC2_ADDR); + breathThrVal = readSetting(BREATH_THR_ADDR); + breathMaxVal = readSetting(BREATH_MAX_ADDR); + portamThrVal = readSetting(PORTAM_THR_ADDR); + portamMaxVal = readSetting(PORTAM_MAX_ADDR); + pitchbThrVal = readSetting(PITCHB_THR_ADDR); + pitchbMaxVal = readSetting(PITCHB_MAX_ADDR); + transpose = readSetting(TRANSP_ADDR); + MIDIchannel = readSetting(MIDI_ADDR); + breathCC = readSetting(BREATH_CC_ADDR); + breathAT = readSetting(BREATH_AT_ADDR); + velocity = readSetting(VELOCITY_ADDR); + portamento = readSetting(PORTAM_ADDR); + PBdepth = readSetting(PB_ADDR); + extraCT = readSetting(EXTRA_ADDR); + vibrato = readSetting(VIBRATO_ADDR); + deglitch = readSetting(DEGLITCH_ADDR); + extracThrVal = readSetting(EXTRAC_THR_ADDR); + extracMaxVal = readSetting(EXTRAC_MAX_ADDR); + patch = readSetting(PATCH_ADDR); + octave = readSetting(OCTAVE_ADDR); + ctouchThrVal = readSetting(CTOUCH_THR_ADDR); + curve = readSetting(BREATHCURVE_ADDR); + velSmpDl = readSetting(VEL_SMP_DL_ADDR); + velBias = readSetting(VEL_BIAS_ADDR); + pinkySetting = readSetting(PINKY_KEY_ADDR); + fastPatch[0] = readSetting(FP1_ADDR); + fastPatch[1] = readSetting(FP2_ADDR); + fastPatch[2] = readSetting(FP3_ADDR); + fastPatch[3] = readSetting(FP4_ADDR); + fastPatch[4] = readSetting(FP5_ADDR); + fastPatch[5] = readSetting(FP6_ADDR); + fastPatch[6] = readSetting(FP7_ADDR); + dipSwBits = readSetting(DIPSW_BITS_ADDR); + parallel = readSetting(PARAL_ADDR); + rotations[0] = readSetting(ROTN1_ADDR); + rotations[1] = readSetting(ROTN2_ADDR); + rotations[2] = readSetting(ROTN3_ADDR); + rotations[3] = readSetting(ROTN4_ADDR); + priority = readSetting(PRIO_ADDR); + vibSens = readSetting(VIB_SENS_ADDR); + vibRetn = readSetting(VIB_RETN_ADDR); + vibSquelch = readSetting(VIB_SQUELCH_ADDR); + vibDirection = readSetting(VIB_DIRECTION_ADDR); + breathCC2 = readSetting(BREATH_CC2_ADDR); breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR); vibSensBite = readSetting(VIB_SENS_BITE_ADDR); vibSquelchBite = readSetting(VIB_SQUELCH_BITE_ADDR); vibControl = readSetting(VIB_CONTROL_ADDR); - + dacMode = readSetting(DAC_MODE_ADDR); trill3_interval = readSetting(TRILL3_INTERVAL_ADDR); - if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible bad values - dacMode = readSetting(DAC_MODE_ADDR); + + if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible zero/bad values + + + + //Flags stored in bit field + fastBoot = dipSwBits & (1< + // EEPROM addresses for settings #define VERSION_ADDR 0 #define BREATH_THR_ADDR 2 @@ -61,6 +62,15 @@ #define DAC_MODE_BREATH 0 #define DAC_MODE_PITCH 1 +#define DIPSW_FASTBOOT 0 +#define DIPSW_LEGACY 1 +#define DIPSW_LEGACYBRACT 2 +#define DIPSW_SLOWMIDI 3 +#define DIPSW_GATEOPEN 4 +#define DIPSW_SPKEYENABLE 5 +#define DIPSW_BCASMODE 6 + + //"factory" values for settings #define EEPROM_VERSION 32 #define BREATH_THR_FACTORY 1400 @@ -112,6 +122,7 @@ bool readEEPROM(); +void setBit(uint16_t &bitfield, const uint8_t pos, const uint16_t value); #endif diff --git a/simulation/Makefile b/simulation/Makefile index 22f646f..903471c 100644 --- a/simulation/Makefile +++ b/simulation/Makefile @@ -28,6 +28,8 @@ TARGET=nuevisim CXXFILES= ../NuEVI/menu.cpp \ ../NuEVI/adjustmenu.cpp \ + ../NuEVI/midi.cpp \ + ../NuEVI/settings.cpp \ src/nuevisim.cpp \ src/simeeprom.cpp \ src/Print.cpp \ @@ -35,8 +37,6 @@ CXXFILES= ../NuEVI/menu.cpp \ src/simwire.cpp \ src/simusbmidi.cpp \ src/filters.cpp \ - ../NuEVI/midi.cpp \ - ../NuEVI/settings.cpp \ src/Adafruit_GFX_sim.cpp \ src/Adafruit_SSD1306_sim.cpp \ src/Adafruit_MPR121_sim.cpp \ From 33bfc9ea08a1c0a0c84b2146602628e7061086ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Thu, 25 Jul 2019 07:57:31 +0200 Subject: [PATCH 04/18] Use settings flag for DAC output mode (remove CVSCALEBOARD define) --- NuEVI/NuEVI.ino | 6 +++--- NuEVI/config.h | 8 +------- NuEVI/menu.cpp | 5 ----- NuEVI/settings.cpp | 2 -- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 88dd235..02c5260 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -709,7 +709,7 @@ void loop() { pixelUpdateTime = millis(); } - #if defined(CVSCALEBOARD) // pitch CV from DAC and breath CV from PWM on pin 6, for filtering and scaling on separate board + if(dacMode == DAC_MODE_PITCH) { // pitch CV from DAC and breath CV from PWM on pin 6, for filtering and scaling on separate board targetPitch = (fingeredNote-24)*42; if (portIsOn){ if (targetPitch > cvPitch){ @@ -726,9 +726,9 @@ void loop() { } analogWrite(dacPin,constrain(cvPitch+map(pitchBend,0,16383,-84,84),0,4095)); analogWrite(pwmDacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,500,4095))); //starting at 0.6V to match use of cv from sensor, so recalibration of cv offset/scaler is not needed - #else // else breath CV on DAC pin, directly to unused pin of MIDI DIN jack + else if(dacMode == DAC_MODE_BREATH) { // else breath CV on DAC pin, directly to unused pin of MIDI DIN jack analogWrite(dacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095))); - #endif + } midiDiscardInput(); diff --git a/NuEVI/config.h b/NuEVI/config.h index 86fae05..0ebceae 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,14 +5,9 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.3.9" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< - - -//#define CASSIDY -#define CVSCALEBOARD +#define FIRMWARE_VERSION "1.4.0" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< #define ON_Delay 20 // Set Delay after ON threshold before velocity is checked (wait for tounging peak) -//#define touch_Thr 1200 // sensitivity for Teensy touch sensors #define CCN_Port 5 // Controller number for portamento level #define CCN_PortOnOff 65// Controller number for portamento on/off @@ -21,7 +16,6 @@ #define CC_INTERVAL 2 -// MAybe move these to config.h (as defines?) #define breathLoLimit 0 #define breathHiLimit 4095 #define portamLoLimit 700 diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index a0e2808..c2a058b 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -156,10 +155,6 @@ void initDisplay() { void showVersion() { display.setTextColor(WHITE); display.setTextSize(1); - #if defined(CVSCALEBOARD) - display.setCursor(15,0); - display.print("CV"); - #endif display.setCursor(85,52); display.print("v."); display.println(FIRMWARE_VERSION); diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 0e3d688..b68860b 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -154,8 +154,6 @@ bool readEEPROM() { if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible zero/bad values - - //Flags stored in bit field fastBoot = dipSwBits & (1< Date: Tue, 23 Jul 2019 10:32:33 +0200 Subject: [PATCH 05/18] Remove global var for wireless power, add wl channel menu --- NuEVI/NuEVI.ino | 4 +--- NuEVI/globals.h | 1 - NuEVI/menu.cpp | 21 ++++++++++++++++++--- NuEVI/midi.cpp | 18 +++++++++++++++++- NuEVI/midi.h | 3 +-- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 02c5260..a3cffbb 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -95,8 +95,6 @@ uint16_t gateOpenEnable = 0; uint16_t specialKeyEnable = 0; -uint16_t wlPower = 0; - int touch_Thr = 1300; byte ccList[11] = {0,1,2,7,11,1,2,7,11,74,20}; // OFF, Modulation, Breath, Volume, Expression (then same sent in hires), CC74 (cutoff/brightness), CC20 (UNO Cutoff) @@ -726,7 +724,7 @@ void loop() { } analogWrite(dacPin,constrain(cvPitch+map(pitchBend,0,16383,-84,84),0,4095)); analogWrite(pwmDacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,500,4095))); //starting at 0.6V to match use of cv from sensor, so recalibration of cv offset/scaler is not needed - else if(dacMode == DAC_MODE_BREATH) { // else breath CV on DAC pin, directly to unused pin of MIDI DIN jack + } else if(dacMode == DAC_MODE_BREATH) { // else breath CV on DAC pin, directly to unused pin of MIDI DIN jack analogWrite(dacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095))); } diff --git a/NuEVI/globals.h b/NuEVI/globals.h index 5d1954a..4cb0a8b 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -78,7 +78,6 @@ extern uint16_t trill3_interval; extern uint16_t fastBoot; extern uint16_t dacMode; -extern uint16_t wlPower; extern int touch_Thr; diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index c2a058b..1f908a8 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -530,15 +530,29 @@ const MenuEntrySub fastBootMenu = { , nullptr }; + +static uint16_t wireless_power=0; +static uint16_t wireless_channel=4; + const MenuEntrySub wlPowerMenu = { - MenuType::ESub, "WL POWER", "WL POWER", &wlPower, 0, 3, MenuEntryFlags::ENone, + MenuType::ESub, "WL POWER", "WL POWER", &wireless_power, 0, 3, MenuEntryFlags::ENone, [](SubMenuRef __unused, char* out, const char** __unused unit) { - numToString(-6*wlPower, out, true); + numToString(-6*wireless_power, out, true); }, - [](SubMenuRef __unused) { sendWLPower(wlPower); } + [](SubMenuRef __unused) { sendWLPower(wireless_power); } , nullptr }; +const MenuEntrySub wlChannelMenu = { + MenuType::ESub, "WL CHAN", "WL CHAN", &wireless_channel, 4, 80, MenuEntryFlags::ENone, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + numToString(wireless_channel, out, false); + }, + [](SubMenuRef __unused) { sendWLChannel(wireless_channel); } + , nullptr +}; + + const MenuEntry* extrasMenuEntries[] = { (MenuEntry*)&legacyPBMenu, (MenuEntry*)&legacyBRMenu, @@ -549,6 +563,7 @@ const MenuEntry* extrasMenuEntries[] = { (MenuEntry*)&dacModeMenu, (MenuEntry*)&fastBootMenu, (MenuEntry*)&wlPowerMenu, + (MenuEntry*)&wlChannelMenu, }; const MenuPage extrasMenuPage = { diff --git a/NuEVI/midi.cpp b/NuEVI/midi.cpp index 8a49feb..56e8d74 100644 --- a/NuEVI/midi.cpp +++ b/NuEVI/midi.cpp @@ -163,4 +163,20 @@ void sendWLPower(const uint8_t level) { buf[5] = level; dinMIDIsendSysex(buf, 6); -} \ No newline at end of file +} + + +void sendWLChannel(const uint8_t channel) { + uint8_t buf[6] = { + 0x00, 0x21, 0x11, //Manufacturer id + 0x02, //TX02 + 0x05, //Set channel + 0x04 //Channel value (4-80) + }; + + if(channel<4 || channel>80) return; //Don't send invalid values + + buf[5] = channel; + dinMIDIsendSysex(buf, 6); + +} diff --git a/NuEVI/midi.h b/NuEVI/midi.h index 2b2e85f..800d1db 100644 --- a/NuEVI/midi.h +++ b/NuEVI/midi.h @@ -30,8 +30,7 @@ void dinMIDIsendProgramChange(uint8_t value, uint8_t ch); void dinMIDIsendPitchBend(uint16_t pb, uint8_t ch); void dinMIDIsendSysex(const uint8_t data[], const uint8_t length); - - void sendWLPower(const uint8_t level); +void sendWLChannel(const uint8_t channel); #endif From ae41482351218f7c05f61dfca0544b497ddc16b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Wed, 24 Jul 2019 23:58:38 +0200 Subject: [PATCH 06/18] Move all EEPROM stuff into settings file Refactor version upgrade logic Add some new settings values --- NuEVI/NuEVI.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index a3cffbb..3ad6f2e 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -267,6 +267,7 @@ void setup() { //Read eeprom data into global vars readEEPROM(); + activePatch = patch; touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); From 16e9bd04074fcc26cf7e752c74e9c1a54b713e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Thu, 25 Jul 2019 07:50:29 +0200 Subject: [PATCH 07/18] Define constant for "dipswitch" positions --- NuEVI/NuEVI.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 3ad6f2e..a3cffbb 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -267,7 +267,6 @@ void setup() { //Read eeprom data into global vars readEEPROM(); - activePatch = patch; touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); From 9fbfde3867f7d68d6c741f6e78577168e84bcb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Thu, 25 Jul 2019 09:24:58 +0200 Subject: [PATCH 08/18] Force flags from dipSw to "nice 1-bit values" to prevent menus from locking up --- NuEVI/settings.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index b68860b..8a0bb66 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -155,13 +155,13 @@ bool readEEPROM() { if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible zero/bad values //Flags stored in bit field - fastBoot = dipSwBits & (1< Date: Thu, 25 Jul 2019 11:07:41 +0200 Subject: [PATCH 09/18] Move EEPROM read/write functions to settings --- NuEVI/menu.cpp | 24 ------------------------ NuEVI/menu.h | 2 -- NuEVI/settings.cpp | 23 +++++++++++++++++++++++ NuEVI/settings.h | 3 ++- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 1f908a8..08c2e60 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -365,29 +364,6 @@ void drawMenuCursor(byte itemNo, byte color){ //*********************************************************** -// TODO: Move these to a settings.cpp maybe? -void writeSetting(byte address, unsigned short value){ - union { - byte v[2]; - unsigned short val; - } data; - data.val = value; - EEPROM.update(address, data.v[0]); - EEPROM.update(address+1, data.v[1]); -} - -unsigned short readSetting(byte address){ - union { - byte v[2]; - unsigned short val; - } data; - data.v[0] = EEPROM.read(address); - data.v[1] = EEPROM.read(address+1); - return data.val; -} - -//*********************************************************** - static int readTrills() { readSwitches(); return K5+2*K6+4*K7; diff --git a/NuEVI/menu.h b/NuEVI/menu.h index 93567a8..20373ab 100644 --- a/NuEVI/menu.h +++ b/NuEVI/menu.h @@ -41,8 +41,6 @@ void initDisplay(); void showVersion(); void menu(); void drawSensorPixels(); -unsigned short readSetting(byte address); -void writeSetting(byte address, unsigned short value); 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 8a0bb66..5858943 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -1,4 +1,5 @@ #include +#include #include "settings.h" #include "globals.h" @@ -171,4 +172,26 @@ bool readEEPROM() { //Poke at a certain bit in a bit field void setBit(uint16_t &bitfield, const uint8_t pos, const uint16_t value) { bitfield = (bitfield & ~(1< Date: Thu, 25 Jul 2019 11:58:09 +0200 Subject: [PATCH 10/18] Make (almost) all EEPROM settings read be bounded, and rewritten if "out of bounds" --- NuEVI/settings.cpp | 150 +++++++++++++++++++++++---------------------- NuEVI/settings.h | 4 +- 2 files changed, 80 insertions(+), 74 deletions(-) diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 5858943..913e06f 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -5,11 +5,11 @@ #include "globals.h" #include "menu.h" #include "hardware.h" +#include "config.h" //Read settings from eeprom. Returns wether or not anything was written (due to factory reset or upgrade) -bool readEEPROM() { +void readEEPROM() { bool factoryReset = !digitalRead(ePin) && !digitalRead(mPin); - bool hasWritten = false; // if stored settings are not for current version, or Enter+Menu are pressed at startup, they are replaced by factory settings uint16_t settingsVersion = readSetting(VERSION_ADDR); @@ -97,63 +97,59 @@ bool readEEPROM() { } writeSetting(VERSION_ADDR, EEPROM_VERSION); - hasWritten = true; } - // read all settings from EEPROM - breathThrVal = readSetting(BREATH_THR_ADDR); - breathMaxVal = readSetting(BREATH_MAX_ADDR); - portamThrVal = readSetting(PORTAM_THR_ADDR); - portamMaxVal = readSetting(PORTAM_MAX_ADDR); - pitchbThrVal = readSetting(PITCHB_THR_ADDR); - pitchbMaxVal = readSetting(PITCHB_MAX_ADDR); - transpose = readSetting(TRANSP_ADDR); - MIDIchannel = readSetting(MIDI_ADDR); - breathCC = readSetting(BREATH_CC_ADDR); - breathAT = readSetting(BREATH_AT_ADDR); - velocity = readSetting(VELOCITY_ADDR); - portamento = readSetting(PORTAM_ADDR); - PBdepth = readSetting(PB_ADDR); - extraCT = readSetting(EXTRA_ADDR); - vibrato = readSetting(VIBRATO_ADDR); - deglitch = readSetting(DEGLITCH_ADDR); - extracThrVal = readSetting(EXTRAC_THR_ADDR); - extracMaxVal = readSetting(EXTRAC_MAX_ADDR); - patch = readSetting(PATCH_ADDR); - octave = readSetting(OCTAVE_ADDR); - ctouchThrVal = readSetting(CTOUCH_THR_ADDR); - curve = readSetting(BREATHCURVE_ADDR); - velSmpDl = readSetting(VEL_SMP_DL_ADDR); - velBias = readSetting(VEL_BIAS_ADDR); - pinkySetting = readSetting(PINKY_KEY_ADDR); - fastPatch[0] = readSetting(FP1_ADDR); - fastPatch[1] = readSetting(FP2_ADDR); - fastPatch[2] = readSetting(FP3_ADDR); - fastPatch[3] = readSetting(FP4_ADDR); - fastPatch[4] = readSetting(FP5_ADDR); - fastPatch[5] = readSetting(FP6_ADDR); - fastPatch[6] = readSetting(FP7_ADDR); + breathThrVal = readSettingBounded(BREATH_THR_ADDR, breathLoLimit, breathHiLimit, BREATH_THR_FACTORY); + breathMaxVal = readSettingBounded(BREATH_MAX_ADDR, breathLoLimit, breathHiLimit, BREATH_MAX_FACTORY); + portamThrVal = readSettingBounded(PORTAM_THR_ADDR, portamLoLimit, portamHiLimit, PORTAM_THR_FACTORY); + portamMaxVal = readSettingBounded(PORTAM_MAX_ADDR, portamLoLimit, portamHiLimit, PORTAM_MAX_FACTORY); + pitchbThrVal = readSettingBounded(PITCHB_THR_ADDR, pitchbLoLimit, pitchbHiLimit, PITCHB_THR_FACTORY); + pitchbMaxVal = readSettingBounded(PITCHB_MAX_ADDR, pitchbLoLimit, pitchbHiLimit, PITCHB_MAX_FACTORY); + transpose = readSettingBounded(TRANSP_ADDR, 0, 24, TRANSP_FACTORY); + MIDIchannel = readSettingBounded(MIDI_ADDR, 1, 16, MIDI_FACTORY); + breathCC = readSettingBounded(BREATH_CC_ADDR, 0, 127, BREATH_CC_FACTORY); + breathAT = readSettingBounded(BREATH_AT_ADDR, 0, 1, BREATH_AT_FACTORY); + velocity = readSettingBounded(VELOCITY_ADDR, 0, 127, VELOCITY_FACTORY); + portamento = readSettingBounded(PORTAM_ADDR, 0, 2, PORTAM_FACTORY); + PBdepth = readSettingBounded(PB_ADDR, 0, 12, PB_FACTORY); + extraCT = readSettingBounded(EXTRA_ADDR, 0, 4, EXTRA_FACTORY); + vibrato = readSettingBounded(VIBRATO_ADDR, 0, 9, VIBRATO_FACTORY); + deglitch = readSettingBounded(DEGLITCH_ADDR, 0, 70, DEGLITCH_FACTORY); + extracThrVal = readSettingBounded(EXTRAC_THR_ADDR, extracLoLimit, extracHiLimit, EXTRAC_THR_FACTORY); + extracMaxVal = readSettingBounded(EXTRAC_MAX_ADDR, extracLoLimit, extracHiLimit, EXTRAC_MAX_FACTORY); + patch = readSettingBounded(PATCH_ADDR, 0, 127, PATCH_FACTORY); + octave = readSettingBounded(OCTAVE_ADDR, 0, 6, OCTAVE_FACTORY); + ctouchThrVal = readSettingBounded(CTOUCH_THR_ADDR, ctouchLoLimit, ctouchHiLimit, CTOUCH_THR_FACTORY); + curve = readSettingBounded(BREATHCURVE_ADDR, 0, 12, BREATHCURVE_FACTORY); + velSmpDl = readSettingBounded(VEL_SMP_DL_ADDR, 0, 30, VEL_SMP_DL_FACTORY); + velBias = readSettingBounded(VEL_BIAS_ADDR, 0, 9, VEL_BIAS_FACTORY); + pinkySetting = readSettingBounded(PINKY_KEY_ADDR, 0, 24, PINKY_KEY_FACTORY); + fastPatch[0] = readSettingBounded(FP1_ADDR, 0, 127, 0); + fastPatch[1] = readSettingBounded(FP2_ADDR, 0, 127, 0); + fastPatch[2] = readSettingBounded(FP3_ADDR, 0, 127, 0); + fastPatch[3] = readSettingBounded(FP4_ADDR, 0, 127, 0); + fastPatch[4] = readSettingBounded(FP5_ADDR, 0, 127, 0); + fastPatch[5] = readSettingBounded(FP6_ADDR, 0, 127, 0); + fastPatch[6] = readSettingBounded(FP7_ADDR, 0, 127, 0); dipSwBits = readSetting(DIPSW_BITS_ADDR); - parallel = readSetting(PARAL_ADDR); - rotations[0] = readSetting(ROTN1_ADDR); - rotations[1] = readSetting(ROTN2_ADDR); - rotations[2] = readSetting(ROTN3_ADDR); - rotations[3] = readSetting(ROTN4_ADDR); - priority = readSetting(PRIO_ADDR); - vibSens = readSetting(VIB_SENS_ADDR); - vibRetn = readSetting(VIB_RETN_ADDR); - vibSquelch = readSetting(VIB_SQUELCH_ADDR); - vibDirection = readSetting(VIB_DIRECTION_ADDR); - breathCC2 = readSetting(BREATH_CC2_ADDR); - breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR); - vibSensBite = readSetting(VIB_SENS_BITE_ADDR); - vibSquelchBite = readSetting(VIB_SQUELCH_BITE_ADDR); - vibControl = readSetting(VIB_CONTROL_ADDR); - dacMode = readSetting(DAC_MODE_ADDR); - trill3_interval = readSetting(TRILL3_INTERVAL_ADDR); - - if(trill3_interval<3 || trill3_interval > 4) trill3_interval = TRILL3_INTERVAL_FACTORY; //Deal with possible zero/bad values + parallel = readSettingBounded(PARAL_ADDR, 0, 48, PARAL_FACTORY); + rotations[0] = readSettingBounded(ROTN1_ADDR, 0, 48, ROTN1_FACTORY); + rotations[1] = readSettingBounded(ROTN2_ADDR, 0, 48, ROTN2_FACTORY); + rotations[2] = readSettingBounded(ROTN3_ADDR, 0, 48, ROTN3_FACTORY); + rotations[3] = readSettingBounded(ROTN4_ADDR, 0, 48, ROTN4_FACTORY); + priority = readSettingBounded(PRIO_ADDR, 0, 1, PRIO_FACTORY); + vibSens = readSettingBounded(VIB_SENS_ADDR, 1, 12, VIB_SENS_FACTORY); + vibRetn = readSettingBounded(VIB_RETN_ADDR, 0, 4, VIB_RETN_FACTORY); + vibSquelch = readSettingBounded(VIB_SQUELCH_ADDR, 1, 30, VIB_SQUELCH_FACTORY); + vibDirection = readSettingBounded(VIB_DIRECTION_ADDR, 0, 1, VIB_DIRECTION_FACTORY); + breathCC2 = readSettingBounded(BREATH_CC2_ADDR, 0, 127, BREATH_CC2_FACTORY); + breathCC2Rise = readSettingBounded(BREATH_CC2_RISE_ADDR, 1, 10, BREATH_CC2_RISE_FACTORY); + vibSensBite = readSettingBounded(VIB_SENS_BITE_ADDR, 1, 12, VIB_SENS_BITE_FACTORY); + vibSquelchBite = readSettingBounded(VIB_SQUELCH_BITE_ADDR, 1, 30, VIB_SQUELCH_BITE_FACTORY); + vibControl = readSettingBounded(VIB_CONTROL_ADDR, 0, 1, VIB_CONTROL_FACTORY); + dacMode = readSettingBounded(DAC_MODE_ADDR, DAC_MODE_BREATH, DAC_MODE_PITCH, DAC_MODE_FACTORY); + trill3_interval = readSettingBounded(TRILL3_INTERVAL_ADDR, 3, 4, TRILL3_INTERVAL_FACTORY); //Flags stored in bit field fastBoot = (dipSwBits & (1< max) { + val = defaultValue; + writeSetting(address, val); + } + return val; +} diff --git a/NuEVI/settings.h b/NuEVI/settings.h index bdd9771..cab78ba 100644 --- a/NuEVI/settings.h +++ b/NuEVI/settings.h @@ -121,9 +121,11 @@ #define DAC_MODE_FACTORY DAC_MODE_BREATH -bool readEEPROM(); +void readEEPROM(); void setBit(uint16_t &bitfield, const uint8_t pos, const uint16_t value); uint16_t readSetting(uint16_t address); void writeSetting(uint16_t address, uint16_t value); +uint16_t readSettingBounded(uint16_t address, uint16_t min, uint16_t max, uint16_t defaultValue); + #endif From e04a14ef95cfc148ee5af78fcc62d8c32ad2d947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Fri, 26 Jul 2019 23:42:08 +0200 Subject: [PATCH 11/18] Simplify readSwitches() --- NuEVI/NuEVI.ino | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index a3cffbb..7242683 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -1131,42 +1131,35 @@ void portOff() { void readSwitches() { - int qTransp; - // Read touch pads (MPR121) and put value in variables - int touchValue[12]; + // Read touch pads (MPR121), compare against threshold value + bool touchKeys[12]; for (byte i = 0; i < 12; i++) { - touchValue[i] = touchSensor.filteredData(i); + touchKeys[i] = touchSensor.filteredData(i) < ctouchThrVal; } // Octave rollers octaveR = 0; - if ((touchValue[R5Pin] < ctouchThrVal) && (touchValue[R3Pin] < ctouchThrVal)) octaveR = 6; //R6 = R5 && R3 - else if (touchValue[R5Pin] < ctouchThrVal) octaveR = 5; //R5 - else if (touchValue[R4Pin] < ctouchThrVal) octaveR = 4; //R4 - else if ((touchValue[R3Pin] < ctouchThrVal) && lastOctaveR) octaveR = 3; //R3 - else if (touchValue[R2Pin] < ctouchThrVal) octaveR = 2; //R2 - else if (touchValue[R1Pin] < ctouchThrVal) octaveR = 1; //R1 + if (touchKeys[R5Pin] && touchValue[R3Pin]) octaveR = 6; //R6 = R5 && R3 + else if (touchKeys[R5Pin]) octaveR = 5; //R5 + else if (touchKeys[R4Pin]) octaveR = 4; //R4 + else if (touchKeys[R3Pin] && lastOctaveR) octaveR = 3; //R3 + else if (touchKeys[R2Pin]) octaveR = 2; //R2 + else if (touchKeys[R1Pin]) octaveR = 1; //R1 lastOctaveR = octaveR; // Valves and trill keys - K4 = (touchValue[K4Pin] < ctouchThrVal); - K1 = (touchValue[K1Pin] < ctouchThrVal); - K2 = (touchValue[K2Pin] < ctouchThrVal); - K3 = (touchValue[K3Pin] < ctouchThrVal); - K5 = (touchValue[K5Pin] < ctouchThrVal); - K6 = (touchValue[K6Pin] < ctouchThrVal); - K7 = (touchValue[K7Pin] < ctouchThrVal); + K1 = touchKeys[K1Pin]; + K2 = touchKeys[K2Pin]; + K3 = touchKeys[K3Pin]; + K4 = touchKeys[K4Pin]; + K5 = touchKeys[K5Pin]; + K6 = touchKeys[K6Pin]; + K7 = touchKeys[K7Pin]; pinkyKey = (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" - if ((pinkySetting < 12) && pinkyKey) { - qTransp = pinkySetting - 12; - } else if ((pinkySetting > 12) && pinkyKey) { - qTransp = pinkySetting - 12; - } else { - qTransp = 0; - } + int qTransp = pinkyKey ? pinkySetting-12 : 0; // Calculate midi note number from pressed keys From 6f976ea14d9d11cf29887a4de5ac0c149bd956ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 00:02:25 +0200 Subject: [PATCH 12/18] Use proper 3rd trill value for readTrills() --- NuEVI/menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 08c2e60..8fec04d 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -366,7 +366,7 @@ void drawMenuCursor(byte itemNo, byte color){ static int readTrills() { readSwitches(); - return K5+2*K6+4*K7; + return K5+2*K6+trill3_interval*K7; } //*********************************************************** From a5385a9ec19d0272ffb95e5f3c9871c8a8f4d352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 00:06:52 +0200 Subject: [PATCH 13/18] Wrap status led usage in neat functions --- NuEVI/NuEVI.ino | 61 +++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 7242683..6fc1f62 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -305,11 +305,8 @@ void setup() { vibThrBiteLo = vibZeroBite + vibSquelchBite; if(!fastBoot) { - digitalWrite(statusLedPin, LOW); - delay(250); - digitalWrite(statusLedPin,HIGH); - delay(250); - digitalWrite(statusLedPin,LOW); + statusLedFlash(500); + statusLedOff(); showVersion(); @@ -328,7 +325,7 @@ void setup() { //Serial.begin(9600); // debug - digitalWrite(statusLedPin,HIGH); // Switch on the onboard LED to indicate power on/ready + statusLedOn(); // Switch on the onboard LED to indicate power on/ready } @@ -700,9 +697,9 @@ void loop() { // this is one of the big reasons the display is for setup use only drawSensorPixels(); // live sensor monitoring for the setup screens if (rotatorOn || slurSustain || parallelChord || subOctaveDouble || gateOpen) { - digitalWrite(statusLedPin, !digitalRead(statusLedPin)); - } else if (!digitalRead(statusLedPin)) { - digitalWrite(statusLedPin, HIGH); + statusLedFlip(); + } else { + statusLedOn(); } pixelUpdateTime = millis(); } @@ -944,10 +941,10 @@ void pitch_bend() { pitchBend = constrain(pitchBend, 0, 16383); if (subVibSquelch && (8192 != pitchBend)) { - digitalWrite(statusLedPin, LOW); + statusLedOff(); vibLedOff = 1; } else if (vibLedOff) { - digitalWrite(statusLedPin, HIGH); + statusLedOn(); vibLedOff = 0; } @@ -972,25 +969,14 @@ void doorKnobCheck() { if ((touchValue[K4Pin] < ctouchThrVal) && (touchValue[R1Pin] < ctouchThrVal) && (touchValue[R2Pin] < ctouchThrVal) && (touchValue[R3Pin] < ctouchThrVal)) { // doorknob grip on canister if (!gateOpen && (pbUp > ((pitchbMaxVal + pitchbThrVal) / 2))) { gateOpen = 1; - digitalWrite(statusLedPin, LOW); - delay(50); - digitalWrite(statusLedPin, HIGH); - delay(50); + statusLedFlash(100); } else if (gateOpen && (pbDn > ((pitchbMaxVal + pitchbThrVal) / 2))) { gateOpen = 0; midiPanic(); - digitalWrite(statusLedPin, LOW); - delay(50); - digitalWrite(statusLedPin, HIGH); - delay(50); - digitalWrite(statusLedPin, LOW); - delay(50); - digitalWrite(statusLedPin, HIGH); - delay(50); - digitalWrite(statusLedPin, LOW); - delay(50); - digitalWrite(statusLedPin, HIGH); - delay(700); + statusLedFlash(100); + statusLedFlash(100); + statusLedFlash(100); + delay(600); } } } else if (gateOpen) { @@ -1184,3 +1170,24 @@ void readSwitches() { } lastFingering = fingeredNoteRead; } + + + +void statusLedOn() { + digitalWrite(statusLedPin, HIGH); +} + +void statusLedOff() { + digitalWrite(statusLedPin, LOW); +} + +void statusLedFlip() { + digitalWrite(statusLedPin, !digitalRead(statusLedPin)); +} + +void statusLedFlash(uint16_t delayTime) { + statusLedOff(); + delay(delayTime/2); + statusLedOn(); + delay(delayTime/2); +} From 3903ec7b9823902b6f32ea72342e58d3f5ab6623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 00:20:01 +0200 Subject: [PATCH 14/18] Mistakes were made --- NuEVI/NuEVI.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 6fc1f62..7ba93ed 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -1125,7 +1125,7 @@ void readSwitches() { // Octave rollers octaveR = 0; - if (touchKeys[R5Pin] && touchValue[R3Pin]) octaveR = 6; //R6 = R5 && R3 + if (touchKeys[R5Pin] && touchKeys[R3Pin]) octaveR = 6; //R6 = R5 && R3 else if (touchKeys[R5Pin]) octaveR = 5; //R5 else if (touchKeys[R4Pin]) octaveR = 4; //R4 else if (touchKeys[R3Pin] && lastOctaveR) octaveR = 3; //R3 From 3ae4147d7e7b38d618b53dcfd98f283bfbf345a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 00:42:27 +0200 Subject: [PATCH 15/18] Move all the LED things to a separate file, as mentioned in comments --- NuEVI/NuEVI.ino | 46 +++---------------------------------------- NuEVI/config.h | 5 +++++ NuEVI/globals.h | 4 ++++ NuEVI/led.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++ NuEVI/led.h | 12 ++++++++++++ NuEVI/menu.cpp | 16 +++------------ simulation/Makefile | 1 + 7 files changed, 76 insertions(+), 56 deletions(-) create mode 100644 NuEVI/led.cpp create mode 100644 NuEVI/led.h diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 7ba93ed..d94a939 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -11,6 +11,7 @@ #include "menu.h" #include "config.h" #include "settings.h" +#include "led.h" /* NAME: NuEVI @@ -233,9 +234,6 @@ byte slurSustain = 0; byte parallelChord = 0; byte subOctaveDouble = 0; -const int breathLedBrightness = 500; // up to 4095, PWM -const int portamLedBrightness = 500; // up to 4095, PWM - Adafruit_MPR121 touchSensor = Adafruit_MPR121(); // This is the 12-input touch sensor FilterOnePole breathFilter; @@ -291,7 +289,7 @@ void setup() { vibZero += touchRead(vibratoPin); breathCalZero += analogRead(breathSensorPin); if (biteJumper) vibZeroBite += analogRead(A7); else vibZeroBite += touchRead(bitePin); - digitalWrite( statusLedPin, i&1 ); + statusLed(i&1); delay(fastBoot?75:250); //Shorter delay for fastboot } @@ -687,7 +685,7 @@ void loop() { } else { if (slowMidi) breath(); extraController(); - statusLEDs(); + updateSensorLEDs(); doorKnobCheck(); } ccSendTime = millis(); @@ -778,23 +776,6 @@ int patchLimit(int value) { //************************************************************** -void statusLEDs() { - if (breathLevel > breathThrVal) { // breath indicator LED, labeled "B" on PCB - //analogWrite(bLedPin, map(breathLevel,0,4096,5,breathLedBrightness)); - analogWrite(bLedPin, map(constrain(breathLevel, breathThrVal, breathMaxVal), breathThrVal, breathMaxVal, 5, breathLedBrightness)); - } else { - analogWrite(bLedPin, 0); - } - if (portIsOn) { // portamento indicator LED, labeled "P" on PCB - //analogWrite(pLedPin, map(biteSensor,0,4096,5,portamLedBrightness)); - analogWrite(pLedPin, map(constrain(oldport, 0, 127), 0, 127, 5, portamLedBrightness)); - } else { - analogWrite(pLedPin, 0); - } -} - -//************************************************************** - void breath() { int breathCCval, breathCCvalFine,breathCC2val; unsigned int breathCCvalHires; @@ -1170,24 +1151,3 @@ void readSwitches() { } lastFingering = fingeredNoteRead; } - - - -void statusLedOn() { - digitalWrite(statusLedPin, HIGH); -} - -void statusLedOff() { - digitalWrite(statusLedPin, LOW); -} - -void statusLedFlip() { - digitalWrite(statusLedPin, !digitalRead(statusLedPin)); -} - -void statusLedFlash(uint16_t delayTime) { - statusLedOff(); - delay(delayTime/2); - statusLedOn(); - delay(delayTime/2); -} diff --git a/NuEVI/config.h b/NuEVI/config.h index 0ebceae..84520ea 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -30,4 +30,9 @@ #define ttouchHiLimit 1900 +#define MIN_LED_BRIGHTNESS 5 // lowest PWM value that still is visible +#define BREATH_LED_BRIGHTNESS 500 // up to 4095, PWM +#define PORTAM_LED_BRIGHTNESS 500 // up to 4095, PWM + + #endif diff --git a/NuEVI/globals.h b/NuEVI/globals.h index 4cb0a8b..03fabd6 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -116,6 +116,10 @@ extern int vibZeroBite; extern int vibThrBite; extern int vibThrBiteLo; +extern int breathLevel; +extern byte portIsOn; +extern int oldport; + // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed extern byte K1; // Valve 1 (pitch change -2) extern byte K2; // Valve 2 (pitch change -1) diff --git a/NuEVI/led.cpp b/NuEVI/led.cpp new file mode 100644 index 0000000..0f0d2f4 --- /dev/null +++ b/NuEVI/led.cpp @@ -0,0 +1,48 @@ +#include +#include "hardware.h" +#include "globals.h" +#include "config.h" + +// Do things with status LED. +void statusLedOn() { + digitalWrite(statusLedPin, HIGH); +} + +void statusLedOff() { + digitalWrite(statusLedPin, LOW); +} + +void statusLed(bool state) { + digitalWrite(statusLedPin, state); +} + +void statusLedFlip() { + digitalWrite(statusLedPin, !digitalRead(statusLedPin)); +} + +void statusLedFlash(uint16_t delayTime) { + statusLedOff(); + delay(delayTime/2); + statusLedOn(); + delay(delayTime/2); +} + +void statusLedBlink() { + statusLedFlash(300); + statusLedFlash(300); +} + +void updateSensorLEDs() { + if (breathLevel > breathThrVal) { // breath indicator LED, labeled "B" on PCB + //analogWrite(bLedPin, map(breathLevel,0,4096,5,breathLedBrightness)); + analogWrite(bLedPin, map(constrain(breathLevel, breathThrVal, breathMaxVal), breathThrVal, breathMaxVal, MIN_LED_BRIGHTNESS, BREATH_LED_BRIGHTNESS)); + } else { + analogWrite(bLedPin, 0); + } + if (portIsOn) { // portamento indicator LED, labeled "P" on PCB + //analogWrite(pLedPin, map(biteSensor,0,4096,5,portamLedBrightness)); + analogWrite(pLedPin, map(constrain(oldport, 0, 127), 0, 127, MIN_LED_BRIGHTNESS, PORTAM_LED_BRIGHTNESS)); + } else { + analogWrite(pLedPin, 0); + } +} \ No newline at end of file diff --git a/NuEVI/led.h b/NuEVI/led.h new file mode 100644 index 0000000..cd893d1 --- /dev/null +++ b/NuEVI/led.h @@ -0,0 +1,12 @@ +#ifndef __LED_H +#define __LED_H + +void statusLedOn(); +void statusLedOff(); +void statusLedFlip(); +void statusLed(bool state); +void statusLedFlash(uint16_t delayTime); +void statusLedBlink(); +void updateSensorLEDs(); + +#endif \ No newline at end of file diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 8fec04d..5788e68 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -10,6 +10,7 @@ #include "globals.h" #include "midi.h" #include "numenu.h" +#include "led.h" enum CursorIdx { EMain, @@ -1228,17 +1229,6 @@ static bool updatePage(const MenuPage *page, KeyState &input, uint32_t timeNow) return redraw; } -//*********************************************************** -// This should be moved to a separate file/process that handles only led -static void statusBlink() { - digitalWrite(statusLedPin,LOW); - delay(150); - digitalWrite(statusLedPin,HIGH); - delay(150); - digitalWrite(statusLedPin,LOW); - delay(150); - digitalWrite(statusLedPin,HIGH); -} //*********************************************************** @@ -1391,12 +1381,12 @@ static bool idlePageUpdate(KeyState& __unused input, uint32_t __unused timeNow) legacyBrAct = !legacyBrAct; dipSwBits = dipSwBits ^ (1<<2); writeSetting(DIPSW_BITS_ADDR,dipSwBits); - statusBlink(); + statusLedBlink(); } else if ((exSensor >= ((extracThrVal+extracMaxVal)/2))) { // switch pb pad activated legacy settings control on/off legacy = !legacy; dipSwBits = dipSwBits ^ (1<<1); writeSetting(DIPSW_BITS_ADDR,dipSwBits); - statusBlink(); + statusLedBlink(); } else if (pinkyKey && !specialKey){ //hold pinky key for rotator menu, and if too high touch sensing blocks regular menu, touching special key helps display.ssd1306_command(SSD1306_DISPLAYON); menuState= ROTATOR_MENU; diff --git a/simulation/Makefile b/simulation/Makefile index 903471c..71ec82e 100644 --- a/simulation/Makefile +++ b/simulation/Makefile @@ -30,6 +30,7 @@ CXXFILES= ../NuEVI/menu.cpp \ ../NuEVI/adjustmenu.cpp \ ../NuEVI/midi.cpp \ ../NuEVI/settings.cpp \ + ../NuEVI/led.cpp \ src/nuevisim.cpp \ src/simeeprom.cpp \ src/Print.cpp \ From c6ad2b6c53bb114b88d631e179b719c15285f753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 13:32:39 +0200 Subject: [PATCH 16/18] Init variables to avoid (incorrect) compiler warnings --- NuEVI/NuEVI.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index d94a939..72742b5 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -821,8 +821,8 @@ void pitch_bend() { int vibMax; int calculatedPBdepth; byte pbTouched = 0; - int vibRead; - int vibReadBite; + 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 From 4966a7ea429c3e197c1626974c79abe9273df56a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 14:31:27 +0200 Subject: [PATCH 17/18] Incorporate Filters code into NuEVI repo for smoother setup. --- NuEVI/FilterOnePole.cpp | 240 +++++++++++++++++++++++++++++++++++++ NuEVI/FilterOnePole.h | 89 ++++++++++++++ NuEVI/NuEVI.ino | 3 +- simulation/Makefile | 3 +- simulation/src/filters.cpp | 2 +- 5 files changed, 333 insertions(+), 4 deletions(-) create mode 100644 NuEVI/FilterOnePole.cpp create mode 100644 NuEVI/FilterOnePole.h diff --git a/NuEVI/FilterOnePole.cpp b/NuEVI/FilterOnePole.cpp new file mode 100644 index 0000000..478cd03 --- /dev/null +++ b/NuEVI/FilterOnePole.cpp @@ -0,0 +1,240 @@ +// Copyright 2014 Jonathan Driscoll +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "FilterOnePole.h" + +#include + +FilterOnePole::FilterOnePole( FILTER_TYPE ft, float fc, float initialValue ) { + setFilter( ft, fc, initialValue ); +} + +void FilterOnePole::setFilter( FILTER_TYPE ft, float fc, float initialValue ) { + FT = ft; + setFrequency( fc ); + + Y = initialValue; + Ylast = initialValue; + X = initialValue; + + LastUS = micros(); +} + +float FilterOnePole::input( float inVal ) { + long time = micros(); + ElapsedUS = float(time - LastUS); // cast to float here, for math + LastUS = time; // update this now + + // shift the data values + Ylast = Y; + X = inVal; // this is now the most recent input value + + // filter value is controlled by a parameter called X + // tau is set by the user in microseconds, but must be converted to samples here + TauSamps = TauUS / ElapsedUS; + + float ampFactor; +#ifdef ARM_FLOAT + ampFactor = expf( -1.0 / TauSamps ); // this is 1 if called quickly +#else + ampFactor = exp( -1.0 / TauSamps ); // this is 1 if called quickly +#endif + + Y = (1.0-ampFactor)*X + ampFactor*Ylast; // set the new value + + return output(); +} + +void FilterOnePole::setFrequency( float newFrequency ) { + setTau( 1.0/(TWO_PI*newFrequency ) ); // τ=1/ω +} + +void FilterOnePole::setTau( float newTau ) { + TauUS = newTau * 1e6; +} + +float FilterOnePole::output() { + // figure out which button to read + switch (FT) { + case LOWPASS: + // return the last value + return Y; + break; + case INTEGRATOR: + // using a lowpass, but normaize + return Y * (TauUS/1.0e6); + break; + case HIGHPASS: + // highpass is the _difference_ + return X-Y; + break; + case DIFFERENTIATOR: + // like a highpass, but normalize + return (X-Y)/(TauUS/1.0e6); + break; + default: + // should never get to here, return 0 just in case + return 0; + } +} + +void FilterOnePole::print() { + Serial.println(""); + Serial.print(" Y: "); Serial.print( Y ); + Serial.print(" Ylast: "); Serial.print( Ylast ); + Serial.print(" X "); Serial.print( X ); + Serial.print(" ElapsedUS "); Serial.print( ElapsedUS ); + Serial.print(" TauSamps: "); Serial.print( TauSamps ); + //Serial.print(" ampFactor " ); Serial.print( ampFactor ); + Serial.print(" TauUS: "); Serial.print( TauUS ); + Serial.println(""); +} + +void FilterOnePole::test() { + float tau = 10; + float updateInterval = 1; + float nextupdateTime = millis()*1e-3; + + float inputValue = 0; + FilterOnePole hp( HIGHPASS, tau, inputValue ); + FilterOnePole lp( LOWPASS, tau, inputValue ); + + while( true ) { + float now = millis()*1e-3; + + // switch input values on a 20 second cycle + if( round(now/20.0)-(now/20.0) < 0 ) + inputValue = 0; + else + inputValue = 100; + + hp.input(inputValue); + lp.input(inputValue); + + if( now > nextupdateTime ) { + nextupdateTime += updateInterval; + + Serial.print("inputValue: "); Serial.print( inputValue ); + Serial.print("\t high-passed: "); Serial.print( hp.output() ); + Serial.print("\t low-passed: "); Serial.print( lp.output() ); + Serial.println(); + } + } +} + +void FilterOnePole::setToNewValue( float newVal ) { + Y = Ylast = X = newVal; +} + + +// stuff for filter2 (lowpass only) +// should be able to set a separate fall time as well +FilterOnePoleCascade::FilterOnePoleCascade( float riseTime, float initialValue ) { + setRiseTime( riseTime ); + setToNewValue( initialValue ); +} + +void FilterOnePoleCascade::setRiseTime( float riseTime ) { + float tauScale = 3.36; // found emperically, by running test(); + + Pole1.setTau( riseTime / tauScale ); + Pole2.setTau( riseTime / tauScale ); +} + +float FilterOnePoleCascade::input( float inVal ) { + Pole2.input( Pole1.input( inVal )); + return output(); +} + +// clears out the values in the filter +void FilterOnePoleCascade::setToNewValue( float newVal ) { + Pole1.setToNewValue( newVal ); + Pole2.setToNewValue( newVal ); +} + +float FilterOnePoleCascade::output() { + return Pole2.output(); +} + +void FilterOnePoleCascade::test() { + // make a filter, how fast does it run: + + float rise = 1.0; + FilterOnePoleCascade myFilter( rise ); + + // first, test the filter speed ... + long nLoops = 1000; + + Serial.print( "testing filter with a rise time of "); + Serial.print( rise ); Serial.print( "s" ); + + Serial.print( "\n running filter speed loop ... "); + + float startTime, stopTime; + + startTime = millis()*1e-3; + for( long i=0; i 0.1 && !crossedTenPercent ) { + // filter first crossed the 10% point + startTime = millis()*1e-3; + crossedTenPercent = true; + } + } + stopTime = millis()*1e-3; + + Serial.print( "done, rise time: " ); Serial.print( stopTime-startTime ); + + Serial.print( "testing attenuation at f = 1/risetime" ); + + myFilter.setToNewValue( 0.0 ); + + float maxVal = 0; + float valWasOutputThisCycle = true; + + __unused float lastFilterVal = 0; + + while( true ) { + float now = 1e-3*millis(); + + float currentFilterVal = myFilter.input( sin( TWO_PI*now) ); + + if( currentFilterVal < 0.0 ) { + if( !valWasOutputThisCycle ) { + // just crossed below zero, output the max + Serial.print( maxVal*100 ); Serial.print( " %\n" ); + valWasOutputThisCycle = true; + } + + } + + } + +} diff --git a/NuEVI/FilterOnePole.h b/NuEVI/FilterOnePole.h new file mode 100644 index 0000000..cf55b86 --- /dev/null +++ b/NuEVI/FilterOnePole.h @@ -0,0 +1,89 @@ +// Copyright 2014 Jonathan Driscoll +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// FilterOnePole has been copied from https://github.com/JonHub/Filters + + +#ifndef FilterOnePole_h +#define FilterOnePole_h + +enum FILTER_TYPE { + HIGHPASS, + LOWPASS, + INTEGRATOR, + DIFFERENTIATOR +}; + +// the recursive filter class implements a recursive filter (low / pass / highpass +// note that this must be updated in a loop, using the most recent acquired values and the time acquired +// Y = a0*X + a1*Xm1 +// + b1*Ylast +struct FilterOnePole { + FILTER_TYPE FT; + float TauUS; // decay constant of the filter, in US + float TauSamps; // tau, measued in samples (this changes, depending on how long between input()s + + // filter values - these are public, but should not be set externally + float Y; // most recent output value (gets computed on update) + float Ylast; // prevous output value + + float X; // most recent input value + + // elapsed times are kept in long, and will wrap every + // 35 mins, 47 seconds ... however, the wrap does not matter, + // because the delta will still be correct (always positive and small) + float ElapsedUS; // time since last update + long LastUS; // last time measured + + FilterOnePole( FILTER_TYPE ft=LOWPASS, float fc=1.0, float initialValue=0 ); + + // sets or resets the parameters and state of the filter + void setFilter( FILTER_TYPE ft, float tauS, float initialValue ); + + void setFrequency( float newFrequency ); + + void setTau( float newTau ); + + float input( float inVal ); + + float output(); + + void print(); + + void test(); + + void setToNewValue( float newVal ); // resets the filter to a new value +}; + +// two pole filter, these are very useful +struct FilterOnePoleCascade { + + FilterOnePole Pole1; + FilterOnePole Pole2; + + FilterOnePoleCascade( float riseTime=1.0, float initialValue=0 ); // rise time to step function, 10% to 90% + + // rise time is 10% to 90%, for a step input + void setRiseTime( float riseTime ); + + void setToNewValue( float newVal ); + + float input( float inVal ); + + float output(); + + void test(); +}; + +#endif diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 72742b5..2f22029 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -1,10 +1,9 @@ #include - #include #include #include -#include // for the breath signal LP filtering, https://github.com/edgar-bonet/Filters +#include "FilterOnePole.h" // for the breath signal low-pass filtering, from https://github.com/JonHub/Filters #include "globals.h" #include "hardware.h" #include "midi.h" diff --git a/simulation/Makefile b/simulation/Makefile index 71ec82e..1a603dd 100644 --- a/simulation/Makefile +++ b/simulation/Makefile @@ -17,7 +17,7 @@ CXXFLAGS= $(CFLAGS) -std=c++14 LIBS=-framework SDL2 -lc++ -lc -framework OpenGL LDFLAGS=-macosx_version_min 10.9 -rpath @executable_path/../Frameworks -SYSINC = ~/Documents/Arduino/libraries/Filters ./include +SYSINC = ./include INCS = ../NuEVI ./include ./imgui ./gl3w INCDIRS = $(addprefix -isystem ,$(SYSINC)) @@ -47,6 +47,7 @@ CXXFILES= ../NuEVI/menu.cpp \ imgui/examples/imgui_impl_sdl.cpp \ imgui/examples/imgui_impl_opengl3.cpp + CFILES= gl3w/gl3w.c OBJS=$(CXXFILES:.cpp=.o) $(CFILES:.c=.o) diff --git a/simulation/src/filters.cpp b/simulation/src/filters.cpp index 6f7eed9..2860caf 100644 --- a/simulation/src/filters.cpp +++ b/simulation/src/filters.cpp @@ -1,3 +1,3 @@ #include -#include "FilterOnepole.cpp" +#include "FilterOnePole.cpp" From fe39e29f0360ee5cfb8dd56f917d412768e7c037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20St=C3=A4ck?= Date: Sat, 27 Jul 2019 17:15:38 +0200 Subject: [PATCH 18/18] Update readme about filters lib --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index c8f04fb..d39ee77 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,7 @@ added directly via the Library Manager in the Arduino IDE: * Adafruit MPR121 * Adafruit GFX * Adafruit SSD1306 (version 1.2.9 or above) - -You also need to install [Edgar Bonet's Filters library](https://github.com/edgar-bonet/Filters), -specifically the `fix-integer-overflow` branch. One of the easiest way to do that is to download the -git repo [as a zip file](https://github.com/edgar-bonet/Filters/archive/fix-integer-overflow.zip), -and then add that in the Arduino IDE (under Sketch -> Include Library -> Add .ZIP library) +* NuEVI also includes on the [Filters](https://github.com/JonHub/Filters) library by Jonathan Driscoll, but that is no longer an external dependency. ### Compile options