//Kestrel sequencer - By Phil Cranmer unsigned long pulseDirectionFrequency = 460;// Kestrel motor A direction changing frequency unsigned long timeadjust = 0;// Adjustment to compensate for slight pause in the music (as the beats are not constant all the way through the track) unsigned long timeadjust2 = 0;// 2nd adjustment unsigned long sequencerSpeed = 100;// the times stored in the sequencing arrays will be multiplied by this... defines resolution // saves on memory. if this number is 500 and the rest of the code works in milliseconds // then we have a halfsecond resolution, but with millisecond precision. unsigned long repeatTime = 18000;// to convert to seconds, = (sequencerSpeed/1000)*repeatTime (48 = 24 seconds if sequencerSpeed is 500) unsigned long startTime; boolean reverseToo = true;// if this is true, then the pulse makes the motor go in both directions. Otherwise it just goes, stops, goes, stops etc. int numberofmotors = 6; //Actually 3 motors, but the lasers, smoke and strobe switches have been named as motors 4, 5 and 6. int motorPulsePins[6] = {2,3,4,5,6,8}; int motorDirectionPins[1] = {13}; //MOTOR A: unsigned long motor1Times[10] = {0,295,443,738,1034,1107,1182,1255,1551,1845};// each number represents a state change. to convert to seconds, = (sequencerSpeed/1000)*time in array boolean motor1HighLow[10] = {true,false,false,true,true,true,true,true,true,false};// state in each step boolean motor1Direction[10] = {true,true,true,true,true,true,true,true,true,true};// direction. matches motor1Times boolean motor1Pulse[10] = {true,true,true,true,true,true,true,true,false,false};// is the direction pulsing? unsigned long motor1Step = 0;// start step //MOTOR B: unsigned long motor2Times[10] = {0,295,443,738,1034,1107,1182,1255,1551,1845};// each number represents a state change. to convert to seconds, = (sequencerSpeed/1000)*time in array boolean motor2HighLow[10] = {false,false,true,false,true,false,true,true,false,false};// state in each step unsigned long motor2Step = 0;// start step //MOTOR C: unsigned long motor3Times[3] = {0,1551,1845};// each number represents a state change. to convert to seconds, = (sequencerSpeed/1000)*time in array boolean motor3HighLow[3] = {false,true,false};// state in each step unsigned long motor3Step = 0;// start step //LASER: unsigned long motor4Times[5] = {0,1549,1550,1551,1845};// each number represents a state change. to convert to seconds, = (sequencerSpeed/1000)*time in array boolean motor4HighLow[5] = {false,true,false,true,false};// state in each step unsigned long motor4Step = 0;// start step //STROBE: unsigned long motor5Times[5] = {0,295,443,1255,1551};// each number represents a state change. to convert to seconds, = (sequencerSpeed/1000)*time in array boolean motor5HighLow[5] = {false,true,false,true,false};// state in each step unsigned long motor5Step = 0;// start step //SMOKE: unsigned long motor6Times[7] = {0,295,320,1255,1280,1501,1551};// each number represents a state change. to convert to seconds, = (sequencerSpeed/1000)*time in array boolean motor6HighLow[7] = {false,true,false,true,false,true,false};// state in each step unsigned long motor6Step = 0;// start step void setup(){ for(int x = 0; x < numberofmotors; x++){ pinMode(motorPulsePins[x], OUTPUT); pinMode(motorDirectionPins[x], OUTPUT); } startTime = millis();// capture the time everything starts } void loop(){ if(millis()-startTime< 60000){ timeadjust = 0; }else{ timeadjust = 230;// Adjustment to compensate for slight pause in the music (as the beats are not constant all the way through the track) } if(millis()-startTime< 118150){ timeadjust2 = 0; }else{ timeadjust2 = 230;// Adjustment to compensate for slight pause in the music (as the beats are not constant all the way through the track) } boolean pulseNow = ((pulseDirectionFrequency)>((millis()-startTime-timeadjust+timeadjust2)%(pulseDirectionFrequency*2)));// this should... make pulse now true and false in a cycle //Motor 1 if((motor1HighLow[motor1Step]==true)){// at this stage, do we want motor 1 high digitalWrite(motorPulsePins[0], HIGH);// motorPulsePin[0] is the first location in the motorPulsePin array - so the pin for motor 1 }else{// otherwise, low digitalWrite(motorPulsePins[0], LOW); } //this bit looks to see which direction it should be going in. if pulsing is turned on, then it keeps reversing the direction or if reverseToo is set to false at the top // then it will, go, stop, go, stop. direction can be used to make two motors move together, or one go CW the other CCW (even when pulsing) if((motor1Direction[motor1Step]==true)){// at this stage, do we want motor 1 high (&& means "and") // also consideres if the pulse is high or low and this exact moment, and if the pulse is turned on at all if((!motor1Pulse[motor1Step]) || (motor1Pulse[motor1Step] && (pulseNow))){// go constant or pulsing - one direction of pulse digitalWrite(motorDirectionPins[0], HIGH);// motorDirectionPins[0] is the first location in the motorDirectionPins array - so the pin for motor 1 }else if(motor1Pulse[motor1Step] && (!pulseNow) && reverseToo){// just the other direction of the pulse digitalWrite(motorDirectionPins[0], LOW);// pulse other direction } }else{// otherwise, low (unless pulsing) if((!motor1Pulse[motor1Step]) || (motor1Pulse[motor1Step] && (pulseNow))){// go constant or pulsing - one direction of pulse digitalWrite(motorDirectionPins[0], LOW);// motorDirectionPins[0] is the first location in the motorDirectionPins array - so the pin for motor 1 }else if(motor1Pulse[motor1Step] && (!pulseNow) && reverseToo){// just the other direction of the pulse digitalWrite(motorDirectionPins[0], HIGH);// pulse other direction } } //Motor 2 if((motor2HighLow[motor2Step]==true)){// at this stage, do we want motor 2 high digitalWrite(motorPulsePins[1], HIGH);// motorPulsePin[1] is the second location in the motorPulsePin array - so the pin for motor 2 }else{// otherwise, low digitalWrite(motorPulsePins[1], LOW); } //Motor 3 if((motor3HighLow[motor3Step]==true)){// at this stage, do we want motor 3 high digitalWrite(motorPulsePins[2], HIGH);// motorPulsePin[2] is the third location in the motorPulsePin array - so the pin for motor 3 }else{// otherwise, low digitalWrite(motorPulsePins[2], LOW); } //LASER if((motor4HighLow[motor4Step]==true)){// at this stage, do we want motor 4 high digitalWrite(motorPulsePins[3], HIGH);// motorPulsePin[0] is the first location in the motorPulsePin array - so the pin for motor 1 }else{// otherwise, low digitalWrite(motorPulsePins[3], LOW); } //STROBE if((motor5HighLow[motor5Step]==true)){// at this stage, do we want motor 5 high digitalWrite(motorPulsePins[4], HIGH);// motorPulsePin[1] is the second location in the motorPulsePin array - so the pin for motor 2 }else{// otherwise, low digitalWrite(motorPulsePins[4], LOW); } //SMOKE if((motor6HighLow[motor6Step]==true)){// at this stage, do we want motor 6 high digitalWrite(motorPulsePins[5], HIGH);// motorPulsePin[2] is the third location in the motorPulsePin array - so the pin for motor 3 }else{// otherwise, low digitalWrite(motorPulsePins[5], LOW); } updateSteps();// calls sub at end of code } boolean updateSteps(){ if(repeatTime*sequencerSpeed<(millis()-startTime)){// then reached the end of the loop so reset things that need to be motor1Step = 0; motor2Step = 0; motor3Step = 0; motor4Step = 0; motor5Step = 0; motor6Step = 0; startTime = millis(); }else{// not end, so check to see if at end of a step in each motor //motor 1 if(motor1Step!=sizeof(motor1Times)/sizeof(int)){// != means not equal to if((motor1Times[motor1Step+1]*sequencerSpeed)<(millis()-startTime)){// time is past next step. so change current sequence step motor1Step++; } } //motor 2 if(motor2Step!=sizeof(motor2Times)/sizeof(int)){// != means not equal to if((motor2Times[motor2Step+1]*sequencerSpeed)<(millis()-startTime)){// time is past next step. so change current sequence step motor2Step++; } } // motor 3 if(motor3Step!=sizeof(motor3Times)/sizeof(int)){// != means not equal to if((motor3Times[motor3Step+1]*sequencerSpeed)<(millis()-startTime)){// time is past next step. so change current sequence step motor3Step++; } }//motor 4 if(motor4Step!=sizeof(motor4Times)/sizeof(int)){// != means not equal to if((motor4Times[motor4Step+1]*sequencerSpeed)<(millis()-startTime)){// time is past next step. so change current sequence step motor4Step++; } } //motor 5 if(motor5Step!=sizeof(motor5Times)/sizeof(int)){// != means not equal to if((motor5Times[motor5Step+1]*sequencerSpeed)<(millis()-startTime)){// time is past next step. so change current sequence step motor5Step++; } } // motor 6 if(motor6Step!=sizeof(motor6Times)/sizeof(int)){// != means not equal to if((motor6Times[motor6Step+1]*sequencerSpeed)<(millis()-startTime)){// time is past next step. so change current sequence step motor6Step++; } } } }