|
@ -26,20 +26,25 @@ Tone freq[NUM_STEPPER]; |
|
|
|
|
|
|
|
|
unsigned long previousMillis[NUM_STEPPER] = {0}; // will store last time LED was updated
|
|
|
unsigned long previousMillis[NUM_STEPPER] = {0}; // will store last time LED was updated
|
|
|
const long interval = 1000; // interval at which to blink (milliseconds)
|
|
|
const long interval = 1000; // interval at which to blink (milliseconds)
|
|
|
volatile byte playing[NUM_STEPPER] = {0}; |
|
|
|
|
|
int enable_pin[NUM_STEPPER] = {X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, E0_ENABLE_PIN, E1_ENABLE_PIN}; |
|
|
int enable_pin[NUM_STEPPER] = {X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, E0_ENABLE_PIN, E1_ENABLE_PIN}; |
|
|
|
|
|
|
|
|
|
|
|
struct playing_t { |
|
|
|
|
|
byte noteNumber; |
|
|
|
|
|
byte channel; |
|
|
|
|
|
}; |
|
|
|
|
|
volatile playing_t playing[NUM_STEPPER] = {0,255}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int findSameNotes(byte noteNumber) { |
|
|
int findSameNotes(byte noteNumber) { |
|
|
int candidate = -1; |
|
|
int candidate = -1; |
|
|
bool alreadyPlayingHarmonic = false; |
|
|
bool alreadyPlayingHarmonic = false; |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
if (playing[i] == noteNumber) return -2; // already playing this note
|
|
|
if (playing[i].noteNumber == noteNumber) return -2; // already playing this note
|
|
|
if (noteNumber+12 == playing[i] || noteNumber == playing[i]+12) alreadyPlayingHarmonic = true; |
|
|
if (noteNumber+12 == playing[i].noteNumber || noteNumber == playing[i].noteNumber+12) alreadyPlayingHarmonic = true; |
|
|
for (int k=i+1; k<NUM_STEPPER; k++) { |
|
|
for (int k=i+1; k<NUM_STEPPER; k++) { |
|
|
if (playing[k] == playing[i]) { |
|
|
if (playing[k].noteNumber == playing[i].noteNumber) { |
|
|
return k; |
|
|
return k; |
|
|
} else if (playing[k]+12 == playing[i] || playing[k] == playing[i]+12) { |
|
|
} else if (playing[k].noteNumber+12 == playing[i].noteNumber || playing[k].noteNumber == playing[i].noteNumber+12) { |
|
|
candidate = k; |
|
|
candidate = k; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -67,10 +72,11 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) |
|
|
//digitalWrite(LED_PIN, HIGH);
|
|
|
//digitalWrite(LED_PIN, HIGH);
|
|
|
bool sent = false; |
|
|
bool sent = false; |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
if (playing[i] == 0) { |
|
|
if (playing[i].noteNumber == 0) { |
|
|
digitalWrite(enable_pin[i], LOW); |
|
|
digitalWrite(enable_pin[i], LOW); |
|
|
freq[i].play(f); |
|
|
freq[i].play(f); |
|
|
playing[i] = inNumber; |
|
|
playing[i].noteNumber = inNumber; |
|
|
|
|
|
playing[i].channel = inChannel; |
|
|
previousMillis[i] = millis(); |
|
|
previousMillis[i] = millis(); |
|
|
sent = true; |
|
|
sent = true; |
|
|
break; |
|
|
break; |
|
@ -83,7 +89,8 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) |
|
|
if (i >= 0) { |
|
|
if (i >= 0) { |
|
|
digitalWrite(enable_pin[i], LOW); |
|
|
digitalWrite(enable_pin[i], LOW); |
|
|
freq[i].play(f); |
|
|
freq[i].play(f); |
|
|
playing[i] = inNumber; |
|
|
playing[i].noteNumber = inNumber; |
|
|
|
|
|
playing[i].channel = inChannel; |
|
|
previousMillis[i] = millis(); |
|
|
previousMillis[i] = millis(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -101,14 +108,26 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) |
|
|
|
|
|
|
|
|
digitalWrite(LED_PIN, LOW); |
|
|
digitalWrite(LED_PIN, LOW); |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
if (playing[i] == inNumber) { |
|
|
if (playing[i].noteNumber == inNumber) { |
|
|
freq[i].stop(); |
|
|
freq[i].stop(); |
|
|
playing[i] = 0; |
|
|
playing[i].noteNumber = 0; |
|
|
|
|
|
playing[i].channel = 255; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
void handlePitchBend(byte inChannel, int inValue) { |
|
|
|
|
|
int bend = inValue >> 7; |
|
|
|
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
|
|
|
if (inChannel == playing[i].channel) { |
|
|
|
|
|
long f = sNotePitches[playing[i].noteNumber]; |
|
|
|
|
|
long f_b = f * pow(2, (double)inValue/(4096.0*12)); |
|
|
|
|
|
freq[i].play(f_b); |
|
|
|
|
|
previousMillis[i] = millis(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void setup() |
|
|
void setup() |
|
|
{ |
|
|
{ |
|
@ -149,6 +168,7 @@ void setup() |
|
|
|
|
|
|
|
|
MIDI.setHandleNoteOn(handleNoteOn); |
|
|
MIDI.setHandleNoteOn(handleNoteOn); |
|
|
MIDI.setHandleNoteOff(handleNoteOff); |
|
|
MIDI.setHandleNoteOff(handleNoteOff); |
|
|
|
|
|
MIDI.setHandlePitchBend(handlePitchBend); |
|
|
MIDI.begin(MIDI_CHANNEL_OMNI); |
|
|
MIDI.begin(MIDI_CHANNEL_OMNI); |
|
|
|
|
|
|
|
|
freq[0].begin(X_STEP_PIN); |
|
|
freq[0].begin(X_STEP_PIN); |
|
@ -166,7 +186,8 @@ void loop() |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
for (int i=0; i<NUM_STEPPER; i++) { |
|
|
if (currentMillis - previousMillis[i] >= interval || previousMillis[i] == 0) { |
|
|
if (currentMillis - previousMillis[i] >= interval || previousMillis[i] == 0) { |
|
|
digitalWrite(enable_pin[i], HIGH); |
|
|
digitalWrite(enable_pin[i], HIGH); |
|
|
playing[i] = 0; |
|
|
playing[i].noteNumber = 0; |
|
|
|
|
|
playing[i].channel = 255; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|