music with stepper motors
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 lines
4.4 KiB

/*
* Blink
* Turns on an LED on for one second,
* then off for one second, repeatedly.
*/
#include <Arduino.h>
#include "pins/pins_TRIGORILLA_14.h"
#include <Tone.h>
#include <MIDI.h>
//#include "midi/noteList.h"
//#include "midi/pitches.h"
#include "stepper.h"
struct MySettings : public midi::DefaultSettings
{
static const long BaudRate = 115200;
};
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, MIDI, MySettings);
const int NUM_STEPPER = 5;
TimerStepper stepper[NUM_STEPPER];
unsigned long previousMillis[NUM_STEPPER] = {0}; // will store last time LED was updated
const long interval = 1000; // interval at which to blink (milliseconds)
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 candidate = -1;
bool alreadyPlayingHarmonic = false;
for (int i=0; i<NUM_STEPPER; i++) {
if (playing[i].noteNumber == noteNumber) return -2; // already playing this note
if (noteNumber+12 == playing[i].noteNumber || noteNumber == playing[i].noteNumber+12) alreadyPlayingHarmonic = true;
for (int k=i+1; k<NUM_STEPPER; k++) {
if (playing[k].noteNumber == playing[i].noteNumber) {
return k;
} else if (playing[k].noteNumber+12 == playing[i].noteNumber || playing[k].noteNumber == playing[i].noteNumber+12) {
candidate = k;
}
}
}
if (candidate >= 0 && !alreadyPlayingHarmonic) return candidate;
return -1;
}
void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
{
// Serial.print("NoteOn ");
// Serial.print(inNumber);
// Serial.print("\tvelocity: ");
// Serial.println(inVelocity);
// Serial.flush();
//noTone();
//if (inChannel == 0 || inChannel >= 32) return;
//if (inChannel == 8) return;
bool sent = false;
for (int i=0; i<NUM_STEPPER; i++) {
if (playing[i].noteNumber == 0) {
stepper[i].playNote(inNumber);
playing[i].noteNumber = inNumber;
playing[i].channel = inChannel;
previousMillis[i] = millis();
sent = true;
break;
}
}
if (!sent) {
digitalWrite(LED_PIN, HIGH);
int i = findSameNotes(inNumber);
if (i >= 0) {
stepper[i].playNote(inNumber);
playing[i].noteNumber = inNumber;
playing[i].channel = inChannel;
previousMillis[i] = millis();
}
}
}
void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
{
// Serial.print("NoteOff ");
// Serial.print(inNumber);
// Serial.print("\tvelocity: ");
// Serial.println(inVelocity);
//if (inChannel == 0 || inChannel >= 32) return;
//if (inChannel == 8) return;
digitalWrite(LED_PIN, LOW);
for (int i=0; i<NUM_STEPPER; i++) {
if (playing[i].noteNumber == inNumber) {
stepper[i].stopTone();
playing[i].noteNumber = 0;
playing[i].channel = 255;
break;
}
}
}
void handlePitchBend(byte inChannel, int inValue) {
int bend = inValue >> 7;
for (int i=0; i<NUM_STEPPER; i++) {
if (inChannel == playing[i].channel) {
stepper[i].bend(inValue);
previousMillis[i] = millis();
}
}
}
void setup()
{
Serial.begin(115200);
/* delay(500);
Serial.println("##########");
Serial.println("MIDI");
Serial.println("##########");
Serial.flush();
*/
// initialize LED digital pin as an output.
pinMode(LED_PIN, OUTPUT);
stepper[0].begin( X_DIR_PIN, X_STEP_PIN, X_ENABLE_PIN);
stepper[1].begin( Y_DIR_PIN, Y_STEP_PIN, Y_ENABLE_PIN);
stepper[2].begin( Z_DIR_PIN, Z_STEP_PIN, Z_ENABLE_PIN);
stepper[3].begin(E0_DIR_PIN, E0_STEP_PIN, E0_ENABLE_PIN);
stepper[4].begin(E1_DIR_PIN, E1_STEP_PIN, E1_ENABLE_PIN);
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
MIDI.setHandlePitchBend(handlePitchBend);
MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop()
{
unsigned long currentMillis = millis();
for (int i=0; i<NUM_STEPPER; i++) {
if (currentMillis - previousMillis[i] >= interval || previousMillis[i] == 0) {
stepper[i].disable();
playing[i].noteNumber = 0;
playing[i].channel = 255;
}
}
//Serial.println("test");
MIDI.read();
for (int i=0; i<NUM_STEPPER; i++) stepper[i].loop();
}