Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news


  

Author Topic: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade  (Read 414 times)

0 Members and 1 Guest are viewing this topic.

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Like the title says, this is the thread for developing and testing a printable LS-30 handle for the J-Stik/ServoStik Ikari 12-way Rotary Upgrade announced here.

Ultimarc product page:
http://www.ultimarc.com/controls.html

Installation directions:
http://www.ultimarc.com/12wayrotary.pdf

Anyone who wants to join in, grab a copy of OpenSCAD and bookmark the OpenSCAD cheatsheet to help you with the commands and syntax.   ;D

---------------------

The plan is to start with the code from the 3d printed LS-30 replacement handle for the Happ Rotary Joystick and remix it to include these features:

  - Removable top like the original handle.

  - Two free-floating eject pins instead of the long legs on the original top.
(less likely to break and easier to print)


  - M6 locknut and maybe a star washer or two to secure the handle to the shaft.


  - No shaft mods, just print and assemble.

Any more features you'd like to see added or changed?

--------------------

Needed measurements to design the part:

Shaft diagram.


Mounting plate to shaft shoulder distance = 46mm.


Next step:  A diagram to work out the vertical positioning of the handle on the shaft.


Scott

05SRT4

  • Trade Count: (+5)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1042
  • Check out my Pow Pow
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #1 on: September 12, 2018, 11:40:11 am »
Just ordered the rotary kit.

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #2 on: September 12, 2018, 04:43:29 pm »
Looking forward to your advice and observations, Deven.   ;D

Here's the promised vertical positioning diagram. (Not drawn to scale.)



First thing to do is solve for Shaft Height with a typical 3/4" wood panel (19.05mm) and a typical metal panel (1.6 mm) since most panels will fall within that range.

3/4" wood panel:
  PanelThickness + 15.6mm (handle to panel distance) +ShaftHeight = Shoulder Height
  19.05mm + 15.6mm + ShaftHeight = 46mm
  ShaftHeight = 11.35mm

Metal panel:
  1.6mm + 15.6mm + ShaftHeight = 46mm
  ShaftHeight = 28.8mm

The original handle BodyHeight is 35.6mm, so ShaftHeight + ThreadedHeight + TopThickness (the removable cover) have to fit into that vertical space.

Wood panel:
  ShaftHeight + ThreadedHeight + TopThickness <= BodyHeight
  11.35mm + 9.4mm + TopThickness <= 35.6mm
  TopThickness <= 14.85mm -- Lots of wiggle room there.   ;D

Metal panel:
  28.8mm + 9.4mm + TopThickness <= 35.6mm
  TopThickness <= -2.6mm -- Threads are higher than the handle body, needs some 5mm spacers (or larger) between the stick and panel.

Metal panel + 5mm spacers:
  23.8mm + 9.4mm + TopThickness <= 35.6mm
  TopThickness <= 2.4mm -- Just enough wiggle room for a 2mm top.

------------------

Looks like the handle will work with 6.6mm (metal panel + 5mm spacers) - 19.05mm (3/4" wood) panels and leaves room for a 2mm recess for the top cover.

Next step: Define variable names and trim/organize the code.


Scott
EDIT: Fixed several errors in the metal panel calculations.   :embarassed:
« Last Edit: September 18, 2018, 06:06:08 am by PL1 »

esoteric_rt

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 28
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #3 on: September 12, 2018, 09:38:56 pm »
Great work, id be in for 2 x tops if anyone makes them in nice quality :-)

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #4 on: September 13, 2018, 05:18:38 am »
Test print updated with new variables and comments.   ;D

LS30_Test_Print_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// - Test print

// This test print allows you to verify the correct variable values for your specific hardware and your slicer software before you render/export/print the whole handle.

// Hardware tested:
// - Joystick M6 threaded diameter (clears without engaging threads)
// - Joysick shaft diameter (snug fit)

// This part is oriented upside-down compared to the handle so print supports are not needed.

/////////////////////////////
//      Define variables
/////////////////////////////

ShaftDiameter = 9.35;  // Default = 9.35
ShaftHeight = 9;        // Default = 9
ThreadedDiameter = 6.2; // Default = 6.2
// The diameter values may need to be *very slightly* larger to account for the 180-sided polygon used to render circles -- see "undersized holes" at https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder
$fn=180; // Number of fragments (polygon sides) used to render a circle

/////////////////////////////
//      Make the part
/////////////////////////////

// Make the shaft test layer
difference() {
    cylinder(ShaftHeight, d=ShaftDiameter+6, center=true);   // Shaft outer cylinder
    cylinder(ShaftHeight+2, d=ShaftDiameter, center=true);
    // Remove Shaft Collar hole
    }
//
// Make the thread test layer (red)
difference() {
    color("red") translate([0,0,-1 - ShaftHeight/2]) cylinder(2, d=ShaftDiameter + 6, center=true);
    // Outer cylinder
    translate([0,0,-1 - ShaftHeight/2]) cylinder(ShaftHeight, d=ThreadedDiameter, center=true);
    // Remove threaded hole
}


Scott

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #5 on: September 13, 2018, 07:25:00 am »
First pass on the handle updated with new variables and comments.   ;D

LS30_Handle_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// -- Handle

// Required hardware:
// - 6mm locknut
// - 6mm star washer

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Body
    BodyHeight = 35.6; // Default = 35.6
    // Height of the body, not including the dome

    TopDiameter = 22; // Default = 22
    // Hole for remvable top. 2mm deep.

// Sides
    SideRoundSphere = 0.7; // Default = 0.7
    // Radius of the side roundover sphere

    LowerBodyDiameter = 31.51; // Default = 31.51
    // Farthest distance from lower point-to-point edge

    UpperBodyDiameter = 29.41; // Default = 29.41
    // Farthest distance from upper point-to-point edge

// Bottom octagon
    LowerRoundSphere = 1.59; // Default = 1.59
    // Radius of the lower roundover sphere

// Top octagon
    UpperRoundSphere = 3.18; // Default = 3.18
    // Radius of the upper roundover sphere

// Spaces to remove from body
    ShaftHeight = 11.35; // Default = 11.35 (3/4" wood panel) or 23.5 (1.6mm metal panel with 2mm spacers)
    // Height of the unthreaded shaft cavity

    ShaftDiameter = 9.35; // Default = 9.35
    // Diameter of the joystick unthreaded shaft cavity

    ThreadedHeight = 6; // Default = 6
    // Height of the thread hole

    ThreadedDiameter = 6.2; // Default = 6.2
    // Outer diameter of the thread hole
   
    LocknutHeight = (BodyHeight - ShaftHeight - ThreadedHeight);

    LocknutDiameter = 12; // Default = 12
    // Diameter of the locknut cavity

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Non-adjustable variables
/////////////////////////////

// Bottom octagon
    LowerSmallArccosine = SideRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from center of lower small sphere to point of lower octagon [radius*acos(22.5)]

    LowerLargeArccosine = LowerRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from point of lower octagon to center of lower large sphere [radius*acos(22.5)]

    LowerLargeSphereCenter = LowerBodyDiameter/2 - SideRoundSphere + LowerSmallArccosine - LowerLargeArccosine;
    // Rounded octagon point - side (small) sphere radius + distance from center of small sphere to point of octagon - distance from point of octagon to center of large sphere

// Top octagon
    UpperSmallArccosine = SideRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from center of upper small sphere to point of upper octagon [radius*acos(22.5)]

    UpperLargeArccosine = UpperRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from point of upper octagon to center of upper large sphere [radius*acos(22.5)]

    UpperLargeSphereCenter = UpperBodyDiameter/2 - SideRoundSphere + UpperSmallArccosine - UpperLargeArccosine;
    // Rounded octagon point - side (small) sphere radius + distance from center of small sphere to point of octagon - distance from point of octagon to center of large sphere

/////////////////////////////
//  Make the part
/////////////////////////////

// Make the main body
difference(){ // Main body minus holes
    hull() {  // Main body hull
    // Lower roundover large spheres
    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    // Lower side small spheres
    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    // Upper side small spheres
    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere, center = true);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    // Upper roundover large spheres
    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);     

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);
   
    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);
    } // End main body hull

// Holes
color("gray") translate ([0, 0, ShaftHeight/2]) rotate ([0, 0, 0]) cylinder (ShaftHeight+2, d = ShaftDiameter, center=true); // Make hole for Shaft

color("blue") translate ([0, 0, ShaftHeight+ThreadedHeight/2]) cylinder (2 + ThreadedHeight, d = ThreadedDiameter, center=true); // Make hole for threaded

color("white") translate ([0, 0, ShaftHeight + ThreadedHeight + LocknutHeight/2]) cylinder (LocknutHeight + 1, d = LocknutDiameter, center=true);
    // Make hole for locknut

color("red") translate ([0, 0, BodyHeight]) cylinder (4, d = TopDiameter, center=true);
    // Make hole for removable top

color("green") translate ([-9, 0, 0]) cylinder (6, d = 2, center=true);
    // Eject pin access hole 1

color("green") translate ([9, 0, 0]) cylinder (6, d = 2, center=true);
    // Eject pin access hole 2

color("purple") translate ([-9, 0, BodyHeight/2 + 2]) cylinder (BodyHeight, d = 4, center=true);
    // Eject pin hole 1

color("purple") translate ([9, 0, BodyHeight/2 + 2]) cylinder (BodyHeight, d = 4, center=true);
    // Eject pin hole 2
} //End difference main body hull minus holes
//

Eject pin (print 2)

LS30_Eject_Pin_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// -- Eject pin (handle requires 2)

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360

/////////////////////////////
//  Make the part
/////////////////////////////

// Make the main body
translate ([0, 0, 15]) cylinder (22, d = 3.8, center=true);  // Eject pin body
translate ([0, 0, 2]) cylinder (4, d1 = 3.2, d2 = 3.8, center=true);  // Eject pin bottom
translate ([0, 0, 28]) cylinder (4, d1 = 3.8, d2 =3.2, center=true);  // Eject pin body


Scott
« Last Edit: September 13, 2018, 07:45:01 am by PL1 »

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #6 on: September 19, 2018, 06:36:20 am »
Almost done.   ;D



Items remaining:
- Print a handle and two pins to confirm two tiny changes.

- Get a 6mm locknut and star washer to confirm, but it looks like there is enough clearance even on a 1.6mm metal panel + 5mm spacers. (panel + spacers = 6.6mm total thickness)

- Review documentation for errors and typos.

I'd greatly appreciate if someone (Deven? :angel:) with a 3d printer and the Ultimarc Upgrade Kit or other Ultimarc 9mm shaft stick can do a test print to check if ShaftDiameter = 9.35 is good default value for a 9mm shaft stick.
-- ShaftDiameter is set on line 21 of LS30_Test_Print_Ultimarc.scad and line 45 of LS30_Handle_Ultimarc.scad.
-- ShaftDiameter = 10.35 works for the 10mm shaft on a Zippyy.

LS30_Test_Print_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// - Test print

// Other prints needed:
// -- Handle
// -- Handle top
// -- Eject pin (2 pins per handle)

// This test print allows you to verify the correct variable values for your specific hardware and your slicer software before you render/export/print the whole handle.

// Hardware tested:
// - Joystick M6 threaded diameter (clears without engaging threads)
// - Joysick shaft diameter (snug fit)

// This part is oriented upside-down compared to the handle so print supports are not needed.

/////////////////////////////
//      Define variables
/////////////////////////////

ShaftDiameter = 9.35;  // Default = 9.35
ShaftHeight = 9;        // Default = 9
ThreadedDiameter = 6.2; // Default = 6.2
// The diameter values may need to be *very slightly* larger to account for the 180-sided polygon used to render circles -- see "undersized holes" at [url]https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder[/url]
$fn=180; // Number of fragments (polygon sides) used to render a circle

/////////////////////////////
//      Make the part
/////////////////////////////

// Make the shaft test layer
difference() {
    cylinder(ShaftHeight, d=ShaftDiameter+6, center=true);   // Shaft outer cylinder
    cylinder(ShaftHeight+2, d=ShaftDiameter, center=true);
    // Remove Shaft Collar hole
    }
//
// Make the thread test layer (red)
difference() {
    color("red") translate([0,0,-1 - ShaftHeight/2]) cylinder(2, d=ShaftDiameter + 6, center=true);
    // Outer cylinder
    translate([0,0,-1 - ShaftHeight/2]) cylinder(ShaftHeight, d=ThreadedDiameter, center=true);
    // Remove threaded hole
}

LS30_Handle_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// -- Handle

// Other prints needed:
// -- Test print
// -- Handle top
// -- Eject pin (2 pins per handle)

// Required hardware:
// - 6mm locknut
// - 6mm star washer

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Body
    BodyHeight = 35.6; // Default = 35.6
    // Height of the body, not including the dome

// Sides
    SideRoundSphere = 0.7; // Default = 0.7
    // Radius of the side roundover sphere

    LowerBodyDiameter = 31.51; // Default = 31.51
    // Farthest distance from lower point-to-point edge

    UpperBodyDiameter = 29.41; // Default = 29.41
    // Farthest distance from upper point-to-point edge

// Bottom octagon
    LowerRoundSphere = 1.59; // Default = 1.59
    // Radius of the lower roundover sphere

// Top octagon
    UpperRoundSphere = 3.18; // Default = 3.18
    // Radius of the upper roundover sphere

// Spaces to remove from body
    ShaftHeight = 23.8; // Default = 30.4mm - panel thickness. (This formula positions the bottom of the handle 15.6mm above the top of the panel, same as Ikari Warriors.)
    // 11.35 for a 3/4" wood panel (19.05mm)
    // 23.8 for a 1.6mm metal panel with 5mm spacers (6.6mm)
    // Height of the unthreaded shaft cavity   

    ShaftDiameter = 9.35; // Default = 9.35 for a 9mm shaft
    // Diameter of the joystick unthreaded shaft cavity.  This value needs to be *very slightly* larger than the actual joystick shaft diameter to allow for the 180-sided polygon used to render circles -- see "undersized holes" at [url]https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder[/url]

    ThreadedHeight = 6; // Default = 6
    // Height of the thread hole

    ThreadedDiameter = 6.2; // Default = 6.2
    // Outer diameter of the thread hole

    LocknutDiameter = 12; // Default = 12
    // Diameter of the locknut cavity. (Height is automatically calculated below.)

    PinDistance = 9; // Default =9
    // Horizontal distance from handle center to eject pin center
   
    PinDiameter = 4; // Default = 4
    // Diameter of the eject pin body

    TopDiameter = 22.6; // Default = 22.6
    // Hole for removable top.
   
    TopHeight = 2; // Default = 2
    // Hole for removable top.
   
// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Non-adjustable variables
/////////////////////////////

// Bottom octagon
    LowerSmallArccosine = SideRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from center of lower small sphere to point of lower octagon [radius*acos(22.5)]

    LowerLargeArccosine = LowerRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from point of lower octagon to center of lower large sphere [radius*acos(22.5)]

    LowerLargeSphereCenter = LowerBodyDiameter/2 - SideRoundSphere + LowerSmallArccosine - LowerLargeArccosine;
    // Rounded octagon point - side (small) sphere radius + distance from center of small sphere to point of octagon - distance from point of octagon to center of large sphere

// Top octagon
    UpperSmallArccosine = SideRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from center of upper small sphere to point of upper octagon [radius*acos(22.5)]

    UpperLargeArccosine = UpperRoundSphere * 1.0823922002923939687994464107328;
    // Calculates distance from point of upper octagon to center of upper large sphere [radius*acos(22.5)]

    UpperLargeSphereCenter = UpperBodyDiameter/2 - SideRoundSphere + UpperSmallArccosine - UpperLargeArccosine;
    // Rounded octagon point - side (small) sphere radius + distance from center of small sphere to point of octagon - distance from point of octagon to center of large sphere

// Locknut cavity
    LocknutHeight = (BodyHeight - ShaftHeight - ThreadedHeight);
    // Height of the locknut cavity

/////////////////////////////
//  Make the part
/////////////////////////////

// Make the main body
difference(){ // Main body minus holes
    hull() {  // Main body hull
    // Lower roundover large spheres
    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([LowerLargeSphereCenter, 0, LowerRoundSphere/2]) sphere (r = LowerRoundSphere);     

    // Lower side small spheres
    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, LowerRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([-SideRoundSphere + LowerBodyDiameter/2, 0, LowerRoundSphere/2]) sphere (r = SideRoundSphere);

    // Upper side small spheres
    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere, center = true);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([-SideRoundSphere + UpperBodyDiameter/2, 0, - UpperRoundSphere/2]) sphere (r = SideRoundSphere);

    // Upper roundover large spheres
    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 22.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 67.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 112.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 157.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);     

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 202.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 247.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);
   
    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 292.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);

    translate ([0, 0, BodyHeight - UpperRoundSphere/2])
    rotate ([0, 0, 337.5]) translate ([UpperLargeSphereCenter, 0, - UpperRoundSphere/2]) sphere (r = UpperRoundSphere);
    } // End main body hull

// Holes
color("limegreen") translate ([0, 0, ShaftHeight/2]) cylinder (ShaftHeight, d = ShaftDiameter, center=true); // Make hole for Shaft

color("blue") translate ([0, 0, ShaftHeight+ThreadedHeight/2]) cylinder (ThreadedHeight + .001, d = ThreadedDiameter, center=true); // Make hole for threaded

color("white") translate ([0, 0, ShaftHeight + ThreadedHeight + LocknutHeight/2]) cylinder (LocknutHeight + .001, d = LocknutDiameter, center=true);
    // Make hole for locknut

color("red") translate ([0, 0, BodyHeight - TopHeight/2]) cylinder (TopHeight, d = TopDiameter, center=true);
    // Make hole for removable top

color("aqua") translate ([-PinDistance, 0, 1]) cylinder (2.01, d1 = 3.5, d2 = 2, center=true);
    // Eject pin access hole 1

color("aqua") translate ([PinDistance, 0, 1]) cylinder (2.01, d1 = 3.5, d2 = 2, center=true);
    // Eject pin access hole 2

color("purple") translate ([-PinDistance, 0, BodyHeight/2 + 2]) cylinder (BodyHeight, d = PinDiameter, center=true);
    // Eject pin hole 1

color("purple") translate ([PinDistance, 0, BodyHeight/2 + 2]) cylinder (BodyHeight, d = PinDiameter, center=true);
    // Eject pin hole 2
} //End difference main body hull minus holes
//

LS30_Handle_Top_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// -- Handle top

// Other prints needed:
// -- Test print
// -- Handle
// -- Eject pin (2 pins per handle)

// Logo exported from Inkscape to .dxf file using [url]https://github.com/brad/Inkscape-OpenSCAD-DXF-Export[/url]

/////////////////////////////
//  Adjustable variables
/////////////////////////////

// Logo
    LogoDepth = 1.0; // Default = 1.0
    // Logo height above the main body

// Dome
    DomeHeight = 0.8; // Default = 0.8
    // Dome height above the main body

    DomeDiameter = 22; // Default = 22
    // This variable is not used to generate the part, but is used to calculate DomeSphereRadius.

    DomeSphereRadius = 76.02; // Default = 76.02
    // Sphere radius that will generate the desired dome.
    // Enter the "Width of Arc" (DomeDiameter) and "Height of Arc" (DomeHeight) into the calculator at http://handymath.com/cgi-bin/arc18mm2.cgi?submit=Entry The resulting "Radius of Arc" = DomeSphereRadius.

// Body
    TopHeight = 2; // Default = 2
    // Height of the body, not including the dome

    TopDiameter = 22.6; // Default = 22.6
    // Diameter of the body that fits inside the handle

    TopWiggleRoom = 0.65; // Default = 0.65
    // Amount to decrease the body diameter for easier insertion/removal of top.  It also allows for the 180-sided polygon used to render circles -- see "undersized holes" at [url]https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder[/url]

    TopTaper = 0.2; // Default = 0.2
    // Amount to reduce the bottom diameter of the body

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360
    // 6 will render a circular hole as a hexagon, 8 will render a circular hole as an octagon.
    // Lower the number for faster rendering, raise the number for smoother rendering.


/////////////////////////////
//  Make the part
/////////////////////////////

// Make the SNK Logo (Optional)
// Comment out the next three lines to skip the logo
translate([-6, -3, 0])
linear_extrude(height = LogoDepth, convexity = 10)
import(file = "SNK_Logo.dxf", layer="Logo");
// The "SNK_Logo.dxf" file needs to be in the same directory as this SCAD file.
//

// Make the dome
difference(){ // Sphere minus cube
    translate([0,0,DomeHeight-DomeSphereRadius]) sphere(r=DomeSphereRadius, center=true); // Sphere
    translate([0,0,- DomeSphereRadius]) cube([DomeSphereRadius*2,DomeSphereRadius*2,DomeSphereRadius*2], center=true);
    // Cube to cut off bottom of sphere
}
//

// Make the body
translate ([0, 0, -TopHeight/2]) cylinder (TopHeight, d1 = TopDiameter - TopTaper - TopWiggleRoom, d2 = TopDiameter - TopWiggleRoom, center=true);
//

LS30_Eject_Pin_Ultimarc.scad
Code: [Select]
// LS-30 handle for Ultimarc Ikari 12-way Rotary Upgrade
// -- Eject pin (2 pins per handle)

// Other prints needed:
// -- Test print
// -- Handle
// -- Handle top

/////////////////////////////
//  Adjustable variables
/////////////////////////////

PinHeight = 30; // Default = 30
// Height of the whole pin

TaperHeight = 2; // Default = 2
// Height of the taper on each end

PinDiameter = 4; // Default = 4
// Diameter of the eject pin body

TaperDiameter = 3.2; // Default = 3.2
// Diameter of the pin tips

PinWiggleRoom = 0.5; // Default = 0.5
// Amount to decrease pin diameter and tips for easier insertion/removal.  It also allows for the 180-sided polygon used to render circles -- see "undersized holes" at [url]https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids#cylinder[/url]

// Number of fragments (polygon sides) used to render a full circle.
    $fn = 180; // Default = 180  Typical range = 6 - 360

/////////////////////////////
//  Make the part
/////////////////////////////

// Make the first pin
translate ([0, 0, PinHeight/2]) cylinder (PinHeight - TaperHeight*2, d = PinDiameter - PinWiggleRoom, center=true);
// Eject pin body 1

translate ([0, 0, TaperHeight/2]) cylinder (TaperHeight, d1 = TaperDiameter - PinWiggleRoom, d2 = PinDiameter - PinWiggleRoom, center=true);
// Eject pin bottom 1

translate ([0, 0, PinHeight - TaperHeight/2]) cylinder (TaperHeight, d1 = PinDiameter - PinWiggleRoom, d2 = TaperDiameter - PinWiggleRoom, center=true);
// Eject pin top 1

// Make the second pin
translate ([0, PinDiameter * 2, PinHeight/2]) cylinder (PinHeight - TaperHeight*2, d = PinDiameter - PinWiggleRoom, center=true);
// Eject pin body 2

translate ([0, PinDiameter * 2, TaperHeight/2]) cylinder (TaperHeight, d1 = TaperDiameter - PinWiggleRoom, d2 = PinDiameter - PinWiggleRoom, center=true);
// Eject pin bottom 2

translate ([0, PinDiameter * 2, PinHeight - TaperHeight/2]) cylinder (TaperHeight, d1 = PinDiameter - PinWiggleRoom, d2 = TaperDiameter - PinWiggleRoom, center=true);
// Eject pin top 2


Scott
EDIT: Updated LS30_Eject_Pin_Ultimarc.scad to generate two pins instead of just one.
« Last Edit: Yesterday at 02:44:23 pm by PL1 »

05SRT4

  • Trade Count: (+5)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1042
  • Check out my Pow Pow
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #7 on: September 19, 2018, 07:37:19 am »
Lots of good work here! I have the upgrade and servo stick in hand. Need to find some sample mounting panels and will try your test print.

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #8 on: September 19, 2018, 08:51:23 am »
Lots of good work here! I have the upgrade and servo stick in hand. Need to find some sample mounting panels and will try your test print.
Thanks.   :cheers:

You don't need mounting panels for the test print. (LS30_Test_Print_Ultimarc.scad)

It's just a small cylinder (15.35mm diameter x 11 mm high) that lets you test different values for ShaftDiameter (yellow part) and ThreadedDiameter (red part) without printing a whole handle.
- Test print = 0.44 meters / 1 gram of filament
- Handle     = 3.96 meters / 12 grams of filament




Scott

05SRT4

  • Trade Count: (+5)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1042
  • Check out my Pow Pow
Re: 3d printed LS-30 handle for the Ultimarc Ikari 12-way Rotary Upgrade
« Reply #9 on: September 19, 2018, 04:57:31 pm »
Did a super rough print. The inner diameter has enough play that you can wiggle it back and forth. Im thinking bringing it down to maybe 9.15-9.20 would be enough so it doesn't have much play but still slides on and off.

****JUST NOTICED THE TEST IS DIFFERENT FROM THE ACTUAL ONE****




I printed it at .2 mm layer height, the top part gets a little rough. Im not sure if adding the cap would help smooth it out. Might try doing .1mm layer height to smooth it out but adds another hour to the print.
Also the bottom curve had to much overhang, printing at .1mm might fix that.



I need to get some hardware from the store, printing another one out with other settings. Need more top layers, 2 was not enough.
« Last Edit: September 19, 2018, 05:34:14 pm by 05SRT4 »

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Online Online
  • Posts: 6833
  • 2013 UCA Awardee
Did a super rough print. The inner diameter has enough play that you can wiggle it back and forth. Im thinking bringing it down to maybe 9.15-9.20 would be enough so it doesn't have much play but still slides on and off.
Yeah, there are lots of little tweaks to the variables that will dial-in these prints for your slicer/firmware-settings/printer.

A firmware setting that I changed on my printer possibly causes it to over-extrude by about 4-6%.

Once you get a good clean print for the handle, it's easy to adjust variables and reprint the smaller pin and handle top prints to fit the handle.

You can probably reduce the "WiggleRoom" variables in the eject pin and handle top OpenSCAD files.

I printed it at .2 mm layer height, the top part gets a little rough. Im not sure if adding the cap would help smooth it out. Might try doing .1mm layer height to smooth it out but adds another hour to the print.
Also the bottom curve had to much overhang, printing at .1mm might fix that.
The overhang on the bottom prints OK here.   :dunno

The cap should help to smooth the top, but you might also want to slightly reduce TopDiameter so you get a circle connecting the inside of the top layer's 8 triangles. (red circle)



If you do that, you might also need to reduce PinDistance. (handle file, line 57)


Scott

  
 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31