Arduino code
Arduino motor code
#include <AccelStepper.h>
//declare motors
AccelStepper guitar(1,8,9);
AccelStepper drums(1,10,11);
//motor parameters
volatile long drumSpeed = 0;
const long guitarSpeed = 1000; //pulses/second*0.15=150rpm
const long minDrumSpeed = 100;
const long maxDrumSpeed = 350; //(300pulse/sec)*(1/400rev/pulse)*(60sec/min)=45rpm
int enableGuitarPin = 3; //turns motor on/off
int enableDrumPin = 4; //turns motor on/off
//pot and switch setup
int potPin = 2;
int potVal = 0;
int drumSwitchPin = 7;
int drumSwitchState = 0;
int guitarSwitchPin = 5;
int guitarSwitchState = 0;
float rest = 15.6445; //15.6445
float correctionFactor = 1.0156; //1.0156
float myDiv = 0;//milliseconds per 1/8th note
float processTime = 0; //for calculating lag time in "moveX" function
float endTime = 0;
float startTime = 0;
float start = 0;// for "hold" function
float endtime = 0;
//note distances on cams
const int EF = 38; const int FE = -EF; //34 initial 38 final
const int FG = 36; const int GF = -FG; //32 36
const int GA = 38; const int AG = -GA; //34 38
const int AB = 38; const int BA = -AB; //34 38
const int BC = 38; const int CB = -BC; //32 38
const int CD = 44; const int DC = -CD; //34 44
const int EB = EF + FG + GA + AB; const int BE = -EB;
const int EG = EF + FG; const int GE = -EG;
const int GB = GA + AB;
void setup() {
attachInterrupt(0,interrupt,RISING); //enters speed control/guitar solo at button push
guitar.setMaxSpeed(1000);
guitar.setSpeed(guitarSpeed);
drums.setMaxSpeed(maxDrumSpeed);
drums.setSpeed(drumSpeed);
pinMode(enableGuitarPin, OUTPUT);
pinMode(enableDrumPin, OUTPUT);
pinMode(drumSwitchPin, INPUT);
pinMode(guitarSwitchPin, INPUT); }
// button interrupt function
void interrupt(){
SpeedControl();
guitarSolo(); }
//move guitar # of steps while drums run continuous
void moveX(long target){
startTime = millis();
guitar.move(-target);
guitar.setSpeed(guitarSpeed);
while (guitar.distanceToGo() != 0)
{ guitar.runSpeedToPosition();
drums.runSpeed(); }
endTime = millis();
processTime = endTime - startTime; }
//hold guitar and run drums (msecs)
void hold(float holdtime) {
start = millis();
endtime = start + holdtime - processTime;
while(millis() < endtime)
drums.runSpeed(); }
//potentiometer drum speed. Calls at beginning of loop, or at button press.
void SpeedControl() {
potVal = analogRead(potPin);
drumSpeed = -map(potVal,0,1023,minDrumSpeed,maxDrumSpeed);
drums.setSpeed(drumSpeed);
myDiv = -50000/drumSpeed*correctionFactor; }
//loops one measure of drums only, as long as switch is on. After switched off, takes one measure to return to main loop.
void DrumSolo() {
while(drumSwitchState){
hold(8*myDiv);
SpeedControl();
drumSwitchState = digitalRead(drumSwitchPin); }
digitalWrite(enableGuitarPin, LOW); //turns guitar motor back on
hold(8*myDiv); }
//Loops through song with drums off. Uselful for tuning cam distances.
void guitarSolo(){
guitarSwitchState = digitalRead(guitarSwitchPin);
if(guitarSwitchState){
digitalWrite(enableDrumPin, HIGH); //turns off drum motor
} else {
digitalWrite(enableDrumPin, LOW); } }
//main function
void loop() {
guitarSolo();
SpeedControl();
//drum solo?
drumSwitchState = digitalRead(drumSwitchPin);
if (drumSwitchState){
digitalWrite(enableGuitarPin, HIGH);//turns off (releases) guitar motor coils.
DrumSolo(); }
guitarSolo();
for (int i = 0; i<=1; i++){
//measure 1
hold(3*myDiv);
moveX(EF);
hold(myDiv);
moveX(FG);
hold(2*myDiv);
moveX(GA);
hold(2*myDiv);
//measure 2
moveX(AB);
hold(3*myDiv);
moveX(BC);
hold(myDiv);
moveX(CD);
hold(2*myDiv);
moveX(DC);
hold(2*myDiv);
//measure 3 & 4
moveX(CB);
if(i==0){
hold(rest*myDiv);
moveX(BE);
} else {
hold(rest*myDiv); } }
//measure 9
moveX(BC);
hold(myDiv);
moveX(CB);
hold(2*myDiv);
moveX(BC);
hold(myDiv);
moveX(CB);
hold(2*myDiv);
moveX(BA);
hold(2*myDiv);
//measure 10
moveX(AB);
hold(myDiv);
moveX(BA);
hold(2*myDiv);
moveX(AB);
hold(myDiv);
moveX(BA);
hold(2*myDiv);
moveX(AG);
hold(myDiv);
moveX(GE);
hold(myDiv);
//measure 11 & 12
moveX(EG);
hold(rest*myDiv);
//measure 13
moveX(GB);
hold(myDiv);
moveX(BA);
hold(2*myDiv);
moveX(AB);
hold(myDiv);
moveX(BA);
hold(2*myDiv);
moveX(AG);
hold(2*myDiv);
//measure 14
moveX(GA);
hold(myDiv);
moveX(AG);
hold(2*myDiv);
moveX(GA);
hold(myDiv);
moveX(AG);
hold(2*myDiv);
moveX(GF);
hold(2*myDiv);
//measures 15 & 16
moveX(FE);
hold(rest*myDiv);
}
, multiple selections available,