Compare commits

...

11 Commits
v1.0 ... master

Author SHA1 Message Date
Sebastian 492021bea2 Merge branch 'master' of github.com:LongHairedHacker/fmp-capsule 2017-01-11 00:37:24 +01:00
Sebastian 8b1fbf7b5d Fixed wrong path 2017-01-11 00:36:08 +01:00
Sebastian 22b1057220 Update README.md
Added note about support
2016-12-05 19:35:30 +01:00
Sebastian b830ed33ee Seperated handle and lid for faster rendering
Moved stls to own directory
Updated readme
2016-12-01 16:15:24 +01:00
Sebastian 5915e55702 Updated lid.stl 2016-08-03 20:00:00 +02:00
Sebastian 66f6fa529e Semifinal version of mark II 2016-08-03 19:57:55 +02:00
Sebastian a5b199c549 Added new handle 2016-08-01 12:51:03 +02:00
Sebastian 68bdb9268a First prototype 2016-08-01 11:58:41 +02:00
Sebastian b5b5787b94 First version with bayonet mount 2016-05-03 19:10:09 +02:00
Sebastian 45ba6a95a5 First version of top lid 2016-04-19 01:14:56 +02:00
Sebastian 71f20287b0 Started work an a possibly better version 2016-04-18 22:37:53 +02:00
21 changed files with 641822 additions and 189181 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
gcode

View File

@ -1,4 +1,11 @@
all: top.stl lid.stl bottom.stl
all: stl/top.stl stl/lid.stl stl/bottom.stl
%.stl: %.scad constants.scad cap.scad
stl/%.stl: %.scad constants.scad
@mkdir -p $$(dirname $@)
openscad -o $@ $<
stl/lid.stl: bayonetmount.scad support.scad stl/handle.stl
stl/top.stl: bayonetmount.scad support.scad
clean:
rm stl/*.stl

View File

@ -8,16 +8,20 @@ The fmp is a simpler 3D-printable capsule for the
How to build it
---------------
1. Go to a hardware store of choice
2. Try to get some M3 screws and nuts
2. Try to get some 2 component epoxy and nuts
and some plastic tubing with an inner diameter of 70mm (*DN75 HT-Rohr* works fine).
3. Fire up your 3D-Printer and print the lid, top
and bottom segment of the capsule.
20-25% Infill works fine and provides enough stability.
4. Cut about 150mm long piece of tube.
5. Press M3 nuts into the top and bottom cap.
6. Drill the holes into the tube.
7. Put everything together.
8. Go get some Mate or something ...
Also you should be able to print them without support material.
The models already contain all necessary support structures.
4. Remove the support structure (marked red) from lid and top.
![Top part with support](./images/top.png) ![Lid with support](./images/lid.png)
5. Clean up the latches on the lid and the channels on the top part.
Make sure the lid fits well (the latches may need to be filed down).
6. Cut about 150mm long piece of tube.
7. Glue top end bottom to the tube piece using 2 component epoxy.
8. Go get some Mate or something, while the epoxy sets...
Suggestions ?

63
bayonetmount.scad Normal file
View File

@ -0,0 +1,63 @@
module lid(outer_diameter,
inner_diameter,
latch_width,
latch_height,
lid_height) {
translate([0,0, latch_height / 2])
intersection() {
cube([outer_diameter,
latch_width,
latch_height],
center = true);
cylinder(r = outer_diameter / 2,
h = latch_height,
center = true);
}
cylinder(r = inner_diameter / 2, h = lid_height);
}
module hole(outer_diameter,
inner_diameter,
latch_width,
latch_height,
lid_height) {
translate([0, 0, lid_height / 2])
intersection() {
cube([outer_diameter,
latch_width,
lid_height],
center = true);
cylinder(r = outer_diameter / 2,
h = lid_height,
center = true);
}
translate([0, 0, latch_height / 2])
difference() {
cylinder(r = outer_diameter / 2,
h = latch_height,
center = true);
for(pos = [outer_diameter / 4, -outer_diameter / 4])
translate([pos, pos, 0])
cube([outer_diameter / 2,
outer_diameter / 2,
latch_height],
center=true);
}
translate([0,0, lid_height / 2])
cylinder(r = inner_diameter / 2,
h = lid_height,
center = true);
}

View File

@ -1,13 +1,28 @@
include <constants.scad>
use <cap.scad>
include <constants.scad>;
difference() {
translate([0, 0, bumper_height / 2])
minkowski() {
radius = bumper_diameter / 2 - bumper_edge_radius;
height = bumper_height - 2 * bumper_edge_radius;
cylinder(r = radius, h = height, center = true);
sphere(r = bumper_edge_radius, center = true);
}
translate([0, 0, lid_height / 2])
cylinder(r = tube_inner_diameter / 2,
h = lid_height,
center = true);
translate([0, 0, bumper_tube_depth / 2])
cylinder(r = tube_outer_diameter / 2,
h = bumper_tube_depth,
center = true);
}
cap();
// Make the cap hollow
translate([0, 0, -1.5 * height_unit])
cylinder(r = body_hole_diameter / 2,
h = 4 * height_unit + 0.1,
center = true);
}

23970
bottom.stl

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
include <constants.scad>;
module cap() {
difference() {
// Actual cap
union() {
// Bumper
cylinder(r = bumper_diameter / 2,
h = height_unit,
center = true);
// Lower cone
translate([0, 0, - 1.5 * height_unit])
cylinder(r2 = bumper_diameter / 2,
r1 = body_diameter /2,
h = height_unit * 2,
center = true);
// Upper cone
translate([0, 0, height_unit])
cylinder(r1 = bumper_diameter / 2,
r2 = body_diameter /2,
h = height_unit,
center = true);
// End piece that goes into the tube
translate([0, 0, -2.5 * height_unit])
cylinder(r = body_diameter / 2,
h = 2 * height_unit,
center = true);
}
// Make a grove to slide the tube into
#translate([0, 0, -1.75 * height_unit])
difference() {
cylinder(r = tube_outer_diameter / 2,
h = 1.5 * height_unit,
center = true);
cylinder(r = body_diameter / 2,
h = 1.5 * height_unit + 0.1,
center = true);
}
// Make the end piece of the cap hollow
translate([0, 0, -2.5 * height_unit])
cylinder(r = body_hole_diameter / 2,
h = 2 * height_unit + 0.1,
center = true);
// Place the nuts
nut_y_offset = body_diameter / 2
- (body_diameter/2 - body_hole_diameter/2)
+ m3nut_depth / 2 - 0.5;
for(angle = [0, 90, 180, 270]) {
rotate([0,0,angle])
translate([0,
nut_y_offset,
- 2.5 * height_unit])
rotate([90, 0 ,0])
//This is one nut and the hole attched to it
union() {
cylinder(r = m3nut_diameter / 2,
h = m3nut_depth,
center = true,
$fn = 6);
translate([0, 0, -m3hole_depth / 2 -m3nut_depth / 2])
cylinder(r = m3hole_diameter / 2,
h = m3hole_depth + 0.1,
center = true);
};
}
}
}
cap();

View File

@ -1,25 +1,29 @@
$fn = 90;
bumper_diameter = 85;
body_diameter = 70;
body_hole_diameter = body_diameter - 10;
tube_inner_diameter = 71;
tube_outer_diameter = 76;
m3nut_diameter = 6.5;
m3nut_depth = 3.6;
// Lid
lid_height = 10;
lid_depth = 7.5;
latch_width = 20;
latch_height = 5;
brim_height = 2.5;
m3hole_diameter = 3.5;
m3hole_depth = (body_diameter - body_hole_diameter) / 2 - m3nut_depth + 0.5;
handle_length = 75;
handle_thickness = 10;
handle_height = 15;
handle_max_width = 30;
handle_min_width = 10;
handle_minkowski_dia = 5;
// Top
bumper_height = 15;
bumper_diameter = 85;
// Flat surface starts after bumper_edge_radius from the outside
bumper_edge_radius = bumper_diameter - tube_outer_diameter - 4;
bumper_tube_depth = 5;
height_unit = 5;
thread_diameter = body_diameter - 12;
thread_hole_diameter = thread_diameter - 5;
thread_pitch = 4;
thread_lenght_top = 12.5;
thread_lenght_lid = 7.5;
thread_tolerance = 0.25;
lid_diameter = body_diameter - 5;
lid_tolerance = 0.1;

39
handle.scad Normal file
View File

@ -0,0 +1,39 @@
include <constants.scad>;
module handle() {
center_offset = (handle_length / 2)
- handle_height;
// Doesn't make much sense but gives nice proportions
handle_bevel_radius = 2 * handle_length - handle_min_width;
rotate([-90, 0, 0])
minkowski() {
translate([0, center_offset, 0])
difference() {
cylinder(d = handle_length,
h = handle_max_width,
center = true);
cylinder(d = handle_length - handle_thickness,
h = handle_max_width,
center = true);
translate([0, handle_height, 0])
cube([handle_length,
handle_length,
handle_max_width
],
center = true);
for(z = [-handle_length, handle_length])
translate([0, -center_offset, z])
rotate([90,0,0])
cylinder(d = handle_bevel_radius,
h =handle_max_width);
}
sphere(d = handle_minkowski_dia, center = true);
}
}
handle();

BIN
images/lid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
images/top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -1,56 +1,32 @@
include <constants.scad>;
include <bayonetmount.scad>;
include <support.scad>;
use <cap.scad>;
use <threads.scad>;
delta = 0.75;
module thread() {
intersection() {
metric_thread(thread_diameter - thread_tolerance,
thread_pitch,
thread_lenght_lid);
union() {
translate([0, 0, 0.5 * height_unit])
cylinder(r = thread_diameter / 2,
h = thread_lenght_lid - 0.5 * height_unit);
cylinder(r2 = thread_diameter / 2,
r1 = thread_diameter / 2 - height_unit,
h = 0.5 * height_unit);
}
difference() {
union() {
lid(tube_outer_diameter - delta * 2,
tube_inner_diameter - delta * 2,
latch_width - delta,
latch_height - delta,
lid_height - delta);
translate([0, 0, lid_height])
import("stl/handle.stl");
translate([0, 0, lid_height - brim_height / 2])
cylinder(r = tube_outer_diameter / 2,
h = brim_height,
center = true);
}
}
difference() {
union() {
translate([0, 0, 0.25 * height_unit])
cylinder(r = lid_diameter / 2,
h=0.5 * height_unit,
center=true);
translate([0, 0, -thread_lenght_lid])
thread();
}
union() {
for(pos = [-3 * height_unit, 3 * height_unit]) {
translate([pos, 0, height_unit])
sphere(r = 1.5 * height_unit, center=true);
}
translate([0, 0, height_unit])
rotate([0, 90, 0])
cylinder(r = 1.5 * height_unit, h=6 * height_unit, center=true);
}
//Make the thread hollow
translate([0, 0, - 1.5 * height_unit])
cylinder(r = thread_diameter / 2 - 5,
h = 1.5 * height_unit + 0.01,
center=true);
translate([0, 0, lid_height /2]) {
color("red")
support(tube_outer_diameter, lid_height);
color("red")
support(tube_outer_diameter * 0.96, lid_height);
}

82000
lid.stl

File diff suppressed because it is too large Load Diff

119618
stl/bottom.stl Normal file

File diff suppressed because it is too large Load Diff

219270
stl/handle.stl Normal file

File diff suppressed because it is too large Load Diff

176304
stl/lid.stl Normal file

File diff suppressed because it is too large Load Diff

126394
stl/top.stl Normal file

File diff suppressed because it is too large Load Diff

12
support.scad Normal file
View File

@ -0,0 +1,12 @@
module support(outer_diameter, height) {
inner_diameter = outer_diameter - 0.5;
difference() {
cylinder(r = outer_diameter / 2,
h = height,
center=true);
cylinder(r = inner_diameter / 2,
h = height * 1.01,
center = true);
}
}

View File

@ -1,312 +0,0 @@
/*
* ISO-standard metric threads, following this specification:
* http://en.wikipedia.org/wiki/ISO_metric_screw_thread
*
* Dan Kirshner - dan_kirshner@yahoo.com
*
* You are welcome to make free use of this software. Retention of my
* authorship credit would be appreciated.
*
* Version 1.7. 2015-11-28 Larger x-increment - for small-diameters.
* Version 1.6. 2015-09-01 Options: square threads, rectangular threads.
* Version 1.5. 2015-06-12 Options: thread_size, groove.
* Version 1.4. 2014-10-17 Use "faces" instead of "triangles" for polyhedron
* Version 1.3. 2013-12-01 Correct loop over turns -- don't have early cut-off
* Version 1.2. 2012-09-09 Use discrete polyhedra rather than linear_extrude ()
* Version 1.1. 2012-09-07 Corrected to right-hand threads!
*/
// Examples.
//
// Standard M8 x 1.
// metric_thread (diameter=8, pitch=1, length=4);
// Square thread.
// metric_thread (diameter=8, pitch=1, length=4, square=true);
// Non-standard: long pitch, same thread size.
//metric_thread (diameter=8, pitch=4, length=4, thread_size=1, groove=true);
// Non-standard: 20 mm diameter, long pitch, square "trough" width 3 mm,
// depth 1 mm.
//metric_thread (diameter=20, pitch=8, length=16, square=true, thread_size=6,
// groove=true, rectangle=0.333);
// English: 1/4 x 20.
//english_thread (diameter=1/4, threads_per_inch=20, length=1);
// Thread for mounting on Rohloff hub.
//difference () {
// cylinder (r=20, h=10, $fn=100);
//
// metric_thread (diameter=34, pitch=1, length=10, internal=true, n_starts=6);
//}
// ----------------------------------------------------------------------------
function segments (diameter) = min (50, ceil (diameter*6));
// ----------------------------------------------------------------------------
// internal - true = clearances for internal thread (e.g., a nut).
// false = clearances for external thread (e.g., a bolt).
// (Internal threads should be "cut out" from a solid using
// difference ()).
// n_starts - Number of thread starts (e.g., DNA, a "double helix," has
// n_starts=2). See wikipedia Screw_thread.
// thread_size - (non-standard) size of a single thread "V" - independent of
// pitch. Default: same as pitch.
// groove - (non-standard) subtract inverted "V" from cylinder (rather than
// add protruding "V" to cylinder).
// square - Square threads (per
// https://en.wikipedia.org/wiki/Square_thread_form).
// rectangle - (non-standard) "Rectangular" thread - ratio depth/width
// Default: 1 (square).
module metric_thread (diameter=8, pitch=1, length=1, internal=false, n_starts=1,
thread_size=-1, groove=false, square=false, rectangle=0)
{
// thread_size: size of thread "V" different than travel per turn (pitch).
// Default: same as pitch.
local_thread_size = thread_size == -1 ? pitch : thread_size;
local_rectangle = rectangle ? rectangle : 1;
n_segments = segments (diameter);
h = (square || rectangle) ? local_thread_size*local_rectangle/2 : local_thread_size * cos (30);
h_fac1 = (square || rectangle) ? 0.90 : 0.625;
// External thread includes additional relief.
h_fac2 = (square || rectangle) ? 0.95 : 5.3/8;
if (! groove) {
metric_thread_turns (diameter, pitch, length, internal, n_starts,
local_thread_size, groove, square, rectangle);
}
difference () {
// Solid center, including Dmin truncation.
if (groove) {
cylinder (r=diameter/2, h=length, $fn=n_segments);
} else if (internal) {
cylinder (r=diameter/2 - h*h_fac1, h=length, $fn=n_segments);
} else {
// External thread.
cylinder (r=diameter/2 - h*h_fac2, h=length, $fn=n_segments);
}
if (groove) {
metric_thread_turns (diameter, pitch, length, internal, n_starts,
local_thread_size, groove, square, rectangle);
}
}
}
// ----------------------------------------------------------------------------
// Input units in inches.
// Note: units of measure in drawing are mm!
module english_thread (diameter=0.25, threads_per_inch=20, length=1,
internal=false, n_starts=1, thread_size=-1, groove=false,
square=false, rectangle=0)
{
// Convert to mm.
mm_diameter = diameter*25.4;
mm_pitch = (1.0/threads_per_inch)*25.4;
mm_length = length*25.4;
echo (str ("mm_diameter: ", mm_diameter));
echo (str ("mm_pitch: ", mm_pitch));
echo (str ("mm_length: ", mm_length));
metric_thread (mm_diameter, mm_pitch, mm_length, internal, n_starts,
thread_size, groove, square, rectangle);
}
// ----------------------------------------------------------------------------
module metric_thread_turns (diameter, pitch, length, internal, n_starts,
thread_size, groove, square, rectangle)
{
// Number of turns needed.
n_turns = floor (length/pitch);
intersection () {
// Start one below z = 0. Gives an extra turn at each end.
for (i=[-1*n_starts : n_turns+1]) {
translate ([0, 0, i*pitch]) {
metric_thread_turn (diameter, pitch, internal, n_starts,
thread_size, groove, square, rectangle);
}
}
// Cut to length.
translate ([0, 0, length/2]) {
cube ([diameter*3, diameter*3, length], center=true);
}
}
}
// ----------------------------------------------------------------------------
module metric_thread_turn (diameter, pitch, internal, n_starts, thread_size,
groove, square, rectangle)
{
n_segments = segments (diameter);
fraction_circle = 1.0/n_segments;
for (i=[0 : n_segments-1]) {
rotate ([0, 0, i*360*fraction_circle]) {
translate ([0, 0, i*n_starts*pitch*fraction_circle]) {
thread_polyhedron (diameter/2, pitch, internal, n_starts,
thread_size, groove, square, rectangle);
}
}
}
}
// ----------------------------------------------------------------------------
// z (see diagram) as function of current radius.
// (Only good for first half-pitch.)
function z_fct (current_radius, radius, pitch)
= 0.5* (current_radius - (radius - 0.875*pitch*cos (30)))
/cos (30);
// ----------------------------------------------------------------------------
module thread_polyhedron (radius, pitch, internal, n_starts, thread_size,
groove, square, rectangle)
{
n_segments = segments (radius*2);
fraction_circle = 1.0/n_segments;
local_rectangle = rectangle ? rectangle : 1;
h = (square || rectangle) ? thread_size*local_rectangle/2 : thread_size * cos (30);
outer_r = radius + (internal ? h/20 : 0); // Adds internal relief.
//echo (str ("outer_r: ", outer_r));
// A little extra on square thread -- make sure overlaps cylinder.
h_fac1 = (square || rectangle) ? 1.1 : 0.875;
inner_r = radius - h*h_fac1; // Does NOT do Dmin_truncation - do later with
// cylinder.
translate_y = groove ? outer_r + inner_r : 0;
reflect_x = groove ? 1 : 0;
// Make these just slightly bigger (keep in proportion) so polyhedra will
// overlap.
x_incr_outer = (! groove ? outer_r : inner_r) * fraction_circle * 2 * PI * 1.02;
x_incr_inner = (! groove ? inner_r : outer_r) * fraction_circle * 2 * PI * 1.02;
z_incr = n_starts * pitch * fraction_circle * 1.005;
/*
(angles x0 and x3 inner are actually 60 deg)
/\ (x2_inner, z2_inner) [2]
/ \
(x3_inner, z3_inner) / \
[3] \ \
|\ \ (x2_outer, z2_outer) [6]
| \ /
| \ /|
z |[7]\/ / (x1_outer, z1_outer) [5]
| | | /
| x | |/
| / | / (x0_outer, z0_outer) [4]
| / | / (behind: (x1_inner, z1_inner) [1]
|/ | /
y________| |/
(r) / (x0_inner, z0_inner) [0]
*/
x1_outer = outer_r * fraction_circle * 2 * PI;
z0_outer = z_fct (outer_r, radius, thread_size);
//echo (str ("z0_outer: ", z0_outer));
//polygon ([[inner_r, 0], [outer_r, z0_outer],
// [outer_r, 0.5*pitch], [inner_r, 0.5*pitch]]);
z1_outer = z0_outer + z_incr;
// Give internal square threads some clearance in the z direction, too.
bottom = internal ? 0.235 : 0.25;
top = internal ? 0.765 : 0.75;
translate ([0, translate_y, 0]) {
mirror ([reflect_x, 0, 0]) {
if (square || rectangle) {
// Rule for face ordering: look at polyhedron from outside: points must
// be in clockwise order.
polyhedron (
points = [
[-x_incr_inner/2, -inner_r, bottom*thread_size], // [0]
[x_incr_inner/2, -inner_r, bottom*thread_size + z_incr], // [1]
[x_incr_inner/2, -inner_r, top*thread_size + z_incr], // [2]
[-x_incr_inner/2, -inner_r, top*thread_size], // [3]
[-x_incr_outer/2, -outer_r, bottom*thread_size], // [4]
[x_incr_outer/2, -outer_r, bottom*thread_size + z_incr], // [5]
[x_incr_outer/2, -outer_r, top*thread_size + z_incr], // [6]
[-x_incr_outer/2, -outer_r, top*thread_size] // [7]
],
faces = [
[0, 3, 7, 4], // This-side trapezoid
[1, 5, 6, 2], // Back-side trapezoid
[0, 1, 2, 3], // Inner rectangle
[4, 7, 6, 5], // Outer rectangle
// These are not planar, so do with separate triangles.
[7, 2, 6], // Upper rectangle, bottom
[7, 3, 2], // Upper rectangle, top
[0, 5, 1], // Lower rectangle, bottom
[0, 4, 5] // Lower rectangle, top
]
);
} else {
// Rule for face ordering: look at polyhedron from outside: points must
// be in clockwise order.
polyhedron (
points = [
[-x_incr_inner/2, -inner_r, 0], // [0]
[x_incr_inner/2, -inner_r, z_incr], // [1]
[x_incr_inner/2, -inner_r, thread_size + z_incr], // [2]
[-x_incr_inner/2, -inner_r, thread_size], // [3]
[-x_incr_outer/2, -outer_r, z0_outer], // [4]
[x_incr_outer/2, -outer_r, z0_outer + z_incr], // [5]
[x_incr_outer/2, -outer_r, thread_size - z0_outer + z_incr], // [6]
[-x_incr_outer/2, -outer_r, thread_size - z0_outer] // [7]
],
faces = [
[0, 3, 7, 4], // This-side trapezoid
[1, 5, 6, 2], // Back-side trapezoid
[0, 1, 2, 3], // Inner rectangle
[4, 7, 6, 5], // Outer rectangle
// These are not planar, so do with separate triangles.
[7, 2, 6], // Upper rectangle, bottom
[7, 3, 2], // Upper rectangle, top
[0, 5, 1], // Lower rectangle, bottom
[0, 4, 5] // Lower rectangle, top
]
);
}
}
}
}

View File

@ -1,46 +1,42 @@
include <constants.scad>;
use <threads.scad>;
use <cap.scad>;
module thread() {
metric_thread(thread_diameter + thread_tolerance,
thread_pitch,
thread_lenght_top,
internal=true);
translate([0, 0, thread_lenght_top - height_unit])
cylinder(r2 = body_hole_diameter / 2,
r1 = thread_hole_diameter / 2,
h = height_unit);
cylinder(r1 = body_hole_diameter / 2,
r2 = thread_hole_diameter / 2,
h = height_unit);
}
include <bayonetmount.scad>;
include <support.scad>;
difference() {
translate([0, 0, bumper_height / 2])
minkowski() {
radius = bumper_diameter / 2 - bumper_edge_radius;
height = bumper_height - 2 * bumper_edge_radius;
cylinder(r = radius, h = height, center = true);
sphere(r = bumper_edge_radius, center = true);
}
translate([0, 0, bumper_height - lid_depth])
hole(tube_outer_diameter,
tube_inner_diameter,
latch_width,
latch_height,
lid_height);
cap();
// Hole for the lid
union() {
// Metric Thread
translate([0, 0, - 1 * height_unit])
thread();
// Make the rest of the cap hollow
translate([0, 0, -height_unit])
cylinder(r = body_hole_diameter / 2,
h = 1 * height_unit + 0.01,
center = true);
}
translate([0, 0, lid_height / 2])
cylinder(r = tube_inner_diameter / 2,
h = lid_height,
center = true);
translate([0, 0, bumper_tube_depth / 2])
cylinder(r = tube_outer_diameter / 2,
h = bumper_tube_depth,
center = true);
}
translate([0, 0, bumper_tube_depth / 2])
color("red")
support(tube_inner_diameter + 0.5, bumper_tube_depth);
translate([0, 0, bumper_height - lid_depth + latch_height / 2])
color("red")
support(tube_inner_diameter + 0.5, latch_height);

82700
top.stl

File diff suppressed because it is too large Load Diff