Last active
June 1, 2022 20:42
-
-
Save cowboy/1af3a69d4b6cae6a099fcf76431bda02 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// =============================================================== | |
// MIDI to 24 PPQN Clock + Run (USB MIDI) - Teensy LC Firmware | |
// "Cowboy" Ben Alman, 2022 | |
// https://gist.github.com/cowboy/1af3a69d4b6cae6a099fcf76431bda02 | |
// =============================================================== | |
int PPQN = 24; | |
int RUN_PIN = 26; | |
int RUN_LED_PIN = 20; | |
int CLOCK_PIN = 17; | |
int CLOCK_LED_PIN = 5; | |
int counter = 0; | |
void setup() { | |
// Setup pins | |
pinMode(RUN_PIN, OUTPUT); | |
pinMode(RUN_LED_PIN, OUTPUT); | |
pinMode(CLOCK_PIN, OUTPUT); | |
pinMode(CLOCK_LED_PIN, OUTPUT); | |
// MIDI message handlers | |
usbMIDI.setHandleClock(onClock); | |
usbMIDI.setHandleStart(onStart); | |
usbMIDI.setHandleStop(onStop); | |
blink(3); | |
} | |
void blink(int count) { | |
for (int i = 0; i < count; i++) { | |
digitalWrite(RUN_LED_PIN, HIGH); | |
digitalWrite(CLOCK_LED_PIN, LOW); | |
delay(250); | |
digitalWrite(RUN_LED_PIN, LOW); | |
digitalWrite(CLOCK_LED_PIN, HIGH); | |
delay(250); | |
} | |
digitalWrite(CLOCK_LED_PIN, LOW); | |
} | |
void loop() { | |
usbMIDI.read(); | |
} | |
void onClock() { | |
digitalWrite(CLOCK_PIN, HIGH); | |
delay(5); | |
digitalWrite(CLOCK_PIN, LOW); | |
if (counter == 0) { | |
digitalWrite(CLOCK_LED_PIN, HIGH); | |
} else if (counter == (PPQN / 2)) { | |
digitalWrite(CLOCK_LED_PIN, LOW); | |
} | |
if (++counter == PPQN) { | |
counter = 0; | |
} | |
} | |
void onStart() { | |
counter = 0; | |
digitalWrite(RUN_PIN, HIGH); | |
digitalWrite(RUN_LED_PIN, HIGH); | |
} | |
void onStop() { | |
digitalWrite(RUN_PIN, LOW); | |
digitalWrite(RUN_LED_PIN, LOW); | |
digitalWrite(CLOCK_PIN, LOW); | |
digitalWrite(CLOCK_LED_PIN, LOW); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// =============================================================== | |
// MIDI to 24 PPQN Clock + Run (USB MIDI) - OpenSCAD Enclosure | |
// "Cowboy" Ben Alman, 2022 | |
// https://gist.github.com/cowboy/1af3a69d4b6cae6a099fcf76431bda02 | |
// =============================================================== | |
$fs=0.1; | |
o=0.001; | |
outer_border=1.5; | |
pcb_w=35.75; | |
pcb_d=18; | |
pcb_h=1.75; | |
pcb_y_offset=1.2; | |
pcb_z_offset=7; | |
pcb_top=pcb_z_offset+pcb_h; | |
pcb_jack_divider=4.5; | |
pcb_guide_w=3; | |
pcb_guide_h=2; | |
pcb_button_h=3.1; | |
button_x=33.25; | |
button_r=1; | |
button_cut=0.4; | |
button_w=5; | |
button_indent=0.4; | |
button_ramp_offset=1; | |
usb_cutout_w=9; | |
usb_cutout_h=3.7; | |
usb_cutout_z_offset=0.5; | |
led_offset_x=19; | |
led_cutout_r=1.8; | |
led_base_h=2; | |
led_base_r=3.1; | |
jack_x=outer_border+pcb_w+pcb_jack_divider; | |
jack_w=10.5; | |
jack_d=8.75; | |
jack_h=10.5; | |
jack_metal_r=3.25; | |
jack_metal_z=4.5; | |
jack_divider=1; | |
jack_y_offset=(jack_d+jack_divider)/2; | |
lid_lip_w=pcb_w-4; | |
lid_lip_x_offset=(pcb_w-lid_lip_w)/2; | |
lid_pcb_holder_w=pcb_w*0.7; | |
lid_pcb_holder_x_offset=(pcb_w-lid_pcb_holder_w)/2; | |
lid_pcb_holder_z=pcb_top+outer_border; | |
length=2*outer_border+pcb_w+pcb_jack_divider+jack_w; | |
depth=2*outer_border+(pcb_d/2+pcb_y_offset)*2; | |
height=2*outer_border+jack_h; | |
module box(w,d,h) { | |
cube([w,d,h]); | |
} | |
module center_box(w,d,h) { | |
translate([0,-d/2,0]) | |
box(w,d,h); | |
} | |
module right_triangle(x,y) { | |
polygon([[0,0],[x,0],[x,y]]); | |
} | |
module lid() { | |
lid_w=length-2*outer_border-0.1; | |
lid_d=depth-2*outer_border-0.1; | |
notch_w=1; | |
notch_d=5; | |
rotate(180, [30,0,0]) | |
translate([outer_border,30,-height]) { | |
difference() { | |
// lid | |
translate([0,0,height-outer_border]) | |
center_box(lid_w,lid_d,outer_border); | |
// notch | |
translate([lid_w-notch_w+o,0,height-outer_border-o]) | |
center_box(notch_w,notch_d,outer_border+2*o); | |
} | |
// lip | |
translate([lid_lip_x_offset,0,height-2]) { | |
translate([0,(depth-2*outer_border+1-0.2)/2,0]) | |
lid_lip(1); | |
translate([0,-(depth-2*outer_border+1-0.2)/2,0]) | |
lid_lip(-1); | |
} | |
// pcb holder | |
translate([lid_pcb_holder_x_offset,0,lid_pcb_holder_z]) | |
center_box(lid_pcb_holder_w,2,height-lid_pcb_holder_z-outer_border+o); | |
} | |
} | |
module lid_lip(dir) { | |
translate([0,0,1]) | |
rotate(270,[0,0,1]) | |
rotate(270,[1,0,0]) | |
linear_extrude(lid_lip_w) | |
polygon([[0,0],[1.5*dir,0],[1.5*dir,1],[0.5*dir,1]]); | |
} | |
module body() { | |
difference() { | |
union() { | |
difference() { | |
center_box(length, depth, height); | |
translate([outer_border,0,outer_border]) | |
center_box(length-2*outer_border+o, depth-2*outer_border+o, height-outer_border+o); | |
jacks(); | |
lid_cutout(); | |
usb_cutout(); | |
button_cutout(); | |
labels(); | |
} | |
jack_guides(); | |
pcb_guides(); | |
button(); | |
leds_base(); | |
} | |
leds_cutout(); | |
} | |
} | |
module lid_cutout() { | |
translate([outer_border,0,height-2]) | |
center_box(pcb_w,depth-2*outer_border+1,1.2); | |
} | |
module usb_cutout() { | |
translate([-o,pcb_y_offset,outer_border+pcb_z_offset+usb_cutout_z_offset-usb_cutout_h]) | |
center_box(outer_border+2*o,usb_cutout_w,usb_cutout_h); | |
} | |
module button_cutout() { | |
translate([button_x,pcb_y_offset,-o]) { | |
cylinder(outer_border+o*2,button_r+button_cut,button_r+button_cut); | |
translate([-button_w,0,0]) | |
center_box(button_w,2*button_r+button_cut*2,outer_border+o*2); | |
} | |
} | |
module button() { | |
translate([button_x,pcb_y_offset,0]) { | |
difference() { | |
union() { | |
cylinder(outer_border+pcb_z_offset-pcb_button_h,button_r,button_r); | |
translate([-button_w,0,0]) { | |
center_box(button_w,2*button_r,outer_border); | |
translate([button_ramp_offset,button_r,outer_border]) | |
rotate(90, [1,0,0]) | |
linear_extrude(2*button_r) | |
right_triangle(button_w-button_ramp_offset,pcb_z_offset-pcb_button_h); | |
} | |
} | |
sphere(button_indent); | |
} | |
} | |
} | |
module jack_guides() { | |
difference() { | |
translate([jack_x-pcb_jack_divider,0,outer_border-o]) | |
center_box(jack_w+pcb_jack_divider+o,depth-2*outer_border+o,height-2*outer_border); | |
translate([jack_x-pcb_jack_divider,0,0]) | |
resize([20,0,0]) | |
translate([-jack_x,0,0]) | |
jacks(); | |
} | |
} | |
module jack(idx) { | |
y_offset=[-jack_y_offset, jack_y_offset][idx]; | |
translate([jack_x,y_offset,outer_border]) { | |
color("#000",0.5) | |
center_box(jack_w,jack_d,jack_h); | |
color("#fff",0.5) | |
translate([jack_w,0,jack_metal_z]) | |
rotate([0,90,0]) | |
cylinder(2+2*o,jack_metal_r,jack_metal_r); | |
} | |
} | |
module jacks() { | |
jack(0); | |
jack(1); | |
} | |
module led_cutout(idx) { | |
y_offset=[-jack_y_offset, jack_y_offset][idx]; | |
translate([led_offset_x,y_offset,0-o]) | |
cylinder(outer_border+led_base_h+2*o,led_cutout_r,led_cutout_r); | |
} | |
module leds_cutout() { | |
led_cutout(0); | |
led_cutout(1); | |
} | |
module led_base(idx) { | |
y_offset=[-jack_y_offset, jack_y_offset][idx]; | |
translate([led_offset_x,y_offset,outer_border]) | |
cylinder(led_base_h,led_base_r,led_base_r); | |
} | |
module leds_base() { | |
led_base(0); | |
led_base(1); | |
} | |
module pcb() { | |
color("#0a0", 0.5) | |
translate([outer_border,pcb_y_offset,outer_border+pcb_z_offset]) | |
center_box(pcb_w,pcb_d,pcb_h); | |
} | |
module pcb_guide() { | |
translate([outer_border,0,outer_border-o]) | |
center_box(pcb_guide_w,pcb_guide_h,pcb_z_offset); | |
} | |
module pcb_guides() { | |
mid_x=(pcb_w-pcb_guide_w)/2.3; | |
top_y=(depth-2*outer_border-pcb_guide_h)/2; | |
bot_y=pcb_y_offset*2-top_y; | |
translate([mid_x*2,top_y,0]) | |
pcb_guide(); | |
translate([mid_x,top_y,0]) | |
pcb_guide(); | |
translate([0,top_y,0]) | |
pcb_guide(); | |
translate([mid_x*2,bot_y,0]) | |
pcb_guide(); | |
translate([mid_x-2.5,bot_y,0]) | |
pcb_guide(); | |
translate([0,bot_y,0]) | |
pcb_guide(); | |
translate([outer_border,pcb_y_offset+outer_border-depth/2,outer_border-o]) | |
center_box(mid_x*2+pcb_guide_w,pcb_y_offset*2,pcb_top); | |
} | |
module labels() { | |
translate([16,0,0-o]) { | |
linear_extrude(height = 0.5) { | |
mirror([0,1,0]) | |
translate([0,-jack_y_offset,0]) | |
text("CLOCK", size=3, valign="center", halign="right", font="Liberation Sans:style=Bold"); | |
mirror([0,1,0]) | |
translate([0,jack_y_offset,0]) | |
text("RUN", size=3, valign="center", halign="right", font="Liberation Sans:style=Bold"); | |
translate([6.3,-jack_y_offset-0.25,0]) | |
square([26,0.5]); | |
translate([6.3,jack_y_offset-0.25,0]) | |
square([26,0.5]); | |
} | |
} | |
} | |
body(); | |
//jacks(); | |
//pcb(); | |
lid(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// =============================================================== | |
// MIDI to 24 PPQN Clock + Run (USB MIDI) - Teensy LC Firmware | |
// "Cowboy" Ben Alman, 2022 | |
// https://gist.github.com/cowboy/1af3a69d4b6cae6a099fcf76431bda02 | |
// =============================================================== | |
// To give your project a unique name, this code must be | |
// placed into a .c file (its own tab). It can not be in | |
// a .cpp file or your main sketch (the .ino file). | |
#include "usb_names.h" | |
// Edit these lines to create your own name. The length must | |
// match the number of characters in your custom name. | |
#define MIDI_NAME {'C', 'o', 'w', 'b', 'o', 'y', ' ', 'C', 'l', 'o', 'c', 'k', ' ', '+', ' ', 'R', 'u', 'n'} | |
#define MIDI_NAME_LEN 18 | |
// Do not change this part. This exact format is required by USB. | |
struct usb_string_descriptor_struct usb_string_product_name = { | |
2 + MIDI_NAME_LEN * 2, | |
3, | |
MIDI_NAME | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Videos
Prototype: https://www.instagram.com/p/CeG2_JkDAA0/
Final version: https://www.instagram.com/p/CePUMbxDVG4/
BOM
1x Teensy LC
2x PJ301CM 3.5mm jacks (not using them as stereo, just mono)
1x 3mm Green LED
1x 3mm Orange LED
1x 47 ohm resistor
1x 330 ohm resistor
Bottom, showing Teensy LC + 2x 3.5mm jacks
Top, showing 2x 3mm LEDs
Iterations...