Archive for October, 2015

Murder Mystery

The stains appeared black-red under the cold LED light and my first thought went along the lines of “Somebody dragged a corpse out of the kitchen!”:

Restaurant back door

Restaurant back door

The dumpsters sit off the sidewalk behind me on the left, so, most likely, they just have a bit of trouble maneuvering overstuffed trash cans and grease tanks around the door. At least, that’s what we hoped.

Notice how the door hinges the wrong way? Perhaps the architect never anticipated moving waste from the kitchen to the dumpsters.

The food was OK (we did not order the Chef’s Special Long Pig), but their overly loud “background music” reverberated far too long inside a cavernous room with hard walls. We gave it 2/10: would not eat there again.

This has absolutely nothing to do with stabbing guides.

1 Comment

LED Ring Desk Lamp

A defunct desk lamp emerged from the clutter and cried out for bright, new LEDs. This adapter puts a small LED ring and nine white LEDs on the original lamp head:

Ring Light Mount - in operation

Ring Light Mount – in operation

Peering into the business end, before mounting it on the lamp, shows some abrasive adjustment on the inside layer:

Ring Light Mount - LEDs installed

Ring Light Mount – LEDs installed

That layer printed over a quick-and-easy support spider:

Ring Light Mount - solid model - bottom

Ring Light Mount – solid model – bottom

The Slic3r preview looking down through the layer just over the support shows that the perimeter of those LED holes doesn’t have much support:

Ring Light Mount - Slic3r preview - bridge layer

Ring Light Mount – Slic3r preview – bridge layer

The obvious threads drooped in the predictable way, so I just clipped them off, sanded the high spots into submission, and epoxied everything in place:

Ring Light Mount - LED wiring

Ring Light Mount – LED wiring

That nice Hilbert Curve infill is completely wasted inside the OEM shade, but the smooth curve around the rim had to be on the top surface.

Rather than beefing up the support, you should print the bottom ring (or the top rim) separately, then glue it back on, but I wanted to see how well simple support worked with PETG.

It came out reasonably well:

Ring Light Mount - support spider

Ring Light Mount – support spider

That’s far more hair than usual, even for PETG, because I made the spider’s legs exactly three thread widths wide. Slic3r reduced the single infill thread to, literally, a hair that didn’t stick to the platform; the model now has four-thread-wide legs.

Slic3r’s automatic support would do a better job of holding up the underside, albeit with more plastic and printing time:

Ring Light Mount - Slic3r preview - auto support

Ring Light Mount – Slic3r preview – auto support

The top view looks about like you’d expect:

Ring Light Mount - solid model - top

Ring Light Mount – solid model – top

Those two solid models show the small hole for the LED ring wiring, which I drilled into the as-printed plastic. The original layout included just the LED ring, with the wire through a big central hole, but then I realized the wall wart had enough moxie for a few more LEDs. So it goes.

Anyhow, the lamp provides just enough illumination below my big monitors to suffice. The gooseneck might not be quite long enough, but that’ll be another project…

The OpenSCAD source code:

// LED Ring Light Mount
// Ed Nisley KE4ZNU October 2015

DoSupport = true;

//- Extrusion parameters must match reality!

ThreadThick = 0.25;
ThreadWidth = 0.40;

HoleWindage = 0.2;

Protrusion = 0.1;			// make holes end cleanly

inch = 25.4;

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);

//----------------------
// Dimensions

NumSides = 8*4;						// number of sides on each "cylinder"

LENGTH = 0;
ID = 1;
OD = 2;

Shade = [6.0,45.2,47.5];			// threaded end of OEM lamp shade
RingLED = [4.5,36.0,51.0];

SpotLED = [2.0,0,5.0];				// discrete LEDs in center
NumSpots = 8;						// discrete LEDs around the one in the middle

Support = [(RingLED[LENGTH] - 1*ThreadThick),0,(RingLED[OD] - 4*ThreadWidth)];
NumSupports = NumSides/2;

ThreadBase = RingLED[LENGTH] + SpotLED[LENGTH];
OAHeight = ThreadBase + Shade[LENGTH];

//----------------------
// Useful routines

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=(FixDia + HoleWindage)/2,
           h=Height,
	   $fn=Sides);
}

//----------------------
// Build it

	difference() {
		union() {																				// overall shape
			translate([0,0,ThreadBase])
				rotate_extrude(convexity = 2, $fn=NumSides)
					translate([Shade[OD]/2,0])
						circle(r=Shade[LENGTH],$fn=NumSides);
			cylinder(d=(Shade[OD] + 2*Shade[LENGTH]),h=ThreadBase,$fn=NumSides);
			translate([0,0,ThreadBase])
				cylinder(d=Shade[OD],h=Shade[LENGTH],$fn=NumSides);
		}
		
		translate([0,0,ThreadBase - Protrusion])
			cylinder(d=(Shade[ID] + HoleWindage),h=(Shade[LENGTH] + 2*Protrusion),$fn=NumSides);	// opening for shade thread
			
		translate([0,0,-Protrusion])
			cylinder(d=(RingLED[OD] + HoleWindage),h=(RingLED[LENGTH] + Protrusion),$fn=NumSides);	// opening for LED ring
			
		rotate(180/NumSides)																		// LED ring power wire
			translate([RingLED[ID]/2,0,0])
				rotate(180/6)
					PolyCyl(2.5,OAHeight,6);
			
		rotate(180/8  - 180/NumSides)
			PolyCyl(SpotLED[OD],OAHeight,8);														// central LED SpotLED
			
		for (i=[0:NumSpots-1])																		// surrounding spots
			rotate(i*360/NumSpots - 180/NumSides)
				translate([(RingLED[ID] - 2*SpotLED[OD])/2,0,0])
						rotate(180/8)
							PolyCyl(SpotLED[OD],OAHeight,8);
	}
	
//-- Support structure

	if (DoSupport)
		color("Yellow")
		rotate(180/NumSides)													// align bars to flat internal faces
			for (i=[0:NumSupports/2 - 1]) {
				rotate(i * 360 / NumSupports)
					translate([0,0,Support[LENGTH]/2])
						cube([Support[OD],4*ThreadWidth,Support[LENGTH]],center=true);
			}

,

2 Comments

USB-to-SATA Drive Adapter Performance

The discussion about scrubbing hard drives suggested I really should be using larger block sizes to wring better performance from the hardware.

So I ran variations on this theme:

time sudo dd if=/dev/urandom of=/dev/sdc bs=4K count=32K

For the BS (“block size”) parameter, 1K = 1024 and 1KB = 1000. Similarly for 1M vs. 1MB.

The results, viewed as a picture because WordPress seems unable to import a formatted spreadsheet from LibreOffice like it used to:

USB-SATA Adapter - Barracuda 7200.10 drive

USB-SATA Adapter – Barracuda 7200.10 drive

Each operation transfers 128 MB (128 x 220 = 131 x 106) bytes. The variations probably come from other stuff going on, most notably the USB-to-serial adapter driving the plotter while I’m testing a tweak to the Superformula demo code.

Reads ever so much faster than writes, so the USB adapter definitely isn’t getting in the way; I assume the drive accepts the commands & data as fast as its little heads can carry them away. The data, being relentlessly pseudo-random, won’t get compressed along the way.

So, in round numbers, the block size just absolutely does not make any difference.

Update: Based on an early comment from Edward Berner to a previous post, I was looking in the wrong place:

dd if=/dev/urandom of=/dev/zero bs=4K count=32K
32768+0 records in
32768+0 records out
134217728 bytes (134 MB) copied, 9.63064 s, 13.9 MB/s
dd if=/dev/urandom of=test.bin bs=4K count=32K
32768+0 records in
32768+0 records out
134217728 bytes (134 MB) copied, 10.018 s, 13.4 MB/s
dd if=test.bin of=/dev/zero bs=4K count=32K
32768+0 records in
32768+0 records out
134217728 bytes (134 MB) copied, 0.0385358 s, 3.5 GB/s
dd if=test.bin of=test2.bin bs=4K count=32K
32768+0 records in
32768+0 records out
134217728 bytes (134 MB) copied, 0.45044 s, 298 MB/s

I installed an SSD on this box a while ago, so the 3.5 GB/s disk-to-discard speed represents the SSD’s read rate. The 298 MB/s disk-to-disk speed would be its write speed, probably with some clever buffering going on.

So the real bandwidth limitation in wiping a disk comes from the pseudo-random generator behind /dev/urandom, not the disk or USB interface. It would probably be faster to fill a 1 GB (or more) file with noise at 14 MB/s, then copy it enough times to fill the drive at whatever speed the drive can handle it.

Thanks, Edward, for figuring that out!

2 Comments

SATA vs. USB Hard Drive Write Speeds

The stack of drives-to-be-scrubbed disgorged a pair of SATA drives, so I plugged one of them into an internal SATA port and unleashed dd on it:

time sudo dd if=/dev/urandom of=/dev/sdb bs=4096 count=10000
10000+0 records in
10000+0 records out
40960000 bytes (41 MB) copied, 4.19793 s, 9.8 MB/s

real	0m4.208s
user	0m0.004s
sys	0m2.880s

time sudo dd if=/dev/urandom of=/dev/sdb bs=1024 count=40000
40000+0 records in
40000+0 records out
40960000 bytes (41 MB) copied, 7.38392 s, 5.5 MB/s

real	0m7.394s
user	0m0.004s
sys	0m3.505s

time sudo dd if=/dev/urandom of=/dev/sdb bs=16384 count=2500
2500+0 records in
2500+0 records out
40960000 bytes (41 MB) copied, 4.2042 s, 9.7 MB/s

real	0m4.214s
user	0m0.000s
sys	0m2.880s

The timing for a few (tens of) thousand blocks comes out somewhat below the long-term average, which was the same 12 to 14 MB/s produced by the USB 2.0 adapter. It just doesn’t get any better than that, mostly due to rotational delays.

In round numbers, that’s 40 to 50 GB/h, so it’s best to start scrubbing those terabyte drives early in the day…

8 Comments

Stabbing Guides

Many of my solid models have holes for alignment pins made from filament snippets that let me glue the pieces together with near-perfect registration:

Alignment Hole and Pin

Alignment Hole and Pin

A reader who designs oil-field equipment for a living pointed out that, in his world, they’re called “stabbing guides”:

Stabbing_Point_on_Leg_1

Stabbing_Point_on_Leg_1

He specifies steel plate and welding instructions:

Stabbing_Guide_Type_3

Stabbing_Guide_Type_3

Stabbing guides for large modules may rise 25 feet above the deck plates…

After they install all the little bits on a “part” like this:

Generator Module - during assembly

Generator Module – during assembly

It fits neatly atop the stabbing guides and gets welded to a somewhat larger structure:

Generator Module - installed

Generator Module – installed

No sissy plastic for him!

My puny pins don’t qualify as stabbing guides, but forgive me if I sneak the term in every now and then…

Thanks, Tom!

,

3 Comments

Swept Claw Model

Our Larval Engineer asked for help with an OpenSCAD model of a 3D printable claw that, she says, has nothing at all to do with the upcoming Night of Little Horrors. Not having had an excuse to fiddle with the new (and lightly documented) sweep() functions, I gnawed on the sweep-drop.scad example until this popped out:

Swept Claw - solid model

Swept Claw – solid model

That might be too aggressively sloped up near the top, but it’s a start.

The OpenSCAD source code:

use <sweep.scad>
use <scad-utils/transformations.scad>

function shape() = [[0,-25],[0,25],[100,0]];

function path(t) = [100*(1+sin(-90-t*90)), 0, (100 * t)];

step = 0.01;

path_transforms = [for (t=[0:step:1-step]) 
    translation(path(t)) * 
    scaling([0.5*(1-t) + 0.1,0.75*(1-t) + 0.1,1])];
    
sweep(shape(), path_transforms);

It’s perfectly manifold and slices just as you’d expect; you could affix it to a mounting bracket easily enough.

Some notes on what’s going on…

The t index determines all the other values as a function of the layer from the base at t=0 to the top at t=0.99.

The shape() defines the overall triangular blade cross-section at the base; change the points / size to make it look like you want.

The path() defines the XYZ translation of each slab that’s extruded from the shape() cross-section. I think the Z value sets the offset & thickness of each slab. The constant 100 in the X value interacts with the overall size of the shape(). The 90 values inside the sin() function set the phase & scale t so the claw bends the right way; that took some fiddling.

The parameters in scaling() determine how the shape() shrinks along the path() as a function of the t parameter. The 0.1 Finagle Constants prevent the claw from tapering to a non-printable point at the tip. I think the Z value must be 1.000 to avoid weird non-manifold issues: the slabs must remain whatever thickness the sweep functions set them to be.

It compiles & renders almost instantly: much faster than I expected from the demos.

The folks who can (and do!) figure that kind of model (and the libraries behind it) from first principles have my undying admiration!

Leave a comment

Painting By Numbers

The south- and snowplow-facing numbers on the mailbox weren’t up to the challenge:

Mailbox - faded numbers

Mailbox – faded numbers

I wiped the crud off the reflective labels with denatured alcohol before painting, but that was the extent of the surface preparation.

I’m not getting graded on my ability to paint within the lines using a foam brush and that’s a Good Thing:

Mailbox - repainted numbers

Mailbox – repainted numbers

That’s Rustoleum Rusty Metal Primer, chosen entirely because it was oil-based, outdoor-rated, and near the front of the shelf. I’m not going to topcoat it; that stuff is on its own. The slight color variations show still-wet primer here & there.

The north-facing numbers were in better shape, so a few dabs covered the obvious problems.

Hey, I wiped that peeling paint off the top of the box, too…

15 Comments