Found culprit in long lags issue in doorKnobCheck function. Reading keys again for that was not very clever... Fixed! Still want some more speed for main loop though. Now getting 6-7 ms. Had 5 ms back in 1.3.5 release. Removed scaling/curve for DAC and PWM DAC CV output. Instead made them FAST using timed interrupts. Now updates every 500 microseconds, allowing for audio rate modulation of CV on these outputs by humming into mouthpiece, just like with direct analog CV from sensor.

This commit is contained in:
Johan Berglund 2019-10-15 16:43:54 +02:00
parent fee9e04ad6
commit cd91e6eece
3 changed files with 52 additions and 17 deletions

View file

@ -89,6 +89,9 @@ uint16_t trill3_interval;
uint16_t fastBoot;
uint16_t dacMode;
volatile uint16_t dacModeCopy;
volatile unsigned short brZero;
byte rotatorOn = 0;
byte currentRotation = 0;
uint16_t rotations[4]; // semitones { -5, -10, -7, -14 };
@ -228,6 +231,12 @@ byte K5; // Trill key 1 (pitch change +2)
byte K6; // Trill key 2 (pitch change +1)
byte K7; // Trill key 3 (pitch change +4)
byte R1;
byte R2;
byte R3;
byte R4;
byte R5;
byte octaveR = 0;
byte lastOctaveR = 0;
@ -245,6 +254,7 @@ byte subOctaveDouble = 0;
Adafruit_MPR121 touchSensor = Adafruit_MPR121(); // This is the 12-input touch sensor
FilterOnePole breathFilter;
IntervalTimer cvTimer;
bool configManagementMode = false;
@ -256,6 +266,7 @@ void setup() {
analogReadResolution(12); // set resolution of ADCs to 12 bit
analogWriteResolution(12);
analogWriteFrequency(pwmDacPin,11718.75);
Wire.setClock(400000);
pinMode(dPin, INPUT_PULLUP);
pinMode(ePin, INPUT_PULLUP);
@ -348,6 +359,8 @@ void setup() {
statusLedOn(); // Switch on the onboard LED to indicate power on/ready
cvTimer.begin(cvUpdate,500); // Update breath CV output every 500 microseconds
}
//_______________________________________________________________________________________________ MAIN LOOP
@ -558,7 +571,7 @@ void loop() {
if ((pressureSensor > breathThrVal) || gateOpen) {
// Has enough time passed for us to collect our second
// sample?
if ((millis() - breath_on_time > velSmpDl) || (0 == velSmpDl)) {
if ((millis() - breath_on_time > velSmpDl) || (0 == velSmpDl) || velocity) {
// Yes, so calculate MIDI note and velocity, then send a note on event
// We should be at tonguing peak, so set velocity based on current pressureSensor value unless fixed velocity is set
breathLevel = constrain(max(pressureSensor, initial_breath_value), breathThrVal, breathMaxVal);
@ -722,7 +735,7 @@ void loop() {
}
// Is it time to send more CC data?
currentTime = millis();
if (currentTime - ccBreathSendTime > (CC_BREATH_INTERVAL*(slowMidi+1))){
if (currentTime - ccBreathSendTime > (CC_BREATH_INTERVAL+slowMidi*SLOW_MIDI_ADD)){
breath();
ccBreathSendTime = currentTime;
}
@ -737,8 +750,8 @@ void loop() {
readTeensySwitches();
ccSendTime2 = currentTime;
}
if (currentTime - ccSendTime3 > CC_INTERVAL3) {
doorKnobCheck();
if (currentTime - ccSendTime3 > CC_INTERVAL3) {
if (gateOpenEnable || gateOpen) doorKnobCheck();
if (((pinkySetting == LVL) || (pinkySetting == LVLP)) && pinkyKey){
// show LVL indication
} else updateSensorLEDs();
@ -772,11 +785,15 @@ void loop() {
cvPitch = targetPitch;
}
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
//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
analogWrite(dacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095)));
//analogWrite(dacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095)));
}
noInterrupts();
dacModeCopy = dacMode;
brZero = breathThrVal;
interrupts();
midiDiscardInput();
//do menu stuff
@ -785,6 +802,16 @@ void loop() {
//_______________________________________________________________________________________________ FUNCTIONS
void cvUpdate(){
int cvPressure = analogRead(breathSensorPin);
if(dacModeCopy == DAC_MODE_PITCH){
analogWrite(pwmDacPin,cvPressure);
} else { //DAC_MODE_BREATH
analogWrite(dacPin,map(constrain(cvPressure,brZero,4095),brZero,4095,0,4095));
}
}
// non linear mapping function (http://playground.arduino.cc/Main/MultiMap)
// note: the _in array should have increasing values
unsigned int multiMap(unsigned short val, const unsigned short * _in, const unsigned short * _out, uint8_t size) {
@ -1004,7 +1031,7 @@ void doorKnobCheck() {
touchValue[i] = touchSensor.filteredData(i);
}
if (gateOpenEnable){
if ((touchValue[K4Pin] < ctouchThrVal) && (touchValue[R1Pin] < ctouchThrVal) && (touchValue[R2Pin] < ctouchThrVal) && (touchValue[R3Pin] < ctouchThrVal)) { // doorknob grip on canister
if (K4 && R1 && R2 && R3) { // doorknob grip on canister
if (!gateOpen && (pbUp > ((pitchbMaxVal + pitchbThrVal) / 2))) {
gateOpen = 1;
statusLedFlash(100);
@ -1215,13 +1242,20 @@ void readSwitches() {
}
// Octave rollers
R1 = touchKeys[R1Pin];
R2 = touchKeys[R2Pin];
R3 = touchKeys[R3Pin];
R4 = touchKeys[R4Pin];
R5 = touchKeys[R5Pin];
octaveR = 0;
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
else if (touchKeys[R2Pin]) octaveR = 2; //R2
else if (touchKeys[R1Pin]) octaveR = 1; //R1
if (R5 && R3) octaveR = 6; //R6 = R5 && R3
else if (R5) octaveR = 5; //R5
else if (R4) octaveR = 4; //R4
else if (R3 && lastOctaveR) octaveR = 3; //R3
else if (R2) octaveR = 2; //R2
else if (R1) octaveR = 1; //R1
lastOctaveR = octaveR;

View file

@ -5,7 +5,7 @@
// Compile options, comment/uncomment to change
#define FIRMWARE_VERSION "1.4.1" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
#define FIRMWARE_VERSION "1.4.2" // 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
@ -14,8 +14,9 @@
// 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
#define SLOW_MIDI_ADD 7
#define CC_INTERVAL 13
#define CC_INTERVAL2 25
#define CC_INTERVAL2 19
#define CC_INTERVAL3 37

View file

@ -769,7 +769,7 @@ const MenuEntrySub velSmpDlMenu = {
[](SubMenuRef __unused, char *out, const char** label) {
if (velSmpDl) {
numToString(velSmpDl, out);
*label = "ms";
*label = "";
} else strncpy(out, "OFF", 4);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VEL_SMP_DL_ADDR,velSmpDl); }