NuEVI and NuRAD: Timing and speed issue solved - SSD1306 display library needed editing to prevent it from lowering I2C bus speed. Added setting to enable/disable the on the fly key switching. NuRAD: Changed touch sensor reading equalisation from offset to multiplier to improve coherence of readings.

This commit is contained in:
Johan Berglund 2020-07-22 13:24:56 +02:00
parent cc188f2196
commit b9a8742fc1
11 changed files with 10772 additions and 25 deletions

View file

@ -98,7 +98,9 @@ unsigned short fwcType; // 6, m6, 7, m7
unsigned short fwcLockH; // OFF:ON
unsigned short fwcDrop2; // OFF:ON
unsigned short hmzKey; // 0-11 (0 is C)
unsigned short hmzLimit; // 2-5:
unsigned short hmzLimit; // 2-5
unsigned short otfKey; //OFF:ON
unsigned short breathInterval = 6; // 3-15
unsigned short vibSens = 2; // vibrato sensitivity
unsigned short vibRetn = 2; // vibrato return speed
@ -169,6 +171,8 @@ byte activeMIDIchannel; // MIDI channel
byte activePatch=0;
byte doPatchUpdate=0;
byte cvPortaTuneCount = 0;
uint16_t legacy = 0;
uint16_t legacyBrAct = 0;
byte halfTime = 0;
@ -190,7 +194,7 @@ int breathCalZero;
int leverPortZero;
#if defined(NURAD)
int leverPortThr = 40;
int leverPortThr = 50;
#else
int leverPortThr = 50;
#endif
@ -550,7 +554,7 @@ void setup() {
analogReadResolution(12); // set resolution of ADCs to 12 bit
analogWriteResolution(12);
analogWriteFrequency(pwmDacPin,11718.75);
Wire.setClock(400000);
Wire.setClock(1000000);
pinMode(dPin, INPUT_PULLUP);
pinMode(ePin, INPUT_PULLUP);
@ -1293,7 +1297,8 @@ void loop() {
}
// Is it time to send more CC data?
currentTime = millis();
if (currentTime - ccBreathSendTime > (CC_BREATH_INTERVAL+slowMidi*SLOW_MIDI_ADD)){
//if (currentTime - ccBreathSendTime > (CC_BREATH_INTERVAL+slowMidi*SLOW_MIDI_ADD)){
if (currentTime - ccBreathSendTime > (breathInterval-1)){
breath();
ccBreathSendTime = currentTime;
}
@ -1331,10 +1336,22 @@ void loop() {
targetPitch = (fingeredNote-24)*42;
if (portIsOn){
if (targetPitch > cvPitch){
cvPitch += 1+(127-oldport)/4;
if (!cvPortaTuneCount) {
cvPitch += 1+(127-oldport)/4;
}
else {
cvPortaTuneCount++;
if (cvPortaTuneCount > CVPORTATUNE) cvPortaTuneCount=0;
}
if (cvPitch > targetPitch) cvPitch = targetPitch;
} else if (targetPitch < cvPitch){
cvPitch -= 1+(127-oldport)/4;
if (!cvPortaTuneCount) {
cvPitch -= 1+(127-oldport)/4;
}
else {
cvPortaTuneCount++;
if (cvPortaTuneCount > CVPORTATUNE) cvPortaTuneCount=0;
}
if (cvPitch < targetPitch) cvPitch = targetPitch;
} else {
cvPitch = targetPitch;
@ -1842,7 +1859,8 @@ void readSwitches() {
// Octave rollers
int touchValueRollers[12];
for (byte i=0; i<6; i++){
touchValueRollers[i]=touchSensorRollers.filteredData(i) - calOffsetRollers[i];
//touchValueRollers[i]=touchSensorRollers.filteredData(i) - calOffsetRollers[i];
touchValueRollers[i]=touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300;
}
// 6-pin version
octaveR = 0;
@ -1852,6 +1870,13 @@ void readSwitches() {
else if (R3=(touchValueRollers[rPin3] < ctouchThrVal)) octaveR = 3; //R3 (store for combo check)
else if (R2=(touchValueRollers[rPin2] < ctouchThrVal)) octaveR = 2; //R2 (store for combo check)
else if (touchValueRollers[rPin1] < ctouchThrVal) octaveR = 1; //R1
else if (lastOctaveR > 1) {
octaveR = lastOctaveR;
if (otfKey && polySelect && (polySelect<RT1) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12;
}
//if rollers are released and we are not coming down from roller 1, stay at the higher octave
lastOctaveR = octaveR;
/*
//5-pin version
octaveR = 0;
@ -1867,7 +1892,8 @@ void readSwitches() {
// RH keys
int touchValueRH[12];
for (byte i=0; i<12; i++){
touchValueRH[i]=touchSensorRH.filteredData(i) - calOffsetRH[i];
//touchValueRH[i]=touchSensorRH.filteredData(i) - calOffsetRH[i];
touchValueRH[i]=touchSensorRH.filteredData(i) * (300-calOffsetRH[i])/300;
}
RHs=(touchValueRH[RHsPin] < ctouchThrVal);
RH1=(touchValueRH[RH1Pin] < ctouchThrVal);
@ -1882,7 +1908,8 @@ void readSwitches() {
// LH keys
int touchValueLH[12];
for (byte i=0; i<12; i++){
touchValueLH[i]=touchSensorLH.filteredData(i) - calOffsetLH[i];
//touchValueLH[i]=touchSensorLH.filteredData(i) - calOffsetLH[i];
touchValueLH[i]=touchSensorLH.filteredData(i) * (300-calOffsetLH[i])/300;
}
LHs=(touchValueLH[LHsPin] < ctouchThrVal);
LHb=(touchValueLH[LHbPin] < ctouchThrVal);
@ -1984,7 +2011,10 @@ 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;
else if (lastOctaveR > 1) {
octaveR = lastOctaveR;
if (otfKey && polySelect && (polySelect<RT1) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12;
}
//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

9
NuEVI/adjustmenu.cpp Executable file → Normal file
View file

@ -240,17 +240,20 @@ void plotSensorPixels(){
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);
//int pos = map(constrain(touchSensorRH.filteredData(i) - calOffsetRH[i], ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
int pos = map(constrain(touchSensorRH.filteredData(i) * (300-calOffsetRH[i])/300, 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);
//int pos = map(constrain(touchSensorLH.filteredData(i) - calOffsetLH[i], ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
int pos = map(constrain(touchSensorLH.filteredData(i) * (300-calOffsetLH[i])/300, 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);
//int pos = map(constrain(touchSensorRollers.filteredData(i) - calOffsetRollers[i], ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
int pos = map(constrain(touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300, ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
display.drawPixel(pos, 39, WHITE);
}
redraw = 1;

View file

@ -5,7 +5,7 @@
// Compile options, comment/uncomment to change
#define FIRMWARE_VERSION "1.4.7" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
#define FIRMWARE_VERSION "1.4.8" // 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
@ -13,12 +13,13 @@
#define CCN_PortSE02 9 // Controller number for portamento type on Roland SE-02
// Send breath CC data no more than every CC_BREATH_INTERVAL
// milliseconds (due to timing errors, the value should be about half the actual wanted value)
#define CC_BREATH_INTERVAL 1
// milliseconds
#define CC_BREATH_INTERVAL 5
#define SLOW_MIDI_ADD 7
#define CC_INTERVAL 13
#define CC_INTERVAL2 19
#define CC_INTERVAL3 37
#define CVPORTATUNE 2
#define breathLoLimit 0

View file

@ -107,6 +107,8 @@ extern unsigned short fwcLockH; // OFF:ON
extern unsigned short fwcDrop2; // OFF:ON
extern unsigned short hmzKey; // 0-11 (0 is C)
extern unsigned short hmzLimit; // 2-5
extern unsigned short otfKey; //OFF:ON
extern unsigned short breathInterval; // 3-15
extern uint16_t gateOpenEnable;
extern uint16_t specialKeyEnable;
extern byte rotatorOn;

View file

@ -2,7 +2,7 @@
#define __HARDWARE_H
#define REVB
//#define NURAD
#define NURAD
#if defined(NURAD) //NuRAD <<<<<<<<<<<<<<<<<<<<<<<

View file

@ -822,9 +822,26 @@ const MenuEntrySub hmzLimitMenu = {
hmzLimitOptionGet, hmzLimitSave, nullptr,
};
static void otfKeyOptionGet(SubMenuRef __unused, char* out, const char** __unused) {
if (otfKey) strncpy(out, "ON", 4);
else strncpy(out, "OFF", 4);
}
static void otfKeySave(SubMenuRef __unused) {
writeSetting(OTFKEY_ADDR,otfKey);
}
const MenuEntrySub otfKeyMenu = {
MenuType::ESub, "OTF KEY", "OTF KEYSW", &otfKey, 0,1, MenuEntryFlags::EMenuEntryWrap,
otfKeyOptionGet, otfKeySave, nullptr,
};
const MenuEntry* rotatorMenuEntries[] = {
(MenuEntry*)&polySelectMenu,
(MenuEntry*)&hmzKeyMenu,
(MenuEntry*)&otfKeyMenu,
(MenuEntry*)&hmzLimitMenu,
(MenuEntry*)&fwcTypeMenu,
(MenuEntry*)&fwcLockHMenu,
@ -885,14 +902,16 @@ const MenuEntrySub octaveMenu = {
};
static void midiSaveFunc(const MenuEntrySub & __unused sub) { writeSetting(MIDI_ADDR, MIDIchannel); }
static void midiCustomDrawFunc(SubMenuRef __unused, char* __unused, const char** __unused) {
char buff[7];
numToString(MIDIchannel, buff);
plotSubOption(buff);
if (slowMidi) {
display.setTextSize(1);
display.setCursor(116,51);
display.print("S");
//replaced with breathInterval setting and not used anymore.. do cleanup later removing all slowMidi related stuff
//display.setTextSize(1);
//display.setCursor(116,51);
//display.print("S");
}
}
@ -1057,6 +1076,8 @@ const MenuPage extrasMenuPage = {
};
static bool midiEnterHandlerFunc() {
/*
//this switching is removed due to new breathInterval setting
readSwitches();
if (pinkyKey){
slowMidi = !slowMidi;
@ -1067,6 +1088,9 @@ static bool midiEnterHandlerFunc() {
writeSetting(MIDI_ADDR, MIDIchannel);
return true;
}
*/
writeSetting(MIDI_ADDR, MIDIchannel);
return true;
}
const MenuEntrySub midiMenu = {
@ -1196,7 +1220,7 @@ const MenuEntrySub velSmpDlMenu = {
[](SubMenuRef __unused, char *out, const char** label) {
if (velSmpDl) {
numToString(velSmpDl, out);
*label = "";
*label = "ms";
} else strncpy(out, "OFF", 4);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VEL_SMP_DL_ADDR,velSmpDl); }
@ -1213,6 +1237,15 @@ const MenuEntrySub velBiasMenu = {
, nullptr
};
const MenuEntrySub breathIntervalMenu = {
MenuType::ESub, "BR INTERV", "CC INTERV", &breathInterval, 3, 15, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* out, const char** __unused unit) {
numToString(breathInterval, out, false);
},
[](SubMenuRef __unused) { writeSetting(BRINTERV_ADDR, breathInterval); }
, nullptr
};
const MenuEntry* breathMenuEntries[] = {
(MenuEntry*)&breathCCMenu,
(MenuEntry*)&breathCC2Menu,
@ -1221,7 +1254,8 @@ const MenuEntry* breathMenuEntries[] = {
(MenuEntry*)&velocityMenu,
(MenuEntry*)&curveMenu,
(MenuEntry*)&velSmpDlMenu,
(MenuEntry*)&velBiasMenu
(MenuEntry*)&velBiasMenu,
(MenuEntry*)&breathIntervalMenu
};
const MenuPage breathMenuPage = {

View file

@ -146,6 +146,11 @@ void readEEPROM(const bool factoryReset) {
if(settingsVersion < 38) {
writeSetting(HMZLIMIT_ADDR, HMZLIMIT_FACTORY);
}
if(settingsVersion < 39) {
writeSetting(BRINTERV_ADDR, BRINTERV_FACTORY);
writeSetting(OTFKEY_ADDR, OTFKEY_FACTORY);
}
writeSetting(VERSION_ADDR, EEPROM_VERSION);
@ -230,6 +235,8 @@ void readEEPROM(const bool factoryReset) {
rotationsc[1] = readSettingBounded(ROTC2_ADDR, 0, 48, ROTC2_FACTORY);
rotationsc[2] = readSettingBounded(ROTC3_ADDR, 0, 48, ROTC3_FACTORY);
rotationsc[3] = readSettingBounded(ROTC4_ADDR, 0, 48, ROTC4_FACTORY);
otfKey = readSettingBounded(OTFKEY_ADDR, 0, 1, OTFKEY_FACTORY);
breathInterval = readSettingBounded(BRINTERV_ADDR, 3, 15, BRINTERV_FACTORY);
//Flags stored in bit field
fastBoot = (dipSwBits & (1<<DIPSW_FASTBOOT))?1:0;

View file

@ -79,8 +79,10 @@
#define FWCLCH_ADDR 152
#define FWCDP2_ADDR 154
#define HMZLIMIT_ADDR 156
#define BRINTERV_ADDR 158
#define OTFKEY_ADDR 160
#define EEPROM_SIZE 158 //Last address +2
#define EEPROM_SIZE 162 //Last address +2
//DAC output modes
@ -97,7 +99,7 @@
//"factory" values for settings
#define EEPROM_VERSION 38
#define EEPROM_VERSION 39
#define BREATH_THR_FACTORY 1400
#define BREATH_MAX_FACTORY 4000
#define PORTAM_THR_FACTORY 2600
@ -122,7 +124,7 @@
#define OCTAVE_FACTORY 3 // 3 is 0 octave change
#define CTOUCH_THR_FACTORY 125 // MPR121 touch threshold
#define BREATHCURVE_FACTORY 4 // 0 to 12 (-4 to +4, S1 to S4)
#define VEL_SMP_DL_FACTORY 15 // 0 to 30
#define VEL_SMP_DL_FACTORY 20 // 0 to 30
#define VEL_BIAS_FACTORY 0 // 0 to 9
#define PINKY_KEY_FACTORY 12 // 0 - 11 (QuickTranspose -12 to -1), 12 (pb/2), 13 - 22 (QuickTranspose +1 to +12)
#define DIPSW_BITS_FACTORY 0 // virtual dip switch settings for special modes (work in progress)
@ -167,6 +169,8 @@
#define FWCLCH_FACTORY 0
#define FWCDP2_FACTORY 0
#define HMZLIMIT_FACTORY 5
#define BRINTERV_FACTORY 6
#define OTFKEY_FACTORY 0
#define NO_CHECKSUM 0x7F007F00