Now we introduce the possibility to switch between forward and backward playing while the sequencer is running. The code is now also made clearer, by leaving unimportant parts away.
Parts list
-2 x Resistor 220 Ohm
-1 x Resistor 100 kOhm
-1 x Diode
-1 x opto coupler IC GNY17-2
-2 x 5-pole DIN female connector (180°)
-1 x MIDI cable
-1 x MIDI sync master (here: Roland TR-505)
-1 x MIDI sync slave (here: DIY synthesizer with MIDI-input)
-1 x Arduino (here: Arduino Mega. For this demo also Arduinos with less input and output channels will work)
-N x Potentiometer 10 kOhm for N steps
-Switch for turning shuffle on and off
-1 x Switch for 2 posibilities of playing the step order
Schematics
--> like before, but with a switch that connects either pin 3 to ground and pin 4 to 5V and wise versa, if the switch is switched. Use pull up resistors like in the examples in the Fritzing software.
Software
// Declaration of Varialbes
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
int play_flag = 0;
byte data;
int clock_step=0;
int note = 0x3F;
int noteval = 0;
int LowestNote=36;
int HighestNote=36+3*12; //3 Octaves over LowestNote
int Note1 = (96*1)/16-5;
int Note2 = (96*2)/16-5;
int Note3 = (96*3)/16-5;
int Note4 = (96*4)/16-5;
int Note5 = (96*5)/16-5;
int Note6 = (96*6)/16-5;
int Note7 = (96*7)/16-5;
int Note8 = (96*8)/16-5;
int Note9 = (96*9)/16-5;
int Note10 = (96*10)/16-5;
int Note11 = (96*11)/16-5;
int Note12 = (96*12)/16-5;
int Note13 = (96*13)/16-5;
int Note14 = (96*14)/16-5;
int Note15 = (96*15)/16-5;
int Note16 = (96*16)/16-5;
int SeqLength = 6*16; //Sequence length is 16*16th notes
int ShufflePin = 2;
int Shuffle_Flag = 0;
int ShuffleDelay = 0;
int Seq1_Flag = HIGH;
int Seq2_Flag = LOW;
int Seq1Pin = 3;
int Seq2Pin = 4;
int PlayMode = 1;
// Initialization
void setup() {
Serial.begin(31250);
pinMode(ShufflePin, INPUT); //Pin 0 for shuffle on/off as input
pinMode(22, OUTPUT);
pinMode(24, OUTPUT);
pinMode(26, OUTPUT);
pinMode(28, OUTPUT);
pinMode(30, OUTPUT);
pinMode(32, OUTPUT);
pinMode(34, OUTPUT);
pinMode(36, OUTPUT);
pinMode(38, OUTPUT);
pinMode(40, OUTPUT);
pinMode(42, OUTPUT);
pinMode(44, OUTPUT);
pinMode(46, OUTPUT);
pinMode(48, OUTPUT);
pinMode(50, OUTPUT);
pinMode(52, OUTPUT);
digitalWrite(22, HIGH);
digitalWrite(24, LOW);
digitalWrite(26, LOW);
digitalWrite(28, LOW);
digitalWrite(30, LOW);
digitalWrite(32, LOW);
digitalWrite(34, LOW);
digitalWrite(36, LOW);
digitalWrite(38, LOW);
digitalWrite(40, LOW);
digitalWrite(42, LOW);
digitalWrite(44, LOW);
digitalWrite(46, LOW);
digitalWrite(48, LOW);
digitalWrite(50, LOW);
digitalWrite(52, LOW);
}
// Main Programm
void loop() {
Shuffle_Flag = digitalRead(ShufflePin);
if(Shuffle_Flag == LOW) {
ShuffleDelay = 0;
}
if (Shuffle_Flag == HIGH){
ShuffleDelay = 2; // start every 2nd note two MIDI clock signals later (ShuffleDelay = 1...4)
}
Seq1_Flag = digitalRead(Seq1Pin); //Play sequence forwards
Seq2_Flag = digitalRead(Seq2Pin); //Play sequence backwards
if(Seq1_Flag == HIGH && Seq2_Flag == LOW) {
PlayMode = 1; //Play sequence forwards
}
if (Seq1_Flag == LOW && Seq2_Flag == HIGH){
PlayMode = 2; //Play sequence backwards
}
if(Serial.available() > 0) {
data = Serial.read();
if(data == midi_start) {
play_flag = 1;
clock_step=0;
}
else if(data == midi_continue) {
play_flag = 1;
}
else if(data == midi_stop) {
play_flag = 0;
clock_step=0;
sendMidiNote (0x80, note, 0x7F); //last note off
digitalWrite(22, HIGH);
digitalWrite(24, LOW);
digitalWrite(26, LOW);
digitalWrite(28, LOW);
digitalWrite(30, LOW);
digitalWrite(32, LOW);
digitalWrite(34, LOW);
digitalWrite(36, LOW);
digitalWrite(38, LOW);
digitalWrite(40, LOW);
digitalWrite(42, LOW);
digitalWrite(44, LOW);
digitalWrite(46, LOW);
digitalWrite(48, LOW);
digitalWrite(50, LOW);
digitalWrite(52, LOW);
}
else if((data == midi_clock) && (play_flag == 1) && PlayMode == 1) {
Sync1(); //Play sequence forwards
}
else if((data == midi_clock) && (play_flag == 1) && PlayMode == 2) {
Sync2(); //Play sequence backwards
}
}
}
// Functions
void Sync1() { // play forwards 16 x 16th notes, repeat after the cycle is finshed
clock_step = clock_step+1;
Note1 = (96*1)/16-5;
Note2 = (96*2)/16-5+ShuffleDelay;
Note3 = (96*3)/16-5;
Note4 = (96*4)/16-5+ShuffleDelay;
Note5 = (96*5)/16-5;
Note6 = (96*6)/16-5+ShuffleDelay;
Note7 = (96*7)/16-5;
Note8 = (96*8)/16-5+ShuffleDelay;
Note9 = (96*9)/16-5;
Note10 = (96*10)/16-5+ShuffleDelay;
Note11 = (96*11)/16-5;
Note12 = (96*12)/16-5+ShuffleDelay;
Note13 = (96*13)/16-5;
Note14 = (96*14)/16-5+ShuffleDelay;
Note15 = (96*15)/16-5;
Note16 = (96*16)/16-5+ShuffleDelay;
if (clock_step==Note1){
PlayNote1();
digitalWrite(22, HIGH);
digitalWrite(52, LOW);
}
if (clock_step==Note2){
PlayNote2();
digitalWrite(24, HIGH);
digitalWrite(22, LOW);
}
if (clock_step==Note3){
PlayNote3();
digitalWrite(26, HIGH);
digitalWrite(24, LOW);
}
if (clock_step==Note4){
PlayNote4();
digitalWrite(28, HIGH);
digitalWrite(26, LOW);
}
if (clock_step==Note5){
PlayNote5();
digitalWrite(30, HIGH);
digitalWrite(28, LOW);
}
if (clock_step==Note6){
PlayNote6();
digitalWrite(32, HIGH);
digitalWrite(30, LOW);
}
if (clock_step==Note7){
PlayNote7();
digitalWrite(34, HIGH);
digitalWrite(32, LOW);
}
if (clock_step==Note8){
PlayNote8();
digitalWrite(36, HIGH);
digitalWrite(34, LOW);
}
if (clock_step==Note9){
PlayNote9();
digitalWrite(38, HIGH);
digitalWrite(36, LOW);
}
if (clock_step==Note10){
PlayNote10();
digitalWrite(40, HIGH);
digitalWrite(38, LOW);
}
if (clock_step==Note11){
PlayNote11();
digitalWrite(42, HIGH);
digitalWrite(40, LOW);
}
if (clock_step==Note12){
PlayNote12();
digitalWrite(44, HIGH);
digitalWrite(42, LOW);
}
if (clock_step==Note13){
PlayNote13();
digitalWrite(46, HIGH);
digitalWrite(44, LOW);
}
if (clock_step==Note14){
PlayNote14();
digitalWrite(48, HIGH);
digitalWrite(46, LOW);
}
if (clock_step==Note15){
PlayNote15();
digitalWrite(50, HIGH);
digitalWrite(48, LOW);
}
if (clock_step==Note16){
PlayNote16();
digitalWrite(52, HIGH);
digitalWrite(50, LOW);
}
else if (clock_step==SeqLength){
clock_step=0;
}
}
void Sync2() { // play backwards 16 x 16th notes, repeat after the cycle is finshed,
clock_step = clock_step+1;
Note1 = (96*1)/16-5;
Note2 = (96*2)/16-5+ShuffleDelay;
Note3 = (96*3)/16-5;
Note4 = (96*4)/16-5+ShuffleDelay;
Note5 = (96*5)/16-5;
Note6 = (96*6)/16-5+ShuffleDelay;
Note7 = (96*7)/16-5;
Note8 = (96*8)/16-5+ShuffleDelay;
Note9 = (96*9)/16-5;
Note10 = (96*10)/16-5+ShuffleDelay;
Note11 = (96*11)/16-5;
Note12 = (96*12)/16-5+ShuffleDelay;
Note13 = (96*13)/16-5;
Note14 = (96*14)/16-5+ShuffleDelay;
Note15 = (96*15)/16-5;
Note16 = (96*16)/16-5+ShuffleDelay;
if (clock_step==Note1){
PlayNote16();
digitalWrite(52, HIGH);
digitalWrite(22, LOW);
}
if (clock_step==Note2){
PlayNote15();
digitalWrite(50, HIGH);
digitalWrite(52, LOW);
}
if (clock_step==Note3){
PlayNote14();
digitalWrite(48, HIGH);
digitalWrite(50, LOW);
}
if (clock_step==Note4){
PlayNote13();
digitalWrite(46, HIGH);
digitalWrite(48, LOW);
}
if (clock_step==Note5){
PlayNote12();
digitalWrite(44, HIGH);
digitalWrite(46, LOW);
}
if (clock_step==Note6){
PlayNote11();
digitalWrite(42, HIGH);
digitalWrite(44, LOW);
}
if (clock_step==Note7){
PlayNote10();
digitalWrite(40, HIGH);
digitalWrite(42, LOW);
}
if (clock_step==Note8){
PlayNote9();
digitalWrite(38, HIGH);
digitalWrite(40, LOW);
}
if (clock_step==Note9){
PlayNote8();
digitalWrite(36, HIGH);
digitalWrite(38, LOW);
}
if (clock_step==Note10){
PlayNote7();
digitalWrite(34, HIGH);
digitalWrite(36, LOW);
}
if (clock_step==Note11){
PlayNote6();
digitalWrite(32, HIGH);
digitalWrite(34, LOW);
}
if (clock_step==Note12){
PlayNote5();
digitalWrite(30, HIGH);
digitalWrite(32, LOW);
}
if (clock_step==Note13){
PlayNote4();
digitalWrite(28, HIGH);
digitalWrite(30, LOW);
}
if (clock_step==Note14){
PlayNote3();
digitalWrite(26, HIGH);
digitalWrite(28, LOW);
}
if (clock_step==Note15){
PlayNote2();
digitalWrite(24, HIGH);
digitalWrite(26, LOW);
}
if (clock_step==Note16){
PlayNote1();
digitalWrite(22, HIGH);
digitalWrite(24, LOW);
}
else if (clock_step==SeqLength){
clock_step=0;
}
}
void sendMidiNote (byte midiCommand, byte noteValue, byte velocityValue){
Serial.print(midiCommand, BYTE);
Serial.print(noteValue, BYTE);
Serial.print(velocityValue, BYTE);
}
void PlayNote1() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(0);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote2() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(1);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote3() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(2);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote4() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(3);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote5() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(4);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote6() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(5);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote7() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(6);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote8() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(7);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote9() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(8);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote10() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(9);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote11() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(10);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote12() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(11);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote13() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(12);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote14() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(13);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote15() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(14);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
void PlayNote16() {
sendMidiNote (0x80, note, 0x7F); //last note off
noteval = analogRead(15);
note = map(noteval, 0, 1023, LowestNote, HighestNote);
sendMidiNote (0x90, note, 0x7F); //note of this step on
}