Added ICM, knob CCs

This commit is contained in:
Brian Hrebec 2023-08-30 23:54:06 -05:00
parent e757ebc885
commit 00cdfc08e0
7 changed files with 125 additions and 46 deletions

View file

@ -104,6 +104,9 @@ struct instrument_state_t {
byte leverVal = 0; // keep track and make sure we send CC with 0 value when off threshold
int pitchBend = 8192;
int pbSend = 8192; // Pitch bend actually sent, modified by vibrato, etc
byte knobVals[4];
byte rollCCVal = 0;
byte tiltCCVal = 0;
// Key states
byte quarterToneTrigger;

View file

@ -44,6 +44,7 @@ void initHardware() {
breathFilter.setFilter(LOWPASS, FILTER_FREQ, 0.0); // create a one pole (RC) lowpass filter
breathAltFilter.setFilter(LOWPASS, FILTER_FREQ, 0.0); // create a one pole (RC) lowpass filter
spikeFilter.setFilter(HIGHPASS, 200, 0.0); // create a one pole (RC) lowpass filter
icmSensor.begin_I2C(ICM20948_I2CADDR_DEFAULT, &MainI2CBus);
ledStrip.begin();
@ -168,4 +169,17 @@ int readPressure() {
int readAltPressure() {
return breathAltFilter.input(pressureSensorAlt.readPressure()) * PRESSURE_SENS_MULTIPLIER;
}
icm_result_t readICM() {
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t mag;
sensors_event_t temp;
icmSensor.getEvent(&accel, &gyro, &temp, &mag);
return {
mag.magnetic.y,
mag.magnetic.x,
};
}

View file

@ -16,6 +16,11 @@ extern WS2812Serial ledStrip;
extern Adafruit_Sensor *accelSensor;
extern Adafruit_ICM20948 icmSensor;
struct icm_result_t {
float tilt;
float roll;
};
void initHardware();
void updateFilters(preset_t &preset);
bool checkButtonState(uint8_t mask); // return true if the given buttons are pressed
@ -28,6 +33,7 @@ uint16_t utilTouched();
int readPressure();
int readAltPressure();
int readSpikePressure();
icm_result_t readICM();
// xEVI hardware setup

View file

@ -778,9 +778,7 @@ private:
class StatusMenu : public MenuScreen {
public:
StatusMenu(MenuScreen& mainMenu) : _mainMenu(mainMenu) {
Serial.println("init statusmenu");
}
StatusMenu(MenuScreen& mainMenu) : _mainMenu(mainMenu) { }
void update(state_t& state, InputState& input, bool redraw) {
InputState nullinput;
if (input.changed && input.btnMenu) {
@ -1005,13 +1003,14 @@ ChoiceMenu<4, PortamentoMode> portMenu("GLIDE MOD", &preset_t::portamentoMode, {
});
PresetValueMenu<0, uint8_t> portLimitMenu("GLIDE LMT", &preset_t::portamentoLimit, 1, 127, true);
PresetValueMenu<0, uint8_t> pitchBendMenu("PITCHBEND", &preset_t::PBdepth, 0, 12, true);
ChoiceMenu<4, ExtraControl> extraCtlMenu("EXT CTL", &preset_t::extraControl, { {OFF, VIBRATO, GLIDE, CC} }, {
"OFF",
"VIBRATO",
"GLIDE",
"CC"
});
ChoiceMenu<4, ExtraControl> extraCtlMenu("EXT CTL", &preset_t::extraControl, { {OFF, VIBRATO, GLIDE, CC} }, { "OFF", "VIBRATO", "GLIDE", "CC" });
PresetValueMenu<128, uint8_t> extraCCMenu("EXT CC", &preset_t::extraCC, 0, 127, true, CC_NAMES);
ChoiceMenu<4, ExtraControl> tiltModeMenu("TILT MODE", &preset_t::icmTiltMode, { {OFF, VIBRATO, GLIDE, CC} }, { "OFF", "VIBRATO", "GLIDE", "CC" });
PresetValueMenu<128, uint8_t> tiltCCMenu("TILT CC", &preset_t::icmTiltCC, 0, 127, true, CC_NAMES);
ChoiceMenu<4, ExtraControl> rollModeMenu("ROLL MODE", &preset_t::icmRollMode, { {OFF, VIBRATO, GLIDE, CC} }, { "OFF", "VIBRATO", "GLIDE", "CC" });
PresetValueMenu<128, uint8_t> rollCCMenu("ROLL CC", &preset_t::icmRollCC, 0, 127, true, CC_NAMES);
ChoiceMenu<4, ExtraControl> accelModeMenu("ACCEL MODE", &preset_t::icmAccelMode, { {OFF, VIBRATO, GLIDE, CC} }, { "OFF", "VIBRATO", "GLIDE", "CC" });
PresetValueMenu<128, uint8_t> accelCCMenu("ACCEL CC", &preset_t::icmAccelCC, 0, 127, true, CC_NAMES);
PresetValueMenu<1, uint8_t> deglitchMenu("DEGLITCH", &preset_t::deglitch, 0, 70, true, { "OFF" }, "ms");
PresetValueMenu<29, uint8_t> pinkyMenu("PINKY KEY", &preset_t::pinkySetting, 0, 29, true, {
"-12", "-11", "-10", "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
@ -1065,7 +1064,7 @@ std::array<MenuScreen *const, 11> breathMenuEntries = {
};
SubMenu<11> breathMenu("BR SETUP", breathMenuEntries);
const std::array<MenuScreen *const, 13> controlMenuEntries = {
const std::array<MenuScreen *const, 19> controlMenuEntries = {
&fingeringMenu,
&rollerMenu,
&biteCtlMenu,
@ -1078,9 +1077,15 @@ const std::array<MenuScreen *const, 13> controlMenuEntries = {
&portLimitMenu,
&deglitchMenu,
&pinkyMenu,
&pitchBendMenu
&pitchBendMenu,
&tiltModeMenu,
&tiltCCMenu,
&rollModeMenu,
&rollCCMenu,
&accelModeMenu,
&accelCCMenu,
};
SubMenu<13> controlMenu("CTL SETUP", controlMenuEntries);
SubMenu<19> controlMenu("CTL SETUP", controlMenuEntries);
const std::array<MenuScreen *const, 5> vibratoMenuEntries = {
&vibDepthMenu,
@ -1225,6 +1230,10 @@ void initDisplay() {
currentMenu = &statusMenu;
}
bool inMenu() {
return currentMenu != &statusMenu;
}
void handleMenu(state_t& state, bool draw) {
unsigned long timeNow = millis();
bool wakeUp = false;

View file

@ -38,6 +38,7 @@ class MenuScreen {
};
void initDisplay();
bool inMenu();
void displayOff(state_t &state);
void showVersion();
void displayError(const char *error);

View file

@ -83,12 +83,12 @@ struct preset_t {
uint8_t knob3CC = 73;
uint8_t knob4CC = 74;
uint8_t icmAccelMode;
uint8_t icmAccelCC;
uint8_t icmTiltMode;
uint8_t icmTiltCC;
uint8_t icmRotationMode;
uint8_t icmRotationCC;
ExtraControl icmAccelMode = ExtraControl::CC;
uint8_t icmAccelCC = 75;
ExtraControl icmTiltMode = ExtraControl::CC;
uint8_t icmTiltCC = 76;
ExtraControl icmRollMode = ExtraControl::CC;
uint8_t icmRollCC = 77;
uint8_t breathFilterFreq = 20;
uint8_t spikeFilterFreq = 20;

View file

@ -231,17 +231,17 @@ int breath() {
// send midi cc
midiSendControlChange(state.currentPreset->breathCC, breathCCval);
}
if (state.currentPreset->breathMode == BreathMode::BREATH_AT
|| state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT
|| state.currentPreset->breathMode == BreathMode::BREATH_ACC_AT) {
if (state.currentPreset->breathMode == BreathMode::BREATH_AT
|| state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT
|| state.currentPreset->breathMode == BreathMode::BREATH_ACC_AT) {
// send aftertouch
midiSendAfterTouch(breathCCval);
}
oldbreath = breathCCval;
}
if (breathCCvalHires != oldbreathhires
&& (state.currentPreset->breathMode == BreathMode::BREATH_LSB || state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT)) {
if (breathCCvalHires != oldbreathhires
&& (state.currentPreset->breathMode == BreathMode::BREATH_LSB || state.currentPreset->breathMode == BreathMode::BREATH_LSB_AT)) {
midiSendControlChange(state.currentPreset->breathCC + 32, breathCCvalFine);
}
@ -299,13 +299,13 @@ void pitch_bend() {
if (ExtraControl::VIBRATO == state.currentPreset->leverControl) { // lever vibrato
vibRead = instrument.leverSignal;
if (vibRead > instrument.vibThr) {
instrument.vibSignal = (instrument.vibSignal +
mapConstrain(vibRead, (instrument.vibZero - vibMax), instrument.vibThr, calculatedDepth, 0)
) / 2;
instrument.vibSignal = (instrument.vibSignal +
mapConstrain(vibRead, (instrument.vibZero - vibMax), instrument.vibThr, calculatedDepth, 0)
) / 2;
} else if (vibRead < instrument.vibThrLo) {
instrument.vibSignal = (instrument.vibSignal +
mapConstrain(vibRead, (instrument.vibZero + vibMax), instrument.vibThr, calculatedDepth, 0)
) / 2;
instrument.vibSignal = (instrument.vibSignal +
mapConstrain(vibRead, (instrument.vibZero + vibMax), instrument.vibThr, calculatedDepth, 0)
) / 2;
} else {
instrument.vibSignal = instrument.vibSignal / 2;
}
@ -425,6 +425,52 @@ void sendCC() {
}
instrument.extraVal = extraVal;
}
if (!inMenu()) {
for (int i = 0; i < 4; i++) {
byte val = constrain((int)state.instrument->knobVals[i] + readKnob(i), 0, 127);
if (state.instrument->knobVals[i] != val) {
switch (i) {
case 0:
midiSendControlChange(state.currentPreset->knob1CC, val);
break;
case 1:
midiSendControlChange(state.currentPreset->knob2CC, val);
break;
case 2:
midiSendControlChange(state.currentPreset->knob3CC, val);
break;
case 3:
midiSendControlChange(state.currentPreset->knob4CC, val);
break;
}
}
state.instrument->knobVals[i] = val;
}
}
icm_result_t icmSignal = readICM();
Serial.print(">roll: ");
Serial.println(icmSignal.roll);
Serial.print(">tilt: ");
Serial.println(icmSignal.tilt);
if (ExtraControl::CC == state.currentPreset->icmRollMode) {
byte roll = mapConstrain(abs(icmSignal.roll), 0, 40, 127, 0);
if (roll != state.instrument->rollCCVal) {
midiSendControlChange(state.currentPreset->icmRollCC, roll);
state.instrument->rollCCVal = roll;
}
}
if (ExtraControl::CC == state.currentPreset->icmTiltMode) {
byte tilt = mapConstrain(abs(icmSignal.tilt), -20, 40, 0, 127);
if (tilt != state.instrument->tiltCCVal) {
midiSendControlChange(state.currentPreset->icmTiltCC, tilt);
state.instrument->tiltCCVal = tilt;
}
}
}
// Re-zero floating calibration values
@ -444,7 +490,7 @@ void autoCal() {
instrument.vibZero = instrument.vibZeroBite = 0;
long int bZero = 0;
long int bAltZero = 0;
for(int i = 1 ; i <= CALIBRATE_SAMPLE_COUNT; ++i) {
for (int i = 1; i <= CALIBRATE_SAMPLE_COUNT; ++i) {
bZero += readPressure();
bAltZero += readAltPressure();
instrument.vibZero += readTouchUtil(leverPin);
@ -464,9 +510,9 @@ void fullAutoCal() {
int calReadNext;
calibration.breathAltThrValOffset = 5;
calibration.breathAltMaxValOffset = 1500 ;
calibration.breathAltMaxValOffset = 1500;
calibration.breathThrValOffset = 5;
calibration.breathMaxValOffset = 1500 ;
calibration.breathMaxValOffset = 1500;
autoCal();
// Lever
@ -841,7 +887,7 @@ void setup() {
Serial.begin(9600); // debug
Serial.println("Debug Startup");
if (CrashReport) {
while (!Serial) ; // wait for serial monitor open
while (!Serial); // wait for serial monitor open
Serial.print(CrashReport);
}
@ -912,7 +958,7 @@ void loop() {
int16_t spikeSignal = constrain(readSpikePressure(), -SPIKE_HI_LIMIT, SPIKE_HI_LIMIT);
if (state.currentPreset->breathMode == BREATH_ACC || state.currentPreset-> breathMode == BREATH_ACC_AT) {
if (state.currentPreset->breathMode == BREATH_ACC || state.currentPreset->breathMode == BREATH_ACC_AT) {
int delta = breathSignal - instrument.breathZero;
if (abs(delta) > state.calibration->breathAltThrValOffset) {
instrument.breathSignal = constrain(instrument.breathSignal + delta / 10, instrument.breathZero, instrument.breathMaxVal);
@ -922,18 +968,18 @@ void loop() {
}
instrument.breathAltSignal = constrain(readAltPressure(), BREATH_LO_LIMIT, BREATH_HI_LIMIT); // Get the filtered pressure sensor reading from analog pin A0, input from sensor MP3V5004GP
/*
Serial.print(">breathThr:");
Serial.println(instrument.breathThrVal);
Serial.print(">note:");
Serial.println(state.mainState);
Serial.print(">spike:");
Serial.println(spikeSignal);
Serial.print(">breath:");
Serial.println(breathSignal);
Serial.print(">combo:");
Serial.println(instrument.breathSignal);
*/
/*
Serial.print(">breathThr:");
Serial.println(instrument.breathThrVal);
Serial.print(">note:");
Serial.println(state.mainState);
Serial.print(">spike:");
Serial.println(spikeSignal);
Serial.print(">breath:");
Serial.println(breathSignal);
Serial.print(">combo:");
Serial.println(instrument.breathSignal);
*/
runStateMachine();
sendCCs();