fischertechnik-box-foundation

OpenSCAD sorting box construction foundation for Fischertechnik parts

View the Project on GitHub proggi64/fischertechnik-box-foundation

Wie konstruiere ich einen Sortierkasten?

Im folgenden Tutorial erfährt man

Was brauche ich?

Erste Schritte: Eine kleine Box für den Elektronik-Grundbaustein

Ziel des Tutorials ist der Bau eines 130 x 95 kleinen Sortierkastens, in den der Silberling mitsamt Verbindungsstecker, Drehknopf, zwei Kontrollleuchten und einigen Kleinteilen Platz findet. Der Kasten ist nur halb so groß wie ein Standardeinsatz im Fischertechnik-Kasten 1000. Wenn man den auf einen Sortierkasten 190 x 130 stapelt, hat man daneben noch Platz für einen zweiten.

h4 G

Falls man sein Ergebnis hier auf GitHub veröffentlichen will: Der Platz für Eigenentwürfe ist im Ordner Building Kits vorgesehen. Die relativen Pfade bei den use-Anweisungen gehen davon aus, dass die Dateien dort in einem weiteren Unterverzeichnis stehen. Das Beispiel hier existiert bereits im Unterverzeichnis hobby als h4 GB.scad.

Neue SCAD.Datei

Wir legen die SCAD-Datei an und speichern sie.

// Box 130x95
// h4 G
// Elektronik Grundbeistein
// 39581

Datei speichern)

Erst nach dem Speichern können die Pfade der noch folgenden use-Anweisungen aufgelöst werden, damit wir ein Vorschaubild unseres Kastens sehen können.

Wenn wir die Datei wie hier im Beispiel innerhalb der Pfadstruktur der Bibliothek anlegen (hier tutorial), bauen wir automatisch eine Kopplung an GitHub auf, d.h. wir können unser Beispiel auch ins Git pushen, falls wir einen Fork statt eines Downloads verwenden. Wem das zu kompliziert ist, dem sei empfohlen, einfach die Bibliothek per Download zu holen.

Der Basiskasten

Wir legen den Basiskasten 130 x 95 an. Dieser ist die halb so große Version der acht Standard-Sortierkästen aus der Box 1000. Für unseren Silberling reicht das, für alle größeren gibt’s die Box190.

use <../../Base/Boxes.scad>

Box130();

Die leere Box wird so platziert, dass die Oberfläche des Bodens exakt auf Höhe 0 liegt. Der verwendbare Bereich liegt an X/Y-Position 0,0, so dass man die Wände bei der Positionierung nicht berücksichtigen muss.

Box 130)

Für die Kleinteile

Wir erzeugen eine Trennwand für den Bereich, in den später die Kabel, der Kondensator und der Widerstand Platz finden.

use <../../Base/Boxes.scad>
use <../../ModelBase/Simple.scad>

Box130();

boxSpace=getBox130Space();
dividerWidth = 20;

Divider(dividerWidth, boxSpace=boxSpace);

Divider)

Zumeist ist es eine gute Idee, konstante Werte Variablen zuzuweisen. Wir brauchen diese später noch an anderen Stellen, deswegen werden hier boxSpace und dividerWidth zugewiesen, bevor sie Divider übergeben werden.

Zwei Anmerkungen zu SCAD:

“Variablen” sind nicht variabel. Sie können nicht wie in den prozeduralen Sprachen Java oder C verändert werden. Stattdessen bekommen sie den zuletzt zugewiesenen Wert, und der gilt auch in allen Zeilen desselben Gültigkeitsbereichs zuvor. Wenn in Zeile 10 x=5 steht und in Zeile 20 x=10, dann hat x in Zeile 10 schon den Wert 10. Eine Warnung in der Konsole bei der Ausführung weist zumindest auf die überschreibende Zuweisung hin. Wenn man Variablen verändern will, muss man die let-Anweisung verwenden.

Optionale Parameter kann man durch Angabe des Parameternamens beim Aufruf setzen. Das passiert in unserem Beispiel, wo der Name des optionalen Parameters boxSpace zufällig dem der Variablen boxSpace entspricht. Was was ist, erkennt SCAD am Kontext, gleiche Namen sind hier also erlaubt und durchaus sinnvoll.

Für den Silberling

Wir erzeugen einen an zwei Wände angedockten Rahmen für den Silberlink rechts vorne in der Ecke.

use <../../Base/Boxes.scad>
use <../../Base/Placement.scad>
use <../../ModelBase/Simple.scad>
use <../../Elements/FrameElectronicBlock.scad>

include <../../Base/PlacementOptions.scad>

Box130();

boxSpace=getBox130Space();
dividerWidth = 20;
electronicBlockSpace = getFrameElectronicBlockSpace(alignX=AlignRight, alignY=AlignBottom);

Divider(dividerWidth, boxSpace=boxSpace);

Place(alignX=AlignRight, alignY=AlignBottom, 
    elementSpace=electronicBlockSpace,
    boxSpace=getBox130Space())
    FrameElectronicBlock(alignX=AlignRight, alignY=AlignBottom);

FrameElectronicBlock)

Placement.scad enthält das Place-Modul. Das kann u.a. Elemente auf Flächen ausrichten. Das verwenden wir hier, um das Element FrameElectronicBlock in der vorderen rechten Ecke zu verankern.

Dafür benötigt Place die Fläche, die das Element hat (elementSpace), und die Fläche, auf der ausgerichtet wird (getBox130Space). In OpenSCAD kann man das nicht über das Element ermitteln, sondern muss es explizit in einer separaten Funktion zur Verfügung stellt. jedes Element der Bibliothek hat dafür die Funktion mit den Namensschema getElementNameSpace(), wobei man ElementName durch den tatsächlichen namend es Elements ersetzen muss. Hier verwenden wir getframeElectronicBlockSpace().

Damit die Funktion getframeElectronicBlockSpace() dies auch korrekt errechnen kann, benötigt es die notwendigen Parameter. Die meisten Element haben keine Parameter, so das man dort auch der Funktion keine übergeben muss. Hier verändert sich aber der Rahmen durch die Angabe, an welche Seiten angedockt werden soll, und dadurch verändert sich auch die Fläche des Elements.

Die Parameter xAlign und yAlign sind optional. Wenn der Rahmen nicht angedockt wird, fallen beide weg. Da wir hier an zwei Seiten docken, brauchen wir aber beide. Es gibt einige Elemente, die auch durch Andocken ihre Gestalt ändern, und bei allen werden dieselben Parameter verwendet. Damit man sich keine Zahlen merken muss, wurden in der Datei Base/PlacementOptions.scad Variablen mit sprechenden Namen definiert, die man hier als Werte für die Variablen übergeben kann. Diese Datei muss als einzige per include eingebunden werden, da use keine Variablen, sondern nur Funktionen und Module importiert. Bei den Beschreibungen aller Module und Elemente, die solche Wert verwenden können, sind diese Namen dokumentiert.

Das Ergebnis: Der Rahmen für den Silberling sieht so aus, wie er auch in den ec-Kästen vorkommt. Es werden Stege als Abstandshalter zu den Wänden generiert, die mit den Außenwänden verschmelzen. Wenn man ein “#” vor Box130 stellt und dadurch die Box teilweise transparent macht, kann man diese Verschmelzung gut erkennen.

Dock Melting)

Einige Elemente in der Bibliothek unterstützen explizit das Andocken. Die Vorbilder dazu finden sich in den Kunststoffkästen von Fischertechnik, wie sie in den 70er Jahren geliefert wurden.

Elemente für die Spezialteile

Ziel der Bibliothek ist es, einen umfangreichen Grundstock an Elementen zur Verfügung zu stellen. Für unseren Kasten sind die Elemente bereits alle vorhanden:

Um auf diese Element zugreifen zu können, fügen wir oben im Code die folgenden _use-Anweisungen ein:

use <../../Elements/FrameControlLight.scad>
use <../../Elements/AxisDial.scad>
use <../../Elements/FrameElectronicBlockConnector.scad>

Vorbereitung der Platzierung

Jetzt müssen wir die Elemente noch platzieren. Kriterien sollten dabei sein:

Der freie Platz zwischen dem Silberling und der Trennwand links bietet sich für die Elemente an. Die Bibliothek stellt einige Module zur Verfügung, die Elemente ausrichten oder verteilen können. Prinzipiell kann man sich auch auf die mit OpenSCAD gelieferten Funktionalitäten beschränken, aber Ausrichten und Verteilen kann OpenSCAD nicht von allein.

Nachträgliche Veränderungen fallen in einigen Situationen leichter, wenn die Positionen relativ zueinander berechnet werden, anstatt sie alle absolut anzugeben. Dadurch kann die Änderung eines Wertes reichen, um eine Korrektur durchzuführen. Das muss aber nicht immer so sein. Hier muss man sich vorher die Frage stellen, wo Änderungen und Anpassungen während des Entwurfs am wahrscheinlichsten sind und welche Wirkung das haben kann.

In unserem Fall werden Position und Größe der freien Fläche mit relativen Werten bezogen auf die beiden schon platzierten Elemente berechnet. Jetzt brauchen wir noch die Datei Base/Constants.scad:

use <../../Base/Constants.scad>

Hier finden wir Funktionen, die Standardwerte liefern, z.B. die Stärke von Trennwänden (getDividerThickness), den Durchmesser von Fischertechnik-Achsen (getAxisDiameter), die Toleranzen und eine Reihe weiterer Werte.

    boxSpace=getBox130Space();

    electronicBlockSpace = getFrameElectronicBlockSpace(alignX=AlignRight, alignY=AlignBottom);

Wie weiter oben schon gezeigt, benötigen wir die tatsächliche Fläche des Rahmens für den Silberling und stellen sie in die Variable electronicBlockSpace.

    dividerWidth = 20;
    leftOffset = dividerWidth + getDividerThickness();
    rightOffset = getBox130Space().x - electronicBlockSpace.x;

Auch die Breite des Fachs mit der Trennwand spielt eine wichtige Rolle und wird in dividerWidth gespeichert. leftOffset wird dann berechnet, indem zu diesem betrag noch die Stärke der Trennwand addiert wird. Ab dort beginnt der freie Platz links.

Für rightOffset rechnen wir die Breite des nutzbaren BEreichs des Sortierkastens und ziehen den Platz für den Rahmen des Silberlings ab. Die Stärke von dessen Trennwand ist bereits im Wert entahlten, den electronicBlockSpace gespeichert hat.

Damit haben wir die linke und rechte X-Position des freien Bereichs.

Left Right Offset)

    distance = 15;
    bottomOffset = 15;
    topOffset = 15;

    partsSpace = [rightOffset - leftOffset - 2*distance, boxSpace.y - bottomOffset - topOffset];

Die Abstände zu diesen Positionen legen wir mit konstanten Werten fest und stellen sie in diese Variablen:

Damit können wir auch den Platz berechnen, der für die Teile genutzt werden soll. Dieser wird in partsSpace als [x,y]-Liste abgelegt.

Hilfreich für die Konstruktion ist es oft, diese Fläche über ein transparentes Rechteck sichtbar zu machen. Das kann man nach dem Platzieren wieder löschen, hilft aber für die Einschätzung und ob alles richtig gerechnetund platziert wurde:

partsXPosition = leftOffset + distance;
partsYPosition = bottomOffset;

Place(partsXPosition, partsYPosition) {
    #cube([partsSpace.x, partsSpace.y, 2]);
}

Parts Space)

Das ist also die Ausgangsposition, um die letzten Elemente zu platzieren. partsSpace und die Koordinaten brauchen wir beim nächsten Schritt.

Die gute Nachricht ist, dass die Bibliothek das Konstruieren der Kästen weitestgehend mit nur zweidimensionsionaler Geometrie ermöglicht. um die dritte Dimension kümmern sich die vorgefertigten Elemente.

Verteilen der Elemente

Wir brauchen jetzt noch eine weitere use-Anweisung:

use <../../Base/Deployment.scad>

Deployment.scad liefert uns Zugriff auf die Module zur Verteilung von Elementen. Wir wollen davon das Modul DeploySame verwenden.

Jetzt werden noch die drei Elemente FrameElectronicBlockConnector, FrameControlLight und AxisDial auf der Fläche verteilt.

Wir starten mit FrameElectronicBlockConnector:

Place(partsXPosition, partsYPosition) {
    #cube([partsSpace.x, partsSpace.y, 2]);

    DeploySame(partsSpace, getFrameElectronicBlockConnectorSpace(), rotation=Rotate90, columns=1)
        FrameElectronicBlockConnector();

DeploySame erzeugt und verteilt das angegebene children-Element einmal oder mehrfach. Es hat eine Reihe optionaler Parameter. In unserem Fall wollen wir nur ein Element (columns=1), und dieses soll um 90° gedreht werden. Weil keine weiteren Koordinaten angegeben sind, wird das eine Element mittig unten (lokale 0-X-Position) auf der Fläche platziert.

Damit die Rotation und die Verteilung möglich sind, müssen sowohl die Fläche des Elements, wie auch die Zielfläche angegeben werden.

Alternativ kann man in unserem Fall mit dem einen Element auch Center verwenden. Durch DeploySame können wir aber durch Setzen von columns auf 2 einfach zwei Elemente platzieren. Diese werden dann links und rechts an den Rand gestellt. Bei 3 wären die drei Elemente im gleichen Abstand verteilt. Einfach mal im Code ausprobieren.

In denselben Block setzen wir jetzt die Kontrolleuchten:

    CenterVertical(depth=getFrameControlLightSpace().y, space=partsSpace)
        DeploySame(partsSpace, getFrameControlLightSpace())
            FrameControlLight();

Standardwert für columns ist 2, so dass wir durch Weglassen dieses optionalen Parameters Rahmen für zwei Kontrollleuchten bekommen. Mit __CenterVertical sorgen wir dafür, dass das Element vertikal mittig platziert wird.

Zum Schluss noch die Achse für den Drehregler, wieder innerhalb desselben Blocks:

    Place(elementSpace=getAxisDialSpace(), alignY=AlignTop, alignX=AlignCenter, boxSpace=partsSpace)
        AxisDial();

Die Ausrichtung oben in der Fläche erledigt wieder Place mit dem Parameterwerten alignY=AlignTop und alignX=AlignCenter.

BoxSilberling

Ausblick

Das Beispiel mit dem Silberling ist eine vereinfachte Variante der flexibler einsetzbaren SCAD-Datei BuildingKits/hobby/ElectronicBlockBoxBase.scad. Bei diesem Modul kann die Anzahl der Spezialelemente jeweils als Parameter übergeben werden, so dass Kästen für Silberlinge mit 0 bis 2 Drehknöpfen oder Kontrollleuchten nur durch Parameter erzeugt werden können. Das Modul unterstützt dabei auch den Customizer von OpenSCAD, um diese Parameter dynamisch in der Oberfläche zu setzen.

Voraussichtlich werden immer wieder neue Elemente hinzukommen, aber auch komfortablere Verteil- und Platzierungsfunktionen. Am besten immer wieder mal die neue Version holen.