Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
Sometimes crickets make their way into the basement. This one, a model that I’ve always known as a Jerusalem Cricket(*) evidently lost a pitched battle with one of the Dust Bunnies guarding the Basement Laboratory:
Jerusalem Cricket vs Dust Bunny – top view
A rear view:
Jerusalem Cricket vs Dust Bunny – rear view
From the front:
Jerusalem Cricket vs Dust Bunny – front view
I deported it to the flower garden outside the basement door, where I hope it can brush off the Bunny’s entrapments…
It may not be a Jerusalem Cricket, because they’re more common out west, but that’s the best match in our bug books and that’s what we’ve always called them.
[Update: (*) It’s most likely a Cave Cricket. See the comments for details.]
Then generate the sphere (well, two spheres, one for each dent) and offset it to scoop out the dent:
for (i=[-1,1]) {
translate([i*(DentSphereRadius + HandleThick/2 - DentDepth),0,StringHeight])
sphere(r=DentSphereRadius);
HandleThick controls exactly what you’d expect. StringHeight sets the location of the hole punched through the handle for a string, which is also the center of the dents.
The spheres have many facets, but only a few show up in the dent. I like the way the model looks, even if the facets don’t come through clearly in the plastic:
Quilting circle template – handle dent closeup – solid model
It Just Works and the exact math produces a better result than by-guess-and-by-gosh positioning.
The sphere radius will come out crazy large for very shallow dents. Here’s the helmet plate for my Bicycle Helmet Mirror Mount, which has an indentation (roughly) matching the curve on the side of my bike helmet:
Helmet mirror mount – plate
Here’s the sphere that makes the dent, at a somewhat different zoom scale:
Helmet mirror mount – plate with sphere
Don’t worry: trust the math, because It Just Works.
You find equations like that in Thomas Glover’s invaluable Pocket Ref. If you don’t have a copy, fix that problem right now; I don’t get a cut from the purchase, but you’ll decide you owe me anyway. Small, unmarked bills. Lots and lots of small unmarked bills…
The humidity in the basement safe started rising this month:
Basement Safe – 2013-07-28
The bag of new silica gel weighed 575 g, so it adsorbed about 67 g of water as the humidity rose from bone dry to 24%. Last month it had soaked up 31 g, so the safe admits nearly an ounce of water each month with 50% RH in the basement. It takes five months to accumulate 60-ish g of water during the winter.
According to the Sorbent Systems charts, silica gel’s equilibrium capacity at 24% is about 12% of the gel’s weight, which would work out to 60 g. That’s close enough, methinks, given the graph resolution; the humidity changes slowly enough that it’s sorta-kinda equilibrated in there… 67 g works out to 13.4% of the dry weight, which is in the same ballpark.
I made up three more bags of dry gel (500 g + 7 or 8 g tare), tossed one in the safe, one in the 6 gallon plastic bucket of 3D printer filament, and one in an empty 6 gallon bucket for comparison. Some 6 dot (10-through-60%) humidity indicator cards are on their way, seeing as how I don’t have nearly enough dataloggers to keep up with the demand…
Decades ago, one jaw on my little 1/4 inch wrench that fits 4-40 nuts broke off. I brazed it back on, fully aware that one day it would break off again, because brazing isn’t really a suitable repair technique for a wrench, even one labeled as “Precision” in that time-honored manner of all low-cost tools.
Time passes, I’m tightening screws against 4-40 nuts, and the jaw gives way:
Precision wrench – broken jaw
So I sawed off a strip of bedframe steel that fit the nuts better than the original stamped steel, did a bit of hand filing, and came up with a reasonable replacement:
Precision wrench – detail
I rammed it into the handle, just as they’d done with the original stamped steel shape:
Mary just started an ambitious pieced quilt that requires 50-some-odd precisely sized 1-1/2 inch circles, with marks to locate a 1 inch circle in the middle. She started using a drafting template to mark the smaller circle on freezer paper (don’t ask, it’s complicated), but we couldn’t find the template I know I have with the larger circles.
So I says to my wife, I sez, “Hey, we have the technology. What would really simplify what you’re doing?” After a bit of doodling, we came up with a ring having the proper ID and OD, plus a flat handle of some sort.
Half an hour later, I had a solid model:
Quilting circle template – solid model
An hour after that I handed her a warm piece of plastic:
Quilting circle template
The bottom ring is exactly 1-1/2 inch OD, 1 inch ID, and thin enough to draw around. The handle keeps her fingers out of the way and even has grips and a hole for a string.
The print quality near the hole isn’t as good as I’d like, because the slicer turned that entire volume into a solid slab of plastic. I can fix that in the second version, but right now she has something to work with, evaluate, and figure out what would improve it.
3D printing isn’t for everybody, but it’s a vital part of my shop!
The OpenSCAD source code has parameters for everything, so we can crank out more templates without fuss:
// Quilting - Circle Template
// Ed Nisley KE4ZNU - July 2013
Layout = "Show"; // Show Build Circle Handle
//-------
//- Extrusion parameters must match reality!
// Print with 2 shells
ThreadThick = 0.25;
ThreadWidth = 0.40;
HoleFinagle = 0.2;
HoleFudge = 1.00;
function HoleAdjust(Diameter) = HoleFudge*Diameter + HoleFinagle;
Protrusion = 0.1; // make holes end cleanly
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
function IntegerMultipleMin(Size,Unit) = Unit * floor(Size / Unit);
inch = 25.4;
//-------
// Dimensions
CircleID = (1) * inch;
SeamAllowance = (1/4) * inch;
CircleOD = CircleID + 2*SeamAllowance;
CircleThick = 6*ThreadThick;
CircleSides = 12*4;
HandleHeight = (2) * inch;
HandleThick = IntegerMultiple(5.0,ThreadWidth);
HandleSides = 12*4;
StringDia = 4.0;
StringSides = 8;
StringHeight = 0.75*HandleHeight;
DentDepth = HandleThick/4;
DentDia = 15.0;
DentSphereRadius = (pow(DentDepth,2) + pow(DentDia,2)/4)/(2*DentDepth);
//-------
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
cylinder(r=HoleAdjust(FixDia)/2,h=Height,$fn=Sides);
}
module ShowPegGrid(Space = 10.0,Size = 1.0) {
RangeX = floor(100 / Space);
RangeY = floor(125 / Space);
for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//-------
// Circle ring plate
module CircleRing() {
rotate(180/CircleSides)
difference() {
cylinder(r=CircleOD/2,h=CircleThick,$fn=CircleSides);
translate([0,0,-Protrusion])
cylinder(r=CircleID/2,h=(CircleThick + 2*Protrusion),$fn=CircleSides);
}
}
//-------
// Handle
module Handle() {
difference() {
rotate([0,90,0])
scale([HandleHeight/(CircleOD/2),0.9,1])
rotate(180/HandleSides)
cylinder(r=CircleOD/2,h=HandleThick,center=true,$fn=HandleSides);
translate([0,0,-HandleHeight])
cube([2*CircleOD,2*CircleOD,2*HandleHeight],center=true);
translate([-HandleThick,0,StringHeight])
rotate([0,90,0])
rotate(180/StringSides)
PolyCyl(StringDia,2*HandleThick,StringSides);
# for (i=[-1,1]) {
translate([i*(DentSphereRadius + HandleThick/2 - DentDepth),0,StringHeight])
sphere(r=DentSphereRadius);
}
}
}
module Template() {
CircleRing();
Handle();
}
//-------
// Build it!
ShowPegGrid();
if (Layout == "Circle")
CircleRing();
if (Layout == "Handle")
Handle();
if (Layout == "Show")
Template();
I put the XY coordinate origin in the middle of the platform, so that laying objects out for printing doesn’t require knowing how large the platform will be: as long as the printer is Big Enough, you (well, I) can print without further attention.
The RepRap world puts the XY coordinate origin in the front left corner of the platform, so that the platform size sets the maximum printable coordinates and all printing happens in Quadrant I. This has the (major, to some folks) advantage of using only positive coordinates, while requiring an offset for each different platform.
Yes, depending on which printer software you use, you can (automagically) center objects on your platform; this is often the only way to find objects created with Trimble (formerly Google) Sketchup. I am a huge fan of knowing exactly what’s going to happen before the printing starts, so I position my solid models exactly where I want them, right from the start. For example, this OpenSCAD model of the bike helmet mirror parts laid out for printing:
Helmet mirror mount – 3D model – Show layout
… exactly matches the plastic on the Thing-O-Matic’s platform, with the XY origin right down the middle of the platform:
Helmet mirror mount on build platform – smaller mirror shaft
It’d print exactly the same, albeit with more space around the edges, on the M2’s platform.
Similarly, the Z axis origin sits exactly on the surface of the platform. That way, the Z axis coordinate equals the actual height of the current thread extrusion in a measurable way: when you set the Z axis to, say, 2.0 mm, you can measure that exact distance between the extruder nozzle and the platform:
Taper gauge below nozzle
Now, admittedly, I fine-tune that distance by measuring the height of the skirt thread around the printed object, but the principle remains: a thread printed on the platform with Z=0.25 should be exactly 0.25 mm thick.
The start.gcode file handles all that:
;-- Slic3r Start G-Code for M2 starts --
; Ed Nisley KE4NZU - 15 April 2013
M140 S[first_layer_bed_temperature] ; start bed heating
G90 ; absolute coordinates
G21 ; millimeters
M83 ; relative extrusion distance
M84 ; disable stepper current
G4 S3 ; allow Z stage to freefall to the floor
G28 X0 ; home X
G92 X-95 ; set origin to 0 = center of plate
G1 X0 F30000 ; origin = clear clamps on Y
G28 Y0 ; home Y
G92 Y-127 ; set origin to 0 = center of plate
G1 Y-125 F30000 ; set up for prime at front edge
G28 Z0 ; home Z
G92 Z1.0 ; set origin to measured z offset
M190 S[first_layer_bed_temperature] ; wait for bed to finish heating
M109 S[first_layer_temperature] ; set extruder temperature and wait
G1 Z0.0 F2000 ; plug extruder on plate
G1 E10 F300 ; prime to get pressure
G1 Z5 F2000 ; rise above blob
G1 X5 Y-122 F30000 ; move away from blob
G1 Z0.0 F2000 ; dab nozzle to remove outer snot
G4 P1 ; pause to clear
G1 Z0.5 F2000 ; clear bed for travel
;-- Slic3r Start G-Code ends --
The wipe sequence, down near the bottom, positions the extruder at the front center edge of the glass plate, waits for it to reach the extrusion temperature, then extrudes 10 mm of filament to build up pressure behind the nozzle. The blob generally hangs over the edge of the platform and usually doesn’t follow the nozzle during the next short move and dab to clear the mess:
M2 – Wipe blobs on glass platform
I’ve also configured Slic3r to extrude at least 25 mm of filament in at least three passes around the object. After that, the extruder pressure has stabilized and the first layer of the object begins properly.
Which brings up another difference: the first layer printed on the platform is exactly like all the others. It’s not smooshed to get better adhesion or overfilled to make the threads stick together:
Robot cookie cutter – printing first layer
I print the first layer at 25 mm/s to give the plastic time to bond to the platform and use hairspray to make PLA stick to glass like it’s glued down.
I think the exported config.ini file corresponds to the currently selected set of sub-configurations; I find it difficult to keep a myriad of selections up-to-date while tweaking things, so mostly I don’t bother with named configurations.
The start.gcode and end.gcode lines go on forever, with embedded newlines.
# generated by Slic3r 0.9.11-dev on Mon Jul 22 09:28:22 2013
avoid_crossing_perimeters =
bed_size = 190,250
bed_temperature = 70
bottom_solid_layers = 3
bridge_acceleration = 0
bridge_fan_speed = 100
bridge_flow_ratio = 1
bridge_speed = 150
brim_width = 0
complete_objects = 0
cooling = 1
default_acceleration = 0
disable_fan_first_layers = 0
duplicate = 1
duplicate_distance = 6
duplicate_grid = 1,1
end_gcode = ;-- Slic3r End G-Code for M2 starts --\n; Ed Nisley KE4NZU - March 2013\nM104 S0 ; drop extruder temperature\nM140 S0 ; drop bed temperature\nM106 S0 ; bed fan off\nG1 Z180 F2000 ; lower bed\nG1 X0 Y0 F30000 ; center nozzle\nM84 ; disable motors\n;-- Slic3r End G-Code ends --
external_perimeter_speed = 50
external_perimeters_first = 0
extra_perimeters = 1
extruder_clearance_height = 20
extruder_clearance_radius = 20
extruder_offset = 0x0
extrusion_axis = E
extrusion_multiplier = .99
extrusion_width = 0.40
fan_always_on = 0
fan_below_layer_time = 45
filament_diameter = 1.72
fill_angle = 45
fill_density = 0.15
fill_pattern = honeycomb
first_layer_bed_temperature = 70
first_layer_extrusion_width = 0
first_layer_height = 100%
first_layer_speed = 25
first_layer_temperature = 175
g0 = 0
gap_fill_speed = 50
gcode_arcs = 0
gcode_comments = 0
gcode_flavor = reprap
infill_acceleration = 0
infill_every_layers = 1
infill_extruder = 1
infill_extrusion_width = 0
infill_first = 1
infill_only_where_needed = 1
infill_speed = 125
layer_gcode =
layer_height = 0.25
max_fan_speed = 100
min_fan_speed = 45
min_print_speed = 15
min_skirt_length = 25
notes =
nozzle_diameter = 0.35
only_retract_when_crossing_perimeters = 1
output_filename_format = [input_filename_base].gcode
overhangs = 1
perimeter_acceleration = 0
perimeter_extruder = 1
perimeter_extrusion_width = 0
perimeter_speed = 100
perimeters = 1
post_process =
print_center = 0,0
raft_layers = 0
randomize_start = 1
resolution = 0
retract_before_travel = 0.5
retract_layer_change = 0
retract_length = 1
retract_length_toolchange = 5
retract_lift = 0
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
retract_speed = 80
rotate = 0
scale = 1
skirt_distance = 5
skirt_height = 1
skirts = 3
slowdown_below_layer_time = 20
small_perimeter_speed = 25
solid_fill_pattern = rectilinear
solid_infill_below_area = 15
solid_infill_every_layers = 0
solid_infill_extrusion_width = 0
solid_infill_speed = 100
spiral_vase = 0
start_gcode = ;-- Slic3r Start G-Code for M2 starts --\n; Ed Nisley KE4NZU - 15 April 2013\nM140 S[first_layer_bed_temperature] ; start bed heating\nG90 ; absolute coordinates\nG21 ; millimeters\nM83 ; relative extrusion distance\nM84 ; disable stepper current\nG4 S3 ; allow Z stage to freefall to the floor\nG28 X0 ; home X\nG92 X-95 ; set origin to 0 = center of plate\nG1 X0 F30000 ; origin = clear clamps on Y\nG28 Y0 ; home Y\nG92 Y-127 ; set origin to 0 = center of plate\nG1 Y-125 F30000 ; set up for prime at front edge\nG28 Z0 ; home Z\nG92 Z1.0 ; set origin to measured z offset\nM190 S[first_layer_bed_temperature] ; wait for bed to finish heating\nM109 S[first_layer_temperature] ; set extruder temperature and wait\nG1 Z0.0 F2000 ; plug extruder on plate\nG1 E10 F300 ; prime to get pressure\nG1 Z5 F2000 ; rise above blob\nG1 X5 Y-122 F30000 ; move away from blob\nG1 Z0.0 F2000 ; dab nozzle to remove outer snot\nG4 P1 ; pause to clear\nG1 Z0.5 F2000 ; clear bed for travel\n;-- Slic3r Start G-Code ends --
start_perimeters_at_concave_points = 1
start_perimeters_at_non_overhang = 1
support_material = 0
support_material_angle = 0
support_material_enforce_layers = 0
support_material_extruder = 1
support_material_extrusion_width = 0
support_material_interface_layers = 0
support_material_interface_spacing = 0
support_material_pattern = rectilinear
support_material_spacing = 2.5
support_material_speed = 125
support_material_threshold = 0
temperature = 175
thin_walls = 1
threads = 2
toolchange_gcode =
top_infill_extrusion_width = 0
top_solid_infill_speed = 50
top_solid_layers = 3
travel_speed = 250
use_relative_e_distances = 0
vibration_limit = 0
wipe = 0
z_offset = 0