From f90ec047a6c07f2259b184ef29cde145855b8eac Mon Sep 17 00:00:00 2001 From: shy Date: Wed, 1 Jun 2022 08:29:44 +0200 Subject: [PATCH] Moved to github.com. --- .gitignore | 5 + LICENSE | 121 +++ README.md | 18 + back.scad | 536 +++++++++++++ buttons.scad | 243 ++++++ colors.scad | 16 + front.scad | 401 ++++++++++ svg/back borders lower.svg | 87 ++ svg/back borders.svg | 67 ++ svg/back construction.svg | 858 ++++++++++++++++++++ svg/back hull.svg | 79 ++ svg/back loops.svg | 67 ++ svg/back pillars struts.svg | 67 ++ svg/back pillars.svg | 72 ++ svg/back sticks pillars top.svg | 70 ++ svg/back sticks pillars.svg | 70 ++ svg/back sticks struts.svg | 72 ++ svg/back struts.svg | 67 ++ svg/back top.svg | 80 ++ svg/buttons action base.svg | 69 ++ svg/buttons action carvings.svg | 104 +++ svg/buttons action main.svg | 66 ++ svg/buttons trigger lower.svg | 59 ++ svg/buttons trigger upper.svg | 69 ++ svg/front analog sticks struts.svg | 67 ++ svg/front analog sticks.svg | 67 ++ svg/front borders lower.svg | 68 ++ svg/front borders.svg | 68 ++ svg/front button action lower.svg | 67 ++ svg/front button action upper.svg | 67 ++ svg/front button system lower.svg | 67 ++ svg/front button system upper.svg | 67 ++ svg/front construction.svg | 1181 ++++++++++++++++++++++++++++ svg/front hull.svg | 78 ++ svg/front led bottom.svg | 69 ++ svg/front led gauge.svg | 65 ++ svg/front led y.svg | 65 ++ svg/front struts.svg | 68 ++ svg/front top.svg | 70 ++ 39 files changed, 5497 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 back.scad create mode 100644 buttons.scad create mode 100644 colors.scad create mode 100644 front.scad create mode 100644 svg/back borders lower.svg create mode 100644 svg/back borders.svg create mode 100644 svg/back construction.svg create mode 100644 svg/back hull.svg create mode 100644 svg/back loops.svg create mode 100644 svg/back pillars struts.svg create mode 100644 svg/back pillars.svg create mode 100644 svg/back sticks pillars top.svg create mode 100644 svg/back sticks pillars.svg create mode 100644 svg/back sticks struts.svg create mode 100644 svg/back struts.svg create mode 100644 svg/back top.svg create mode 100644 svg/buttons action base.svg create mode 100644 svg/buttons action carvings.svg create mode 100644 svg/buttons action main.svg create mode 100644 svg/buttons trigger lower.svg create mode 100644 svg/buttons trigger upper.svg create mode 100644 svg/front analog sticks struts.svg create mode 100644 svg/front analog sticks.svg create mode 100644 svg/front borders lower.svg create mode 100644 svg/front borders.svg create mode 100644 svg/front button action lower.svg create mode 100644 svg/front button action upper.svg create mode 100644 svg/front button system lower.svg create mode 100644 svg/front button system upper.svg create mode 100644 svg/front construction.svg create mode 100644 svg/front hull.svg create mode 100644 svg/front led bottom.svg create mode 100644 svg/front led gauge.svg create mode 100644 svg/front led y.svg create mode 100644 svg/front struts.svg create mode 100644 svg/front top.svg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a046280 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.swp + +notes.md + +specs/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc8ebe8 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Hülle für die u23-Spielekonsole. + +## STL-Dateien +*back full.stl* – Rückseite mit genug Raum für das WLAN-Modul. +*back slim.stl* – Schmalere Rückseite. +*buttons.stl* – Buttons. +*front sticks.stl* – Vorderseite mit Durchbrüchen für die Analog-Sticks. +*front.stl* – Vorderseite. + +## Anmerkungen +* Notwendige Stützstrukturen sind bereits in den Dateien Angelegt. +* Für den Zusammenbau der Hülle braucht es 4 M3-Schrauben und Muttern. + * Schraubenlänge für die schmale Variante: 16mm. + * Schraubenlänge für die dickere Variante: 25mm. +* Die Datei "buttons.scad" liest Parameter aus der Datei "front.scad". Wenn Parameter in "front.scad" geändert werden, sollten auch die Buttons neu gerendert werden. + +## Lizenz +[CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/deed.de) diff --git a/back.scad b/back.scad new file mode 100644 index 0000000..25f954f --- /dev/null +++ b/back.scad @@ -0,0 +1,536 @@ +/************************************************************************* + * Hülle für die u23-Spielekonsole. * + * Rückseite. * + * * + * Author: Shy * + * License: CC0 * + *************************************************************************/ + + include ; + +/* Höhe wichtiger Bauteile: + * + * NRF-Modul: + * H: ~ 15 mm + * + * USB Port: + * GCT USB4105-GF-A + * H: 3.31 mm + * B: 8.94 mm / 9.58 mm + * L: 7.53 mm + * + * Klinkennuchse: + * CUI SJ1-3523N + * H: 6 mm + * B: 12 mm + * L: 14 mm + * + * RJ-45 Buchse: + * RJMG1BD3B8K1ANR + * H: 13.35 mm + * B: 15.75 mm + * L: 21.72 mm + * + * Vibrationsmotor: + * Jinlong Z4KC1B1051202 + * H: 4.5 mm + * B: 4.6 mm + * L: 15.6 mm + * + * CF-Kartenadapter: + * Hirose DM3AT-SF-PEJM5 + * H: 1.6 mm + */ + +/* Default slim (Schrauben: M3, 16mm). + * + * space = 8; + * border_height = 4; + * nut_sink = 6; + * side_recess = 0; + * + * + * Default full (Schrauben: M3, 25mm). + * + * space = 15; + * border_height = 8; + * nut_sink = 4; + * side_recess = 4; + */ + +// Stützstrukturen. +support = true; + +// Abgerundete Kanten (aufwendig). +rounded_corners = true; + +// Dicke der Decke. +thickness = 1; + +// Höhe des Innenraumes. +space = 8; + +// Höhe des Randes. (Empfohlen: space/2.) +border_height = 4; + +// Höhe der Verstrebungen. +struts = 2; + +// Dicke der Aufhängungen an der Vorderkante. +loop_thickness = 3.5; + +// Durchmesser der Bohrungen. +drill = 3.4; + +// Durchmesser der Bohrschäfte. +drill_shaft = 7.4; + +// Wird ein Gewindeeinsatz verwendet? +threaded_insert = false; + +// Tiefe der Versenkung für die Mutter. +nut_sink = 6.0; + +// Schlüsselweite der Mutter (M3 = 5.5 + Spiel). +wrench_size = 5.8; + +// Durchmesser der Mutter von Kante zu Kante. +nut_size = wrench_size * 2 / sqrt(3); + +// Position der Bohrungen. +drill_pos = [ + [10, 10], + [10, 90], + [140, 10], + [140, 90], +]; + + +// Platziere Reflektionsflächen unter den LEDs. +led_reflectors = false; + +// Aussparungen über den Befestigungslöchern an den Seiten. +side_recess = 0; + +// Füge Strukturen zur Stützung der Buttons auf der Vorderseite hinzu. +button_support = true; + +// Füge Strukturen zur Stützung der Analog Sticks hinzu. +stick_support = true; + +// Höhe, die der USB-Port benötigt. +limit_usb = 3.4; + +// Höhe, die die Klinkenbuchse benötigt. +limit_audio_jack = 6.5; + +// Soll ein nRF24-Modul verbaut werden? +nrf_module = false; + +// Höhe, die das nRF24-Modul benötigt. +limit_nrf = 15; + +// Höhe, die der Vibrationsmotor benötigt. +limit_vib = 7.5; + + +/************************************************************************* + * Überprüfe Parameter auf Fehler. * + *************************************************************************/ + +// Achte auf die Höhe ausgewählter Bauteile. +if ((space - border_height) < limit_usb) { + if ($preview) { + // Zeige den Platz, den der USB-Port braucht. + color(color_warning) + translate([40, 92.35, space + thickness - limit_usb]) + cube([9, 8, limit_usb]); + } else { + assert((space - border_height) >= limit_usb, + "USB-Port hat zu wenig Platz!"); + } +} + +if (nrf_module && (space < limit_nrf)) { + if ($preview) { + // Zeige den Platz, den das nRF24-Modul braucht. + color(color_warning) + translate([101.25, 81.75, thickness]) + cube([29.5, 15.75, limit_nrf]); + } else { + assert(space >= limit_nrf, + "nRF24-Modul hat zu wenig Platz!"); + } +} + + +/************************************************************************* + * Einzelteile * + *************************************************************************/ + +// Reflektionsflächen für die LEDs. +module led_reflector() { + h = min(border_height + 2.5, space - 2.5); + l = 12; + w = 4; + $fn = 24; + + // Sockel + translate([-w/2, -l/2, 0]) + cube([w, l, struts]); + + hull() { + translate([0, w/2 - l/2, 0]) { + // Basis. + cylinder(r=w/2, h=1); + // Kuppelform. + translate([0, 0, h - 3.5]) + intersection() { + sphere(r=w/2); + translate([-w/2, -w/2, 0]) + cube([w, w, w]); + } + // Spitze. + translate([0.5 + w/4, 0.5 + w/4, h - 0.25]) + sphere(0.5); + } + translate([0, l/2 - w/2, 0]) { + // Basis. + cylinder(r=w/2, h=1); + // Kuppelform. + translate([0, 0, h - 3.5]) + intersection() { + sphere(r=w/2); + translate([-w/2, -w/2, 0]) + cube([w, w, w]); + } + // Spitze. + translate([0.5 + w/4, 0.5 + w/4, h - 0.25]) + sphere(0.5); + } + } +} + +// Schaft für die Schrauben. +module screw_shaft() { + translate([0, 0, thickness]) + cylinder(h = space, r = drill_shaft/2, $fn=32); + // Verdickung, um die Versenkung zu kompensieren. + if(nut_sink > 0 && !threaded_insert) { + translate([0, 0, thickness]) + cylinder(h = nut_sink, r = (nut_size + drill_shaft - drill)/2, $fn=32); + intersection() { + translate([0, 0, thickness + nut_sink]) + cylinder((nut_size + drill_shaft - drill)/2, (nut_size + drill_shaft - drill)/2, 0, $fn=32); + // Begrenzt die Höhe. + cylinder(r = (nut_size + drill_shaft - drill)/2, h = thickness + space, $fn=32); + } + } +} + +// Bohrung für die Schrauben. +module screw_drill() { + cylinder(h=space + thickness, r=drill/2, $fn=24); + // Versenkung für die Mutter. + if(nut_sink > 0 && !threaded_insert) { + cylinder(h=nut_sink, r=nut_size/2, $fn=6); + } +} + +// Stützstrukturen. +module support(strength) { + + translate([-strength/2, -drill/2, 0]) + cube([strength, drill, nut_sink]); + + $fn = 6; + difference() { + cylinder(h=nut_sink, r=drill/2 + strength); + cylinder(h=nut_sink, r=drill/2); + } +} + + +// Ausschnittobjekt mit zweifach gerundeten Ecken. +// depth = Tiefe +// widht = Weite +// h1 = Höhe links oben +// h2 = Höhe rechts oben +// bevel = Größe der Rungungen +module cutout(depth=4, width=8, h1=2, h2=2, bevel=1) { + + // Addiere 0.01 um im Vorschaumodus Artefakte zu reduzieren. + height = $preview ? max(h1, h2) + 0.01 : max(h1, h2); + assert (width >= bevel * 2); + $fn = 24; + + rotate([90, 0, 0]) { + hull() { + translate([0, max(height * 0.75, bevel), 0]) + cube([width, height/2, depth], center=true); + + translate([-width/2 + bevel, bevel, 0]) + cylinder(h=depth, r=bevel, center=true); + + translate([width/2 - bevel, bevel, 0]) + cylinder(h=depth, r=bevel, center=true); + } + + // Zeichne Rundung nach links außen, falls die Höhe ausreicht. + if (h1 >= bevel * 2) { + translate([-width/2 - bevel, h1 - bevel, 0]) + // Linke Kante. + difference() { + translate([0, 0, -depth/2]) + cube([bevel, bevel, depth]); + cylinder(h=depth, r=bevel, center=true); + } + } + + // Zeichne Rundung nach rechts außen, falls die Höhe ausreicht. + if (h2 >= bevel * 2) { + translate([width/2 + bevel, h2 - bevel, 0]) + difference() { + translate([-bevel, 0, -depth/2]) + cube([bevel, bevel, depth]); + cylinder(h=depth, r=bevel, center=true); + } + } + } +} + +// Aussparungen am Rand der Konsole. +module border_cutouts() { + // Aussparung an der Klinke-Buchse. + if (space - border_height < limit_audio_jack) { + diff = limit_audio_jack - (space - border_height); + + translate([63, 91, border_height - diff]) + cutout(depth=20, width=14, h1=diff, h2=diff); + } + + // Aussparung am Vibrationsmotor. + if (space - border_height < limit_vib) { + diff = limit_vib - (space - border_height); + + translate([118.75, 2 - 0.1 + 15.6/2, border_height - diff]) + cutout(depth=15.6 + 4, width=4.6 + 3.4, h1=diff, h2=diff); + } + + // Aussparungen am Rand neben den seitlichen Befestigungslöchern. + if (side_recess > 0) { + // Die Aussparungen sollten nicht niedriger sein als die Verstrebungen. + recess = min(side_recess, border_height - struts); + + // Aussparung auf der linken Seite. + translate([5, 67, border_height - recess]) + rotate([0, 0, 90]) + cutout( + depth=4, + width=20, + bevel=recess / 2, + h1=recess, + h2=recess); + + // Aussparung auf der rechten Seite. + translate([150 - 5, 67, border_height - recess]) + rotate([0, 0, 90]) + cutout( + depth=4, + width=20, + bevel=recess / 2, + h1=recess, + h2=recess); + + // Bei einer effektiven Höhe der Aussparungen > 2 schrägen wir eine + // Seite ab. + if (recess > 2) { + + multmatrix([ + [1, 0, 0, 0], + [0, 1, -1, border_height - recess ], + [0, 0, 1, 0] + ]) { + + // Linke Seite. + translate([5, 67, border_height - recess]) + rotate([0, 0, 90]) + cutout( + depth=4, + width=20, + bevel=recess / 2, + h1=recess, + h2=recess); + + // Rechte Seite. + translate([150 - 5, 67, border_height - recess]) + rotate([0, 0, 90]) + cutout( + depth=4, + width=20, + bevel=recess / 2, + h1=recess, + h2=recess); + } + } + } +} + +// Die äußeren Teile: Front und Ränder. +module outer() { + // Decke. + color(color_top) + linear_extrude(height=thickness) { + import("./svg/back top.svg"); + } + + // Rand. + translate([0, 0, thickness]) { + // Schneide Aussparungen aus dem Rand. + difference() { + union() { + // Oberer Rand. + color(color_border1) + linear_extrude(height = border_height) { + import("./svg/back borders.svg"); + } + // Unterer Rand. + color(color_border2) + translate([0, 0, border_height]) { + linear_extrude(height=space-border_height) { + import("./svg/back borders lower.svg"); + } + } + } + + render() border_cutouts(); + } + } + + // Verstrebungen. + color(color_struts) + translate([0, 0, thickness]) { + linear_extrude(height=struts) { + import("./svg/back struts.svg"); + } + } + + // Aufhängungen. + color(color_special) + translate([0, 0, 0]) { + linear_extrude(height=max(loop_thickness, thickness)) { + import("./svg/back loops.svg"); + } + } +} + + +/************************************************************************* + * Die Hülle. * + *************************************************************************/ + +module body_back() { + if (rounded_corners) { + intersection() { + union () { + outer(); + } + + color(color_top) + minkowski() { + linear_extrude(height=1) { + import("./svg/back hull.svg"); + } + hull() { + $fn = $preview ? 4 : 16; + for (i = [1:5]) { + translate([0, 0, i - 1]) + cylinder(r=sin(i * (90/5)) * 2, h=thickness + space); + } + } + } + } + } else { + outer(); + } + + // Stützen für die Buttons. + if (button_support) { + color(color_struts) + translate([0, 0, thickness]) { + linear_extrude(height=struts) { + import("./svg/back pillars struts.svg"); + } + } + + color(color_special) + translate([0, 0, thickness]) { + linear_extrude(height=space) { + import("./svg/back pillars.svg"); + } + } + } + + // Stützen für die Analog sticks. + if (stick_support) { + color(color_struts) + translate([0, 0, thickness]) { + linear_extrude(height=struts) { + import("./svg/back sticks struts.svg"); + } + } + + color(color_special) + translate([0, 0, thickness]) { + linear_extrude(height=space - 2) { + import("./svg/back sticks pillars.svg"); + } + } + + color(color_special) + translate([0, 0, thickness + space - 2]) { + linear_extrude(height=2) { + import("./svg/back sticks pillars top.svg"); + } + } + } + + // Schäfte für die Bohrungen. + color(color_drills) + for (i = [0:3]) { + translate([drill_pos[i][0], drill_pos[i][1], 0]) + screw_shaft(); + } + + // LED-Reflektoren. + color(color_special) + if (led_reflectors) { + translate([9, 84, thickness]) + led_reflector(); + translate([141, 84, thickness]) + mirror([1, 0, 0]) + led_reflector(); + } +} + +// Platzierung der Bohrungen. +difference() { + body_back(); + union() { + // Bei einem Gewindeeinsatz wird die Decke nicht durchbohrt. + floor = threaded_insert ? thickness : 0; + for (i = [0:3]) { + translate([drill_pos[i][0], drill_pos[i][1], floor]) + screw_drill(); + } + } +} + +if (support && !threaded_insert) { + color(color_special) + for (i = [0:3]) { + translate([drill_pos[i][0], drill_pos[i][1], 0]) + support(0.5); + } +} + diff --git a/buttons.scad b/buttons.scad new file mode 100644 index 0000000..55c1ce2 --- /dev/null +++ b/buttons.scad @@ -0,0 +1,243 @@ +/************************************************************************* + * Hülle für die u23-Spielekonsole. * + * Buttons. * + * * + * Autor: Shy * + * License: CC0 * + *************************************************************************/ + +/* Maße relevanter Bauteile: + * + * Kurzhubtaster Pads: + * PTS645SL50-2 LFS + * H Taster: 5 mm + * H Gehäuse: 3.45 mm + * D Taster: 3.5 mm + * + * Kurzhubtaster unten: + * PTS645SK43SMTR92 LFS + * H Taster: 4.3 mm + * H Gehäuse: 4.3 + * D Taster: 3.5 mm + * + * Schalter an der Schulter: + * D2FS-FL-N-A + * H: 5.8 mm + * B: 12.8 mm + */ + +include ; +include ; + +// Überstand der Buttons über die Hülle. +protrusion = 2; + +// Tiefe des Zeichnungen auf den Buttons. +carving = 0.5; + +// Buttons haben runde Kanten. (Rechenaufwendiger.) +beveled = true; + +// Größe der Rundung. +bevel_size = 1; + +// Spiel zwischen den Schulterbuttons und der Hülle. +button_trigger_clearance = 0.5; + +// Dicke der Schiene und Widerhaken der Schulterbuttons. +// (5.8 mm - 3 mm) / 2 + 3 mm nach Datenblatt. +button_trigger_rail = space - 4.4 - button_trigger_clearance; + +// Gesamthöhe der Systembuttons. +system_height = space - button_system_size - button_clearance + thickness + protrusion; + +// Gesamthöhe der Aktionsbuttons. +action_height = space - button_action_size - button_clearance + thickness + protrusion; + + +/************************************************************************** + * Einzelteile. * + *************************************************************************/ + +// Aktions-Buttons. +module action_buttons() { + // Basis. + linear_extrude(height = button_action_base) { + import("./svg/buttons action base.svg"); + } + + difference() { + // Hauptteil. + linear_extrude(height = action_height) { + import("./svg/buttons action main.svg"); + } + // Zeichnung. + translate([0, 0, action_height - carving]) + linear_extrude(height = carving) { + import("./svg/buttons action carvings.svg"); + } + + } +} + +// Schulter-Buttons. +module trigger_button() { + // Basis. + linear_extrude(height = button_trigger_rail) { + import("./svg/buttons trigger lower.svg"); + } + + linear_extrude(height = space - button_trigger_clearance) { + import("./svg/buttons trigger upper.svg"); + } +} + +// System-Buttons. +module system_button() { + // Höhe, Basis, Breite. + h = system_height; + b = button_system_base; + w = 3; + + polyhedron(points = [ + // Unterseite + [1, 0, 0], + [9, 0, 0], + [10, b, 0], + [8, b, 0], + [8, h, 0], + [2, h, 0], + [2, b, 0], + [0, b, 0], + // Oberseite + [1, 0, w], + [9, 0, w], + [10, b, w], + [8, b, w], + [8, h, w], + [2, h, w], + [2, b, w], + [0, b, w] + ], faces = [ + [0, 1, 2, 3, 4, 5, 6, 7], + [0, 8, 9, 1], + [1, 9, 10, 2], + [2, 10, 11, 3], + [3, 11, 12, 4], + [4, 12, 13, 5], + [5, 13, 14, 6], + [6, 14, 15, 7], + [7, 15, 8, 0], + [15, 14, 13, 12, 11, 10, 9, 8] + ]); +} + +// Abgerundeter Button. Nur der Hauptteil. +module beveled_button (r=1, h=1, b=1) { + union() { + cylinder(h=h - b, r=r, $fn=24); + + translate([0, 0, h-b*2]) + minkowski() { + cylinder(h=b, r=r-b, $fn=24); + sphere(r=b, $fn=24); + } + } +} + +// Kreuz-Button. +module cross (l=12, w=4, h=2) { + translate([0, 0, h/2]) + union() { + cube([l, w, h], center=true); + rotate([0, 0, 90]) + cube([l, w, h], center=true); + } +} + +// Kreuz-Button mit abgerundeten Kanten. +module beveled_cross (l=12, w=4, h=2, b=1) { + union() { + minkowski() { + cross(l-b*2, w-b*2, h-b*2); + cylinder(r=b, h=b, $fn=12); + } + + translate([0, 0, h-b*2]) + minkowski() { + cross(l-b*2, w-b*2, b); + sphere(r=b, $fn=12); + } + } +} + +// Aktionsbuttons mit abgerundeten Kanten. +module beveled_action(bevel=1) { + // Basis. + linear_extrude(height = button_action_base) { + import("./svg/buttons action base.svg"); + } + + difference() { + union() { + // Plaztiere das Kreuz auf der Basis. + translate([12, 12, 0]) + beveled_cross(l=24, w=8, h=action_height, b=bevel); + + // Platziere vier Buttons auf der Basis. + for (pos = [[31, 7], [41, 17], [53, 7], [63, 17]]) { + translate([pos.x, pos.y, 0]) + beveled_button(r=5, h=action_height, b=bevel); + } + } + // Die Zeichnungen auf der Oberseite. + translate([0, 0, action_height - carving]) + linear_extrude(height = carving) { + import("./svg/buttons action carvings.svg"); + } + } + +} + + +/************************************************************************** + * Anordnung. * + *************************************************************************/ + +// Render nur die Buttons, nicht die eingebundene Datei . +!if(true) { + // Aktions-Buttons. + translate([0, 23, 0]) + if(beveled) { + color(color_buttons) + beveled_action(bevel_size); + } else { + color(color_buttons) + action_buttons(); + } + + // Schulterbuttons. + color(color_buttons) + translate([56, 21, 0]) + rotate([0, 0, 180]) + trigger_button(); + + color(color_buttons) + translate([0, 21, 0]) + rotate([0, 0, 180]) + mirror([1, 0, 0]) + trigger_button(); + + // Drucke drei Systembuttons nebeneinander. + color(color_buttons) + for (i = [0, 11, 22]) { + translate([12 + i, 8, 0]) + system_button(); + } + + // Verbinde die dreit Buttons mit einem dünnen Steg. + color(color_buttons) + translate([12 + 1, 8 + button_system_base / 2, 0]) + cube([30, 1, 3]); +}; + diff --git a/colors.scad b/colors.scad new file mode 100644 index 0000000..06c8297 --- /dev/null +++ b/colors.scad @@ -0,0 +1,16 @@ +/************************************************************************* + * Hülle für die u23-Spielekonsole. * + * Farbdefinitionen. * + * * + * Author: Shy * + * License: CC0 * + *************************************************************************/ + +color_top = "#3399ff"; +color_border1 = "#33cccc"; +color_border2 = "#33ff66"; +color_struts = "#ff9900"; +color_drills = "#ffff33"; +color_buttons = "#ff3399"; +color_special = "#cc33ff"; +color_warning = "#ff000080"; diff --git a/front.scad b/front.scad new file mode 100644 index 0000000..1fe8af5 --- /dev/null +++ b/front.scad @@ -0,0 +1,401 @@ +/************************************************************************* + * Hülle für die u23-Spielekonsole. * + * Vorderseite. * + * * + * Author: Shy * + * License: CC0 * + *************************************************************************/ + +include ; + +/* Höhe wichtiger Bauteile: + * + * Display: + * Z320IT010 + * L: 54 mm + * B: 77.4 mm + * H: 2.4 mm + * Davon LCD: + * L: 48.6 mm + * B: 64.8 mm, mit 3.35 mm Abstand zum rechten Rand + * + * Kurzhubtaster Pads: + * PTS645SL50-2 LFS + * H Taster: 5 mm + * H Gehäuse: 3.45 mm + * D Taster: 3.5 mm + * + * Kurzhubtaster unten: + * PTS645SK43SMTR92 LFS + * H Taster: 4.3 mm + * H Gehäuse: 4.3 + * D Taster: 3.5 mm + * + * Schalter an der Schulter: + * D2FS-FL-N-A + * H: 5.8 mm + * B: 12.8 mm + * + * Analog Stick: + * Alps RKJXV1224005 + * H Gehäuse: 10.8 mm + * H bis Gelenk: 12.46 mm + * L: 21.3 mm + * B: 17.8 mm + * Der Kern ist ein Quadrat mit 13.15 mm Kantenlänge. + * Anschlag 7 mm von der Platine. + */ + +// Abgerundete Kanten (aufwendig). +rounded_corners = true; + +// Dicke der Decke. +thickness = 1.0; + +// Höhe des Innenraumes. +space = 7; + +// Höhe des oberen Randes. +border_height = 4; + +// Höhe der Verstrebungen. +struts = 2; + +// Durchmesser der Bohrungen. +drill = 3.4; + +// Durchmesser der Bohrschäfte. +drill_shaft = 7.4; + +// Position der Bohrungen. +drill_pos = [ + [10, 20], + [10, 100], + [140, 20], + [140, 100], +]; + +// Dicke der Basis der Aktionsbuttons. +button_action_base = 1; + +// Dicke der Basis der Systembuttons. +button_system_base = 2; + +// Tatsächliche Höhe der Taster unter den Aktionsbuttons. +button_action_size = 5; + +// Tatsächliche Höhe der Taster unter den Systembuttons. +button_system_size = 4.3; + +// Spiel der Buttons zwischen Taster und Decke. +button_clearance = 0.2; + +// LEDs am unteren Rand. +led_bottom = true; + +// Y-LED. +led_y = true; + +// LED-Pegel. +led_gauge = true; + +// Aussparungen für die Analog-Sticks. +analog_sticks = false; + + +/************************************************************************* + * Überprüfe Parameter auf Fehler. * + *************************************************************************/ + +//assert(space >= trigger_switch_height + button_trigger_base, +// "Die Höhe reicht nicht für die Schultertasten!"); + + +/************************************************************************* + * Einzelteile * + *************************************************************************/ + +// Durchbrüche in der Front. +module top_cutouts() { + // LEDs am unteren Rand. + if (led_bottom) { + linear_extrude(height=thickness) { + import("./svg/front led bottom.svg"); + } + } + + // LED-Pegel. + if (led_gauge) { + linear_extrude(height=thickness) { + import("./svg/front led gauge.svg"); + } + } + + // Y-LED. + if (led_y) { + linear_extrude(height=thickness) { + import("./svg/front led y.svg"); + } + } +} + +// Schaft für die Schrauben. +module screw_shaft() { + translate([0, 0, thickness]) + cylinder(h = space, r = drill_shaft/2, $fn=32); +} + +// Platzsparendere Stützen für die Bohrungen am oberen Rand. +module screw_support(width, length) { + translate([0, 0, thickness + (space / 2)]) + cube([width, length, space], center=true); +} + +// Bohrung für die Schrauben. +module screw_drill() { + cylinder(h=space + thickness, r=drill/2, $fn=24); +} + +// Maske für Stellen, an denen der Rand nicht ganz auf der Platine aufliegen +// kann. +module border_pcb_cutouts() { + // Vibrator. + translate([28, 10 + 1, -1.5]) + cube([6, 1, 1.5]); + + // Klinkenbuchse. + translate([77.5, 110 - 2, -1]) + cube([13.5, 1, 1]); +} + +// Die äußeren Teile: Front und Ränder. +module outer() { + // Decke. + color(color_top) + linear_extrude(height=thickness) { + import("./svg/front top.svg"); + } + + // Oberer Rand. + color(color_border1) + translate([0, 0, thickness]) { + linear_extrude(height = border_height) { + import("./svg/front borders.svg"); + } + } + + // Unterer Rand. + color(color_border2) + translate([0, 0, thickness + border_height]) { + difference() { + linear_extrude(height=space - border_height) { + import("./svg/front borders lower.svg"); + } + // Stellen, an denen der Rand nicht ganz auf der Platine aufliegen + // kann. + translate([0, 0, space - border_height]) + border_pcb_cutouts(); + } + } + + // Verstrebungen. + color(color_struts) + translate([0, 0, thickness]) { + linear_extrude(height=struts) { + import("./svg/front struts.svg"); + } + } + +} + +// Kleine Streben zwischen Decke und Rand. +module border_strut(width, length, height) { + x = width/2; + y = length/2; + + polyhedron(points = [ + [-x, -y, 0], + [x, -y, 0], + [x, y, 0], + [-x, y, 0], + [-x, y, height], + [x, y, height] + ], faces = [ + [0, 1, 2, 3], + [1, 5, 2], + [2, 5, 4, 3], + [3, 4, 0], + [0, 4, 5, 1] + ]); + +} + + +/************************************************************************* + * Die Hülle. * + *************************************************************************/ + +module casing_front() { + difference() { + if (rounded_corners) { + intersection() { + union () { + outer(); + } + + color(color_top) + minkowski() { + linear_extrude(height=1) { + import("./svg/front hull.svg"); + } + hull() { + $fn = $preview ? 4 : 16; + for (i = [1:5]) { + translate([0, 0, i - 1]) + cylinder(r=sin(i * (90/5)) * 2, h=thickness + space); + } + } + } + } + } else { + outer(); + } + + if ($preview) { + // Vergrößere das zu substrahierende Objekt, um Darstellungsfehler + // in der Voransicht zu vermeiden. + translate([0, 0, -0.1]) + resize([0, 0, thickness + 0.2]) + top_cutouts(); + } else { + top_cutouts(); + } + } + + // Zusätzliche Verstrebungen zwischen Decke und Rand. + if (rounded_corners) { + color(color_struts) + for (pos = [ + // [x, y, rotation, länge] + [49, 107.5, 0, 3], + [57, 107.5, 0, 3], + [65, 107.5, 0, 3], + [73, 107.5, 0, 3], + [80, 107.5, 0, 3], + [87, 107.5, 0, 3], + + [147.5, 85, 270, 3], + [148, 78.5, 270, 2], + [148, 71.5, 270, 2], + [147.5, 65, 270, 3], + [147.5, 57, 270, 3], + [148, 49, 270, 2], + [148, 41, 270, 2], + + [109, 12.5, 180, 3], + [94, 12.5, 180, 3], + [56, 12.5, 180, 3], + [41, 12.5, 180, 3], + [26, 12.5, 180, 3], + + //[5, 40, 90, 2], + [5, 44, 90, 2], + [5, 50, 90, 2], + [2.5, 66, 90, 3], + [2.5, 84, 90, 3], + ]) { + translate([pos[0], pos[1], thickness]) + rotate([0, 0, pos[2]]) + border_strut(1.6, pos[3], pos[3]); + } + } + + // Halterungen für die Aktionsbuttons. + // Begrenzung nach oben. + color(color_buttons) + translate([0, 0, thickness]) { + linear_extrude(height = space - button_action_size - button_action_base - button_clearance) { + import("./svg/front button action upper.svg"); + } + } + + // Führung für die Aktionsbuttons. + color(color_buttons) + translate([0, 0, thickness]) { + // Wir ziehen die Führungen zwei Millimeter tiefer, um auf der sicheren + // Seite zu sein. + linear_extrude(height = space - button_action_size + 2) { + import("./svg/front button action lower.svg"); + } + } + + // Halterungen für die Systembuttons. + // Begrenzung nach oben. + color(color_buttons) + translate([0, 0, thickness]) { + linear_extrude(height = space - button_system_size - button_system_base - button_clearance) { + import("./svg/front button system upper.svg"); + } + } + + // Führung für die Systembuttons. + color(color_buttons) + translate([0, 0, thickness]) { + linear_extrude(height = space - button_system_size) { + import("./svg/front button system lower.svg"); + } + } + + // Schäfte für die Bohrungen. + color(color_drills) + for (i = [0:3]) { + if (drill_pos[i].y > 50) { + // Am oberen Rand brauchen wir andere Stützen, um Platz für die + // Schultertasten zu machen. + if (drill_pos[i].x > 75) { + // Rechts oben. + translate([drill_pos[i].x + (150 - drill_pos[i].x) / 2, drill_pos[i].y, 0]) + // 2 mm kürzer, damit das Bauteil nicht am Rand übersteht. + screw_support(150 - drill_pos[i].x - 2, drill); + } else { + // Links oben. + translate([drill_pos[i].x / 2, drill_pos[i].y, 0]) + screw_support(drill_pos[i].x - 2, drill); + } + + // Die normalen Bohrungen am unteren Rand. + } else { + translate([drill_pos[i].x, drill_pos[i].y, 0]) + screw_shaft(); + } + } + + // Verstärkungen für die Analog-Sticks. + if (analog_sticks) { + color(color_struts) + translate([0, 0, thickness]) { + linear_extrude(height = struts) { + import("./svg/front analog sticks struts.svg"); + } + } + } +} + +// Plazierung der Bohrungen. +difference() { + casing_front(); + union() { + for (i = [0:3]) { + translate([drill_pos[i][0], drill_pos[i][1], 0]) + screw_drill(); + } + + // Die Löcher für die Analog-Sticks. + if (analog_sticks) { + linear_extrude(height = space) { + import("./svg/front analog sticks.svg"); + } + } + } +} + diff --git a/svg/back borders lower.svg b/svg/back borders lower.svg new file mode 100644 index 0000000..cf6ef0d --- /dev/null +++ b/svg/back borders lower.svg @@ -0,0 +1,87 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/svg/back borders.svg b/svg/back borders.svg new file mode 100644 index 0000000..2e3301b --- /dev/null +++ b/svg/back borders.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back construction.svg b/svg/back construction.svg new file mode 100644 index 0000000..4e642ed --- /dev/null +++ b/svg/back construction.svg @@ -0,0 +1,858 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + Shy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svg/back hull.svg b/svg/back hull.svg new file mode 100644 index 0000000..a7a2daf --- /dev/null +++ b/svg/back hull.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back loops.svg b/svg/back loops.svg new file mode 100644 index 0000000..3576d85 --- /dev/null +++ b/svg/back loops.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back pillars struts.svg b/svg/back pillars struts.svg new file mode 100644 index 0000000..6a791b4 --- /dev/null +++ b/svg/back pillars struts.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back pillars.svg b/svg/back pillars.svg new file mode 100644 index 0000000..14e0f9f --- /dev/null +++ b/svg/back pillars.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/svg/back sticks pillars top.svg b/svg/back sticks pillars top.svg new file mode 100644 index 0000000..f2e56d7 --- /dev/null +++ b/svg/back sticks pillars top.svg @@ -0,0 +1,70 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back sticks pillars.svg b/svg/back sticks pillars.svg new file mode 100644 index 0000000..1941aca --- /dev/null +++ b/svg/back sticks pillars.svg @@ -0,0 +1,70 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back sticks struts.svg b/svg/back sticks struts.svg new file mode 100644 index 0000000..384b691 --- /dev/null +++ b/svg/back sticks struts.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back struts.svg b/svg/back struts.svg new file mode 100644 index 0000000..6234bdc --- /dev/null +++ b/svg/back struts.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/back top.svg b/svg/back top.svg new file mode 100644 index 0000000..22051a5 --- /dev/null +++ b/svg/back top.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/svg/buttons action base.svg b/svg/buttons action base.svg new file mode 100644 index 0000000..dcf5d3f --- /dev/null +++ b/svg/buttons action base.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/svg/buttons action carvings.svg b/svg/buttons action carvings.svg new file mode 100644 index 0000000..31cce47 --- /dev/null +++ b/svg/buttons action carvings.svg @@ -0,0 +1,104 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/svg/buttons action main.svg b/svg/buttons action main.svg new file mode 100644 index 0000000..2e21a13 --- /dev/null +++ b/svg/buttons action main.svg @@ -0,0 +1,66 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/svg/buttons trigger lower.svg b/svg/buttons trigger lower.svg new file mode 100644 index 0000000..668138c --- /dev/null +++ b/svg/buttons trigger lower.svg @@ -0,0 +1,59 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/buttons trigger upper.svg b/svg/buttons trigger upper.svg new file mode 100644 index 0000000..4836d87 --- /dev/null +++ b/svg/buttons trigger upper.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front analog sticks struts.svg b/svg/front analog sticks struts.svg new file mode 100644 index 0000000..c224bf3 --- /dev/null +++ b/svg/front analog sticks struts.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/svg/front analog sticks.svg b/svg/front analog sticks.svg new file mode 100644 index 0000000..54cc222 --- /dev/null +++ b/svg/front analog sticks.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front borders lower.svg b/svg/front borders lower.svg new file mode 100644 index 0000000..bff7d78 --- /dev/null +++ b/svg/front borders lower.svg @@ -0,0 +1,68 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front borders.svg b/svg/front borders.svg new file mode 100644 index 0000000..41dfd9a --- /dev/null +++ b/svg/front borders.svg @@ -0,0 +1,68 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front button action lower.svg b/svg/front button action lower.svg new file mode 100644 index 0000000..20cfbf2 --- /dev/null +++ b/svg/front button action lower.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front button action upper.svg b/svg/front button action upper.svg new file mode 100644 index 0000000..8e6fd26 --- /dev/null +++ b/svg/front button action upper.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front button system lower.svg b/svg/front button system lower.svg new file mode 100644 index 0000000..abe9cfe --- /dev/null +++ b/svg/front button system lower.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front button system upper.svg b/svg/front button system upper.svg new file mode 100644 index 0000000..0bea193 --- /dev/null +++ b/svg/front button system upper.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front construction.svg b/svg/front construction.svg new file mode 100644 index 0000000..2f8d1f8 --- /dev/null +++ b/svg/front construction.svg @@ -0,0 +1,1181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + Shy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svg/front hull.svg b/svg/front hull.svg new file mode 100644 index 0000000..28100c9 --- /dev/null +++ b/svg/front hull.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front led bottom.svg b/svg/front led bottom.svg new file mode 100644 index 0000000..b1eeee2 --- /dev/null +++ b/svg/front led bottom.svg @@ -0,0 +1,69 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/svg/front led gauge.svg b/svg/front led gauge.svg new file mode 100644 index 0000000..6706ce6 --- /dev/null +++ b/svg/front led gauge.svg @@ -0,0 +1,65 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front led y.svg b/svg/front led y.svg new file mode 100644 index 0000000..b3b7795 --- /dev/null +++ b/svg/front led y.svg @@ -0,0 +1,65 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front struts.svg b/svg/front struts.svg new file mode 100644 index 0000000..14bf55e --- /dev/null +++ b/svg/front struts.svg @@ -0,0 +1,68 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg/front top.svg b/svg/front top.svg new file mode 100644 index 0000000..28e0624 --- /dev/null +++ b/svg/front top.svg @@ -0,0 +1,70 @@ + + + + + + + + + + image/svg+xml + + + + + + + + +