Simple MIDI USB Clock Converter for Analogue Sequencers

Title says it all really. I have several analogue sequencers that I designed and built years ago and I clock them with a Kenton Pro Solo Mk3. This unit can switch the MIDI THRU port to SYNC24 mode to work with Roland Drum Machines. This is a great solution but does tie up my Kenton which uses with my Editor and needs MIDI THRU for 2 way comms.

Arduino and the Pro Micro 

I realised it was a simple job to reprogram on of my Pro Micros to convert MIDI Clock and Stop/Start messages. I've used it for a few weeks and its a worker so I thought I build proper unit:
  • Pro Micro
  • 24 Pin DIL Socket
  • 1 x PCB Mounting 1/4 Stereo Jack Socket (my sequencers are all 1/4)
  • 1 x 10K pot (I used a 47K pot)


Like my SYNC24 breakout box this will be mounted on the back of an existing 19" rack panel.






The code is at the bottom of the post - you  will need to install the MIDIUSB.h library

Analog pulses are output on the clock jack connected to Pin 2. When stop is pressed on the sequencer the Stop command  $FC is picked up and a RESET pulse is sent out on Pin 5. This is connected to the RESET IN on my sequencer. This ensures the analogue sequencer is set to STEP 1 before the next MIDI clocks $F8 are received. I don't need to use a START pulse as my sequencer will start on the next clock pulse.

Pin A10 is connected to a 47K pot to adjust the clock divide ratio. Stop the sequencer before changing this value.

The MIDI Start command $FA is used to ensure the first Clock Pulse is sent out and that the RESET line goes LOW

/*
 * BasicMidiClockDiv.ino
 * Tested on Logic 10.6 and Ableton Live 9
 * Proves Clock Out, Reset and CLock Divide
 */

#include "MIDIUSB.h"

#define CLK 5    // Clock 
#define RST 2      // Reset  
#define DEADBAND    24

// Pin A10 uses a 10K (47K) pot to set Clock Divide

//Pulse per quarter note. Each beat has 24 pulses.
//Tempo is based on software inner BPM.
int ppqn = 0;
int ClkOn = 2 ;
int ClkOff = 5 ;
int prev_val;
int value ;

void setup() {
  Serial.begin(115200);
  pinMode(RST, OUTPUT);
  pinMode(CLK, OUTPUT);
}

void loop() {

  midiEventPacket_t rx;
  
  do {
    rx = MidiUSB.read();

    //Count pulses 
    if(rx.byte1 == 0xF8){
       
       if(ppqn == 1) {
      
           digitalWrite(CLK,HIGH);
                      }
       
       if(ppqn == ClkOn) {
           digitalWrite(CLK,LOW); 
                      }
       
       if(ppqn == ClkOff) {
        ppqn = 0;
       }
       ++ppqn ;
                      }

     //Clock start byte
    else if(rx.byte1 == 0xFA){
   digitalWrite(CLK,HIGH);
// digitalWrite(RST,LOW);
      ppqn = 0;
    }
    //Clock stop byte
    else if(rx.byte1 == 0xFC){
        //   MidiUSB.flush();
         digitalWrite(RST,HIGH);
         digitalWrite(CLK,LOW); 
         delay(200);
         digitalWrite(RST,LOW);
          
      ppqn = 0;
                             }
    
  } while (rx.header != 0);

// CLOCK DIVIDE 

  value =  analogRead(A10);
    // Get difference from current and previous value
  int diff = abs(value - prev_val);
// Exit this function if the new value is not within the deadband 
if (diff <= DEADBAND) return;
  // Store new value
  prev_val = value;
  // Get the 7 bit value


  int val2bit = value >> 7;  
  Serial.print(val2bit);
  Serial.println();
 

    prev_val = value;
    //  <3 <6  <12  < 24 1/16 1/8 1/4  1/2
    switch (val2bit) {
  
    
    case 0:
    ClkOn = 1;
    ClkOff = 2 ;
        Serial.print(val2bit);    
        Serial.print(ClkOn );
        Serial.println();
    break ;
 
    case 1:
    ClkOn = 2;
    ClkOff = 3 ;
    Serial.print(val2bit);    
    Serial.print(ClkOn );
    Serial.println();
    break ;

    case 2: 
    ClkOn = 3 ;   
    ClkOff = 6 ;
    Serial.print(val2bit);    
    Serial.print(ClkOn );
    Serial.println();
    break ;

    case 3: 
    ClkOn = 4 ;   
    ClkOff = 8 ;
    Serial.print(val2bit);    
    Serial.print(ClkOn );
    Serial.println();
    break ;

    case 4: 
    ClkOn = 6;
    ClkOff = 12 ;
    Serial.print(val2bit);    
    Serial.print(ClkOn );
    Serial.println();
    break ;
      
    case 5:  
    ClkOn = 8;  // triplet
    ClkOff = 16 ;
    Serial.print(val2bit);     
    Serial.print(ClkOn );
    Serial.println();
    break ;

    case 6:      
    ClkOn = 12;
    ClkOff= 24 ;
    Serial.print(val2bit);    
    Serial.print(ClkOn );     
    Serial.println();
    break ;
    
    case 7:      
    ClkOn = 24;
    ClkOff= 48   ;
    Serial.print(val2bit);    
    Serial.print(ClkOn );     
    Serial.println();
    break ;
    }
 
   // }
    
}

Comments