#include "Controllers.h" // MIDI // First parameter is the event type (0x09 = note on, 0x08 = note off). // Second parameter is note-on/note-off, combined with the channel. // Channel can be anything between 0-15. Typically reported to the user as 1-16. // Third parameter is the note number (48 = middle C). // Fourth parameter is the velocity (64 = normal, 127 = fastest). // First parameter is the event type (0x0B = control change). // Second parameter is the event type, combined with the channel. // Third parameter is the control number number (0-119). // Fourth parameter is the control value (0-127). void noteOn(byte channel, byte pitch, byte velocity) { #ifndef DUMMY midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity}; MidiUSB.sendMIDI(noteOn); #endif #ifdef DEBUG Serial.print("Note on:"); Serial.print(channel); Serial.print(","); Serial.print(pitch); Serial.print(","); Serial.println(velocity); #endif } void noteOff(byte channel, byte pitch, byte velocity) { #ifndef DUMMY midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity}; MidiUSB.sendMIDI(noteOff); #endif #ifdef DEBUG Serial.print("Note off:"); Serial.print(channel); Serial.print(","); Serial.print(pitch); Serial.print(","); Serial.println(velocity); #endif } void controlChange(byte channel, byte control, byte value) { #ifndef DUMMY midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value}; MidiUSB.sendMIDI(event); #endif #ifdef DEBUG Serial.print("Control change:"); Serial.print(channel); Serial.print(","); Serial.print(control); Serial.print(","); Serial.println(value); #endif } // Constructor and methods for analog controls and buttons (encoders use a different library) AnalogControl::AnalogControl(int pin, byte effect, int middle) { this->pin = pin; this->effect = effect; this->middle = middle; } void AnalogControl::init() { pinMode(pin,INPUT); } void AnalogControl::checkStatus() { value = analogRead(pin); if (value < 0+STICKYNESS){ value = 0; } else if (value > 1023-STICKYNESS) { value = 1023; } else if (value > middle-STICKYNESS && value < middle+STICKYNESS) { value = middle; } if ( abs(value - prev_value) > DEAD_ZONE ){ controlChange(1,effect, map(value,0,1023,0,127) ); prev_value = value; #ifndef DUMMY MidiUSB.flush(); #endif } } DigitalButton::DigitalButton(int pin, byte effect, byte effect_toggle, byte effect_long, byte effect_long_toggle) { this->effect = effect; this->effect_toggle = effect_toggle; this->effect_long = effect_long; this->effect_long_toggle = effect_long_toggle; this->pin = pin; } void DigitalButton::init() { pinMode(pin,INPUT_PULLUP); pressed = false; toggled = false; long_pressed = false; long_toggled = false; } void DigitalButton::checkStatus() { bool status = digitalRead(pin); if (status == LOW && pressed == false) { pressed = true; long_pressed = false; debounce = millis(); } if (pressed && (millis() - debounce <= 10) && status == HIGH) { pressed = false; return; } if (pressed && (millis() - debounce > 10) && status == HIGH) { if (long_pressed == true) { long_pressed = false; } else if (effect_toggle == 0) { controlChange(1,effect,1); } else if (toggled) { controlChange(1,effect,1); toggled = false; } else { controlChange(1,effect_toggle,1); toggled = true; } #ifndef DUMMY MidiUSB.flush(); #endif pressed = false; } if (pressed && (millis() - debounce > LONG_INTERVAL) && (status == LOW) && (long_pressed == false)) { long_pressed = true; if (effect_long_toggle == 0) { controlChange(1,effect_long,1); } else if (long_toggled) { controlChange(1,effect_long,1); long_toggled = false; } else { controlChange(1,effect_long_toggle,1); long_toggled = true; } #ifndef DUMMY MidiUSB.flush(); #endif } } MCP23017_Expander::MCP23017_Expander(int address, int effects[16], int effects_toggle[16], int effects_long[16], int effects_long_toggle[16]) { this->address = address; for (int i = 0; i < 16; i++) { this->effects[i] = effects[i]; this->effects_toggle[i] = effects_toggle[i]; this->effects_long[i] = effects_long[i]; this->effects_long_toggle[i] = effects_long_toggle[i]; } } void MCP23017_Expander::init() { Adafruit_MCP23X17 mcp; if (!mcp.begin_I2C(address)) { #ifdef DEBUG Serial.print("MCP23017 not found at address "); Serial.println(address,HEX); #endif while(true); } for (int i = 0; i < 16; i++) { mcp.pinMode(i,INPUT_PULLUP); pressed[i] = false; toggled[i] = false; long_pressed[i] = false; long_toggled[i] = false; } this->mcp = mcp; } void MCP23017_Expander::checkStatus() { for (int i = 0; i < 16; i++){ if (effects[i] == 0 && effects_toggle[i] == 0 && effects_long[i] == 0 && effects_long_toggle[i] == 0) { return; } bool status = mcp.digitalRead(i); if (status == LOW && pressed[i] == false){ Serial.println("button pressed"); pressed[i] = true; long_pressed[i] = false; debounce[i] = millis(); } if (pressed[i] && (millis() - debounce[i] <= 10) && status == HIGH) { pressed[i] = false; return; } if (pressed[i] && (millis() - debounce[i] > 10) && status == HIGH) { if (long_pressed[i] == true) { long_pressed[i] = false; } else if (effects_toggle[i] == 0) { controlChange(1,effects[i],1); } else if (toggled[i]) { controlChange(1,effects[i],1); toggled[i] = false; } else { controlChange(1,effects_toggle[i],1); toggled[i] = true; } #ifndef DUMMY MidiUSB.flush(); #endif pressed[i] = false; } if (pressed[i] && (millis() - debounce[i] > LONG_INTERVAL) && (status == LOW) && (long_pressed[i] == false)) { long_pressed[i] = true; if (effects_long_toggle == 0) { controlChange(1,effects_long[i],1); } else if (long_toggled[i]) { controlChange(1,effects_long[i],1); long_toggled[i] = false; } else { controlChange(1,effects_long_toggle[i],1); long_toggled[i] = true; } #ifndef DUMMY MidiUSB.flush(); #endif } } } Mux::Mux(int pinSIG, int effects[16], int mid_deadzone[16]) { this->pinSIG = pinSIG; for (int i = 0; i < 16; i++) { this->effects[i] = effects[i]; this->mid_deadzone[i] = effects[i]; } } void Mux::init() { pinMode(pinSIG,INPUT); pinMode(pinS0,OUTPUT); pinMode(pinS1,OUTPUT); pinMode(pinS2,OUTPUT); pinMode(pinS3,OUTPUT); } void Mux::checkStatus(byte selector){ if (effects[selector] == 0) { return; } digitalWrite(pinS0, bitRead(selector,0)); digitalWrite(pinS1, bitRead(selector,1)); digitalWrite(pinS2, bitRead(selector,2)); digitalWrite(pinS3, bitRead(selector,3)); int value = analogRead(pinSIG); if (value < STICKYNESS) { value = 0; } else if (value > 1023-STICKYNESS) { value = 1023; } else if (value > mid_deadzone[selector]-STICKYNESS && value < mid_deadzone[selector]+STICKYNESS) { value = mid_deadzone[selector]; } if (abs(value - prev_value[selector]) > DEAD_ZONE ) { byte midi_value = map(value,0,1023,0,127); controlChange(1,effects[selector],midi_value); #ifdef DEBUG Serial.print("Mux effect:"); Serial.print(effects[selector]); Serial.print(", address:"); Serial.print(selector); Serial.print(":"); Serial.print(bitRead(selector,0)); Serial.print(bitRead(selector,1)); Serial.print(bitRead(selector,2)); Serial.print(bitRead(selector,3)); Serial.print(", prev.value:"); Serial.print(prev_value[selector]); Serial.print(", value:"); Serial.println(value); #endif prev_value[selector] = value; #ifndef DUMMY MidiUSB.flush(); #endif } } //Callback function for the encoders void eb_Encoder(EncoderButton& eb) { int inc = eb.increment(); if (inc > 0) { controlChange(1,eb.userId()+1,1); } else { controlChange(1,eb.userId(),1); } #ifndef DUMMY MidiUSB.flush(); #endif }