Fill the repository
This commit is contained in:
+172
@@ -0,0 +1,172 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Customizable girders for fischertechnik.
|
||||
// The modules in this file can be used to generate:
|
||||
// - Angle girders with a customizable length, height and width.
|
||||
// If the height or width are greater than the 15mm basic block size,
|
||||
// the corresponding side of the girder has a row of eyelets every
|
||||
// 15mm. The length sides both have flat grooves (the original angle
|
||||
// girder has a flat groove on one side and a pin on the other side).
|
||||
// If the width is greater than 15mm then there are grooves every 15mm.
|
||||
// - U-Girders with a customizable length and width.
|
||||
//
|
||||
|
||||
//----------------------- parameters ---------------------------
|
||||
/* [Girder type] */
|
||||
//
|
||||
Girder_type = 0; // [0 : no output, 1:Anglegirder, 2: U-Girder]
|
||||
/* [Angel girder options] */
|
||||
// The length of the angel girder
|
||||
Length = 60; // [15,30,45,60,75,90,105,120,150,180]
|
||||
// The height of the angel girder
|
||||
Height = 15; // [15,30,45,60,75,90,105,120,150,180]
|
||||
// The width of the angel girder
|
||||
Width = 15; // [15,30,45,60,75,90,105,120,150,180]
|
||||
/* [U-Girder options] */
|
||||
// The length of the U-Girder
|
||||
U_Length = 90; // [15,30,45,60,75,90,105,120,135, 150,165,180,195]
|
||||
// The width of the U-Girder
|
||||
U_Width = 30; // [15,30,45,60,75,90,105,120,135, 150,165,180,195]
|
||||
|
||||
// Build plate size correction for the eyelets
|
||||
Correction = 0.2; // [0.0, 0.1, 0.2, 0.3]
|
||||
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
|
||||
|
||||
// *********************
|
||||
// ** Helper Modules: **
|
||||
// *********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// The girder body without eyelets and grooves
|
||||
// --------------------------------------------------------------------
|
||||
module girder_body(len = BASIC_BLOCK_SIZE * 4, w = BASIC_BLOCK_SIZE * 2, h = BASIC_BLOCK_SIZE, angle = true) {
|
||||
// make room for the flat grooves
|
||||
additionalheadthickness = 1.5;
|
||||
// the u-girder has an additional wall
|
||||
innerwidth =
|
||||
(angle == true) ?
|
||||
w - WALL_THICKNESS + MANIFOLD_CORRECTION :
|
||||
w - WALL_THICKNESS * 2;
|
||||
|
||||
innerheight = h - WALL_THICKNESS + MANIFOLD_CORRECTION;// + 0.1;
|
||||
difference() {
|
||||
cube([w, len, h]);
|
||||
translate([WALL_THICKNESS, WALL_THICKNESS + additionalheadthickness, WALL_THICKNESS])
|
||||
cube([innerwidth, len - ( 2 * WALL_THICKNESS + 2 * additionalheadthickness), innerheight]);
|
||||
}
|
||||
}
|
||||
|
||||
// *********************
|
||||
// ** Girder Modules: **
|
||||
// *********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Customizable anglegirder
|
||||
// This version of the angle girder has no pin, but grooves on both sides.
|
||||
// The pins are difficult to print, so i decided to use a second groove
|
||||
// and an original Fischertechnik spring cam (Federnocken)
|
||||
// The length of the girder can be set in the customizer, but it should
|
||||
// always be set to multiples of the basic block size (15 mm) to have
|
||||
// complete eylets on the girder.
|
||||
// The same applies to the height and width of the girder.
|
||||
// --------------------------------------------------------------------
|
||||
module angle_girder(len = BASIC_BLOCK_SIZE * 4, w = BASIC_BLOCK_SIZE, h = BASIC_BLOCK_SIZE) {
|
||||
w_cnt = w / BASIC_BLOCK_SIZE;
|
||||
h_cnt = h / BASIC_BLOCK_SIZE;
|
||||
|
||||
difference() {
|
||||
difference() {
|
||||
girder_body(len, w, h);
|
||||
for (i = [0 : BASIC_BLOCK_SIZE : (w_cnt - 1) * BASIC_BLOCK_SIZE]) {
|
||||
translate([i, 0 ,0])
|
||||
eyelet_row(len = len, height = WALL_THICKNESS * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
for (i = [0 : BASIC_BLOCK_SIZE : (h_cnt - 1) * BASIC_BLOCK_SIZE]) {
|
||||
translate([0, 0, i])
|
||||
rotate([0,270,0])
|
||||
eyelet_row(len = len, height = WALL_THICKNESS * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
for (i = [0 : BASIC_BLOCK_SIZE : (w_cnt - 1) * BASIC_BLOCK_SIZE]) {
|
||||
translate([BASIC_BLOCK_HALF + i, 0, h / 2])
|
||||
flat_groove(h);
|
||||
rotate([180,0,0])
|
||||
translate([BASIC_BLOCK_HALF + i, -Length, -(h / 2)])
|
||||
flat_groove(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// customizable u-girder
|
||||
// --------------------------------------------------------------------
|
||||
module u_girder(len = BASIC_BLOCK_SIZE * 6, w = BASIC_BLOCK_SIZE * 3, h = BASIC_BLOCK_SIZE) {
|
||||
separator_thickness = 1;
|
||||
separator_height = 10;
|
||||
hole_diameter = PLATE_HOLE_DIAMETER;
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
// first, the girder body without any holes or eyelets
|
||||
girder_body(len = len, w = w, h = h, angle = false);
|
||||
// now cut out the grooves on both ends of the girder
|
||||
translate([w /2 , 0, BASIC_BLOCK_HALF])
|
||||
rotate([0,90,0])
|
||||
flat_groove(w);
|
||||
translate([w /2 , len, BASIC_BLOCK_HALF])
|
||||
rotate([180,90,0])
|
||||
flat_groove(w);
|
||||
|
||||
// next, cut out the eyelets
|
||||
for (i = [0 : BASIC_BLOCK_SIZE : (h / BASIC_BLOCK_SIZE - 1) * BASIC_BLOCK_SIZE]) {
|
||||
translate([0, 0, i])
|
||||
rotate([0, 270, 0])
|
||||
eyelet_row(len = len, height = WALL_THICKNESS * 2 + MANIFOLD_CORRECTION);
|
||||
translate([w - WALL_THICKNESS, 0, i])
|
||||
rotate([0, 270, 0])
|
||||
eyelet_row(len = len, height = WALL_THICKNESS * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
|
||||
// finally cut out the holes for the pins of the basic blocks
|
||||
for (i = [0 : BASIC_BLOCK_SIZE : len - BASIC_BLOCK_SIZE])
|
||||
for (j = [BASIC_BLOCK_HALF : BASIC_BLOCK_SIZE : w ])
|
||||
translate([j, PLATE_HOLE_DIAMETER - 0.1 + i, 0])
|
||||
cube_with_cylinder(dir = "up");
|
||||
}
|
||||
// now add the inner separator walls and the cylinders for the round holes
|
||||
for(k = [BASIC_BLOCK_SIZE : BASIC_BLOCK_SIZE : len - BASIC_BLOCK_SIZE]) {
|
||||
translate([0, k - separator_thickness,0])
|
||||
cube([w,separator_thickness, separator_height]);
|
||||
for(l = [BASIC_BLOCK_SIZE : BASIC_BLOCK_SIZE : w - BASIC_BLOCK_SIZE])
|
||||
translate([l, k - separator_thickness / 2, 0])
|
||||
cylinder(r = 3.4, h = separator_height);
|
||||
}
|
||||
}
|
||||
// drill the holes through the girder
|
||||
for(m = [BASIC_BLOCK_SIZE : BASIC_BLOCK_SIZE : len - BASIC_BLOCK_SIZE])
|
||||
for(n = [BASIC_BLOCK_SIZE : BASIC_BLOCK_SIZE : w - BASIC_BLOCK_SIZE])
|
||||
translate([n, m - separator_thickness / 2, -(MANIFOLD_CORRECTION / 2)])
|
||||
cylinder(d = PLATE_HOLE_DIAMETER, h = separator_height + MANIFOLD_CORRECTION);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (Girder_type == 1) {
|
||||
angle_girder(len=Length, w=Width, h=Height);
|
||||
}
|
||||
else if (Girder_type == 2) {
|
||||
u_girder(len=U_Length, w=U_Width);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,3 +1,113 @@
|
||||
# ft-parts
|
||||
# FT-Parts
|
||||
|
||||
Customizable OpenSCAD descriptions of fischertechnik parts.
|
||||
|
||||
This collection does not try to rebuild all fischertechnik parts
|
||||
but focuses on parts where it makes sense to customize them to
|
||||
get some variations of standard parts.
|
||||
|
||||
Most of the 3D printble designs of fischertechnik parts come either
|
||||
with only the STL files or, if parameterizable, with a FreeCAD design.
|
||||
STL files can only be changed as a whole, either shrinked or enlarged.
|
||||
|
||||
FreeCAD is a powerful tool but somehow complicated, even if accessing
|
||||
the page for the parameters is quite simple. Any change of other things
|
||||
means that you have to do some kind of CAD construction tasks...
|
||||
|
||||
That's where OpenSCAD comes into play: for a programmer like me it much
|
||||
easier to change some variables or code to adopt the code to my needs.
|
||||
Anyhow, there is a small difference: some of the original parts have
|
||||
chamfered edges while others don't have them. I decided to build all
|
||||
of the parts without the chamfered edges.
|
||||
But hey, the source is here, feel free to add them ...
|
||||
|
||||
The fischertechnik parts in this repository are divided into files each
|
||||
representing a more or less unique kind of building unit. The only
|
||||
exception is the file ft-util.scad which provides some basic parts which
|
||||
are reused in the other files.
|
||||
|
||||
The following files are provided:
|
||||
* **buildingblocks.scad**
|
||||
* Standard building blocks which can be customized by length,
|
||||
the number of pins/grooves on the top and bottom and whether
|
||||
a center hole is used.
|
||||
In addition to the standard blocks a 15 x 7.5 block with
|
||||
customizable length is provided.
|
||||
* Standard angle blocks which can be customized with the angle
|
||||
and the number of pins (0 or 1).
|
||||
* Symmetrical angle blocks which can be customized with various
|
||||
parameters.
|
||||
* **plates.scad**
|
||||
* A base plate with a grid of holes for the pins of the basic
|
||||
building blocks. See section "Options for the base plate"
|
||||
for the parameters that can be changed.
|
||||
This is a configurable version of Art.-No. 32985,
|
||||
the base plate 258x186
|
||||
* A resizable bottom plate with flat grooves.
|
||||
Length and width of the plate may be configured by changing
|
||||
the values in the section "Plate options"
|
||||
This is a configurable version of Art.-No. 32859,
|
||||
the bottom plate 30x90
|
||||
* A resizable plate with holes to be combined with structural
|
||||
design components like angle girders and struts.
|
||||
This plate has the option of a thinner area in the center of
|
||||
one side of the plate.
|
||||
This is a configurable version of Art.-No. 35431
|
||||
the plate 90x90
|
||||
* A configurable version of the mounting plates.
|
||||
It is possible to configure the length and width of the plate,
|
||||
the position of the pins and even 15x15 mm holes in the plate
|
||||
by setting a matrix describing the layout.
|
||||
Each element in the matrix describes a 15x15 plate which are
|
||||
finally combined into one big plate.
|
||||
* **girders.scad**
|
||||
* Angle girders with a customizable length, height and width.
|
||||
If the height or width are greater than the 15mm basic block size,
|
||||
the corresponding side of the girder has a row of eyelets every
|
||||
15mm. The sides both have flat grooves (the original angle
|
||||
girder has a flat groove on one side and a pin on the other side).
|
||||
If the width is greater than 15mm then there are grooves every 15mm.
|
||||
* U-Girders with a customizable length and width.
|
||||
* **struts.scad**
|
||||
* i-struts (struts with a length which is a multiple of the basic
|
||||
building block (15 mm)). i-struts may or may not have additional
|
||||
eyelets every 15 mm.
|
||||
* x-struts with predefined length corresponding to the fischertechnik
|
||||
original struts.
|
||||
* x-struts with any length to connect other diagonal distances than
|
||||
the standard x-struts. The scad file contains a table for this.
|
||||
* **lugs.scad**
|
||||
Provides a number of lugs to connect the struts with each other. The
|
||||
length of the lugs is configurable. I addition to the fischertechnik
|
||||
lugs there are an Y-shaped lug with a configurable angle and an
|
||||
angle lug with a configurable angle between the main lug and the
|
||||
attached one.
|
||||
* Connecting strip
|
||||
* L-shaped lug
|
||||
* T-shaped lug
|
||||
* X-shaped lug
|
||||
* Star-shaped lug
|
||||
* Y-shaped lug
|
||||
* Angle lug
|
||||
* **ft-gears.scad**
|
||||
Gears with the fischertechnik standard modulus 1.5 or 0.5 and with
|
||||
10,15,20,30 and 40 teeth. Can be set to any other values if required.
|
||||
They are:
|
||||
* Solid or optimized
|
||||
* With a round hole or a hole for a clip axle
|
||||
* Single gear or stacked with a smaller gear (no clip axle when stacked)
|
||||
* **flexrail.scad**
|
||||
Flexrails with a customizable height. The pins are not part of the
|
||||
flexrail to make it possible to print the rails without support.
|
||||
Instead of the pin there is a cutout where the pin can be glued in
|
||||
if required.
|
||||
* Straight flexrail with a customizable length and height.
|
||||
* Circular flexrail with acustomizable radius and angle.
|
||||
* A number of pins for the flexrail ends,
|
||||
* **ft_28BYJ-48.scad**
|
||||
A small collection of parts for the 28BYJ-48 stepper motor.
|
||||
* A housing for the stepper. The stepper becomes quite warm,
|
||||
so no backplate to close the housing is supplied.
|
||||
* A gear with modulus 1.5 and 15 teeth.
|
||||
* A coupler for clip axles.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+19182
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
+35618
File diff suppressed because it is too large
Load Diff
+18482
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,317 @@
|
||||
// straight and angeled building blocks
|
||||
//----------------------- parameters ---------------------------
|
||||
/* [Block type] */
|
||||
// Type
|
||||
Block_type = 0; // [0 : no output, 1:Basic block, 2:Angle block, 3:Symmetric angle block]
|
||||
/* [Block options] */
|
||||
// Length of a block
|
||||
Block_length = 30; // [15.0 : 15.0 : 120.0]
|
||||
// Is this a flat block (7.5mm)?
|
||||
Flat_block = false;
|
||||
// Number of pins
|
||||
Pins = 1; // [0, 1, 2]
|
||||
// A hole in the middle of the block?
|
||||
Has_bore=false;
|
||||
// Square holes in the middle?
|
||||
Is_square = false;
|
||||
/* [Options for the angle block] */
|
||||
// Angle of the top side
|
||||
Angle = 7.5;
|
||||
// Use a pin on the standard angle block?
|
||||
With_pin = true;
|
||||
/* [Add. options for the sym. angle block] */
|
||||
// Which pins should be used?
|
||||
Which_pins = 3; // [0: Nothing, 1:left side, 2:right side, 3:both sides]
|
||||
// Which grooves should be used?
|
||||
Which_grooves = 2; // [0: Nothing, 1:left side, 2:right side, 3:both sides]
|
||||
// Which kind of groove at the bottom if no grooves on the sides
|
||||
Which_bottom_groove = 2; // [0: None, 1:Flat groove, 2:Round groove]
|
||||
// Use short grooves (applied to all grooves)
|
||||
Has_short_grooves = true;
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A basic block 7,5 or 15 x 15 of arbitrary length.
|
||||
// The 15 x 15 block may have 0 - 2 pins at the small side of the block
|
||||
// and a hole (either round or a sqare).
|
||||
// If the small side has no pin, a groove is placed instead of the pin
|
||||
// The default is a block of 30 mm with a pin and a groove and
|
||||
// without hole at the center
|
||||
// The flat block 7.5 x 15 has flat grooves on the long side and round
|
||||
// holes at the small side. It also has no pins or grooves at the
|
||||
// bottom or top and no hole in the middle.
|
||||
// --------------------------------------------------------------------
|
||||
module basic_block(length=30, pins=1, flatblock = false, bore=false, squarehole=false) {
|
||||
|
||||
y_offset = flatblock ? (BASIC_BLOCK_SIZE / 2) : BASIC_BLOCK_SIZE;
|
||||
difference() {
|
||||
// First, build the block and cut out the four grooves at the
|
||||
// long sides
|
||||
cube([BASIC_BLOCK_SIZE, y_offset, length], center=true);
|
||||
translate([0, -y_offset/2 ,0])
|
||||
rotate ([0, 0, 0])
|
||||
if (flatblock)
|
||||
flat_groove(length);
|
||||
else
|
||||
round_groove(length);
|
||||
translate([BASIC_BLOCK_HALF, 0, 0])
|
||||
rotate([0, 0, 90])
|
||||
round_groove(length);
|
||||
translate([0, y_offset/2, 0])
|
||||
rotate([0, 0, 180])
|
||||
if (flatblock)
|
||||
flat_groove(length);
|
||||
else
|
||||
round_groove(length);
|
||||
translate([-BASIC_BLOCK_HALF, 0, 0])
|
||||
rotate([0, 0, 270])
|
||||
round_groove(length);
|
||||
// Then, cut out the grooves at the top and bottom as required
|
||||
if (!flatblock)
|
||||
top_grooves(length, pins);
|
||||
// Do we have a hole through the block?
|
||||
if (!flatblock && bore) {
|
||||
rotate ([90, 0, 0])
|
||||
cylinder(h = BASIC_BLOCK_SIZE + MANIFOLD_CORRECTION, r = 2, center = true);
|
||||
// and if yes, does it have square endings?
|
||||
if (squarehole) {
|
||||
translate([0, (BASIC_BLOCK_SIZE - 4.5) / 2, 0])
|
||||
cube(4.51, center=true);
|
||||
translate([0, -(BASIC_BLOCK_SIZE - 4.5) / 2, 0])
|
||||
cube(4.51, center=true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally add the pins as required
|
||||
if (!flatblock)
|
||||
top_pins(length, pins);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// add the grooves at the top and bottom of the block
|
||||
// --------------------------------------------------------------------
|
||||
module top_grooves(length = 30, pins = 1) {
|
||||
// small correction value for the cutouts
|
||||
mfc = 0.01;
|
||||
if (pins < 2) {
|
||||
translate([0, 0, -length / 2]) {
|
||||
rotate([90, 0, 0])
|
||||
round_groove(len = BASIC_BLOCK_SIZE, endcube = 3);
|
||||
}
|
||||
// translate([0, BASIC_BLOCK_HALF - GROOVE_RADIUS, -(length - 4.5) / 2])
|
||||
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
||||
// translate([0, -(BASIC_BLOCK_HALF - GROOVE_RADIUS), -(length - 4.5) / 2])
|
||||
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
||||
}
|
||||
if (pins == 0) {
|
||||
translate([0, 0, length / 2]){
|
||||
rotate([270, 0, 0])
|
||||
round_groove(len = BASIC_BLOCK_SIZE, endcube = 3);
|
||||
}
|
||||
// translate([0, BASIC_BLOCK_HALF - GROOVE_RADIUS, (length - 4.5) / 2])
|
||||
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
||||
// translate([0, -BASIC_BLOCK_HALF - GROOVE_RADIUS, (length - 4.5) / 2])
|
||||
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// add the pins at the top and bottom of the block
|
||||
// --------------------------------------------------------------------
|
||||
module top_pins(length = 30, pins = 1) {
|
||||
if (pins > 0) {
|
||||
translate([0, 0, length / 2 - 0.01])
|
||||
pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH);
|
||||
if (pins == 2) {
|
||||
translate([0, 0, -length / 2 + 0.01])
|
||||
rotate([180, 0, 0])
|
||||
// pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH);
|
||||
pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Angle blocks
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// An angle block to build the standard fischertechnik angle blocks
|
||||
// with 7.5, 15 and 30 degrees. The blocks top and bottom use
|
||||
// the fischertechnik 15 x 15 grid. It always has a round or flat
|
||||
// groove at the bottom and may or may not have a pin at the top.
|
||||
// Caveats:
|
||||
// - Angles smaller than 6 degrees are unusable because the bottom
|
||||
// groove intersects with the top surface.
|
||||
// - Angles greater than 40 degrees look somehow weird because the
|
||||
// trapezoid sides are quite large. The module is mainly ment for
|
||||
// angles between the standard fischertechnik angles (from 7.5 to
|
||||
// 30 degrees) which can not be constructed otherwise.
|
||||
// - Angles greater than 72 degrees result in realy ugly blocks. Don't
|
||||
// use them...
|
||||
// --------------------------------------------------------------------
|
||||
module angle_block(angle, with_pin=true) {
|
||||
// calculate the radius based on the requested angle
|
||||
radius = (angle^2 / 45) - (1.5 * angle) + 40;
|
||||
// Center the block on the x and y axis
|
||||
translate([radius, 0, 0])
|
||||
rotate([270, 0, 0])
|
||||
difference() {
|
||||
union() {
|
||||
// build the basic block
|
||||
rotate_extrude(angle = angle, $fn = 5)
|
||||
translate ([-radius, 0, 0])
|
||||
square(BASIC_BLOCK_SIZE, center = true);
|
||||
// and attach the pin if required
|
||||
if(with_pin)
|
||||
rotate([90, 0, angle])
|
||||
translate([-radius, 0, 0])
|
||||
pin();
|
||||
}
|
||||
// now remove the groove
|
||||
translate([-radius, 0, 0])
|
||||
rotate([0, 0, 180])
|
||||
if (angle >= 15)
|
||||
round_groove(BASIC_BLOCK_SIZE);
|
||||
else
|
||||
flat_groove(BASIC_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// The symmetrical angle block is somehow special. fischertechnik only
|
||||
// has the 60 degree blocks which are symetric by definition.
|
||||
// This block has two variants: one with a groove and two pins and one
|
||||
// with three grooves with a length of 7.5 + 2 mm to get a stable block.
|
||||
// This module builds blocks with a given angle and two equal sides of
|
||||
// 15 x 15mm (the fischertechnik grid).
|
||||
// The length of the base varies, depending on the angle but does NOT
|
||||
// fit in the fischertechnik grid (except the 60 degree part, of course).
|
||||
// This module has a lot of parameters:
|
||||
// angle: The angle between the two 15 x 15 sides
|
||||
// pins: An integer describing the pins to use on the 15 x 15 sides:
|
||||
// 0 - No pins at all
|
||||
// 1 - One pin on the left
|
||||
// 2 - One pin on the right
|
||||
// 3 - Two pins, one on each side
|
||||
// grooves: An integer describing the grooves to use on the 15 x 15
|
||||
// sides:
|
||||
// 0 - No grooves at all
|
||||
// 1 - One groove on the left
|
||||
// 2 - One groove on the right
|
||||
// 3 - Two groove, one on each side
|
||||
// bottom_groove: An integer describing the groove at the bottom.
|
||||
// 0 - No groove at all
|
||||
// 1 - A flat groove
|
||||
// 2 - A round groove. Only used if no grooves are used on
|
||||
// the 15 x 15 sides.
|
||||
// short_grooves: Use short grooves instead of a groove through the
|
||||
// complete block. Gives the block more stability. This
|
||||
// parameter is applied to all grooves of the block.
|
||||
// Caveats:
|
||||
// - Three grooves make no sense if the angle is less than 60 degrees
|
||||
// because in that case the grooves would overlap.
|
||||
// - A groove in the bottom makes no sense if the angle is less than
|
||||
// 30 degrees because it would produce walls which are too thin.
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
module symmetrical_angle_block(angle = 45, pins = 2, grooves = 1, bottom_groove = 2, short_grooves = true) {
|
||||
// some trigonometric calculations for the resulting triangle
|
||||
base = 2 * BASIC_BLOCK_SIZE * sin(angle / 2);
|
||||
height = BASIC_BLOCK_SIZE * cos(angle / 2);
|
||||
offset1 = sqrt(BASIC_BLOCK_HALF^2 - (height/2)^2) - 0.1;
|
||||
// Calculate the length and position of the grooves based on
|
||||
// whether we have short grooves or not
|
||||
flat_groove_len = short_grooves ? BASIC_BLOCK_SIZE / 2 + 2 : BASIC_BLOCK_SIZE;
|
||||
flat_groove_offset = short_grooves ? -2.75 : 0;
|
||||
// If we have two pins, they always win ...
|
||||
which_grooves = pins == 3 ? 0 : grooves;
|
||||
|
||||
// center the block
|
||||
translate([0,-height/2,0])
|
||||
difference() {
|
||||
// Get the basic triangle
|
||||
linear_extrude(height = BASIC_BLOCK_SIZE, center = true)
|
||||
polygon(points = [[-base/2, 0 ],
|
||||
[ base/2, 0 ],
|
||||
[ 0, height]]);
|
||||
// Now substract all the used grooves:
|
||||
// Use a bottom groove at all?
|
||||
if (bottom_groove > 0) {
|
||||
// Then decide whether to use a flat or round groove
|
||||
if (which_grooves == 0 && bottom_groove == 2)
|
||||
round_groove(GROOVE_LENGTH);
|
||||
else
|
||||
translate([0, 0, flat_groove_offset])
|
||||
flat_groove(flat_groove_len);
|
||||
}
|
||||
// Cut out the grooves, but only if no pin is on that side
|
||||
// Remember: the pins always win ...
|
||||
if (which_grooves > 0) {
|
||||
if (is_set(which_grooves, 1) && !is_set(pins, 1)) {
|
||||
translate([-offset1, height / 2, flat_groove_offset])
|
||||
rotate([0, 0, -90 - angle / 2])
|
||||
flat_groove(flat_groove_len);
|
||||
}
|
||||
if (is_set(which_grooves, 2) && !is_set(pins, 2)) {
|
||||
translate([offset1, height / 2, flat_groove_offset])
|
||||
rotate([0, 0, 90 + angle / 2])
|
||||
flat_groove(flat_groove_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we have pins, just add them as required
|
||||
if (pins > 0) {
|
||||
if (is_set(pins, 1)) {
|
||||
translate([-offset1, 0, 0])
|
||||
rotate([-angle / 2, 270, 0])
|
||||
pin();
|
||||
}
|
||||
if (is_set(pins, 2)) {
|
||||
translate([offset1, 0, 0])
|
||||
rotate([-angle / 2, 90, 0])
|
||||
pin();
|
||||
}
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// small helper function to test whether bit 0 (decimal 1) or
|
||||
// bit 1 (decimal 2) is set.
|
||||
// Openscad has no bitwise operators :-(
|
||||
// --------------------------------------------------------------------
|
||||
function is_set(var, which) = (var == which || var == 3);
|
||||
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
|
||||
if (Block_type == 0) {
|
||||
// cube_with_cylinder(dir="right");
|
||||
// pin();
|
||||
// round_groove();
|
||||
eyelet();
|
||||
}
|
||||
else if (Block_type == 1) {
|
||||
basic_block(length=Block_length, pins=Pins, flatblock= Flat_block, bore=Has_bore, squarehole=Is_square);
|
||||
}
|
||||
else if (Block_type == 2) {
|
||||
angle_block(7.5, with_pin=With_pin);
|
||||
translate ([20, 0, 0]) angle_block(15, with_pin=With_pin);
|
||||
translate ([40, 0, 0]) angle_block(30, with_pin=With_pin);
|
||||
}
|
||||
else if (Block_type == 3) {
|
||||
symmetrical_angle_block(Angle, pins = Which_pins, grooves = Which_grooves, bottom_groove = Which_bottom_groove, short_grooves=Has_short_grooves);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
|
||||
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
// ----------------------------------------------------------------
|
||||
// Customizable flexrails
|
||||
//
|
||||
// inspired by:
|
||||
// https://www.printables.com/model/146321-fischertechnik-compatible-flex-rail-flexschiene-15/files
|
||||
//
|
||||
// This package contains straight and circle flexrails.
|
||||
// The straight flexrail has a customizable length and height.
|
||||
// The circular flexrail has acustomizable radius and angle and,
|
||||
// in addition, the outer wall can be set to an other value than
|
||||
// the inner wall
|
||||
|
||||
/* [Flexrail options] */
|
||||
// Type
|
||||
Flexrail_type = 0; // [0 : no output, 1:Straight flexrail, 2:Circular flexrail, 3 : Pair of pins]
|
||||
// Outer height of the wall, may be used for circular flexrails
|
||||
Outer_height = 5.5;
|
||||
// Inner height of the wall, also used for both walls of the straight flexrail
|
||||
Inner_height = 5.5;
|
||||
// Add the required pins?
|
||||
Set_pins = true;
|
||||
/* [Options for the straight flexrail] */
|
||||
// Length of the flexrail, uses standard ft lengths
|
||||
Length = 60; // [30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180]
|
||||
|
||||
/* [Options for the circular flexrail] */
|
||||
// The outer radius of the flexrail
|
||||
Radius = 45;
|
||||
// The angle of the flexrail
|
||||
Angle = 270; // [30 : 15 : 345]
|
||||
|
||||
/* [Options for the flexrail pins] */
|
||||
// The number of rows and columns of pins
|
||||
Count = [5, 4];
|
||||
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
|
||||
$fn=104;
|
||||
// The thickness of the flexrail base and walls
|
||||
thickness = 1.5;
|
||||
// The width of the flexrail
|
||||
flex_width = FT_GRID_SIZE;
|
||||
// width of the pin plate
|
||||
Pin_width = 9.1;
|
||||
// Length of the pin plate
|
||||
Pin_length = 7.1;
|
||||
// length and width of the quadratic hole through the flexrail
|
||||
Pin_hole = 5.01;
|
||||
|
||||
// *********************
|
||||
// ** Helper Modules: **
|
||||
// *********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Cutout for the pins. The pins are separated from the rails to avoid
|
||||
// the need for support when printing the rail.
|
||||
// The pins may be glued into their cutouts, but hey, it's then
|
||||
// difficult to replace them ;-)
|
||||
// --------------------------------------------------------------------
|
||||
module cutout(base_width = FT_GRID_SIZE, width = Pin_width, length = Pin_length, height = thickness, hole = Pin_hole, up = 0 ) {
|
||||
cutout_height = 1.5;
|
||||
offset = height / 2;
|
||||
union() {
|
||||
translate([base_width / 2 - hole / 2, base_width / 2 - hole / 2, -MANIFOLD_CORRECTION / 2])
|
||||
cube([hole, hole, cutout_height]);
|
||||
if (up == 1)
|
||||
translate([base_width / 2 - width / 2, base_width / 2 - length / 2, offset])
|
||||
cube([width, length, cutout_height]);
|
||||
else
|
||||
translate([base_width / 2 - length / 2, base_width / 2 - width / 2, offset])
|
||||
cube([length, width, cutout_height]);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// the slots in the rail
|
||||
// --------------------------------------------------------------------
|
||||
module slot(slot_width, slot_length, slot_height) {
|
||||
translate([0, -MANIFOLD_CORRECTION / 2, -MANIFOLD_CORRECTION / 2])
|
||||
cube([slot_width, slot_length, slot_height]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A slice of a circle to cut a piece out of the circle rail
|
||||
// --------------------------------------------------------------------
|
||||
module slice(r = 10, deg = 30) {
|
||||
degn = (deg % 360 > 0) ? deg % 360 : deg % 360 + 360;
|
||||
difference() {
|
||||
circle(r);
|
||||
if (degn > 180)
|
||||
intersection_for(a = [0, 180 - degn])
|
||||
rotate(a)
|
||||
translate([-r, 0, 0])
|
||||
square(r * 2);
|
||||
else
|
||||
union()
|
||||
for(a = [0, 180 - degn])
|
||||
rotate(a)
|
||||
translate([-r, 0, 0])
|
||||
square(r * 2);
|
||||
}
|
||||
}
|
||||
|
||||
// ***********************
|
||||
// ** Flexrail Modules: **
|
||||
// ***********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A plate with a pin fitting in the cutouts of the flexrails .
|
||||
// They may be glued into the pin hole, but hey: It is difficult to
|
||||
// remove them again whenever maintainance is needed ;-)
|
||||
// --------------------------------------------------------------------
|
||||
module flexrail_pin(width = Pin_width, length = Pin_length, height = thickness, hole = 5) {
|
||||
correction = 0.5;
|
||||
|
||||
translate([0, 0,height])
|
||||
union() {
|
||||
translate([0, 0,-(height / 4)])
|
||||
union() {
|
||||
cube ([hole - correction, hole - correction, height / 2], center = true);
|
||||
translate([0, 0, -(height / 2)])
|
||||
cube ([width - correction, length - correction, height / 2], center = true);
|
||||
}
|
||||
pin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A straight flexrail
|
||||
// --------------------------------------------------------------------
|
||||
module flexrail(length = Length, height = Inner_height) {
|
||||
wall_thickness = thickness;
|
||||
width = flex_width;
|
||||
y_center = width / 2;
|
||||
|
||||
slot_width = 1.1;
|
||||
slot_length = width - wall_thickness + MANIFOLD_CORRECTION;
|
||||
slot_height = height + MANIFOLD_CORRECTION;
|
||||
slot_distance = 10.0;
|
||||
|
||||
difference() {
|
||||
cube([length, width, height]);
|
||||
|
||||
// cut out the inner rail part
|
||||
translate([-MANIFOLD_CORRECTION / 2, wall_thickness, wall_thickness])
|
||||
cube([length + MANIFOLD_CORRECTION, width - 2 * wall_thickness, height]);
|
||||
|
||||
// then cut out the holes for the pins on both ends
|
||||
cutout();
|
||||
translate([length - width, 0, 0])
|
||||
cutout();
|
||||
|
||||
// finally cut out the slots on both sides, but leave a bit
|
||||
// of the flexrail before the wall (substract or add the
|
||||
// MANIFOLD_CORRECTION to the y-axis)
|
||||
for(i=[width : slot_distance : length -width]) {
|
||||
translate([i, -MANIFOLD_CORRECTION, 0])
|
||||
slot(slot_width, slot_length, slot_height);
|
||||
}
|
||||
for(i=[width + slot_distance / 2 : slot_distance : length -width]) {
|
||||
translate([i, wall_thickness + MANIFOLD_CORRECTION, 0])
|
||||
slot(slot_width, slot_length, slot_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a circle rail without cutouts
|
||||
// --------------------------------------------------------------------
|
||||
module circle_rail(radius = 40, outer_height = Outer_height, inner_height = Inner_height, width = flex_width, angle = 270) {
|
||||
v_wall_thickness = thickness;
|
||||
bottom_thickness = thickness;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
cylinder(r = radius, h = outer_height);
|
||||
translate([0, 0, bottom_thickness])
|
||||
cylinder(r = radius - v_wall_thickness, h = outer_height);
|
||||
}
|
||||
cylinder(r = radius - width + v_wall_thickness, h = inner_height);
|
||||
}
|
||||
translate([0, 0,-MANIFOLD_CORRECTION / 2])
|
||||
cylinder(r = radius - width, h = inner_height + MANIFOLD_CORRECTION);
|
||||
|
||||
// finally substract a a slice so that the remaining circle covers
|
||||
// the angle given as parameter
|
||||
if (angle % 360 != 0)
|
||||
translate([0, 0, -MANIFOLD_CORRECTION / 2])
|
||||
linear_extrude(outer_height + MANIFOLD_CORRECTION*2)
|
||||
slice(r = radius + MANIFOLD_CORRECTION , deg = 360 - angle);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// cut slots into the circular flex rail
|
||||
// --------------------------------------------------------------------
|
||||
module slot_circle(radius = 40.0, height = Inner_height, width = flex_width, start_angle = 30, end_angle = 270, segment_angle = 30, offset = 0) {
|
||||
wall_thickness = 1.5;
|
||||
slot_width = 1.1;
|
||||
slot_length = width - wall_thickness + MANIFOLD_CORRECTION + 1.4;
|
||||
slot_height = height + MANIFOLD_CORRECTION;
|
||||
|
||||
for(i=[start_angle : segment_angle : end_angle]) {
|
||||
// echo(i);
|
||||
rotate([0, 0,i])
|
||||
translate([radius - slot_length + offset, 0, -MANIFOLD_CORRECTION / 2])
|
||||
cube([slot_length, slot_width, slot_height]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Draw a slotted circular flexrail with pin cutouts.
|
||||
// --------------------------------------------------------------------
|
||||
module circle_flexrail(radius = 40, outer_height = outer_height, inner_height = inner_height, width = flex_width, angle = 360) {
|
||||
seg_angle = 900 / radius;
|
||||
difference() {
|
||||
circle_rail(radius = radius, outer_height = outer_height, inner_height = inner_height, width = width, angle = angle);
|
||||
// cut out the pin holes
|
||||
translate([radius - width, 0, 0])
|
||||
cutout(up = 1);
|
||||
rotate([0, 0, angle])
|
||||
translate([radius - width, -width, 0])
|
||||
cutout(up = 1);
|
||||
// cut out the slots on both sides, but leave a bit of the
|
||||
// flexrail before the wall (that's what the offset is for)
|
||||
slot_circle(radius = radius, height = inner_height, width = width, start_angle = seg_angle * 1.5, end_angle = angle - seg_angle, segment_angle = seg_angle, offset = -1.8);
|
||||
slot_circle(radius = radius, height = outer_height, width = width, start_angle = seg_angle * 2, end_angle = angle - seg_angle * 1.5, segment_angle = seg_angle, offset = 2.0);
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (Flexrail_type == 1) {
|
||||
flexrail(length = Length, height = Inner_height);
|
||||
if(Set_pins) {
|
||||
translate([-10, 7.5, 0])
|
||||
rotate([0, 0, 90])
|
||||
flexrail_pin();
|
||||
translate([Length + 10, 7.5, 0])
|
||||
rotate([0, 0, 90])
|
||||
flexrail_pin();
|
||||
}
|
||||
}
|
||||
else if (Flexrail_type == 2) {
|
||||
circle_flexrail(radius = Radius, angle = Angle, outer_height = Outer_height, inner_height = Inner_height);
|
||||
if (Set_pins) {
|
||||
translate([-5, 5, 0])
|
||||
rotate([0, 0, 90])
|
||||
flexrail_pin();
|
||||
translate([5, 5, 0])
|
||||
rotate([0, 0, 90])
|
||||
flexrail_pin();
|
||||
}
|
||||
}
|
||||
else if (Flexrail_type == 3) {
|
||||
for (i = [0 : 10 : (Count[1] - 1) * 10])
|
||||
for (j = [0 : 10 : (Count[0] - 1) * 10])
|
||||
translate([i, j, 0])
|
||||
flexrail_pin();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,176 @@
|
||||
// A small collection of parts for the 28BYJ-48 stepper motor:
|
||||
// - A housing for the stepper motor
|
||||
// - A coupler to combine the axle of the stepper with an ft clip axle
|
||||
/* [Stepper options] */
|
||||
// Type
|
||||
type = 0; // [0 : no output, 1:Stepper housing, 2:Shaft coupler, 3:Gear coupler, 4:Bevel gears coupler]
|
||||
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
use<ft_gears.scad>
|
||||
|
||||
shaft_diameter = 5.1;
|
||||
shaft_thickness = 3.1;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A coupler to combine the axle of the stepper with an ft clip axle
|
||||
// --------------------------------------------------------------------
|
||||
module shaft_coupler() {
|
||||
// All dimensions are defined here, no parameters for the shaft
|
||||
// coupler module. Depending on the printer's tolerance, the values
|
||||
// might need some correction.
|
||||
length = BASIC_BLOCK_SIZE;
|
||||
diameter = 8.0;
|
||||
ft_axis_diameter = 4.25;
|
||||
ft_axis_thickness = 2.75;
|
||||
|
||||
difference() {
|
||||
cylinder(d = diameter, h = length, center = true);
|
||||
union() {
|
||||
// cut out the motor axle hole
|
||||
translate([0,0,length / 4 + MANIFOLD_CORRECTION / 2])
|
||||
clip_axle_hole(length / 2, diameter = shaft_diameter, thickness = shaft_thickness);
|
||||
// cut out the clip axle hole
|
||||
translate([0,0,-length / 4 - MANIFOLD_CORRECTION / 2])
|
||||
clip_axle_hole(length / 2, diameter = ft_axis_diameter, thickness = ft_axis_thickness, hor_cutout = diameter + MANIFOLD_CORRECTION);
|
||||
// cut out the horizontal hole of the axle coupler
|
||||
//cube([diameter + MANIFOLD_CORRECTION, ft_axis_thickness, ft_axis_diameter], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A gear for the stepper
|
||||
// --------------------------------------------------------------------
|
||||
module gear_wheel() {
|
||||
difference() {
|
||||
union() {
|
||||
translate([0,0,-4])
|
||||
cylinder(h = 4, d = 8, center = true);
|
||||
normalgear (modulus=1.5, teeth=15, height=5, hole=0.0, clipaxle=false, optimize=false);
|
||||
}
|
||||
translate([0,0,-3])
|
||||
clip_axle_hole(diameter = shaft_diameter, thickness = shaft_thickness);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Build a pair of bevel gears.
|
||||
// Both gears have the same size. The hole in one gear is for the
|
||||
// stepper and the other hole is for a clip axle.
|
||||
// --------------------------------------------------------------------
|
||||
module bevelgears(modulus=1.5, teeth=15, hole=4.2) {
|
||||
shaft_diameter = 5.1;
|
||||
shaft_thickness = 3.1;
|
||||
ft_axis_diameter = 4.25;
|
||||
ft_axis_thickness = 2.75;
|
||||
shaft_length = 7.5;
|
||||
diameter = 8.0;
|
||||
|
||||
// Calculation for the distance of the bevel gears taken from gears.scad,
|
||||
// eleminated the intermediate steps. Simplify more?
|
||||
rkf = (modulus*teeth/2)/sin(45)*sin(((PI*((modulus*teeth/2)/sin(45))*45/90 - 2 * (modulus + modulus / 6)) / 2)/(PI*((modulus*teeth/2)/sin(45))) * 180);
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
translate([0,0,-shaft_length/2+MANIFOLD_CORRECTION])
|
||||
cylinder(h = shaft_length, d = diameter, center = true);
|
||||
translate([rkf*3+modulus,0,-shaft_length/2+MANIFOLD_CORRECTION])
|
||||
cylinder(h = shaft_length, d = diameter, center = true);
|
||||
|
||||
bevel_gear_pair(modul = modulus,
|
||||
gear_teeth = teeth, pinion_teeth = teeth,
|
||||
axis_angle=90, tooth_width = 5,
|
||||
gear_bore = 0, pinion_bore = 0,
|
||||
pressure_angle=20, helix_angle=0,
|
||||
together_built=false);
|
||||
}
|
||||
translate([0,0,-shaft_length/2])
|
||||
#clip_axle_hole(shaft_length+MANIFOLD_CORRECTION, diameter = shaft_diameter, thickness = shaft_thickness);
|
||||
|
||||
translate([rkf*3+modulus,0,-shaft_length/2])
|
||||
#clip_axle_hole(shaft_length+MANIFOLD_CORRECTION, diameter = ft_axis_diameter, thickness = ft_axis_thickness, hor_cutout = diameter + MANIFOLD_CORRECTION);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A housing for the 28BYJ-48. No back becuse the stepper gets quite
|
||||
// warm and the heat has to go somewhere ...
|
||||
// --------------------------------------------------------------------
|
||||
module stepper_housing(width = 60, length = 45, height = 30) {
|
||||
wallthickness = 4;
|
||||
frontthickness = 4;
|
||||
screwdistance = 35;
|
||||
shaftdistance = 8;
|
||||
|
||||
difference() {
|
||||
// The housing
|
||||
cube([width, length, height], center = true);
|
||||
// minus the inner cut out
|
||||
translate([0, 0, frontthickness])
|
||||
cube([width - 2 * wallthickness, length - 2 * wallthickness, height], center = true);
|
||||
// and the grooves
|
||||
grooves(width, length, height);
|
||||
|
||||
// remove the cut outs for the screws and the axle
|
||||
translate([-(screwdistance / 2),0, -(height / 2 + 0.1)])
|
||||
cylinder(d = 3, h = 10);
|
||||
translate([-(screwdistance / 2),0, -(height / 2 + 0.1)])
|
||||
cylinder(d = 5.75, h = 2.5);
|
||||
|
||||
translate([(screwdistance / 2),0, -(height / 2 + 0.1)])
|
||||
cylinder(d = 3, h = 10);
|
||||
translate([(screwdistance / 2),0, -(height / 2 + 0.1)])
|
||||
cylinder(d = 5.75, h = 2.5);
|
||||
|
||||
translate([0,shaftdistance, -(height / 2 + 0.1)])
|
||||
cylinder(d = 9.5, h = 10);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// The grooves around the housing for the cut out
|
||||
// --------------------------------------------------------------------
|
||||
module grooves(width = 60, length = 45, height = 30) {
|
||||
for(i = [0, 180]) {
|
||||
rotate([0,0,i])
|
||||
for (j = [0 : BASIC_BLOCK_SIZE : (width / BASIC_BLOCK_SIZE - 1) * BASIC_BLOCK_SIZE])
|
||||
translate([j - (width / 2) + BASIC_BLOCK_HALF, -(length / 2), 0])
|
||||
flat_groove(len = height);
|
||||
}
|
||||
for(i = [90, 270]) {
|
||||
rotate([0,0,i])
|
||||
for (j = [0 : 15 : (length / BASIC_BLOCK_SIZE - 1) * BASIC_BLOCK_SIZE])
|
||||
translate([j - (length / 2) + BASIC_BLOCK_HALF, -(width / 2), 0])
|
||||
flat_groove(len = height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (type == 1) {
|
||||
stepper_housing();
|
||||
}
|
||||
else if (type == 2) {
|
||||
shaft_coupler();
|
||||
}
|
||||
else if (type == 3) {
|
||||
gear_wheel();
|
||||
}
|
||||
else if (type == 4) {
|
||||
bevelgears(teeth=10);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
// Fischertechnik compatible gears.
|
||||
// Makes use of the library
|
||||
// https://github.com/chrisspen/gears.git
|
||||
// instead of the MCAD "Parametric Involute Bevel and Spur Gears" library
|
||||
// which has really a lot of parameters and looks quite complicate.
|
||||
//
|
||||
// The Fischertechnik technical background is described here:
|
||||
// https://www.ftcommunity.de/ftpedia/2011/2011-2/ftpedia-2011-2.pdf
|
||||
// page 30 ff; // Zahnräder und Übersetzungen (Teil 1)
|
||||
// https://www.ftcommunity.de/ftpedia/2011/2011-3/ftpedia-2011-3.pdf
|
||||
// page 30 ff; // Zahnräder und Übersetzungen (Teil 2)
|
||||
// https://www.ftcommunity.de/ftpedia/2012/2012-1/ftpedia-2012-1.pdf
|
||||
// page 12 ff; // Zahnräder und Übersetzungen (Teil 3)
|
||||
//
|
||||
// Fischertechnik uses two diffferent modules which can be set in the configurator:
|
||||
// m = 1.5 for the gears with the large teeth and
|
||||
// m = 0.5 for the gears with the small teeth.
|
||||
// and also a fixed number of teeth:
|
||||
// 10, 15, 20, 30, 40
|
||||
// Feel free to extend both of them as needed.
|
||||
//
|
||||
/* [Gear type] */
|
||||
// a normal gear or two gears stacked on each other
|
||||
type = 0; // [0:none, 1:normal, 2:stacked]
|
||||
/* [Gear options] */
|
||||
// Type of gear, defined by modulus
|
||||
modulus_1 = 1.5; // [0.5:small gears, 1.5:big gears]
|
||||
// The number of teeth of the bigger gear
|
||||
teeth_1 = 20; // [10, 15, 20, 30, 40]
|
||||
// Only if stacked: the number of teeth of the smaller gear
|
||||
teeth_2 = 10; // [10, 15, 20, 30, 40]
|
||||
// The height of a single gear
|
||||
height_1 = 5;
|
||||
// Is the gear optimized by a cutout?
|
||||
is_optimized = 0; // [0:no, 1:yes]
|
||||
// Do we have a round axis or a clip axis?
|
||||
has_clip_axle = 0; // [0:no, 1:yes]
|
||||
|
||||
/* [Hidden] */
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
include<gears.scad>
|
||||
$fn=50;
|
||||
// Depends on the printer and the ft parts.
|
||||
// For me this seems to work best:
|
||||
hole_diameter = 4.32;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A module to calculate an ft compatible gear.
|
||||
//
|
||||
// The used gears library does some weird optimizations to reduce
|
||||
// material and weight of the gear: in addition to cutting out part
|
||||
// of the inner circle with a small height it also cuts out some holes.
|
||||
// We just want the inner circle cutout, but deeper and without the
|
||||
// additional holes.
|
||||
// In addition we have the option to get a clip axle instead of
|
||||
// a normal hole for a standard axle.
|
||||
// This gears are a bit different than the original gears because
|
||||
// the top of the original teeth is a bit smaller than the gear
|
||||
// itsself. The replicas have the same width of the teeth at the
|
||||
// top and the bottom.
|
||||
// --------------------------------------------------------------------
|
||||
module normalgear(modulus=1.5, teeth=20, height=5, hole=4.25, clipaxle=false, optimize=true) {
|
||||
// adjust?
|
||||
inner_cylinder_radius = 6.75 / 2;
|
||||
clip_axle_length = 7.5;
|
||||
clip_axle_thickness = 2.7;
|
||||
|
||||
// calculate the approx. radius of the cut out
|
||||
r1 = (teeth * modulus / 2) - (modulus >= 1 ? 2 * modulus : 1.5);
|
||||
|
||||
if (optimize == 1) {
|
||||
difference () {
|
||||
// for ease of use we will move the gear to the center position
|
||||
translate([0,0,height/2])
|
||||
rotate([0,180,0])
|
||||
spur_gear (modulus, teeth, height, hole, optimized=false);
|
||||
// leave 1.5 mm of the gear and cut out the rest
|
||||
translate([0,0,1.5])
|
||||
cylinder(h = height, r = r1, center = true );
|
||||
}
|
||||
// add an inner cylinder for the axle and subtract the hole or
|
||||
// clip axle hidden by the just added inner cylinder
|
||||
if (clipaxle == 1) {
|
||||
difference() {
|
||||
cylinder(h = height, r = inner_cylinder_radius, center = true );
|
||||
clip_axle_hole(length = clip_axle_length, diameter = hole, thickness = clip_axle_thickness);
|
||||
}
|
||||
}
|
||||
else {
|
||||
difference() {
|
||||
cylinder(h = height, r = inner_cylinder_radius, center = true );
|
||||
cylinder(h = height + MANIFOLD_CORRECTION, d = hole, center = true );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// A solid gear is much simpler and also needs only the clip axle
|
||||
// to be painted if required
|
||||
translate([0,0,height/2])
|
||||
rotate([0,180,0])
|
||||
spur_gear (modulus, teeth, height, hole, optimized=false);
|
||||
if (clipaxle == 1) {
|
||||
difference() {
|
||||
// the radius could be smaller, but so what ...
|
||||
cylinder(h = height, r = inner_cylinder_radius, center = true );
|
||||
clip_axle_hole(length = clip_axle_length, diameter = hole, thickness = clip_axle_thickness);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// This is no Fischertechnik part. It is here just for convinience.
|
||||
// Build two gears in a line. No optimization because they are stacked
|
||||
// and no clip axle hole: the hole is too long for it (max 7.5 mm with
|
||||
// real length of 5 mm, the rest is for the cone of the clip axle).
|
||||
// --------------------------------------------------------------------
|
||||
module doublegear(modulus=1.5, teeth1=20, teeth2=10, height=5, hole=4.2) {
|
||||
normalgear (modulus, teeth1, height, hole, clipaxle=false, optimize = false);
|
||||
translate([0,0,height-0.01])
|
||||
normalgear (modulus, teeth2, height, hole, clipaxle=false, optimize = false);
|
||||
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (type == 1){
|
||||
normalgear (modulus=modulus_1, teeth=teeth_1, height=height_1, hole=hole_diameter, clipaxle=has_clip_axle, optimize=is_optimized);
|
||||
}
|
||||
else if (type == 2) {
|
||||
doublegear (modulus=modulus_1, teeth1=teeth_1, teeth2=teeth_2, height_1, hole_diameter);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
// --------------------------------------------------------------------
|
||||
// A collection of useful modules to create Fischertechnik parts,
|
||||
// mainly grooves, holes and pins to be added or substracted
|
||||
// --------------------------------------------------------------------
|
||||
// Please be aware that OpenSCAD approximates the size of a hole by
|
||||
// using a polygon according to the $fn variable. The corner points of
|
||||
// the polygon are lying on the circle. Thus the resulting hole is
|
||||
// always smaller than the diameter of the hole! Increasing the $fn
|
||||
// variable helps but increases calculation time. The best is to try
|
||||
// out the size and adopt the settings accordingly. It does not help
|
||||
// to size the final parts in the slicer, because all of the part will
|
||||
// be resized, not only the hole!
|
||||
// See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Circle_resolution:_$fa,_$fs,_and_$fn
|
||||
// for details.
|
||||
|
||||
// Constants used throughout the fischertechnik files. Although all
|
||||
// values in OpenSCAD are constants technically spoken, these are some
|
||||
// kind of special. They define standard values used everywhere and
|
||||
// changing them might influence how a part is redered and exported
|
||||
// to the finsal stl file for printing.
|
||||
|
||||
// The standard grid size of fischertechnik parts is 15 mm. Most
|
||||
// parts fit into that grid.
|
||||
FT_GRID_SIZE = 15;
|
||||
// The basic block has the same size as the grid. The constant name
|
||||
// is just for convinience
|
||||
BASIC_BLOCK_SIZE = FT_GRID_SIZE;
|
||||
// Half of the block size is used quite often, so it has its own
|
||||
// constant
|
||||
BASIC_BLOCK_HALF = BASIC_BLOCK_SIZE / 2;
|
||||
//
|
||||
WALL_THICKNESS = 2;
|
||||
// The Length of the groove is the same as the grid/basic block size.
|
||||
GROOVE_LENGTH = FT_GRID_SIZE;
|
||||
|
||||
// For values from different people see:
|
||||
// https://forum.ftcommunity.de/viewtopic.php?f=38&t=3709
|
||||
|
||||
// The radius of a groove, makes a diameter of 4.5 mm
|
||||
// GROOVE_RADIUS = 2.25;
|
||||
// GROOVE_DIAMETER = GROOVE_RADIUS * 2;
|
||||
GROOVE_RADIUS = 2.1;
|
||||
GROOVE_DIAMETER = GROOVE_RADIUS * 2;
|
||||
|
||||
GROOVE_CENTER = 2.4;
|
||||
GROOVE_BREAKTHROUGH = 3.0;
|
||||
|
||||
FLAT_GROOVE_OFFSET = 0.6;
|
||||
|
||||
PIN_DIAMETER = 4;
|
||||
PIN_BASE_WIDTH = 3;
|
||||
// PIN_BASE_LENGTH = 1.2;
|
||||
PIN_BASE_LENGTH = 1.0;
|
||||
|
||||
PLATE_HOLE_DIAMETER = 4.2;
|
||||
PLATE_BREAKTHROUGH = 3.2;
|
||||
PLATE_HOLE_CORRECTION = 0.8;
|
||||
PLATE_CUTOFF_HEIGHT = 2.8;
|
||||
|
||||
// those settings work for the U-girder,
|
||||
// but not for the base plate where
|
||||
// PLATE_CO_TOP_LENGTH is too long!
|
||||
PLATE_CO_TOP_WIDTH = 3.0;
|
||||
PLATE_CO_TOP_LENGTH = 6.0;
|
||||
PLATE_CO_BOTTOM_WIDTH = 4.3;
|
||||
PLATE_CO_BOTTOM_LENGTH = 4.3;
|
||||
PLATE_CO_CIRCLE_DIAMETER = 4.1;
|
||||
PLATE_CO_CIRCLE_OFFSET = 0.2;
|
||||
|
||||
EYELET_HEIGHT = 2.5;
|
||||
|
||||
|
||||
MANIFOLD_CORRECTION = 0.1;
|
||||
|
||||
$fn=104;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// part for cutting out a clip axle hole
|
||||
// --------------------------------------------------------------------
|
||||
module clip_axle_hole(length = BASIC_BLOCK_HALF, diameter = PLATE_HOLE_DIAMETER, thickness = 2.7, hor_cutout = 0)
|
||||
{
|
||||
cliplen_without_dome = 5;
|
||||
intersection() {
|
||||
cylinder(length + MANIFOLD_CORRECTION, d = diameter, center = true);
|
||||
cube([diameter, thickness, length + MANIFOLD_CORRECTION], center = true);
|
||||
}
|
||||
if (hor_cutout != 0) {
|
||||
// position the horizontal cutout in a way that it is 5mm from the top
|
||||
// so that the cone part of the axle can get some grip
|
||||
translate([0,0, -(length - diameter) / 2 + cliplen_without_dome])
|
||||
intersection() {
|
||||
cylinder(diameter + MANIFOLD_CORRECTION, d = hor_cutout, center = true);
|
||||
cube([hor_cutout + MANIFOLD_CORRECTION, thickness, diameter], center = true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A round groove to be substracted from other solids
|
||||
// Optionally with a cube on each end of the groove
|
||||
// The groove is centered on x and the z axis while it is slightly
|
||||
// moved to a negative y value
|
||||
// For the cutout rotate, translate and difference the groove
|
||||
// --------------------------------------------------------------------
|
||||
module round_groove(len = GROOVE_LENGTH, endcube=0)
|
||||
{
|
||||
// although the union is implicit, it doesn't do any harm and
|
||||
// handles the groove as an entity
|
||||
union()
|
||||
{
|
||||
// first, the groove itselve
|
||||
translate([0, GROOVE_CENTER, 0] )
|
||||
cylinder(r = GROOVE_RADIUS, h = len + 2 * MANIFOLD_CORRECTION, center=true);
|
||||
// Do we have cubes at either end of the groove?
|
||||
// Required if we have horzontal and vertical grooves
|
||||
if (endcube == 1 || endcube == 3)
|
||||
translate([0, GROOVE_CENTER - 2 * MANIFOLD_CORRECTION, -(len - GROOVE_DIAMETER) / 2 - MANIFOLD_CORRECTION] )
|
||||
cube([GROOVE_DIAMETER, GROOVE_DIAMETER + 4 * MANIFOLD_CORRECTION, GROOVE_DIAMETER], center=true);
|
||||
if (endcube == 2 || endcube == 3)
|
||||
translate([0, GROOVE_CENTER - 2 * MANIFOLD_CORRECTION, (len - GROOVE_DIAMETER) / 2 + MANIFOLD_CORRECTION] )
|
||||
cube([GROOVE_DIAMETER, GROOVE_DIAMETER + 4 * MANIFOLD_CORRECTION, GROOVE_DIAMETER], center=true);
|
||||
// now the 3 mm breakthrough for the grooves
|
||||
translate([0, 0.5, 0] )
|
||||
cube([GROOVE_BREAKTHROUGH, 1.5, len + 2 * MANIFOLD_CORRECTION], center = true);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a flat groove to be substracted from other solids
|
||||
// --------------------------------------------------------------------
|
||||
module flat_groove(len = GROOVE_LENGTH, endcube=0)
|
||||
{
|
||||
difference() {
|
||||
// make a round groove and cut off the top part
|
||||
round_groove(len, endcube);
|
||||
translate([-GROOVE_RADIUS, GROOVE_CENTER + FLAT_GROOVE_OFFSET, -len / 2 - (MANIFOLD_CORRECTION + 0.01)] )
|
||||
cube([GROOVE_DIAMETER, GROOVE_CENTER - FLAT_GROOVE_OFFSET, len + 2 * (MANIFOLD_CORRECTION + 0.01)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Apply a size correction to the eyelets which are printed on
|
||||
// the build plate of the 3D printer?
|
||||
// On my Ender 3 the eyelets on the build plate are too tall so
|
||||
// I needed to widen them. The eyelets on the vertical wall of the
|
||||
// girder are ok, they need no correction.
|
||||
function apply_correction(val, correctionVal = 0.0, correction=false) = correction == true ? val + correctionVal : val;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a single eyelet for the girders and struts
|
||||
// --------------------------------------------------------------------
|
||||
module eyelet(height = EYELET_HEIGHT, radius=2.05,
|
||||
cube_len = 7.2, cube_width = 3.1,
|
||||
correctionVal = 0.0)
|
||||
{
|
||||
// Currently used only in the lugs.scad file
|
||||
// See strut_eyelet to decide whether that one can be refactored
|
||||
// or replaced by this library module.
|
||||
|
||||
render()
|
||||
union()
|
||||
{
|
||||
// radius = apply_correction(radius, correctionVal, horizontal);
|
||||
// cube_width = apply_correction(7.2, correctionVal, horizontal);
|
||||
// cube_height = apply_correction(3.1, correctionVal, horizontal);
|
||||
|
||||
// Hmm, horizontal=true raises the eylet above the z axis while
|
||||
// horizontal=false move the eyelet below the z axis.
|
||||
// Is this intended? I assume no, all usages force the eyelet
|
||||
// into horizontal= true. I would suggest that the eyelet cutout
|
||||
// is centered on all four axises and the the horizontal= true
|
||||
// forces the eyelet into x direction while false forces it into
|
||||
// y direction.
|
||||
// translate([0, 0, horizontal == false ? -(height/2) + MANIFOLD_CORRECTION : (height/2) - MANIFOLD_CORRECTION ])
|
||||
// {
|
||||
cylinder(h = height, r = radius, center = true);
|
||||
// cube([cube_height, cube_width, height], center = true);
|
||||
cube([cube_width, cube_len, height], center = true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a row of eyelets
|
||||
// --------------------------------------------------------------------
|
||||
module eyelet_row(len = 1, height = EYELET_HEIGHT, eyelet_dist = FT_GRID_SIZE)
|
||||
{
|
||||
// removed correction
|
||||
cnt = len / eyelet_dist;
|
||||
for (i = [0 : eyelet_dist : (cnt - 1) * eyelet_dist])
|
||||
{
|
||||
translate([eyelet_dist / 2, eyelet_dist / 2 + i, 0])
|
||||
eyelet(height = height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// The cutout for plates, girders and the like
|
||||
// --------------------------------------------------------------------
|
||||
module plate_cutout(w1 = PLATE_CO_TOP_WIDTH, l1 = PLATE_CO_TOP_LENGTH,
|
||||
w2 = PLATE_CO_BOTTOM_WIDTH, l2 = PLATE_CO_BOTTOM_LENGTH,
|
||||
r = PLATE_CO_CIRCLE_DIAMETER, o = PLATE_CO_CIRCLE_OFFSET) {
|
||||
union () {
|
||||
translate([0,-0.01,0]) {
|
||||
translate([-w1/2, 0, 0])
|
||||
cube([w1, r, l1]);
|
||||
translate([-w2/2, 0, l1])
|
||||
cube([w2, r, l2]);
|
||||
translate([0, r / 2 + o, 0])
|
||||
cylinder(h = l1 + l2, d = r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A cube with attached cylinder to cut out holes for the pins of the
|
||||
// basic blocks. Centered on the zero point of the coordinate system.
|
||||
// Supports the four directions up, down, left and right.
|
||||
// The build plate must be face down in the coordinate system to cut
|
||||
// out the holes with this module.
|
||||
// if the holes are too tall, adjust width (the width and height of
|
||||
// the larger square hole) or the segment width s (the width of the
|
||||
// the smaller rectangle)
|
||||
// Used by u_girder and build_plate.
|
||||
// --------------------------------------------------------------------
|
||||
module cube_with_cylinder(w1 = PLATE_CO_TOP_WIDTH, l1 = PLATE_CO_TOP_LENGTH,
|
||||
w2 = PLATE_CO_BOTTOM_WIDTH, l2 = PLATE_CO_BOTTOM_LENGTH,
|
||||
r = PLATE_CO_CIRCLE_DIAMETER, o = PLATE_CO_CIRCLE_OFFSET, dir = "up")
|
||||
{
|
||||
if (dir == "up")
|
||||
{
|
||||
translate([0,(l1+l2)/2,0])
|
||||
rotate([90,0,0])
|
||||
plate_cutout(w1, l1, w2, l2, r, o);
|
||||
}
|
||||
else if (dir == "down")
|
||||
{
|
||||
translate([0,-(l1+l2)/2,0])
|
||||
rotate([90,0,180])
|
||||
plate_cutout(w1, l1, w2, l2, r, o);
|
||||
}
|
||||
else if (dir == "left")
|
||||
{
|
||||
translate([(l1+l2)/2,0,0])
|
||||
rotate([90,0,270])
|
||||
plate_cutout(w1, l1, w2, l2, r, o);
|
||||
}
|
||||
else if (dir == "right")
|
||||
{
|
||||
translate([-(l1+l2)/2,0,0])
|
||||
rotate([90,0,90])
|
||||
plate_cutout(w1, l1, w2, l2, r, o);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Pin which fits into the round and flat grooves.
|
||||
// The base_length is for pins placed on blocks or plates
|
||||
// Parameters:
|
||||
// diameter: the diameter of the hole for the pin
|
||||
// base_width: the width and length of the pin base
|
||||
// base_length: the height of the pin base
|
||||
// The pin is centered at the x and y axis while the z origin is 0
|
||||
// --------------------------------------------------------------------
|
||||
module pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH) {
|
||||
// check the whole thing!
|
||||
rotate([90,0,0])
|
||||
translate([0, (base_width + base_length) / 2, 0])
|
||||
union() {
|
||||
difference() {
|
||||
// build the rounded part of the pin
|
||||
intersection() {
|
||||
cylinder(d = diameter, h = diameter, center = true);
|
||||
rotate([0, 90, 0])
|
||||
cylinder(d = diameter, h = diameter, center = true);
|
||||
}
|
||||
// cut off the top
|
||||
translate([0, diameter / 2 + 0.6, 0])
|
||||
cube([diameter, diameter, diameter], center = true );
|
||||
}
|
||||
// add the base below the rounded part
|
||||
translate([0, -(base_width / 2), 0])
|
||||
cube([base_width, base_length, base_width], center = true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
// ----------------------------------------------------------------
|
||||
// A collection of a few parameterizable lugs for Fischertechnik
|
||||
// struts
|
||||
//
|
||||
|
||||
/* [Lug options] */
|
||||
// Type
|
||||
Lug_type = 0; // [0 : no output, 1:Connecting strip, 2:L-shaped lug, 3:T-shaped lug, 4: X-shaped lug, 5: Star-shaped lug, 6: Y-shaped lug, 7: Angle lug]
|
||||
// Legth of a lug
|
||||
Lug_length = 45; // [45.0 : 0.1 : 150.0]
|
||||
/* [Options for the star shaped lug] */
|
||||
// use only the half of a star?
|
||||
Half_star = 0; // [0:no, 1:yes]
|
||||
/* [Options for the Y-shaped lug] */
|
||||
// Angle between the two branches
|
||||
Y_Angle = 60.0; // [5 : 0.1 : 177]
|
||||
/* [Options for the lug with a branch] */
|
||||
// Angle of the branch in relation to the lug
|
||||
Angle = 30.0; // [22.0 : 0.1 : 158.0]
|
||||
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
|
||||
segment_length = 22.5;
|
||||
segment_width = 10.0;
|
||||
segment_height = 2.0;
|
||||
wall_length = 11.8;
|
||||
wall_width = 1.0;
|
||||
wall_height = 4.0;
|
||||
|
||||
|
||||
// *********************
|
||||
// ** Helper Modules: **
|
||||
// *********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// One part of a lug. Multiple segments asre combined to build the
|
||||
// different forms of as lug
|
||||
// --------------------------------------------------------------------
|
||||
module lug_segment(length = segment_length, eyelet_row = true) {
|
||||
difference() {
|
||||
rotate([0,0,180])
|
||||
translate([0,-length / 2,0])
|
||||
union() {
|
||||
translate([0, 0 , segment_height / 2])
|
||||
cube([segment_width, length, segment_height], center = true);
|
||||
translate([-(segment_width / 2), length / 2 - wall_length ,0])
|
||||
cube([wall_width, wall_length, wall_height]);
|
||||
translate([segment_width / 2 - wall_width, length / 2 - wall_length ,0])
|
||||
cube([wall_width, wall_length, wall_height]);
|
||||
}
|
||||
|
||||
if (eyelet_row == true) {
|
||||
if (length < 22) {
|
||||
translate([0, BASIC_BLOCK_HALF, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
else {
|
||||
for (i = [0 : BASIC_BLOCK_SIZE : length - 22]) {
|
||||
translate([0, BASIC_BLOCK_HALF + i, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
translate([0, BASIC_BLOCK_HALF, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ******************
|
||||
// ** Lug Modules: **
|
||||
// ******************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Two parts in a row with a configurable length and an optional
|
||||
// eyelet in the center
|
||||
// --------------------------------------------------------------------
|
||||
module connecting_strip(length = 45, center_eyelet = true) {
|
||||
part_length = length / 2 + MANIFOLD_CORRECTION;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
translate([0,-part_length + MANIFOLD_CORRECTION,0])
|
||||
lug_segment(part_length);
|
||||
rotate([0,0,180])
|
||||
translate([0, -part_length + MANIFOLD_CORRECTION, 0])
|
||||
lug_segment(part_length);
|
||||
}
|
||||
if (center_eyelet == true)
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a l-lug with configurable length
|
||||
// --------------------------------------------------------------------
|
||||
module l_lug(length = 27.5) {
|
||||
difference() {
|
||||
union() {
|
||||
lug_segment(length);
|
||||
translate([length - (segment_width / 2), length - (segment_width / 2), 0])
|
||||
rotate([0,0,90])
|
||||
lug_segment(length);
|
||||
}
|
||||
translate([0, length - segment_width / 2, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a t-lug with configurable length
|
||||
// --------------------------------------------------------------------
|
||||
module t_lug(length = 45) {
|
||||
l_lug_length = length * 0.6111111;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
l_lug(l_lug_length);
|
||||
rotate([0,0,180])
|
||||
translate([0, -l_lug_length * 2 + segment_width, 0])
|
||||
lug_segment (l_lug_length);
|
||||
}
|
||||
translate([0, l_lug_length - segment_width / 2, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// an x-lug with configurable length
|
||||
// --------------------------------------------------------------------
|
||||
module x_lug(length = 45) {
|
||||
l_lug_length = length * 0.6111111;
|
||||
union() {
|
||||
translate([0,-l_lug_length + segment_width / 2,0])
|
||||
l_lug(l_lug_length);
|
||||
rotate([0,0,180])
|
||||
translate([0,-l_lug_length + segment_width / 2,0])
|
||||
l_lug(l_lug_length);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a star-lug with configurable length and the option to build only
|
||||
// half of the star
|
||||
// --------------------------------------------------------------------
|
||||
module star_lug(length = 45, half_star = 0) {
|
||||
lug_length = length * 0.6111111;
|
||||
lug_length2 = length * 0.5111111;
|
||||
difference() {
|
||||
union() {
|
||||
translate([0,-lug_length + segment_width / 2,0])
|
||||
lug_segment(lug_length);
|
||||
rotate([0,0,60])
|
||||
translate([0,-lug_length + segment_width / 2,0])
|
||||
lug_segment(lug_length2);
|
||||
rotate([0,0,120])
|
||||
translate([0,-lug_length + segment_width / 2,0])
|
||||
lug_segment(lug_length2);
|
||||
rotate([0,0,180])
|
||||
translate([0,-lug_length + segment_width / 2,0])
|
||||
lug_segment(lug_length);
|
||||
if (half_star == 0) {
|
||||
rotate([0,0,240])
|
||||
translate([0,-lug_length + segment_width / 2,0])
|
||||
lug_segment(lug_length2);
|
||||
rotate([0,0,300])
|
||||
translate([0,-lug_length + segment_width / 2,0])
|
||||
lug_segment(lug_length2);
|
||||
}
|
||||
}
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a lug with configurable length and angle of the second part
|
||||
// --------------------------------------------------------------------
|
||||
module angle_lug(length = 45, angle = 158) {
|
||||
save_angle = max(min(angle, 158), 22);
|
||||
part_length = length / 2 + MANIFOLD_CORRECTION;
|
||||
branch_length = part_length * sqrt(1/sin(save_angle));
|
||||
difference() {
|
||||
union() {
|
||||
rotate([0, 0, save_angle])
|
||||
translate([0, -branch_length, 0])
|
||||
lug_segment(branch_length);
|
||||
connecting_strip(length, center_eyelet = false);
|
||||
}
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
if (save_angle < 35) {
|
||||
translate ([0, -length / 2 + BASIC_BLOCK_HALF, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
|
||||
}
|
||||
if (save_angle > 145) {
|
||||
translate ([0, length / 2 - BASIC_BLOCK_HALF, 0])
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// an y-lug with a configurable length and angel between the two ends
|
||||
// --------------------------------------------------------------------
|
||||
module y_lug(length = 45, angle = 60) {
|
||||
save_length = max(length, 45);
|
||||
save_angle = max(min(angle, 177), 5);
|
||||
center_length = segment_width;
|
||||
part_length = save_length / 2 + MANIFOLD_CORRECTION;
|
||||
branch_length = part_length * sqrt(1/sin(save_angle));
|
||||
difference() {
|
||||
union() {
|
||||
if (save_angle > 90) {
|
||||
translate([0, 0 , segment_height / 2])
|
||||
cube([segment_width, center_length, segment_height], center = true);
|
||||
}
|
||||
rotate([0,0,180])
|
||||
translate([0, -part_length + MANIFOLD_CORRECTION, 0])
|
||||
lug_segment(part_length);
|
||||
rotate([0,0,save_angle])
|
||||
translate([0,-branch_length,0])
|
||||
lug_segment(branch_length, eyelet_row = false);
|
||||
rotate([0,0,-save_angle])
|
||||
translate([0,-branch_length,0])
|
||||
lug_segment(branch_length, eyelet_row = false);
|
||||
}
|
||||
eyelet(height = segment_height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (Lug_type == 1) {
|
||||
connecting_strip(length = Lug_length);
|
||||
}
|
||||
else if (Lug_type == 2) {
|
||||
l_lug(length = Lug_length);
|
||||
}
|
||||
else if (Lug_type == 3) {
|
||||
t_lug(length = Lug_length);
|
||||
}
|
||||
else if (Lug_type == 4) {
|
||||
x_lug(length = Lug_length);
|
||||
}
|
||||
else if (Lug_type == 5) {
|
||||
star_lug(length = Lug_length, half_star = Half_star);
|
||||
}
|
||||
else if (Lug_type == 6) {
|
||||
y_lug(length = Lug_length, angle = Y_Angle);
|
||||
}
|
||||
else if (Lug_type == 7) {
|
||||
angle_lug(length = Lug_length, angle = Angle);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
+388
@@ -0,0 +1,388 @@
|
||||
// ----------------------------------------------------------------
|
||||
// A collection of a few parameterizable plates for Fischertechnik
|
||||
//
|
||||
// 1) A base plate with a grid of holes for the pins of the basic
|
||||
// building blocks. See section "Options for the base plate"
|
||||
// for the parameters that can be changed.
|
||||
// This is a configurable version of Art.-No. 32985,
|
||||
// the base plate 258x186
|
||||
//
|
||||
// 2) A resizable bottom plate with flat grooves.
|
||||
// Length and width of the plate may be configured by changing
|
||||
// the values in the section "Plate options"
|
||||
// This is a configurable version of Art.-No. 32859,
|
||||
// the bottom plate 30x90
|
||||
//
|
||||
// 3) A resizable plate with holes to be combined with structural
|
||||
// design components like angele girders and struts.
|
||||
// This plate has the option of a thinner area in the center of
|
||||
// one side of the plate.
|
||||
// This is a configurable version of Art.-No. 35431
|
||||
// the plate 90x90
|
||||
//
|
||||
// 4) A configurable version of the mounting plates.
|
||||
// It is possible to configure the length and width of the plate,
|
||||
// the position of the pins and even 15x15 mm holes in the plate
|
||||
// by setting a matrix describing the layout.
|
||||
// Each element in the matrix describes a 15x15 plate which are
|
||||
// finally combined into one big plate.
|
||||
//
|
||||
//----------------------- parameters ------------------------------
|
||||
/* [Plate options] */
|
||||
// Plate type
|
||||
PlateType = 0; // [0 : no output, 1:Base plate with grid, 2:Bottom plate, 3:Plate with holes, 4:Plate with pins]
|
||||
// Plate length
|
||||
Length = 90; // [30,45,60,75,90,105,120,135,150,165,180]
|
||||
// Plate width
|
||||
Width = 30; // [30,45,60,75,90,105,120,135,150,165,180]
|
||||
|
||||
/* [Options for the base plate] */
|
||||
// The number of pin hole rows
|
||||
Rows = 4; // [2,4,6,8,10,12]
|
||||
// The number of pin hole columns
|
||||
Columns = 4; // [2,4,6,8,10,12]
|
||||
|
||||
/* [Options for the plate with holes] */
|
||||
// Use half thickness for the center area?
|
||||
Thin_Center = false; // [false:No, true:yes]
|
||||
|
||||
/* [Options for the plate with pins] */
|
||||
// Layout of the larger plate grid combined of 15x15 plates:
|
||||
// Every vector in the matrix describes one column of 15x15 mounting plates.
|
||||
// The following values are valid:
|
||||
// 0 - no segment at this position
|
||||
// 1 - segment with a pin
|
||||
// 2 - segment without pin
|
||||
// 3,4,5,6 - half circles
|
||||
// 7,8,9,10 - triangle segments, diagonal half of normal segment
|
||||
// 11,12,13,14 - circle segments
|
||||
// 15,16,17,18 - inverted circle segments
|
||||
// Plate Layout, must be configured in source, configurator doesn't support matrix values
|
||||
Layout =
|
||||
[
|
||||
[ 0, 4, 0, 0, 4, 0],
|
||||
[ 9, 7, 0, 0, 10, 8],
|
||||
[ 2, 0, 0, 0, 0, 2],
|
||||
[ 1, 18, 0, 0, 15, 1],
|
||||
[ 2, 2, 2, 2, 2, 2],
|
||||
[14, 1, 1, 1, 1, 11]
|
||||
];
|
||||
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
include<ft_util.scad>
|
||||
|
||||
// ********************
|
||||
// ** Plate Modules: **
|
||||
// ********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A build plate with a grid of holes for fixing basic blocks like
|
||||
// the base plate 258x186
|
||||
// --------------------------------------------------------------------
|
||||
module build_plate(rows = 4, columns = 4) {
|
||||
assert((rows%2) == 0, "Rows must be a multiple of two!"); //%
|
||||
// some often used values
|
||||
plate_thickness = 2.8;
|
||||
outer_wall = 3.0;
|
||||
inner_wall = 1.6;
|
||||
half_inner_wall = inner_wall / 2;
|
||||
outer_wall_offset = outer_wall - half_inner_wall;
|
||||
cell_size = 13.4;
|
||||
center_fill = 2.2;
|
||||
|
||||
cylinder_outer_d = 8.4;
|
||||
cylinder_inner_d = PLATE_HOLE_DIAMETER;
|
||||
|
||||
width = columns * cell_size + (columns - 1) * inner_wall + 2 * outer_wall;
|
||||
length = rows * cell_size + (rows - 1) * inner_wall + 2 * outer_wall + center_fill * 2;
|
||||
height = BASIC_BLOCK_HALF;
|
||||
|
||||
// from here on no values like 1.1, just variables. That way we
|
||||
// can customize even the values not provided by the customizer.
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
// plate with outer walls
|
||||
difference () {
|
||||
cube([width, length, height]);
|
||||
// substract the inner area
|
||||
translate ([outer_wall, outer_wall, plate_thickness])
|
||||
cube([width - outer_wall * 2, length - outer_wall * 2, height]);
|
||||
}
|
||||
|
||||
// inner walls
|
||||
// wall at the vertical center
|
||||
translate([0, length / 2 - half_inner_wall, 0])
|
||||
cube([width, inner_wall, height]);
|
||||
|
||||
// the horizontal inner walls,
|
||||
// first half from the bottom to the middle
|
||||
// for(i = [FT_GRID_SIZE : FT_GRID_SIZE : ((rows / 2) - 1) * FT_GRID_SIZE])
|
||||
// translate([0, outer_wall_offset + i - half_inner_wall, 0])
|
||||
// cube([width, inner_wall, height]);
|
||||
// // the second half from the top to the middle
|
||||
// for(i = [FT_GRID_SIZE : FT_GRID_SIZE : ((rows / 2) - 1) * FT_GRID_SIZE])
|
||||
// translate([0,length - (outer_wall_offset + i - half_inner_wall) , 0])
|
||||
// cube([width, inner_wall, height]);
|
||||
|
||||
// the horizontal inner walls,
|
||||
for(i = [FT_GRID_SIZE : FT_GRID_SIZE : ((rows / 2) - 1) * FT_GRID_SIZE]) {
|
||||
// first half from the bottom to the middle
|
||||
translate([0, outer_wall_offset + i - half_inner_wall, 0])
|
||||
cube([width, inner_wall, height]);
|
||||
// the second half from the top to the middle
|
||||
translate([0,length - (outer_wall_offset + i - half_inner_wall) , 0])
|
||||
cube([width, inner_wall, height]);
|
||||
}
|
||||
// for(i = [FT_GRID_SIZE : FT_GRID_SIZE : (columns - 1) * FT_GRID_SIZE])
|
||||
// // vertical inner walls
|
||||
// translate([outer_wall_offset + i - half_inner_wall, 0, 0])
|
||||
// cube([inner_wall, length, height]);
|
||||
|
||||
// // add cylinders, hole is done later !
|
||||
// for(i = [FT_GRID_SIZE : FT_GRID_SIZE : (columns - 1) * FT_GRID_SIZE])
|
||||
// translate([outer_wall_offset + i, length / 2,0])
|
||||
// cylinder(height, d = cylinder_outer_d);
|
||||
|
||||
for(i = [FT_GRID_SIZE : FT_GRID_SIZE : (columns - 1) * FT_GRID_SIZE]) {
|
||||
// vertical inner walls
|
||||
translate([outer_wall_offset + i - half_inner_wall, 0, 0])
|
||||
cube([inner_wall, length, height]);
|
||||
// add cylinders, hole is done later !
|
||||
translate([outer_wall_offset + i, length / 2,0])
|
||||
cylinder(height, d = cylinder_outer_d);
|
||||
}
|
||||
|
||||
}
|
||||
// drill the holes through the cylinders
|
||||
for(i = [FT_GRID_SIZE : FT_GRID_SIZE : (columns - 1) * FT_GRID_SIZE])
|
||||
translate([outer_wall_offset + i, length / 2, -MANIFOLD_CORRECTION / 2])
|
||||
cylinder(height + MANIFOLD_CORRECTION, d = PLATE_HOLE_DIAMETER);
|
||||
|
||||
// finally cut out the hole for the pins
|
||||
for(i = [FT_GRID_SIZE / 2 : FT_GRID_SIZE : columns * FT_GRID_SIZE])
|
||||
for(j = [FT_GRID_SIZE / 2 + outer_wall_offset : FT_GRID_SIZE : ((rows / 2)) * FT_GRID_SIZE]) {
|
||||
translate([outer_wall_offset + i, j, 0])
|
||||
cube_with_cylinder(l1 = 5, dir = "up");
|
||||
translate([outer_wall_offset + i, length - j, 0])
|
||||
cube_with_cylinder(l1=5, dir = "down");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A configurable bottom plate with a lot of flat grooves
|
||||
// --------------------------------------------------------------------
|
||||
module bottom_plate(length = 90, width = 30, height=BASIC_BLOCK_HALF) {
|
||||
groove_distance = BASIC_BLOCK_HALF;
|
||||
thin_wall = 1.4; // 1.5
|
||||
cubic_groove_width = 2.1; // 1.9
|
||||
cubic_groove_height = 2.85;
|
||||
bottom_bridge_width = 6.92;
|
||||
half_man_cor = MANIFOLD_CORRECTION / 2;
|
||||
|
||||
// Attention: the order of unions and differences is important to get the
|
||||
// desired result.
|
||||
difference() {
|
||||
difference() {
|
||||
union() {
|
||||
difference() {
|
||||
// the plate without any cutouts
|
||||
cube([width, length, height]);
|
||||
// two long cubic grooves at the bottom, each of them divided into two separate
|
||||
// grooves by the bridge
|
||||
translate([thin_wall, -half_man_cor, -half_man_cor]) {
|
||||
cube([cubic_groove_width, length + MANIFOLD_CORRECTION, cubic_groove_height + MANIFOLD_CORRECTION]);
|
||||
|
||||
translate([width - 2 * thin_wall - cubic_groove_width, 0, -half_man_cor])
|
||||
cube([cubic_groove_width, length + MANIFOLD_CORRECTION, cubic_groove_height + MANIFOLD_CORRECTION]);
|
||||
}
|
||||
// two long flat grooves at the bottom, each of them divided into two separate
|
||||
// grooves by the bridge
|
||||
rotate([90,0,0]) {
|
||||
translate([groove_distance, 0, -(length / 2)])
|
||||
flat_groove(length);
|
||||
translate([width - groove_distance, 0, -length / 2])
|
||||
flat_groove(length);
|
||||
}
|
||||
}
|
||||
// a bridge in the middle of length, used for the two short flat grooves and
|
||||
// dividing the long grooves into two grooves of equal length
|
||||
translate([0, length / 2 - bottom_bridge_width / 2,0])
|
||||
cube([width, bottom_bridge_width, 4.6]);
|
||||
}
|
||||
// the long cutout at the bottom with dynamic width
|
||||
translate([width / 2 - (6.9 + width - 30) / 2, -half_man_cor, -half_man_cor])
|
||||
cube([6.9 + width - 30, length + MANIFOLD_CORRECTION, cubic_groove_height + MANIFOLD_CORRECTION]);
|
||||
// the thin cubic grooves on the front and rear of the top
|
||||
translate([ -half_man_cor, thin_wall, height - cubic_groove_height])
|
||||
cube([width + MANIFOLD_CORRECTION, cubic_groove_width, cubic_groove_height + MANIFOLD_CORRECTION]);
|
||||
translate([-half_man_cor, length - thin_wall - cubic_groove_width , height - cubic_groove_height])
|
||||
cube([width + MANIFOLD_CORRECTION, cubic_groove_width, cubic_groove_height + MANIFOLD_CORRECTION]);
|
||||
}
|
||||
// the horizontal flat grooves on the top of the plate
|
||||
for (i = [0 : groove_distance : (length / groove_distance - 2) * groove_distance]) {
|
||||
translate([width / 2, i + groove_distance, height])
|
||||
rotate([270,0,90])
|
||||
flat_groove(width);
|
||||
}
|
||||
// the oval cutout through the plate
|
||||
translate([width / 2, 2.35 + 17.8, 0])
|
||||
hull() {
|
||||
cylinder(r=2.35, h=height + MANIFOLD_CORRECTION, center = false);
|
||||
translate([0,3.3,0])
|
||||
cylinder(r=2.35, h=height + MANIFOLD_CORRECTION, center = false);
|
||||
}
|
||||
// a short flat groove in the center of both long sides of the bottom
|
||||
translate([4.55, length / 2, 0])
|
||||
rotate([90,0,90])
|
||||
flat_groove(len = 9.10);
|
||||
translate([width - 4.55, length / 2, 0])
|
||||
rotate([90,0,90])
|
||||
flat_groove(len = 9.10);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A plate with holes to be combined with structural design components
|
||||
// like angele girders and struts
|
||||
// Attention: The thin paraameter makes sense only if the width is
|
||||
// greater than 30.
|
||||
// --------------------------------------------------------------------
|
||||
module plate_with_holes(length = 45, width = 90, height = WALL_THICKNESS, thin = false) {
|
||||
difference() {
|
||||
difference() {
|
||||
cube([width, length, height]);
|
||||
if (thin == true) {
|
||||
translate([BASIC_BLOCK_SIZE, height, height / 2])
|
||||
cube([width - (BASIC_BLOCK_SIZE * 2), length - (height * 2), (height / 2) + MANIFOLD_CORRECTION ]);
|
||||
}
|
||||
}
|
||||
eyelet_row(len = length, height = height * 2 + MANIFOLD_CORRECTION);
|
||||
translate([width - BASIC_BLOCK_SIZE, 0, 0])
|
||||
eyelet_row(len = length, height = height * 2 + MANIFOLD_CORRECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// A mounting plate like Art.No. 38246, optionally without pin
|
||||
// --------------------------------------------------------------------
|
||||
module plate_with_optional_pin(width = BASIC_BLOCK_SIZE, length = BASIC_BLOCK_SIZE, height = 2, with_pin = true) {
|
||||
union() {
|
||||
cube([width, length, height], center = true);
|
||||
if (with_pin == true)
|
||||
translate([0, 0, height / 2 - 0.01])
|
||||
pin();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Variation of the mounting plate, triangle
|
||||
// --------------------------------------------------------------------
|
||||
module plate_triangle(width = BASIC_BLOCK_SIZE, height = 2, orientation = 0) {
|
||||
half_width = width / 2;
|
||||
translate([0, 0, -height / 2])
|
||||
rotate([0, 0, orientation * 90])
|
||||
linear_extrude(height = height)
|
||||
polygon([[-half_width, -half_width], [half_width, -half_width], [-half_width, half_width]]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Variation of the mounting plate, half circle
|
||||
// --------------------------------------------------------------------
|
||||
module plate_half_circle(width = BASIC_BLOCK_SIZE, height = 2, orientation = 0) {
|
||||
rotate([0, 0, orientation * 90])
|
||||
union() {
|
||||
cylinder(d = width, h = height, center = true);
|
||||
translate([0, -width / 4, 0])
|
||||
cube([width, width / 2, height], center = true);
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// Variation of the mounting plate, quarter circle
|
||||
// --------------------------------------------------------------------
|
||||
module plate_quarter_circle(width = BASIC_BLOCK_SIZE, height = 2, orientation = 0) {
|
||||
pos = (orientation == 1 ? [ width / 2, -width / 2, -height / 2] :
|
||||
(orientation == 2 ? [ width / 2, width / 2, -height / 2] :
|
||||
(orientation == 3 ? [-width / 2, width / 2, -height / 2] :
|
||||
[-width / 2, -width / 2, -height / 2])));
|
||||
translate(pos) {
|
||||
intersection() {
|
||||
rotate([0, 0, orientation * 90])
|
||||
cube([width, width, height]);
|
||||
cylinder(r = width, h = height);
|
||||
}
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// Variation of the mounting plate, inverted quarter circle
|
||||
// --------------------------------------------------------------------
|
||||
module plate_quarter_circle_inverted(width = BASIC_BLOCK_SIZE, height = 2, orientation = 0) {
|
||||
difference() {
|
||||
cube([width - 0.01, width - 0.01, height], center = true);
|
||||
translate([0,0, -0.1])
|
||||
plate_quarter_circle(width = width, height = height + 0.3, orientation = orientation);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// A complex mounting plate, configurable by a layout matrix.
|
||||
// Every vector in the matrix describes one y-Column of 15x15 mounting
|
||||
// plates. The following values are valid:
|
||||
// 0 - no segment at this position
|
||||
// 1 - segment with a pin
|
||||
// 2 - segment without pin
|
||||
// 3,4,5,6 - half circles
|
||||
// 7,8,9,10 - triangle segments, diagonal half of normal segment
|
||||
// 11,12,13,14 - circle segments
|
||||
// 15,16,17,18 - inverted circle segments
|
||||
// Play with the grid_layout to see what is possible.
|
||||
// Attention: Only the 15 x 15 segment may have a pin, all others would
|
||||
// place a part of the pin in an empty area of the segment
|
||||
// -------------------------------------------------------------------------
|
||||
module mounting_plate(grid_layout = [[1,2,2,1],[2,2,2,2],[2,2,2,2],[1,2,2,1],], height = 2) {
|
||||
union() {
|
||||
for(i = [0 : len(grid_layout)-1]) {
|
||||
for(j = [0 : len(grid_layout[i])-1]) {
|
||||
translate([BASIC_BLOCK_SIZE*i, BASIC_BLOCK_SIZE*j, 0])
|
||||
if (grid_layout[i][j] == 1)
|
||||
plate_with_optional_pin(height = height);
|
||||
else if (grid_layout[i][j] == 2)
|
||||
plate_with_optional_pin(height = height, with_pin = false);
|
||||
else if (grid_layout[i][j] >= 3 && grid_layout[i][j] <= 6)
|
||||
plate_half_circle(height = height, orientation = grid_layout[i][j] - 3);
|
||||
else if (grid_layout[i][j] >= 7 && grid_layout[i][j] <= 10)
|
||||
plate_triangle(height = height, orientation = grid_layout[i][j] - 7);
|
||||
else if (grid_layout[i][j] >= 11 && grid_layout[i][j] <= 14)
|
||||
plate_quarter_circle(height = height, orientation = grid_layout[i][j] - 11);
|
||||
else if (grid_layout[i][j] >= 15 && grid_layout[i][j] <= 18)
|
||||
plate_quarter_circle_inverted(height = height, orientation = grid_layout[i][j] - 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (PlateType == 1) {
|
||||
build_plate(Rows,Columns);
|
||||
}
|
||||
else if (PlateType == 2) {
|
||||
bottom_plate(length = Length, width = Width);
|
||||
}
|
||||
else if (PlateType == 3) {
|
||||
plate_with_holes(length = Length, width = Width, thin = Thin_Center);
|
||||
}
|
||||
else if (PlateType == 4) {
|
||||
mounting_plate(Layout);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
// ------------------------------------------------------------------------
|
||||
// Customizable struts for Fischertechnik.
|
||||
// The modules in this file can be used to generate:
|
||||
// - i-struts (struts with a length which is a multiple of the basic
|
||||
// building block (15 mm)). i-struts may or may not have additional
|
||||
// eyelets every 15 mm.
|
||||
// - x-struts with predefined length corresponding to the Fischertechnik
|
||||
// original struts.
|
||||
// - x-struts with any length to connect other diagonal distances than
|
||||
// the standard x-struts.
|
||||
//
|
||||
// Diagonal distances between structural design elements (15 mm grid) which
|
||||
// might be printable depending on your 3D printers build plate:
|
||||
// from https://www.ftcommunity.de/data/downloads/beschreibungen/statikhilfe.pdf
|
||||
// R15 | 15 | 30 | 45 | 60 | 75 | 90 | 105 | 120 | 135 |
|
||||
// 15 | 21,2 | | | | | | | | |
|
||||
// 30 | 33,5 | 42,4 | | | | | | | |
|
||||
// 45 | 47,4 | 54,1 | 63,6 | | | | | | |
|
||||
// 60 | 61,8 | 67,1 | 75,0 | 84,9 | | | | | |
|
||||
// 75 | 76,5 | 80,8 | 87,5 | 96,0 | 106,1 | | | | |
|
||||
// 90 | 91,2 | 94,9 | 100,6 | 108,2 | 117,2 | 127,3 | | | |
|
||||
// 105 | 106,1 | 109,2 | 114,2 | 120,9 | 129,0 | 138,3 | 148,5 | | |
|
||||
// 120 | 120,9 | 123,7 | 128,2 | 134,2 | 141,5 | 150,0 | 159,5 | 169,7 | |
|
||||
// 135 | 135,8 | 138,3 | 142,3 | 147,7 | 154,4 | 162,2 | 171,0 | 180,6 | 190,9 |
|
||||
// 150 | 150,7 | 153,0 | 156,6 | 161,6 | 167,7 | 174,9 | 183,1 | 192,1 | 201,8 |
|
||||
// 165 | 165,7 | 167,7 | 171,0 | 175,6 | 181,2 | 187,9 | 195,6 | 204,0 | 213,2 |
|
||||
// 180 | 180,6 | 182,5 | 185,5 | 189,7 | 195,0 | 201,2 | 208,4 | 216,3 | 225,0 |
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
//----------------------- parameters ---------------------------
|
||||
/* [Strut options] */
|
||||
// The type of the strut, may be an I-Strut or an X-Strut
|
||||
StrutType = 0; // [0 : no output, 1:X-Strut, 2:I-Strut, 3:I-Strut with hole]
|
||||
|
||||
// The length of the I-Strut (should be a multiple of the basic block size of 15 mm)
|
||||
I_Strut_Length = 60; // [15:15:195]
|
||||
|
||||
// The length of the X-Strut
|
||||
X_Strut_Length = 42.4; // [21.2, 42.4, 63.6, 84.8, 106.1, 127.3, 148.5, 169.6, 190.9]
|
||||
|
||||
// An individual strut length for X-Struts (overrides X_Strut_Length if > 1.0)
|
||||
Individual_Strut_Length = 0.1;
|
||||
|
||||
// Should the backside be indented too? If printed with indention, the indention is too small to use support structures and remove them successfully.
|
||||
Indent_Backside = 0; // [0:No, 1:Yes ]
|
||||
|
||||
/* [Hidden] */
|
||||
|
||||
// **********************
|
||||
// ** Static Settings: **
|
||||
// **********************
|
||||
|
||||
// $fn = 50;
|
||||
$fa = 0.5; // default minimum facet angle is now 0.5
|
||||
$fs = 0.5; // default minimum facet size is now 0.5 mm
|
||||
// Build plate size correction for the eyelets
|
||||
Correction = 0.2; // [0.0, 0.1, 0.2, 0.3]
|
||||
|
||||
|
||||
strut_radius = 3.975;
|
||||
strut_width = 7.95;
|
||||
strut_thickness = 2.8;
|
||||
// strut_eyelet_radius = 3.2;
|
||||
strut_eyelet_radius = 3.3;
|
||||
jut = 0.1;
|
||||
eyelet_height = strut_thickness + jut;
|
||||
|
||||
// *********************
|
||||
// ** Helper Modules: **
|
||||
// *********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a basic strut without any eyelets
|
||||
// --------------------------------------------------------------------
|
||||
module strut(len = 15, h = strut_thickness, w = strut_width) {
|
||||
hull() {
|
||||
cylinder(d = w, h = h, center = true);
|
||||
translate([0, len, 0])
|
||||
cylinder(d = w, h = h, center = true);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a single eyelet which can be substracted from a strut
|
||||
// --------------------------------------------------------------------
|
||||
module strut_eyelet(radius = strut_eyelet_radius, correctionVal = 0.0) {
|
||||
cube_width = radius * 2;// apply_correction(7.2, correctionVal, horizontal);
|
||||
cube_height = 3.1; // apply_correction(3.1, correctionVal, horizontal);
|
||||
|
||||
union() {
|
||||
// prefix the intersection with render(), otherwise we'll get
|
||||
// a message "Normalized Tree is growing past 200000 elements"
|
||||
// on i_struts with a lot of eyelets.
|
||||
// It takes a bit on the first compile, but the after rendering
|
||||
// the eyelet is in the cache and draws relatively fast.
|
||||
// Without the render() an i_strut(360) takes forever to calculate.
|
||||
render() intersection() {
|
||||
#union() {
|
||||
cube([cube_height,cube_width,eyelet_height], center = true);
|
||||
cylinder(r = 2.1, h = eyelet_height, center = true);
|
||||
}
|
||||
cylinder(r = radius, h = eyelet_height, center = true);
|
||||
}
|
||||
translate([0, 0, 0.375 + 0.65])
|
||||
cylinder(r = radius, h = 0.75 + jut, center = true);
|
||||
translate([0, 0,-(0.375 + 0.65)])
|
||||
cylinder(r = radius, h = 0.75 + jut, center = true);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a single indention to be placed between two eyelets on a strut.
|
||||
// --------------------------------------------------------------------
|
||||
module indention(len = 1, width = 1, off = 1, indention = 1) {
|
||||
translate([0, len / 2, indention])
|
||||
cube([width, len - off * 2, 0.75 + jut], center = true);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a row of eyelets every 15 mm for the i-struts
|
||||
// --------------------------------------------------------------------
|
||||
module strut_eyelet_row(cnt = 1, eyelet_dist = FT_GRID_SIZE, correction = 0.0) {
|
||||
for (i = [0 : eyelet_dist : cnt * eyelet_dist]) {
|
||||
translate([0, i, 0]) {
|
||||
strut_eyelet(correctionVal = correction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a row of indentions between the eyelets on an i-strut
|
||||
// --------------------------------------------------------------------
|
||||
module strut_indention_row(cnt = 1, eyelet_dist = FT_GRID_SIZE, indention = 0.375 + 0.65) {
|
||||
for (i = [0 : eyelet_dist : cnt * eyelet_dist]) {
|
||||
translate([0, i, 0])
|
||||
indention(len = eyelet_dist, width = strut_eyelet_radius * 2, off = strut_radius, indention = indention);
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Strut Modules: **
|
||||
// ********************
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// a strut with an eyelet at both ends and the length as text on the
|
||||
// center of the indendtion
|
||||
// --------------------------------------------------------------------
|
||||
module x_or_i_strut(len = FT_GRID_SIZE * 2, h = strut_thickness, w = strut_width) {
|
||||
union() {
|
||||
difference() {
|
||||
strut(len = len, h = h, w = w);
|
||||
strut_eyelet();
|
||||
translate([0, len, 0])
|
||||
strut_eyelet();
|
||||
indention(len = len, width = strut_eyelet_radius * 2, off = strut_radius, indention = 0.375 + 0.65);
|
||||
if (Indent_Backside == 1)
|
||||
indention(len = len, width = strut_eyelet_radius * 2, off = strut_radius, indention = -(0.375 + 0.65));
|
||||
}
|
||||
linear_extrude(height = 1.1, convexity = 100, twist = 0)
|
||||
translate([0,len / 2 , 1])
|
||||
rotate([0, 0, 90])
|
||||
text(str(len), font="Impact", size = 3.5, valign="center", halign="center");
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------
|
||||
// an i-strut with eyelets every 15mm
|
||||
// --------------------------------------------------------------------
|
||||
module i_strut_with_holes(len = FT_GRID_SIZE * 2, h = strut_thickness, w = strut_width) {
|
||||
difference() {
|
||||
strut(len = len, h = h, w = w);
|
||||
strut_eyelet_row(len / FT_GRID_SIZE);
|
||||
strut_indention_row(cnt = (len / FT_GRID_SIZE) - 1);
|
||||
if (Indent_Backside == 1)
|
||||
strut_indention_row(cnt = (len / FT_GRID_SIZE) - 1, indention = -(0.375 + 0.65));
|
||||
}
|
||||
}
|
||||
|
||||
// ********************
|
||||
// ** Build section: **
|
||||
// ********************
|
||||
module main() {
|
||||
if (StrutType == 1) {
|
||||
if (Individual_Strut_Length > 1.0)
|
||||
x_or_i_strut(len = Individual_Strut_Length);
|
||||
else
|
||||
x_or_i_strut(len = X_Strut_Length);
|
||||
}
|
||||
else if (StrutType == 2) {
|
||||
x_or_i_strut(len = I_Strut_Length);
|
||||
}
|
||||
else if (StrutType == 3) {
|
||||
i_strut_with_holes(len = I_Strut_Length);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user