The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Tag: Improvements

Making the world a better place, one piece at a time

  • Toshiba 3 TB Drive Format & Speed

    A new Toshiba Canvio Basics 3 TB drive has two partitions:

    sudo fdisk -l /dev/sdb
    Disk /dev/sdb: 2.7 TiB, 3000592979968 bytes, 5860533164 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 4096 bytes
    I/O size (minimum/optimal): 4096 bytes / 4096 bytes
    Disklabel type: gpt
    Disk identifier: 575F7910-3F93-4FC5-B50F-7D1F05810EE6
    
    Device      Start        End    Sectors  Size Type
    /dev/sdb1      34     262177     262144  128M Microsoft reserved
    /dev/sdb2  264192 5860532223 5860268032  2.7T Microsoft basic data
    
    Partition 1 does not start on physical sector boundary.
    

    The “Microsoft reserved” partition is new to me. It’s apparently not a real partition, but a dumping ground for Windows disk management information.

    The drive is a classic Black Box:

    Toshiba 3 TB USB drive
    Toshiba 3 TB USB drive

    It comes with no specs, other than the tediously qualified “3 TB”, and the Toshiba web page shows only a 5 Gb/s = 625 MB/s “Max. transfer rate”.

    A quick test slurping data from the Sandisk video-rated MicroSD card extracted from the Fly6 camera shows it can write data at a sustained 21 MB/s:

    time rsync -ahu --progress /mnt/Fly6/ /mnt/part/test/
    sending incremental file list
    ./
    CONFIG.TXT
                 33 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=29/31)
    FLY6.VER
                 14 100%   13.67kB/s    0:00:00 (xfr#2, to-chk=28/31)
    DCIM/
    DCIM/15880604/
    DCIM/15980609/
    DCIM/15980609/09490001.AVI
            499.32M 100%   21.61MB/s    0:00:22 (xfr#3, to-chk=21/31)
    DCIM/15980609/09590002.AVI
            497.75M 100%   20.95MB/s    0:00:22 (xfr#4, to-chk=20/31)
    DCIM/15980609/10090003.AVI
            499.06M 100%   21.31MB/s    0:00:22 (xfr#5, to-chk=19/31)
    DCIM/15980609/10190004.AVI
            278.10M 100%   21.48MB/s    0:00:12 (xfr#6, to-chk=18/31)
    
    ... snippage ...
    
    real	6m26.272s
    user	0m55.900s
    sys	0m25.496s
    

    That’s with the card jammed into an Anker USB 3.0 adapter and both devices plugged into the two USB 3.0 “Super Speed” ports in the front of my desktop box. Plugging them both into the adjacent USB 2.0 ports drops the data rate to 18 MB/s.

    The Sandisk card claims read-write speeds of “up to” 20 MB/s, so it’s the limiting factor.

    Getting reliable performance numbers is surprisingly difficult:

    dd bs=4M count=1000 status=progress if=/dev/urandom of=/mnt/part/random.bin
    4177526784 bytes (4.2 GB, 3.9 GiB) copied, 214.064 s, 19.5 MB/s 
    1000+0 records in
    1000+0 records out
    4194304000 bytes (4.2 GB, 3.9 GiB) copied, 214.922 s, 19.5 MB/s
    
    dd bs=4M count=1000 status=progress if=/dev/urandom of=/mnt/part/random2.bin
    4194304000 bytes (4.2 GB, 3.9 GiB) copied, 217.08 s, 19.3 MB/s  
    1000+0 records in
    1000+0 records out
    4194304000 bytes (4.2 GB, 3.9 GiB) copied, 217.08 s, 19.3 MB/s
    

    Obviously, prying bits out of the random number generator limits the overall write speed.

    Zeros, however, are cheap and readily available:

    dd bs=4M count=1000 status=progress if=/dev/zero of=/mnt/part/null.bin
    4169138176 bytes (4.2 GB, 3.9 GiB) copied, 23.0091 s, 181 MB/s
    1000+0 records in
    1000+0 records out
    4194304000 bytes (4.2 GB, 3.9 GiB) copied, 23.1775 s, 181 MB/s
    
    dd bs=4M count=1000 status=progress if=/dev/zero of=/mnt/part/null2.bin
    4093640704 bytes (4.1 GB, 3.8 GiB) copied, 25.031 s, 164 MB/s 
    1000+0 records in
    1000+0 records out
    4194304000 bytes (4.2 GB, 3.9 GiB) copied, 25.7781 s, 163 MB/s
    

    But the caches take a while to drain, even after the command returns:

    time ( dd bs=4M count=1000 status=progress if=/dev/zero of=/mnt/part/null3.bin ; sync )
    4118806528 bytes (4.1 GB, 3.8 GiB) copied, 23.0004 s, 179 MB/s
    1000+0 records in
    1000+0 records out
    4194304000 bytes (4.2 GB, 3.9 GiB) copied, 23.5305 s, 178 MB/s
    
    real	0m35.887s
    user	0m0.008s
    sys	0m4.824s
    

    Dividing 4 GB / 35.9 s says the mechanical write speed is close to 110 MB/s.

    Reading proceeds a bit faster, while also running up against the effect of the many caches between the spinning platter and the screen:

    time ( cp /mnt/part/random.bin /dev/null )
    real	0m36.565s
    user	0m0.048s
    sys	0m1.712s
    
    time ( cp /mnt/part/random.bin /dev/null )
    real	0m29.157s
    user	0m0.036s
    sys	0m1.800s
    
    time ( cp /mnt/part/random.bin /dev/null )
    real	0m10.265s
    user	0m0.028s
    sys	0m1.040s
    
    time ( cp /mnt/part/random.bin /dev/null )
    real	0m0.608s
    user	0m0.004s
    sys	0m0.600s
    
    time ( cp /mnt/part/random.bin /dev/null )
    real	0m0.590s
    user	0m0.008s
    sys	0m0.580s
    
    time ( cp /mnt/part/random2.bin /dev/null )
    real	0m31.035s
    user	0m0.056s
    sys	0m1.816s
    
    time ( cp /mnt/part/random2.bin /dev/null )
    real	0m31.024s
    user	0m0.052s
    sys	0m1.860s
    

    Unsurprisingly, copying a brace of 4 GB files in parallel takes twice as long as each cold-buffer read, so disk’s raw read speed seems to be around 130 MB/s.

    The drive’s write speed won’t be the limiting factor while saving camera video data!

  • Monthly Science: Calibrated Bottle

    Mary used to mix up her oil-and-vinegar dressing using a measuring cup, then she drew markings on the bottle, then I added tidy labels:

    Calibrated Oil-and-Vinegar bottle
    Calibrated Oil-and-Vinegar bottle

    The labels align with her process: she adds ½ C oil first, then ¼ C vinegar, then various other ingredients. The liquids swirl around, sort themselves out, and it’s all good.

    Surprisingly, the labels survived uncounted dishwasher adventures.

  • Digital Tattoo Power Supply: Polarity Doesn’t Matter

    When I rewired the guts of the digital tattoo power supply to eliminate the series foot switch, I kept the original wiring polarity, with the black wire to the sleeve and the red wire to the tip:

    Tattoo Digital Power Supply - internal view
    Tattoo Digital Power Supply – internal view

    It’s the same color code I (strongly) recommend in the Squidwrench Electronics Workshops: use any color for the ground / common wire as long as it’s black, then, if you have a red wire, use it for the positive supply. You can use yellow for the higher supply voltage, but stop being clever.

    I put suitably colored Powerpoles on the far end of the cable to replace the standard tattoo machine spring clip connector, so I can attach clip leads, battery test fixtures, and so forth and so on.

    We wired the supply into a clip-leaded diode measurement setup with a current limiting resistor and a pair of multimeters to measure the diode current and forward voltage, whereupon we noticed all the meters displayed negative voltages and currents.

    After a frenzy of wire-checking verified their setup was all good, I forced the simplest possible test, herein recreated on my bench:

    Tattoo Digital Power Supply - polarity test
    Tattoo Digital Power Supply – polarity test

    Which produced this display:

    Tattoo Digital Supply - reverse polarity
    Tattoo Digital Supply – reverse polarity

    Huh.

    After a brief exploration of “Trust, but verify” territory, we swapped the clip leads from the power supply and continued the mission.

    Back on my bench, I pulled the supply apart and measured the voltage at the jack terminals:

    Tattoo Digital Power Supply - jack wiring
    Tattoo Digital Power Supply – jack wiring

    Still negative. Huh.

    The bottom of the power supply PCB shows exactly what you should expect by now:

    Tattoo Digital Power Supply - reversed color code
    Tattoo Digital Power Supply – reversed color code

    The red wire near the top of the board is, indeed, soldered to the trace labeled GND and goes to the jack’s tip terminal; the adjacent black wire goes to the front-panel LED. Similarly, the black wire just below it, soldered to the same trace as the yellow wire, goes to the jack’s sleeve terminal; that trace also connects to a resistor leading to the trace labeled LED+ and the LED’s red wire.

    Although tattoo machines run from DC supplies, their motors or vibrators don’t depend on any particular polarity and will run fine with a backwards supply.

    Resoldering the red and black wires where they should go produces the expected sign at the jack:

    Tattoo Digital Supply - meter leads
    Tattoo Digital Supply – meter leads

    Although measuring and plotting diode voltages and currents may seem tedious, actually wiring stuff together and taking data reveals how difficult the real world can be.

    I trusted the supply’s internal color code and, although I’m certain I tested the Powerpoles, I obviously didn’t notice the meter’s sign.

    Memo to self: Sheesh.

  • Summer Downshift

    We have several high-intensity / long-attention-span home projects scheduled this summer, all of which will keep me away from the Basement Laboratory.

    We’re OK, all is right with our world, but painting rooms and yard maintenance always take way more time than they should, while having close to zero intellectual content.

    Like, for example, the result of a strenuous morning devoted to removing a severely overgrown holly bush:

    Mother of All Holly Bush Stumps
    Mother of All Holly Bush Stumps

    I’ll post odd & ends a few times a week until maybe mid-August, whereupon I should get back to more usual pursuits.

    Enjoy your downtime …

  • Subaru Forester Relamping

    Prompted by RCP’s battery misadventure, I replaced a handful of the Forester’s incandescent bulbs:

    Subaru Forester 2015 - replaced bulbs
    Subaru Forester 2015 – replaced bulbs

    Despite what look like “squeeze here” markings, you must push the license plate bulb holders toward the center of the car:

    Subaru Forester 2015 - license plate bulb holders
    Subaru Forester 2015 – license plate bulb holders

    They were both stuck firmly to the trim plate, so I braced a screwdriver against the outboard edge of the trim panel, after which it becomes obvious how pressing inward compresses the (plastic) spring clip so you can pull the outward side of the holder away from the hatch.

    Casual searching turned up a bunch of exceedingly helpful advice for anyone DIY-ing through a Forester.

    The bulbs with conical ends, known as “festoon” lamps, (unsurprisingly) come in  several lengths. The Forester bulbs are about 25 mm long, (unsurprisingly) much shorter than the 31 mm LEDs that seem to be the smallest available replacements, but (surprisingly) the socket tabs have barely enough compliance for the extra half dozen millimeters:

    Subaru Forester 2015 - dome with 31 mm festoon LED bulb
    Subaru Forester 2015 – dome with 31 mm festoon LED bulb

    The LEDs are much much much brighter than the incandescents, although I’d prefer warm white to cool white. The cargo compartment lamp in the back is still way too dim; I don’t understand how Subaru decided on a plastic cover tinted dark smoke gray.

    All in all, a worthwhile upgrade!

    I wonder how long they’ll last? I have one spare of each type …

  • Snapping Turtle Teleportation

    The dark spot in the grass, barely visible over on the left, is a dinner-plate-size snapping turtle recently teleported from the middle of Rt 376 just north of Robinson Lane:

    Snapping Turtle Teleportation - Rt 376 - 2018-06-02
    Snapping Turtle Teleportation – Rt 376 – 2018-06-02

    The driver of the white van managed to stop both lanes during the rescue and, judging from the lack of gore, handled the snapper without incurring organic damage.

    Color me impressed!

  • Tour Easy Front Derailleur Cable Clamp

    In addition to sawing through the side of the cable ferrule, the front derailleur cable began breaking at the edge of the derailleur arm:

    Tour Easy Front Derailleur Cable - frayed
    Tour Easy Front Derailleur Cable – frayed

    It wouldn’t have survived another ride!

    Dan pointed out CNC machined aluminum cable clamps are a thing, but those are sized for larger frame tubes than the 1.0 inch steel used on our Tour Easy ‘bents and, although I’ve shimmed everything else on the frame, I wanted to tweak the cable angle to match the arm on the derailleur.

    A bit of OpenSCAD wrangling produces a likely candidate:

    Front Derailleur Cable Clamp - Slic3r
    Front Derailleur Cable Clamp – Slic3r

    That’s a bulked-up revision of the prototype:

    Tour Easy Front Derailleur Cable Clamp - installed
    Tour Easy Front Derailleur Cable Clamp – installed

    Done up in orange PETG, it demonstrated the idea worked, but two perimeter threads wrapped around 15% infill isn’t quite up to the task. Note the split along the screw on the far half and various irregularities around the ferrule.

    The cable angle isn’t quite right, either, as the proper compound angle would, alas, aim the cable into the pedal crank. The bulky bushings get in the way of putting the ferrule where it should be with the screws aligned in a tidy manner, so I must get used to the jaunty angle.

    The bulkier version, done with 50% infill and four perimeter threads, has the same tilt angle, but the ferrule sits further from the screws:

    Tour Easy Front Derailleur Cable Clamp V2 - rear quarter view
    Tour Easy Front Derailleur Cable Clamp V2 – rear quarter view

    The view from the left side shows the cable angles slightly to the rear, but the smaller angle should make it happier:

    Tour Easy Front Derailleur Cable Clamp V2 - side view
    Tour Easy Front Derailleur Cable Clamp V2 – side view

    Probably should have used black PETG. Next time, for sure!

    The OpenSCAD source code as a GitHub Gist:

    // Tour Easy Derailleur Cable Clamp
    // Ed Nisley KE4ZNU – June 2017
    /* [Build Options] */
    Layout = "Build"; // [Build, Show]
    /* [Extrusion] */
    ThreadThick = 0.25; // [0.20, 0.25]
    ThreadWidth = 0.40; // [0.40]
    function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
    /* [Hidden] */
    Protrusion = 0.01; // [0.01, 0.1]
    HoleWindage = 0.2;
    ID = 0;
    OD = 1;
    LENGTH = 2;
    /* [Cable Clamp] */
    FrameOD = 25.7; // Tour Easy has hard inch tubing + paint
    Ferrule = [1.5,5.1,12.0]; // cable ferrule
    EntryPoint = [0,13,60]; // cable entry to derailleur, +Y to rear of bike
    CableTilt = -20; // tilt from parallel to frame tube
    CableTheta = 0; // rotation around clamp from +X axis
    /* [Screws and Inserts] */
    ClampScrew = [3.0,5.5,35.0]; // M3 button / socket head cap screw
    ClampWasher = [3.7,7.0,0.7]; // M3 washer
    ClampNut = [3.0,6.0,4.0]; // M3 nylock nut
    /*
    ClampScrew = [4.0,7.0,25.0]; // M4 button head cap screw
    ClampWasher = [4.5,9.0,0.8]; // M4 washer
    ClampNut = [4.0,8.0,5.0]; // M4 nylock nut
    */
    NutShift = -0; // slide bushing toward nut for clearance
    //- Set clamp ring dimensions
    WallThick = 10.0;
    BushingSides = 8;
    Bushing = [ClampScrew[ID],
    // ClampWasher[OD]/cos(180/8) + 4*ThreadWidth,
    Ferrule[LENGTH]/cos(180/BushingSides),
    ClampScrew[LENGTH] – 2*ClampWasher[LENGTH] – ClampNut[LENGTH]];
    Ring = [FrameOD + HoleWindage,FrameOD + 2*WallThick,Ferrule[LENGTH]];
    ClampScrewOC = IntegerMultiple(FrameOD + ClampWasher[OD],1);
    echo(str(" screw OC: ",ClampScrewOC));
    ClampKerf = 0.75; // kerf between separated halves
    NumSides = 8*4;
    //- Adjust hole diameter to make the size come out right
    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);
    }
    // Construct things
    module ClampRing() {
    difference() {
    union() {
    cylinder(d=Ring[OD],h=Ring[LENGTH],$fn=NumSides); // basic ring
    for (j=[-1,1]) // screw bushings
    translate([Bushing[LENGTH]/2 + NutShift,j*ClampScrewOC/2,Ring[LENGTH]/2])
    rotate([0,-90,0]) rotate(180/BushingSides)
    cylinder(d=Bushing[OD],h=Bushing[LENGTH],$fn=BushingSides);
    intersection() {
    rotate([CableTilt,0,CableTheta]) // reinforce cable ferrule
    translate([(Ring[ID] + Ring[OD])/4,0,Ferrule[LENGTH]/2])
    rotate(180/8)
    cylinder(d=3*Ferrule[OD] + 0*ThreadWidth,2*Ferrule[LENGTH],center=true,$fn=8);
    cylinder(d=2*Ring[OD],h=Ring[LENGTH],$fn=NumSides); // basic ring
    }
    }
    translate([0,0,-Protrusion]) // frame tube
    cylinder(d=Ring[ID],h=Ring[LENGTH] + 2*Protrusion,$fn=NumSides);
    rotate([CableTilt,0,CableTheta]) // cable ferrule
    translate([(Ring[ID] + Ring[OD])/4,0,-0.25*Ferrule[LENGTH]]) {
    rotate(180/8)
    PolyCyl(Ferrule[OD],Ferrule[LENGTH],8);
    rotate(-22.5)
    PolyCyl(Ferrule[ID],2*Ferrule[LENGTH],4);
    }
    for (j=[-1,1]) // screw holes
    translate([Ring[OD]/2,j*ClampScrewOC/2,Ring[LENGTH]/2])
    rotate([0,-90,0]) rotate(180/6)
    PolyCyl(Bushing[ID],Ring[OD],6);
    for (i=[-1,1], j=[-1,1]) // screw & nut seats
    translate([i*(Bushing[LENGTH]/2) + NutShift,j*ClampScrewOC/2,Ring[LENGTH]/2])
    rotate([0,i*90,0]) rotate(180/BushingSides)
    cylinder(d=Bushing[OD],h=Bushing[LENGTH],$fn=BushingSides);
    translate([0,0,Ring[LENGTH]/2]) // slice it apart
    cube([ClampKerf,2*Ring[OD],2*Ring[LENGTH]],center=true);
    }
    }
    //- Build things
    if (Layout == "Show") {
    translate(EntryPoint)
    cube(1,center=true);
    ClampRing();
    }
    if (Layout == "Build") {
    ClampRing();
    }