Skip to content

Commit f0010cb

Browse files
committed
Support for CV box/CV board (compile option). Match idle CV from PWM breath CV on A6 to direct output idle voltage from breath sensor (so any of them can be used for CV box without need for recalibration of box). Added reading and ignoring incoming USB MIDI messages to prevent buffers from getting filled up blocking outgoing messages.
1 parent f06eb0b commit f0010cb

File tree

7 files changed

+11177
-5469
lines changed

7 files changed

+11177
-5469
lines changed
Binary file not shown.
Binary file not shown.

NuEVI-v134.ino.hex

Lines changed: 0 additions & 5459 deletions
This file was deleted.

NuEVI-v135-CVBD.ino.hex

Lines changed: 5568 additions & 0 deletions
Large diffs are not rendered by default.

NuEVI-v135.ino.hex

Lines changed: 5551 additions & 0 deletions
Large diffs are not rendered by default.

NuEVI/NuEVI.ino

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath
2525

2626
// Compile options, comment/uncomment to change
2727

28-
#define FIRMWARE_VERSION "1.3.4" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
28+
#define FIRMWARE_VERSION "1.3.5" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
2929

3030

3131
//#define CASSIDY
@@ -128,7 +128,7 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath
128128
#define OCTAVE_FACTORY 3 // 3 is 0 octave change
129129
#define CTOUCH_THR_FACTORY 125 // MPR121 touch threshold
130130
#define BREATHCURVE_FACTORY 4 // 0 to 12 (-4 to +4, S1 to S4)
131-
#define VEL_SMP_DL_FACTORY 20 // 0 to 30 ms in steps of 5
131+
#define VEL_SMP_DL_FACTORY 15 // 0 to 30
132132
#define VEL_BIAS_FACTORY 0 // 0 to 9
133133
#define PINKY_KEY_FACTORY 12 // 0 - 11 (QuickTranspose -12 to -1), 12 (pb/2), 13 - 22 (QuickTranspose +1 to +12)
134134
#define DIPSW_BITS_FACTORY 0 // virtual dip switch settings for special modes (work in progress)
@@ -190,8 +190,8 @@ byte gateOpen = 0; // setting for gate always open, note on sent for every time
190190

191191
int breathLoLimit = 0;
192192
int breathHiLimit = 4095;
193-
int portamLoLimit = 1000;
194-
int portamHiLimit = 5000;
193+
int portamLoLimit = 700;
194+
int portamHiLimit = 4700;
195195
int pitchbLoLimit = 500;
196196
int pitchbHiLimit = 4000;
197197
int extracLoLimit = 500;
@@ -277,6 +277,10 @@ int biteSensor=0; // capacitance data from bite sensor, for midi cc and thres
277277
byte portIsOn=0; // keep track and make sure we send CC with 0 value when off threshold
278278
int oldport=0;
279279
int lastBite=0;
280+
byte biteJumper=0;
281+
282+
int cvPitch;
283+
int targetPitch;
280284

281285
int exSensor=0;
282286
byte extracIsOn=0;
@@ -363,6 +367,7 @@ void setup() {
363367

364368
analogReadResolution(12); // set resolution of ADCs to 12 bit
365369
analogWriteResolution(12);
370+
analogWriteFrequency(pwmDacPin,11718.75);
366371

367372
pinMode(dPin, INPUT_PULLUP);
368373
pinMode(ePin, INPUT_PULLUP);
@@ -503,6 +508,11 @@ void setup() {
503508

504509
initDisplay(); //Start up display and show logo
505510

511+
biteJumper = !digitalRead(biteJumperPin);
512+
if (biteJumper){
513+
pinMode(bitePin, INPUT);
514+
}
515+
506516
//auto-calibrate the vibrato threshold while showing splash screen
507517
vibZero = breathCalZero = 0;
508518
const int sampleCount = 4;
@@ -570,42 +580,55 @@ void loop() {
570580
mainState = RISE_WAIT; // Go to next state
571581
}
572582
if (legacy || legacyBrAct) {
583+
#if defined(CASSIDY)
584+
if (((pbUp > ((pitchbMaxVal + pitchbThrVal) / 2)) && (pbDn > ((pitchbMaxVal + pitchbThrVal) / 2)) && legacy) ||
585+
((analogRead(0) < breathCalZero - 900) && legacyBrAct)) { // both pb pads touched or br suck
586+
#else
573587
if (((pbUp > ((pitchbMaxVal + pitchbThrVal) / 2)) && (pbDn > ((pitchbMaxVal + pitchbThrVal) / 2)) && legacy) ||
574588
((analogRead(0) < breathCalZero - 800) && legacyBrAct && (pbUp > (pitchbMaxVal + pitchbThrVal) / 2) && (pbDn < (pitchbMaxVal + pitchbThrVal) / 2))) { // both pb pads touched or br suck
589+
#endif
575590
readSwitches();
576591
fingeredNoteUntransposed = patchLimit(fingeredNoteUntransposed + 1);
577592
if (exSensor >= ((extracThrVal + extracMaxVal) / 2)) { // instant midi setting
578593
if ((fingeredNoteUntransposed >= 73) && (fingeredNoteUntransposed <= 88)) {
579594
MIDIchannel = fingeredNoteUntransposed - 72; // Mid C and up
595+
#if !defined(CASSIDY)
580596
digitalWrite(statusLedPin, LOW);
581597
delay(150);
582598
digitalWrite(statusLedPin, HIGH);
599+
#endif
583600
}
584601
} else {
585602
if (!pinkyKey) { // note number to patch number
586603
if (patch != fingeredNoteUntransposed) {
587604
patch = fingeredNoteUntransposed;
588605
doPatchUpdate = 1;
606+
#if !defined(CASSIDY)
589607
digitalWrite(statusLedPin, LOW);
590608
delay(150);
591609
digitalWrite(statusLedPin, HIGH);
610+
#endif
592611
}
593612
} else { // hi and lo patch numbers
594613
if (fingeredNoteUntransposed > 75) {
595614
if (patch != patchLimit(fingeredNoteUntransposed + 24)) {
596615
patch = patchLimit(fingeredNoteUntransposed + 24); // add 24 to get high numbers 108 to 127
597616
doPatchUpdate = 1;
617+
#if !defined(CASSIDY)
598618
digitalWrite(statusLedPin, LOW);
599619
delay(150);
600620
digitalWrite(statusLedPin, HIGH);
621+
#endif
601622
}
602623
} else {
603624
if (patch != patchLimit(fingeredNoteUntransposed - 36)) {
604625
patch = patchLimit(fingeredNoteUntransposed - 36); // subtract 36 to get low numbers 0 to 36
605626
doPatchUpdate = 1;
627+
#if !defined(CASSIDY)
606628
digitalWrite(statusLedPin, LOW);
607629
delay(150);
608630
digitalWrite(statusLedPin, HIGH);
631+
#endif
609632
}
610633
}
611634
}
@@ -929,12 +952,29 @@ void loop() {
929952
}
930953
lastFingering = fingeredNote;
931954
#if defined(CVSCALEBOARD) // pitch CV from DAC and breath CV from PWM on pin 6, for filtering and scaling on separate board
932-
analogWrite(dacPin,constrain((fingeredNote-24)*42+map(pitchBend,0,16383,-84,84),0,4095));
933-
analogWrite(pwmDacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095)));
955+
targetPitch = (fingeredNote-24)*42;
956+
if (portIsOn){
957+
if (targetPitch > cvPitch){
958+
cvPitch += 1+(127-oldport)/4;
959+
if (cvPitch > targetPitch) cvPitch = targetPitch;
960+
} else if (targetPitch < cvPitch){
961+
cvPitch -= 1+(127-oldport)/4;
962+
if (cvPitch < targetPitch) cvPitch = targetPitch;
963+
} else {
964+
cvPitch = targetPitch;
965+
}
966+
} else {
967+
cvPitch = targetPitch;
968+
}
969+
analogWrite(dacPin,constrain(cvPitch+map(pitchBend,0,16383,-84,84),0,4095));
970+
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
934971
#else // else breath CV on DAC pin, directly to unused pin of MIDI DIN jack
935972
analogWrite(dacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095)));
936973
#endif
937-
974+
975+
while (usbMIDI.read()) {
976+
// read & ignore incoming messages
977+
}
938978
//do menu stuff
939979
menu();
940980
}
@@ -1306,10 +1346,10 @@ void extraController() {
13061346

13071347
void portamento_() {
13081348
// Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece
1309-
if (digitalRead(biteJumperPin)){ //PBITE (if pulled low with jumper, use pressure sensor on A7)
1310-
biteSensor=touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
1349+
if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor on A7)
1350+
biteSensor=analogRead(A7); // alternative kind bite sensor (air pressure tube and sensor) PBITE
13111351
} else {
1312-
biteSensor=analogRead(A7); // alternative kind bite sensor (air pressure tube and sensor) PBITE
1352+
biteSensor=touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
13131353
}
13141354
if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento
13151355
if (!portIsOn) {

NuEVI/menu.ino

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ void showVersion() {
146146
display.setCursor(0,0);
147147
display.print("BC");
148148
#endif
149+
#if defined(CVSCALEBOARD)
150+
display.setCursor(15,0);
151+
display.print("CV");
152+
#endif
149153
display.setCursor(85,52);
150154
display.print("v.");
151155
display.println(FIRMWARE_VERSION);
@@ -3634,6 +3638,10 @@ void drawSensorPixels(){
36343638
display.display();
36353639
}
36363640
lastBite=biteSensor;
3641+
/*if (biteJumper){
3642+
pos = map(constrain(analogRead(bitePin),900,1400), 900, 1400, 28, 118);
3643+
display.drawPixel(pos, 40, WHITE);
3644+
}*/
36373645
}
36383646
if ((state == PITCHB_ADJ_IDL) || (state == PITCHB_ADJ_THR) || (state == PITCHB_ADJ_MAX)){
36393647
pos = map(constrain(pbUp, pitchbLoLimit, pitchbHiLimit), pitchbLoLimit, pitchbHiLimit, 28, 118);

0 commit comments

Comments
 (0)