 # midi clock to bpm

I thought of a new challenge for myself, but it just dont seem to work.

I would like to have my lcd display show the beats per minute. A midi clock signal goes into my arduino. 24 times every quarter note. So theoretically if the code measures how many midi clock signals goes in every second and multiply that with 2,5. The outcome would be the BPM.

60 bpm = 24 clocks/quarternote = 60 quarternotes/minute
1 quarternote = 1 second = 24 clocks
60/24=2,5

120 bpm
1 quarternote = 0,5 seconds
48 clocks/second
48*2,5=120

Now my problem. I must do something with millis() but cant figure out what exactly.
Has anyone done something similar already. I only have found this code which make a led blink every quarternote.

``````byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
int play_flag = 0;
byte data;
byte counter;

void setup() {
Serial.begin(31250);
}

void loop() {
if(Serial.available() > 0) {
if(data == midi_start) {
play_flag = 1;
}
else if(data == midi_continue) {
play_flag = 1;
}
else if(data == midi_stop) {
play_flag = 0;
}
else if((data == midi_clock) && (play_flag == 1)) {
Sync();
}
}
}

void Sync() {
// do something for every MIDI Clock pulse when the sequencer is running

if(counter == 23){
counter = 0;
}
if(counter == 0){
turnLedOn();
}
if(counter == 3){ // this will set the duration of the led on
turnLedOff();
}
counter++;
}
``````

When you set counter to 0, record the value of millis(). When you get to 23 clocks, subtract the current value of millis() from the value you stashed. That will get you the number of milliseconds for 23 clocks.

Well this is what i came up so far. But the value that shows up is always -60. I dont know whats that about. I thought it should change when i increase the bpm.

``````#include

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
int play_flag = 0;
byte data;
byte counter;
int ledPin = 13;
long count = millis();
long lastcount = 0;
long bpm = 120;

void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" bpm ");
pinMode(ledPin, OUTPUT);
}

void loop() {
if (Serial.available() > 0) {
if (data == midi_start) {
play_flag = 1;
}
else if (data == midi_continue) {
play_flag = 1;
}
else if (data == midi_stop) {
lcd.setCursor(0, 1);
lcd.print("         ");
play_flag = 0;
}
else if ((data == midi_clock) && (play_flag == 1)) {
Sync();

}
}
}

void Sync() {
// do something for every MIDI Clock pulse when the sequencer is running

if (counter == 23) {
counter = 0;
bpm = (1000 / (count - lastcount) * 60);
lcd.setCursor(0, 1);
lcd.print(bpm);

}
if (counter == 0) {
digitalWrite(ledPin, HIGH);

lastcount = count;
}
if (counter == 3) { // this will set the duration of the led on
digitalWrite(ledPin, LOW);
}
counter++;

}
``````

You never change count and lastcount.

Allright. I have a working code. It stable at low bpms but not really above 110 bpm. But i can work with it now. Anyone suggestions for some improvements?

``````#include

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
int play_flag = 0;
byte data;
byte counter;
int ledPin = 13;
unsigned long count;
float ccc;
unsigned long lastcount;
int bpm = 120;
float calcbpm = 120;

void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" bpm ");
pinMode(ledPin, OUTPUT);
}

void loop() {
count = micros();
if (Serial.available() > 0) {
if (data == midi_start) {
play_flag = 1;
}
else if (data == midi_continue) {
play_flag = 1;
}
else if (data == midi_stop) {
lcd.setCursor(0, 1);
lcd.print("         ");
play_flag = 0;
}
else if ((data == midi_clock) && (play_flag == 1)) {
Sync();

}
}
}

void Sync() {
// do something for every MIDI Clock pulse when the sequencer is running

if (counter == 23) {
counter = 0;
ccc = (count - lastcount);
calcbpm = ((920200 / ccc) * 60); //920200 is trial and error.  Should be 1000000 theoretically
bpm = calcbpm;
if (bpm < 100) {
lcd.print(" ");
}
lcd.setCursor(0, 1);
lcd.print(bpm);

}
if (counter == 0) {
digitalWrite(ledPin, HIGH);

}
if (counter == 1) { // this will set the duration of the led on
lastcount = count;
}
if (counter == 3) { // this will set the duration of the led on
digitalWrite(ledPin, LOW);
}
counter++;

}
``````