2010-11-19

5) One LED lights up at each step

Up to now everything works and
in this step we want to light up a LED at each step.We asign one digital output for each step and connect a LED to it. Since only one LED will light at a time, we need only one resistor to limit the current for all LEDs.





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
-N x Switch for muting N steps
-N x LEDs for N steps
-1 x Resistor for the LEDs
-Switch for turning shuffle on and off
-10 kOhm pull-down Resistor for the switch

Schematics















Software (tested and working)




// 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;
int note;
int noteval;
int LowestNote;
int HighestNote;

int Note1;
int Note2;
int Note3;
int Note4;
int Note5;
int Note6;
int Note7;
int Note8;
int Note9;
int Note10;
int Note11;
int Note12;
int Note13;
int Note14;
int Note15;
int Note16;

int SeqLength;

int ShufflePin;
int Shuffle_Flag;
int ShuffleDelay;

// Initialization
void setup() {
Serial.begin(31250);
clock_step=0;
note = 0x3F;
noteval = 0;
LowestNote=36;
HighestNote=36+3*12; //3 Octaves over LowestNote

ShufflePin = 2;
pinMode(ShufflePin, INPUT); //Pin 0 for shuffle on/off as input
Shuffle_Flag = 0;
ShuffleDelay = 0;

Note1 = (96*1)/16-5;
Note2 = (96*2)/16-5;
Note3 = (96*3)/16-5;
Note4 = (96*4)/16-5;
Note5 = (96*5)/16-5;
Note6 = (96*6)/16-5;
Note7 = (96*7)/16-5;
Note8 = (96*8)/16-5;
Note9 = (96*9)/16-5;
Note10 = (96*10)/16-5;
Note11 = (96*11)/16-5;
Note12 = (96*12)/16-5;
Note13 = (96*13)/16-5;
Note14 = (96*14)/16-5;
Note15 = (96*15)/16-5;
Note16 = (96*16)/16-5;

SeqLength = 6*16; //Sequence length is 16*16th notes

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
}

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)) {
Sync();
}
}
}


// Functions

void Sync() { // play 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){
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
digitalWrite(22, HIGH);
digitalWrite(52, LOW);
}

if (clock_step==Note2){
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
digitalWrite(24, HIGH);
digitalWrite(22, LOW);
}

if (clock_step==Note3){
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
digitalWrite(26, HIGH);
digitalWrite(24, LOW);
}

if (clock_step==Note4){
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
digitalWrite(28, HIGH);
digitalWrite(26, LOW);
}

if (clock_step==Note5){
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
digitalWrite(30, HIGH);
digitalWrite(28, LOW);
}

if (clock_step==Note6){
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
digitalWrite(32, HIGH);
digitalWrite(30, LOW);
}

if (clock_step==Note7){
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
digitalWrite(34, HIGH);
digitalWrite(32, LOW);
}

if (clock_step==Note8){
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
digitalWrite(36, HIGH);
digitalWrite(34, LOW);
}

if (clock_step==Note9){
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
digitalWrite(38, HIGH);
digitalWrite(36, LOW);
}

if (clock_step==Note10){
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
digitalWrite(40, HIGH);
digitalWrite(38, LOW);
}

if (clock_step==Note11){
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
digitalWrite(42, HIGH);
digitalWrite(40, LOW);
}

if (clock_step==Note12){
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
digitalWrite(44, HIGH);
digitalWrite(42, LOW);
}

if (clock_step==Note13){
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
digitalWrite(46, HIGH);
digitalWrite(44, LOW);
}

if (clock_step==Note14){
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
digitalWrite(48, HIGH);
digitalWrite(46, LOW);
}

if (clock_step==Note15){
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
digitalWrite(50, HIGH);
digitalWrite(48, LOW);
}

if (clock_step==Note16){
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
digitalWrite(52, HIGH);
digitalWrite(50, 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);
}

2010-11-15

4) Implementation of a shuffle rhythm function

Now we will implement a shuffle function to our Arduino Mega based step sequencer. A hardware switch will apply a HIGH signal to a digital input (ShufflePin is Pin 2) and to turn the shuffle on, where against a LOW signal at this pin means shuffle off. The rest is done by the software.


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 fe
male 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

-Switch for turning shuffle on and off
-10 kOhm
pull-down Resistor for the switch


Schematics



















Software

If the readout at the ShufflePin (pin 2) is LOW then the Shuffle_Flag=0 causing the ShuffleDelay to be 0. Then the sequencer runs as in the chapters before this one. However if the ShufflePin is set to HIGH by closing the respective switch, Shuffle_Flag will be 1. This means that every second 16th note will be delayed by 1 MIDI clock signals. The result is a shuffle rhythm. The effect can be increased, e.g. by setting ShuffleDelay = 2...4.


// 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;
int note;
int noteval;
int LowestNote;
int HighestNote;

int Note1;
int Note2;
int Note3;
int Note4;
int Note5;
int Note6;
int Note7;
int Note8;
int Note9;
int Note10;
int Note11;
int Note12;
int Note13;
int Note14;
int Note15;
int Note16;

int SeqLength;

int ShufflePin;
int Shuffle_Flag;
int ShuffleDelay;

// Initialization
void setup() {
Serial.begin(31250);
clock_step=0;
note = 0x3F;
noteval = 0;
LowestNote=36;
HighestNote=36+3*12; //3 Octaves over LowestNote

ShufflePin = 2;
pinMode(ShufflePin, INPUT); //Pin 0 for shuffle on/off as input
Shuffle_Flag = 0;
ShuffleDelay = 0;

Note1 = (96*1)/16-5;
Note2 = (96*2)/16-5;
Note3 = (96*3)/16-5;
Note4 = (96*4)/16-5;
Note5 = (96*5)/16-5;
Note6 = (96*6)/16-5;
Note7 = (96*7)/16-5;
Note8 = (96*8)/16-5;
Note9 = (96*9)/16-5;
Note10 = (96*10)/16-5;
Note11 = (96*11)/16-5;
Note12 = (96*12)/16-5;
Note13 = (96*13)/16-5;
Note14 = (96*14)/16-5;
Note15 = (96*15)/16-5;
Note16 = (96*16)/16-5;

SeqLength = 6*16; //Sequence length is 16*16th notes
}

// 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
}

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
}
else if((data == midi_clock) && (play_flag == 1)) {
Sync();
}
}
}


// Functions

void Sync() { // play 8 fixed 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){ //1st step
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
}

if (clock_step==Note2){ //2nd step
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
}

if (clock_step==Note3){ //3nd step
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
}

if (clock_step==Note4){ //4nd step
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
}

if (clock_step==Note5){ //4nd step
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
}

if (clock_step==Note6){ //4nd step
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
}

if (clock_step==Note7){ //4nd step
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
}

if (clock_step==Note8){ //4nd step
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
}

if (clock_step==Note9){ //4nd step
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
}

if (clock_step==Note10){ //4nd step
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
}

if (clock_step==Note11){ //4nd step
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
}

if (clock_step==Note12){ //4nd step
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
}

if (clock_step==Note13){ //4nd step
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
}

if (clock_step==Note14){ //4nd step
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
}

if (clock_step==Note15){ //4nd step
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
}

if (clock_step==Note16){ //4nd step
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
}

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);
}


2010-11-10

3) Choosing Notes by Potentiometers

In this part we introduce one potentiometer (10 kOhm) per step to choose the note of the step. The current code is for N = 4 steps, but can be easily extended to more steps. As an Arduino Uno has only 6 anolog inputs this would allow N = 6 which is not enough for musical applications. This is why an Arduino Mega with 16 analog inputs should be used here. LowestNote and HighestNote define the range of MIDI notes that can be played. Both parameters should be multiples of 12, because then the note range goes from a C to a higher C.

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

Schematics


















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;
int note;
int noteval;
int LowestNote;
int HighestNote;

// Initialization
void setup() {
Serial.begin(31250);
clock_step=0;
note = 0x3F;
noteval = 0;
LowestNote=36;
HighestNote=36+3*12; //3 Octaves over LowestNote
}

// Main Programm
void loop() {
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
}
else if((data == midi_clock) && (play_flag == 1)) {
Sync();
}
}
}


// Functions

void Sync() { // play 8 fixed 16th notes, repeat after the cycle is finshed
clock_step = clock_step+1;
if (clock_step==1){ //1st step

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
}

if (clock_step==7){ //2nd step

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

}
if (clock_step==13){ //3nd step

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

}
if (clock_step==19){ //4nd step

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

}

else if (clock_step==24){
clock_step=0;
}
}

void sendMidiNote (byte midiCommand, byte noteValue, byte velocityValue){
Serial.print(midiCommand, BYTE);
Serial.print(noteValue, BYTE);
Serial.print(velocityValue, BYTE);
}



2010-11-07

2) Sending MIDI Notes

To send MIDI commands we need a 5 pin DIN jack, like for the MIDI-in, but without a galvanic decoupling. The jack has to be connected to +5V, the serial output (TX) and to ground (via a 220 Ohm resitor).

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)

Schematics













Software

The following code can reveive MIDI clock and send synchronous MIDI notes.


// 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;
int note;

// Initialization
void setup() {
Serial.begin(31250);
clock_step=0;
note = 0x3F;
}

// Main Programm
void loop() {
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
}
else if((data == midi_clock) && (play_flag == 1)) {
Sync();
}
}
}


// Functions

void Sync() { // play 8 fixed 16th notes, repeat after the cycle is finshed
clock_step = clock_step+1;
if (clock_step==1){ //1st step
sendMidiNote (0x80, note, 0x7F); //last note off
note = 0x5A;
sendMidiNote (0x90, note, 0x7F); //note of this step on
}
if (clock_step==7){ //2nd step
sendMidiNote (0x80, note, 0x7F); //last note off
note = 0x4A;
sendMidiNote (0x90, note, 0x7F);
}
if (clock_step==13){ //3nd step
sendMidiNote (0x80, note, 0x7F); //last note off
note = 0x4B;
sendMidiNote (0x90, note, 0x7F);
}
if (clock_step==19){ //4nd step
sendMidiNote (0x80, note, 0x7F); //last note off
note = 0x3F;
sendMidiNote (0x90, note, 0x7F);
}
else if (clock_step==24){
clock_step=0;
}
}

void sendMidiNote (byte midiCommand, byte noteValue, byte velocityValue){
Serial.print(midiCommand, BYTE);
Serial.print(noteValue, BYTE);
Serial.print(velocityValue, BYTE);
}