Parcourir la source

add starting files for the design...

main
John-Mark Gurney il y a 3 ans
Parent
révision
c5405fae48
5 fichiers modifiés avec 674 ajouts et 0 suppressions
  1. +1
    -0
      rack.bracket/LICENSE.txt
  2. +1
    -0
      rack.bracket/README.txt
  3. +221
    -0
      rack.bracket/raspberry-pi-rack-ears.scad
  4. +255
    -0
      rack.bracket/raspberry-pi-rack-frame.scad
  5. +196
    -0
      rack.bracket/raspberry-pi-rack-tray.scad

+ 1
- 0
rack.bracket/LICENSE.txt Voir le fichier

@@ -0,0 +1 @@
This thing was created by Thingiverse user russross, and is licensed under cc-nc.

+ 1
- 0
rack.bracket/README.txt Voir le fichier

@@ -0,0 +1 @@
Raspberry Pi 4 2U rack-mount bracket by russross on Thingiverse: https://www.thingiverse.com/thing:4078710

+ 221
- 0
rack.bracket/raspberry-pi-rack-ears.scad Voir le fichier

@@ -0,0 +1,221 @@
/* [Bolt holes in the corners] */

// Pick the size of the long threaded rods that run through
// the corners and hold everything together.
//
// These are the sizes that are commonly available at
// Home Depot or Lowes:
//
// 1/4 inch: 3.175
// #12 : 2.778125
// #10 : 2.38125 (default and recommended)
//
// Note: you should pick the same size and fudge factor
// for the frame parts.
bolt_size = 2.38125;

// Make the bolt holes this much bigger than the size of the bolt
// to give a more comfortable fit
bolt_hole_fudge = 0.2; // [0:0.25:1]


/* [Notches for attaching to the frame parts] */

// You can optionally omit the notches for one ear that will
// join with a frame on the side that has no tabs.
// For the the other you should leave this at its default of true.
notches_enabled = true;

// Make the slot this much taller than the tabs
// to give a more comfortable fit.
notch_fudge = 0.3; // [0:0.25:1]


/* [Bolt holes for mounting to the rack] */

// The size of the bolt holes for mounting to the server rack.
// The default is for M6 bolts.
ear_bolt_size = 3;

// Make the ear bolt holes this much longer than they are wide
// in case the entire assembled rack is not precisely the right
// length.
ear_bolt_stretch = 3;


/* [Hidden] */

width = 82;
length = 90;
height = 5;
frame_width = 15.875;
distance_to_frame = 10;
distance_between_bolt_holes = 15.875 * 2 + 12.7;
ear_height = distance_to_frame + frame_width;

notch_height = 2;
outer_wall_thickness = 12;
inner_wall_thickness = 7;
back_wall_thickness = 5;
wall_diff = outer_wall_thickness - inner_wall_thickness;
floor_depth = 3;
tray_depth = 5;
tray_slot_depth = 2.5;
spacer_depth = 3;
epsilon = 0.001;

sd_window_width = 40;
sd_window_height = height - (tray_depth + floor_depth)*2;
near_pillar_width = 15;
far_pillar_width = 10;
floor_window_width = sd_window_width;
floor_window_border = (width - floor_window_width - outer_wall_thickness*2) / 2;
floor_window_length = length - back_wall_thickness - floor_window_border*2;
port_window_width = length - near_pillar_width - far_pillar_width;
port_window_frame_height = floor_depth + tray_depth + spacer_depth - notch_height;

bolt_radius = bolt_size + bolt_hole_fudge;

ear_bolt_radius = ear_bolt_size + bolt_hole_fudge;
floor_mini_window_width = (floor_window_width - floor_window_border) / 2;
floor_mini_window_length = (floor_window_length - floor_window_border) / 2;

difference() {
union() {
// the main tray block
translate([0, -epsilon, 0]) {
cube([width, length + epsilon, height]);
}
// the ear
translate([0, -height, 0]) {
cube([width, height, ear_height]);
}
// reinforce the joint
translate([0, 0, 0]) {
rotate([45, 0, 0]) {
cube([width, height-0.5, height-0.5]);
}
}
translate([ (width - distance_between_bolt_holes)/2 - ear_bolt_radius, 0, 0]) {
rotate([45, 0, 0]) {
cube([distance_between_bolt_holes + 2*ear_bolt_radius, height+1, height+1]);
}
}
}
// cut the bolt holes
for (a=[[outer_wall_thickness/2, near_pillar_width/2],
[outer_wall_thickness/2, length - far_pillar_width/2],
[width - outer_wall_thickness/2, near_pillar_width/2],
[width - outer_wall_thickness/2, length - far_pillar_width/2]]) {
translate([a[0], a[1], -epsilon]) {
cylinder( h=height + 2*epsilon,
r=bolt_radius,
center=false,
$fn=360);
}
}

// make the sides thinner
polyhedron(
points = [
[ wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon],
[ wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon],
[ wall_diff, length-far_pillar_width-wall_diff, -epsilon],
[ wall_diff, near_pillar_width+wall_diff, -epsilon],
[-wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon],
[-wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon],
[-wall_diff, length-far_pillar_width+wall_diff, -epsilon],
[-wall_diff, near_pillar_width-wall_diff, -epsilon]
],
faces = [
[1,0,2,3],
[4,5,7,6],
[0,4,6,2],
[6,7,3,2],
[7,5,1,3],
[5,4,0,1]
],
convexity = 10);
polyhedron(
points = [
[width-wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon],
[width-wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon],
[width-wall_diff, near_pillar_width+wall_diff, -epsilon],
[width-wall_diff, length-far_pillar_width-wall_diff, -epsilon],
[width+wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon],
[width+wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon],
[width+wall_diff, near_pillar_width-wall_diff, -epsilon],
[width+wall_diff, length-far_pillar_width+wall_diff, -epsilon]
],
faces = [
[1,0,2,3],
[4,5,7,6],
[0,4,6,2],
[6,7,3,2],
[7,5,1,3],
[5,4,0,1]
],
convexity = 10);

if (notches_enabled) {
// cut the notches
translate([ wall_diff - epsilon,
near_pillar_width + wall_diff,
-epsilon]) {
cube([ inner_wall_thickness-2 + epsilon,
length - near_pillar_width - far_pillar_width - 2*wall_diff,
notch_height + notch_fudge + epsilon]);
}
translate([ width - wall_diff - (inner_wall_thickness-2),
near_pillar_width + wall_diff,
-epsilon]) {
cube([ inner_wall_thickness-2 + epsilon,
length - near_pillar_width - far_pillar_width - 2*wall_diff,
notch_height + notch_fudge + epsilon]);
}
}
// cut some mini windows in the floor
for (a=[[outer_wall_thickness + floor_window_border,
floor_window_border],
[width - outer_wall_thickness - floor_window_border - floor_mini_window_width,
floor_window_border],
[outer_wall_thickness + floor_window_border,
2*floor_window_border + floor_mini_window_length],
[width - outer_wall_thickness - floor_window_border - floor_mini_window_width,
2*floor_window_border + floor_mini_window_length]]) {
translate([a[0], a[1], -epsilon]) {
cube([ floor_mini_window_width,
floor_mini_window_length,
height + 2*epsilon]);
}
}
// cut the bolt holes on the ear
for (a=[ width/2 - distance_between_bolt_holes/2,
width/2 + distance_between_bolt_holes/2]) {
for (b=[-ear_bolt_stretch/2, ear_bolt_stretch/2]) {
translate([ a,
-height-epsilon,
ear_height - frame_width/2 + b]) {
rotate([-90,0,0]) {
cylinder( h=height + 2*epsilon,
r=ear_bolt_radius,
center=false,
$fn=360);
}
}
}
translate([ a - ear_bolt_radius,
-height-epsilon,
ear_height - frame_width/2 - ear_bolt_stretch/2]) {
cube([ ear_bolt_radius*2,
height + 2*epsilon,
ear_bolt_stretch]);
}
}
}

+ 255
- 0
rack.bracket/raspberry-pi-rack-frame.scad Voir le fichier

@@ -0,0 +1,255 @@
/* [Bolt holes in the corners] */

// Pick the size of the long threaded rods that run through
// the corners and hold everything together.
//
// These are the sizes that are commonly available at
// Home Depot or Lowes:
//
// 1/4 inch: 3.175
// #12 : 2.778125
// #10 : 2.38125 (default and recommended)
//
// Note: you should pick the same size and fudge factor
// for the ear parts.
bolt_size = 2.38125;

// Make the bolt holes this much bigger than the size of the bolt
// to give a more comfortable fit
bolt_hole_fudge = 0.2; // [0:0.25:1]


/* [Notches and tabs for stacking] */

// You can optionally omit the notches for the frame on the end
// that joins with an ear with no tabs. For all of the others
// you should leave this at its default of true.
notches_enabled = true;

// Make the slot this much taller than the tabs
// to give a more comfortable fit.
notch_fudge = 0.3; // [0:0.25:1]


/* [Size] */

// The default is to fit 12 units with PoE hats in a standard rack.
// 12 is a good fit, and it works nicely with many PoE switches, which
// often come with 12 or 24 ports. You can bump it up to 13 units and
// they will still fit nicely with PoE hats, or you can go up to 14
// of you are not using the hats.
number_to_fit = 12; // [12:Relaxed fit, 13:Using PoE, 14:Without PoE hats]

/* [Hidden] */
// make the screw holes this much bigger than the
// actual screw for a more comfortable fit
// (a bigger number here will make the screws fit looser)
screw_hole_fudge = 0.15;

height = (450.85 - 20) / number_to_fit;

width = 82;
length = 90;

// The height of the notches and tabs
notch_height = 2;

// epsilon is used to slightly overlap pieces to help the previewer
epsilon = 0.001;

bolt_radius = bolt_size + bolt_hole_fudge;

outer_wall_thickness = 12;
inner_wall_thickness = 7;
back_wall_thickness = 5;
wall_diff = outer_wall_thickness - inner_wall_thickness;
floor_depth = 3;
tray_depth = 5;
tray_slot_depth = 2.5;
spacer_depth = 3;

sd_window_width = 40;
sd_window_height = height - (tray_depth + floor_depth)*2;
near_pillar_width = 15;
far_pillar_width = 10;
floor_window_width = sd_window_width;
floor_window_border = (width - floor_window_width - outer_wall_thickness*2) / 2;
floor_window_length = length - back_wall_thickness - floor_window_border*2;
port_window_width = length - near_pillar_width - far_pillar_width;
port_window_frame_height = floor_depth + tray_depth + spacer_depth - notch_height;

difference() {
union() {
// the main block
cube([width, length, height]);
// the tabs
translate([ wall_diff,
near_pillar_width + wall_diff,
height - epsilon]) {
cube([ inner_wall_thickness - 2,
length - near_pillar_width - far_pillar_width - wall_diff*2,
notch_height + epsilon]);
}
translate([ width - outer_wall_thickness + 2,
near_pillar_width + wall_diff,
height - epsilon]) {
cube([ inner_wall_thickness - 2,
length - near_pillar_width - far_pillar_width - wall_diff*2,
notch_height + epsilon]);
}
}

// carve out the interior
translate([outer_wall_thickness, -epsilon, floor_depth]) {
cube( [width - outer_wall_thickness*2,
length - back_wall_thickness + epsilon,
height + notch_height - floor_depth + epsilon]);
}

// punch a hole for the sd card
translate([ (width - sd_window_width) / 2,
length - back_wall_thickness - epsilon,
tray_depth + floor_depth]) {
cube([ sd_window_width,
back_wall_thickness + 2*epsilon,
height - port_window_frame_height - tray_depth - floor_depth + notch_height]);
}

// punch a hole for side port access
translate([ -epsilon,
near_pillar_width,
port_window_frame_height + notch_height]) {
cube([ width + 2*epsilon,
port_window_width,
height - port_window_frame_height*2]);
}

// punch a hole in the bottom
translate([ outer_wall_thickness + floor_window_border,
floor_window_border,
-epsilon]) {
cube([ floor_window_width,
floor_window_length,
floor_depth + 2*epsilon]);
}
// open a groove that the speaker jack can slide through
translate([ outer_wall_thickness - 2,
-epsilon,
port_window_frame_height + notch_height]) {
cube([ 2 + epsilon,
near_pillar_width + 2*epsilon,
8]);
}
// soften the leading edge a bit
translate([ outer_wall_thickness,
0,
floor_depth-0.5]) {
rotate([25,0,0]) {
cube([ width - outer_wall_thickness*2,
2,
2]);
}
}

if (notches_enabled) {
// cut the notches in the bottom
translate([ -epsilon,
near_pillar_width + wall_diff,
-epsilon]) {
cube([ outer_wall_thickness - 2 + epsilon,
length - near_pillar_width - far_pillar_width - wall_diff*2,
notch_height + notch_fudge + epsilon]);
}
translate([ width - outer_wall_thickness + 2,
near_pillar_width + wall_diff,
-epsilon]) {
cube([ outer_wall_thickness - 2 + epsilon,
length - near_pillar_width - far_pillar_width - wall_diff*2,
notch_height + notch_fudge + epsilon]);
}
}

// cut out the sides to make them thinner
polyhedron(
points = [
[ wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon],
[ wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon],
[ wall_diff, length-far_pillar_width-wall_diff, -epsilon],
[ wall_diff, near_pillar_width+wall_diff, -epsilon],
[-wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon],
[-wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon],
[-wall_diff, length-far_pillar_width+wall_diff, -epsilon],
[-wall_diff, near_pillar_width-wall_diff, -epsilon]
],
faces = [
[1,0,2,3],
[4,5,7,6],
[0,4,6,2],
[6,7,3,2],
[7,5,1,3],
[5,4,0,1]
],
convexity = 10);
polyhedron(
points = [
[width-wall_diff, near_pillar_width+wall_diff, height+notch_height+epsilon],
[width-wall_diff, length-far_pillar_width-wall_diff, height+notch_height+epsilon],
[width-wall_diff, near_pillar_width+wall_diff, -epsilon],
[width-wall_diff, length-far_pillar_width-wall_diff, -epsilon],
[width+wall_diff, near_pillar_width-wall_diff, height+notch_height+epsilon],
[width+wall_diff, length-far_pillar_width+wall_diff, height+notch_height+epsilon],
[width+wall_diff, near_pillar_width-wall_diff, -epsilon],
[width+wall_diff, length-far_pillar_width+wall_diff, -epsilon]
],
faces = [
[1,0,2,3],
[4,5,7,6],
[0,4,6,2],
[6,7,3,2],
[7,5,1,3],
[5,4,0,1]
],
convexity = 10);

// drill the bolt holes
for (a=[[outer_wall_thickness/2, near_pillar_width/2],
[outer_wall_thickness/2, length - far_pillar_width/2],
[width - outer_wall_thickness/2, near_pillar_width/2],
[width - outer_wall_thickness/2, length - far_pillar_width/2]]) {
translate([a[0], a[1], -epsilon]) {
cylinder( h=height + notch_height + 2*epsilon,
r=bolt_radius,
center=false,
$fn=360);
}
}

// cut the tray insert slots
// note: the tray will be slightly narrower to
// give a more comfortable fit. If it is too loose or too tight,
// adjust the tray.
for (a=[ outer_wall_thickness,
width - outer_wall_thickness]) {
translate([ a,
-epsilon,
floor_depth + tray_depth/2]) {
intersection() {
rotate([0, 45, 0]) {
translate([-tray_depth/sqrt(2)/2, 0, -tray_depth/sqrt(2)/2]) {
cube([ tray_depth/sqrt(2),
length - back_wall_thickness + epsilon,
tray_depth/sqrt(2)]);
}
}
translate([-tray_depth/2+0.5, 0, -tray_depth/2]) {
cube([ tray_depth-1,
length - back_wall_thickness + epsilon,
tray_depth]);
}
}
}
}
}

+ 196
- 0
rack.bracket/raspberry-pi-rack-tray.scad Voir le fichier

@@ -0,0 +1,196 @@
/* [Screw holes for attaching the Raspberry Pi 4] */

// Make the screw holes this much bigger than the
// actual screw for a more comfortable fit
// (a bigger number here will make the screws fit looser)
screw_hole_fudge = 0.15; // [0:0.05:0.5]

/* [Tray width] */

// Make the tray this much narrower on each side
// for a more comfortable fit in the frame
// (a bigger number here will make the fit looser)
tray_insert_fudge = 0.25; // [0:0.05:0.75]

/* [Hidden] */

tray_width = 58;
tray_length = 85;
tray_depth = 5;
tray_lip_overhang = 10;
inner_wall_thickness = 5;
spacer_depth = 3;
spacer_outer_radius = 3;

screw_radius = 1.25 + screw_hole_fudge;
screw_head_radius = 3;
screw_head_depth = 2;
pcb_depth = 2;
spacer_center_width = 49;
spacer_center_length = 58;
spacer_from_edge = (tray_width - spacer_center_width) / 2;

sd_window_width = 40;
floor_window_width = sd_window_width;
floor_window_border = (tray_width - floor_window_width) / 2;
floor_window_length = tray_length - floor_window_border*2 - inner_wall_thickness;

epsilon = 0.001;

difference() {
union() {
// the main tray
intersection() {
union() {
translate([tray_insert_fudge, 0, 0]) {
cube([ tray_width - 2*tray_insert_fudge,
tray_length + tray_lip_overhang,
tray_depth]);
}
difference() {
// the outer part of the curved handle
translate([ tray_width/2,
-tray_length*0.5 + 7.5,
0]) {
cylinder(
h=tray_depth + spacer_depth + pcb_depth,
r=tray_length*1.5,
center=false,
$fn=360);
}
// cut away the inside to make it a shell
translate([ tray_width/2,
-tray_length*0.5 + 5.4,
-epsilon]) {
cylinder(
h=tray_depth + spacer_depth + pcb_depth + 2*epsilon,
r=tray_length*1.5,
center=false,
$fn=360);
}
translate([ tray_width,
-tray_length,
-epsilon]) {
cube([ 2*tray_width,
3*tray_length,
tray_depth + spacer_depth + pcb_depth + 2*epsilon]);
}
translate([ -2*tray_width,
-tray_length,
-epsilon]) {
cube([ 2*tray_width,
3*tray_length,
tray_depth + spacer_depth + pcb_depth + 2*epsilon]);
}
}
// reinforce the curved handle
translate([epsilon, tray_length, tray_depth]) {
rotate([-75, 0, 0]) {
cube([tray_width - 2*epsilon, 2*sqrt(2), 6]);
}
}
}
// cut away the ears of the tray
// where they jut through the curved handle
translate([ tray_width/2,
-tray_length*0.5 + 7.5,
0]) {
cylinder(
h=tray_depth + spacer_depth + pcb_depth,
r=tray_length*1.5,
center=false,
$fn=360);
}
}
// place the 4 spacers
for (a=[ [spacer_from_edge,
spacer_from_edge],
[spacer_from_edge + spacer_center_width,
spacer_from_edge],
[spacer_from_edge,
spacer_from_edge + spacer_center_length],
[spacer_from_edge + spacer_center_width,
spacer_from_edge + spacer_center_length]]) {
translate([a[0], a[1], tray_depth-epsilon]) {
// place the spacer
cylinder(
h=spacer_depth + epsilon,
r=spacer_outer_radius,
center=false,
$fn=360);

// place a small cone around it
cylinder(
h=2 + epsilon,
r1=spacer_outer_radius + 1,
r2=spacer_outer_radius,
center=false,
$fn=360);
}
}

// the tray insert edge tabs
for (a=[ tray_insert_fudge,
tray_width - tray_insert_fudge]) {
translate([ a,
0,
tray_depth/2]) {
intersection() {
rotate([0, 45, 0]) {
translate([-tray_depth/sqrt(2)/2, 0, -tray_depth/sqrt(2)/2]) {
cube([ tray_depth/sqrt(2),
tray_length,
tray_depth/sqrt(2)]);
}
}
translate([-tray_depth/2+0.5, 0, -tray_depth/2]) {
cube([ tray_depth-1,
tray_length,
tray_depth]);
}
}
}
}
}

// punch a hole in the bottom
translate([ floor_window_border,
floor_window_border,
-epsilon]) {
cube([ floor_window_width,
floor_window_length,
tray_depth + 2*epsilon]);
}
// drill the 4 screw holes
for (a=[ [spacer_from_edge,
spacer_from_edge],
[spacer_from_edge + spacer_center_width,
spacer_from_edge],
[spacer_from_edge,
spacer_from_edge + spacer_center_length],
[spacer_from_edge + spacer_center_width,
spacer_from_edge + spacer_center_length]]) {
translate([a[0], a[1], -epsilon]) {
// drill the main screw hole
cylinder(
h=tray_depth + spacer_depth + 2*epsilon,
r=screw_radius,
center=false,
$fn=360);

// drill a recessed hole for the screw head
cylinder(
h=screw_head_depth + epsilon,
r=screw_head_radius,
center=false,
$fn=360);
}
}
}

Chargement…
Annuler
Enregistrer