Is there a way to make MIDI clock messages a little more accurate ?

:o :o :o :o

MIDI is Insane.

The two instruments I’m using together (one of them is the arduino sequencer, aka master clock) aren’t quite sync’d up exactly perfect. I even think it might be drifting a bit too. I’m using MIDI.SendRealTime(Clock) as my MIDI clock message. I know usually it’s 24 messages per quarter note, but that seemed to do the trick and started working so I just left it as is.

Any help is extremely appreciated. Thank you.

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();
using namespace midi;

byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;

//int midiSend = Serial.write(248);

//DIGITAL PINS 4 - 11: LED
//Analog Pins A0 - A7: knobs sequencer
//Analog pin A8: tEmpo knob
//Gate pin: digital pin 3
//CV Out pin = DIGITAL PIN 2
//MIDI OUT PIN DIGITAL PIN 12
//switch = 13
int cv_pin = 2;
int gate_pin = 3;
float tempo = 73;
int cv_value = 0;
uint8_t analogPins[] = {A0, A1, A2, A3, A4, A5, A6, A7};
int midi_clk_step = 0;
uint8_t midiClock = 0xF8;
int switchOn = 13;
int midiPin = 1;
int startLED = 4;
int NUM_LED = 8;
int checkPin;
bool midiStarted = false; 

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
   MIDI.begin(); 

  //Digital Pins

  //LEDs
  for (int i = startLED; i < NUM_LED + startLED; i++) {
    pinMode(i, OUTPUT); digitalWrite(i, LOW);
  }


  //GATE PIN
  pinMode(3, OUTPUT); digitalWrite(3, HIGH);
  //CV PIN
  pinMode(cv_pin, OUTPUT); digitalWrite(cv_pin, 0);
  pinMode(switchOn, INPUT);


}

void loop() {
  
  // update tempo
  checkPin = digitalRead(switchOn);
  if (checkPin == HIGH) {
    if (midiStarted == false)
      {
        MIDI.sendRealTime(Start);
         midiStarted = true; 
      }
     
    

    tempo = analogRead(A8);
    tempo = map(tempo, 0, 1024, 20, 2000);

    //SEND MIDI CLK
   
  
 MIDI.sendRealTime(Clock);
    //SEND CV
    if (midi_clk_step % 6 == 0) {
      cv_step(midi_clk_step);
     
    }
    delay(int((60000 / (tempo)) / 24));
    midi_clk_step = (midi_clk_step + 1) % 24;
    //Serial.println(midi_clk_step);

    //switch end
  }
  else {
    analogWrite(cv_pin, 0);
    midiStarted = false;
    MIDI.sendRealTime(Stop);
 
  }

}

void cv_step(int midi_clk_step) {
  static int gate = 0;
  static int seq_step = 0;
  //SEND CV
  cv_value = analogRead(analogPins[seq_step]);
  cv_value = map(cv_value, 0, 1024, 0, 255);
  analogWrite(cv_pin, cv_value);
  //LED
  for (int i = startLED; i < NUM_LED + startLED; i++) {
    if (i == (seq_step + 4) ) {
      

     Serial.println(i);
      digitalWrite(i, HIGH);
    } else {
      digitalWrite(i, LOW);
    }
  }
  //SEND GATE
  digitalWrite(gate_pin, gate);
  gate = (gate + 1) % 2;

  if (midi_clk_step % 12 == 0) {
    seq_step = (seq_step + 1) % 8;
    for (int i = 0; i < 12; i++) {
    
     // digitalWrite(midiPin, midiSend);


    }
  }
}

Sorry its kind of messy and I know i have some code that is unused and commented out. Hope this makes sense.

What timing reference are you using? Most Arduino clocks are not very accurate. ALL devices should have accruate real-time clocks, not just the CPUs resonator, which can be off by a lot, and wander even more as temperature and voltage vary.

Regards, Ray L.