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

  • Bike Rim Reflectorization

    Bike wheel with retroreflective tape
    Bike wheel with retroreflective tape

    Here’s a quick-and-easy way to improve the odds of your arriving home safely after dark: add snippets of retroreflective tape to the inside of the rims on your bike.

    Do half the rim in one color and leave the other half untaped (or taped in a contrasting color) so that the rim flashes as the wheel rotates. I originally applied orange tape, of which I have very nearly a lifetime supply, then added white when I got a sheet as part of a surplus deal.

    At 15 mph the 20-inch front wheel blinks at about 4 Hz, which is wonderfully attention-getting. The rear wheel, a more common 700C size, blinks at 3 Hz.

    It helps to measure the space between spokes, then set up a template to cut all the tape pieces the same length. Wipe the big chunks of dirt off the rim, then remove the remaining grunge with alcohol so the tape actually sticks.

    New York State vehicle law considers reflectorized tires as equal to those in-the-spokes reflectors, which is a Good Thing.

    The more you look like a UFO after dark, the less surprised the drivers are and the less hassle you get.

  • Keeping the Screws in Sherline Hold-Down Clamps

    A small improvement: add a snippet of heat stink shrink tubing to the screw in the L-shaped hold-down clamps and the screw won’t go walkabout in your tooling widget case.

    Make it the same length as the distance from the clamp to the surface and it’ll remind you how far to screw on the T-nut when you swap the clamps from tooling plate to milling machine table.

    The Sherline Mill Vise (PN 3551) comes with a set of clamps. They’re also available separately as the 4-Jaw Hold-Down Set (PN 3058).

  • Red Filter for White LED Bike Headlight

    White 5-LED headlight
    White 5-LED headlight

    As I mentioned there, we have white LED bike headlights clamped to the amateur radio antennas on our bikes, facing rearward to eliminate the “But, Officer, I didn’t see him” line from the accident investigation. That works fine during daylight hours, but it’s rather blinding after dark and, in any event, taillights are supposed to be red (after 1 Nov 2009, they may also be amber).

    The easiest way to get that result, without having to tote along Yet Another Light, is to slip a red filter over the white LED lens. This dramatically reduces the light output, because the yellow phosphor used to get white light out of what’s basically a blue LED doesn’t emit much energy in the red end of the spectrum, but it’s plenty good enough to be seen from the requisite 300 feet.

    Amber filters would be a much, much better match to the phosphor and I’ll use them next year when they’re legal.

    For what it’s worth, we’ve discovered that the more we look like UFOs after dark, the more clearance we get. The bikes are extensively reflectorized and lighted, plus we have reflective arm and leg bands. If somebody hits us, it’s because they did it intentionally; that’s usually the story with drunks and punks, alas.

    Red filter components
    Red filter components

    I cut two transparent disks from ordinary electronics packaging material, plus a red disk from the Primary Red filter material mentioned there, stacked them on the headlight, and fired some big heat stink shrink tubing around them. The tubing extended maybe 3 mm past the end of the headlight and shrank into a neat lip that matched the bezel around the lens.

    The tool to have for this sort of job is an Olfa Compass Circle Cutter. It leaves a pin prick in the center of the circle, but if you’re gentle that won’t be a problem in this application.

    The shrunken tubing will be exceedingly difficult to pull off the headlight, so you may want to wrap a layer of tape around the bezel before shrinking. Peel the tape off when you’re done and the tubing will have a few mils more clearance.

    No adhesive on earth will stick to both the polypropylene disks and the heatshrink tubing, but you can try silicone snot if you want. I made the disks just slightly larger than the bezel so that the tubing captures them as it shrinks. These things spend much of their lives in a ziplock baggie, so durability isn’t an issue.

    Red filter installed
    Red filter installed

    In any event, the filter looks like this when it’s installed. Because of the odd way I mounted the headlights, the side lenses aren’t visible (and they’re white, not red), but we have plenty of other light visible from the side.

    For the straight dope on current NYS bicycle laws, go there, click on the “Laws of New York” link, search for “bicycle”, then click on section 1236. It’s New York’s idea of a useful Web interface: get over it.

    The bezels on our lights are beginning to crack, so it’s probably time to start thinking about a killer street-legal day/night amber taillight. High intensity LEDs are dirt cheap these days…

  • Arduino Hardware-assisted SPI: Synchronous Serial Data I/O

    Many interesting projects require more digital output bits than the Arduino hardware can support. You then use 74HC595 serial-in/parallel-out chips and that tutorial pretty well explains how it works. The shiftOut() library function squirts a byte out through an arbitrary pin, leading with either the high or low bit.

    Software SPI: Clock and Data
    Software SPI: Clock and Data

    Just drop one byte into shiftOut() for each ‘595 lined up on your board. Remember to latch the bits (LOW-to-HIGH on RCK @ pin 12 of the ‘595) and enable the output drivers (LOW on -G @ pin 13, similarly) when you’re done sending everything. You can have separate latches-and-enables for each ‘595 if that suits your needs, although then you once again run out of Arduino bits pretty quickly. It’s entirely possible to devote a ‘595 to latches-and-enables for the rest of the chain, but that gets weird in short order.

    The scope shot shows that shiftOut() ticks along at 15 µs per bit (clock in the upper trace, data in the lower trace). For back-of-the-envelope purposes, call it 8 kB/s, which is probably less than you expected. If you have a string of 5 external bytes, as I did on a recent project, that’s only 1600 updates / second. It was part of a memory board reader & EPROM programmer: reading an 8 kB ROM chip requires two shift-register runs (one to set the address & data, one to read in the chip output), so the overall rate was on the order of 10 seconds per pass and much worse for programming. You can optimize the number of bits by not shifting out all the bytes, but that’s the general idea.

    Because ‘595 chips are output-only, in order to get 8 bits of data into the Arduino board, add a 74HC166 parallel-in/serial-out chip to the string. Alas, shiftOut() doesn’t know about input bits, so you’re on your own.

    Hardware SPI: Clock and Data
    Hardware SPI: Clock and Data

    If you’re going to have to write some code to get input bits anyway, you may as well use the ATmega168 (and its ilk) hardware SPI as it was intended to be used: for high-speed synchronous serial I/O. This scope shot shows the SPI clock (in the top trace again) ticking along at 1 µs per bit, which is 1/16 the Diecimila’s oscillator frequency. You can pick any power of two between 1/2 and 1/128; I used 1/16 because it’s fast enough to make the rest of the software the limiting factor, while slow enough to not require much attention to layout & so forth.

    Start by Reading The Fine Manual section about the ATmega168’s SPI hardware, starting at page 162.

    The pin definitions, being lashed to internal hardware, are not optional. Note that SCK is also the standard Arduino LED, which won’t be a problem unless you need a tremendous amount of drive for a zillion ‘595s. I stuck an additional LED on Arduino digital pin 2.

    #define PIN_HEARTBEAT     2             // added LED
    #define PIN_SCK          13             // SPI clock (also Arduino LED!)
    #define PIN_MISO         12             // SPI data input
    #define PIN_MOSI         11             // SPI data output
    

    Initial hardware setup goes in the usual setup() function:

    pinMode(PIN_SCK,OUTPUT);       // set up for "manual" SPI directions
    digitalWrite(PIN_SCK,LOW);
    pinMode(PIN_MOSI,OUTPUT);
    digitalWrite(PIN_MOSI,LOW);
    
    pinMode(PIN_MISO,INPUT);       // configure inputs
    digitalWrite(PIN_MISO,HIGH);
    
    SPCR = B01110001;              // Auto SPI: no int, enable, LSB first, master, + edge, leading, f/16
    SPSR = B00000000;              // not double data rate
    

    Basically, the “manual” setup allows you to wiggle the bits by hand with the hardware SPI control disabled.

    Arduino Hardware SPI Schematic
    Arduino Hardware SPI Schematic

    Here’s a chunk of the schematic so you can see how the bits rattle around. You’ll surely want to click it to get the details…

    I put the data in a structure that matches the shift register layout, with the first byte (Controls) connected to the ATmega’s MOSI pin and the last byte (DataIn) connected to MISO. The SCK pin drives all of the serial clock pins on the ‘595 and ‘166 chips in parallel. Your structure will certainly be different; this was intended to suck data from a Tek 492 Spectrum Analyzer memory board.

    typedef struct {      // external hardware shift register layout
     byte Controls;       // assorted control bits
     word Address;        // address value
     byte DataOut;        // output to external devices
     byte DataIn;         // input from external devices
    } SHIFTREG;
    
    SHIFTREG Outbound;    // bits to be shifted out
    SHIFTREG Inbound;     // bits as shifted back in
    

    The functions that make it happen are straightforward:

    void TogglePin(char bitpin) {
     digitalWrite(bitpin,!digitalRead(bitpin));
    }
    void PulsePin(char bitpin) {
     TogglePin(bitpin);
     TogglePin(bitpin);
    }
    
    void EnableSPI(void) {
     SPCR |= 1 << SPE;
    }
    
    void DisableSPI(void) {
     SPCR &= ~(1 << SPE);
    }
    
    void WaitSPIF(void) {
     while (! (SPSR & (1 << SPIF))) {
    //        TogglePin(PIN_HEARTBEAT);       // use these for debugging!
    //        TogglePin(PIN_HEARTBEAT);
     continue;
     }
    }
    
    byte SendRecSPI(byte Dbyte) {             // send one byte, get another in exchange
     SPDR = Dbyte;
     WaitSPIF();
     return SPDR;                             // SPIF will be cleared
    }
    
    void CaptureDataIn(void) {                // does not run the shift register!
     digitalWrite(PIN_ENABLE_SHIFT_DI,LOW);   // allow DI bit capture
     PulsePin(PIN_SCK);                       // latch parallel DI inputs
     digitalWrite(PIN_ENABLE_SHIFT_DI,HIGH);  // allow DI bit shifting
    }
    
    void RunShiftRegister(void) {
     EnableSPI();                             // turn on the SPI hardware
    
     Inbound.DataIn  = SendRecSPI(Outbound.DataIn);
     Inbound.DataOut = SendRecSPI(Outbound.DataOut);
    
     Inbound.Address  =         SendRecSPI(lowByte(Outbound.Address));
     Inbound.Address |= ((word) SendRecSPI(highByte(Outbound.Address))) << 8;
    
     Inbound.Controls = SendRecSPI(Outbound.Controls);
    
     PulsePin(PIN_LATCH_DO);                   // make new shift reg contents visible
     PulsePin(PIN_LATCH_ADDRESS);
     PulsePin(PIN_LATCH_CONTROLS);
    
     DisableSPI();                             // return to manual control
    }
    

    Actually using the thing is also straightforward. Basically, you put the data-to-be-sent in the Outbound variables and call RunShiftRegister(), which drops output bytes into SPDR and yanks incoming bytes out, then stuffing them in the Inbound variables. I have separate latch controls for the Controls, Address, and Data chips, although I don’t use them separately here.

    You must wiggle the parallel latch enable line on the 74HC166 chip before shifting to capture the data, as shown in CaptureDataIn(). That chip also requires a separate pulse on its serial clock line to latch the data, which you do manually with the hardware SPI disabled. If you’re paying attention, you’ll wonder if that clock pulse also screws up the data in the rest of the chips: yes, it does. If this is a problem, you must add some external clock-gating circuitry, disable the ‘595s, or pick a different input shift register chip; it wasn’t a problem for what I was doing.

    Here’s a function that reads data from a RAM chip on the Tek memory board, so it must write the address and read the RAM chip’s output. The PIN_DISABLE_DO bit controls the output buffers on the ‘595 that drives the RAM’s data pins; they must be disabled to read data back from the RAM. Don’t worry about the other undefined bits & suchlike; just assume everything does what the comments would have you believe.

    byte ReadRAM(word Address) {
     digitalWrite(PIN_DISABLE_DO,HIGH);            // turn off data latch output
     digitalWrite(PIN_BUS_READ,HIGH);              // allow RAM read access
    
     Outbound.Controls |=  CB_BUS_CLKPH2_MASK;     // set up RAM -CS gate
     Outbound.Address = Address;
     Outbound.DataOut = 0x55;                      // should not be visible
     RunShiftRegister();
    
     digitalWrite(PIN_BUS_N_SYSRAM,LOW);           // activate RAM -CS
     CaptureDataIn();                              // latch RAM data
     digitalWrite(PIN_BUS_N_SYSRAM,HIGH);          //  ... and turn -CS off
    
     Outbound.Controls &= ~CB_BUS_CLKPH2_MASK;     // disable -CS gate
     RunShiftRegister();                           // tell the board and get data
    
     return Inbound.DataIn;
    }
    
    Hardware SPI - Detail of clock and data timing
    Hardware SPI – Detail of clock and data timing

    Here’s a detailed shot of the outbound bit timing. Notice that the upward clock transitions shift bits into the ‘595 and ‘166 chips, while the SPI output data changes on the downward transitions. You can tweak that to match your hardware if you’re using different shift register chips, by messing with the SPCR settings.

    Bottom line: using the ATmega168 hardware SPI provided a factor-of-15 speedup and serial digital input, too.

  • Electric Drill Hung From Nail: Getting It Right

    When you hang an electric hand drill on a nail pounded into a floor joist, you want the chuck jaws to just clear the nail. Too large and the drill tends to fall off. Too small and it won’t go.

    I took way too long to figure this out, but…

    Adjust the chuck properly just once, then run a fat marker around the jaws.

    It’s trivially easy to get it right forever after: spin the chuck adjustment until the marks line up with the chuck nose and hang the drill up.

    Maybe everybody else knows that.

  • LED Flashlight Lens Protector

    Inova X1 lens protector
    Inova X1 lens protector

    Some years ago, a friend convinced me I needed an Inova X1 LED flashlight. He was right; I’ve carried one in my belt pack ever since and, in fact, added a couple of X5s to the household armory.

    Perforce, this is an old X1 with a coated glass lens to make the best of the LED. Newer X1s don’t have (or, likely) need the lens, as LED technology has made great strides in the last few years.

    I couldn’t bear the thought of that lens rattling around in my belt pack, chewed upon by the assortment of other crap in there. So I made a lens protector: a length of heatshrink tubing with a polypropylene window. You might want to do the same for your flashlight to keep from grinding up the optical surfaces on its shiny end.

    This tubing has an internal thermoplastic glue, but ordinary tubing would likely work as well. Position the tubing over the end of the flashlight with a few millimeters sticking out. Cut a circle from the clamshell case around some piece of consumer electronics, drop it on top of the lens, and shrink the tubing around the flashlight: watch it wrap right over the end and hold the circle in place. A dot or three of urethane glue may help for glue-less tubing.

    It’s transparent enough for most purposes, but when you really need more light or a tighter beam, pull it off. That’s aided by dabbing a trace of oil on the X1, which you can get directly from the (outside) of your nose. Yeah, gross, but it’s a renewable natural resource…

  • Recumbent Bicycle Amateur Radio Antenna Mount

    Homebrew antenna mount
    Homebrew antenna mount
    Finished mount top view
    Finished mount top view

    Having had both of our commercial antenna mounts fail, I decided to make something that could survive a direct hit. It turns out that the new mounts are utterly rigid, which means the next failure point will be either the antenna mast or its base structure. We’ve occasionally dropped the bikes and when the antenna hits something on the way down, the mount is not the thing that bends…

    Incidentally, the Nashbar 5-LED blinky white light aimed rearward seems to push motorists over another few feet to the left. Nobody quite knows what we are from a distance, but they do notice that something is up ahead. That’s just about as good as it gets; we tend to not ride in the wee hours of the morning when bike lights just give drunks an aiming point.

    Rough-cut stock
    Rough-cut stock

    The overall structure is a 2-inch square aluminum extrusion, with a hole in the top that matches the right-angle SO-239 base connector salvaged from the Diamond mount and a 1/2″ nylon stiffener plate in the middle. A pair of relentlessly square circumferential clamps attach it firmly to the top seatback rail. A coaxial cable pigtail ensures that the antenna base makes good electrical contact with the seat. I’m not convinced the bike makes a good counterpoise, so we’re now using dual-band antennas that are half-wave on VHF.

    Stainless-steel hardware holds everything together, as I’m sick and tired of rust.

    Drilling box beam
    Drilling box beam

    Not having a huge drill, I helix-milled the SO-239 hole, then reached down through the box to drill the hole for the plastic block retainer screw. Flip the box in the vise, drill four holes for the clamps (I love manual CNC for that sort of thing), manually deburr the holes, and it’s done.

    The block of plastic is a tight slip fit inside the box extrusion, with slightly rounded corners to suit. I milled the slot across the top to a slip fit around the SO-239 connector.

    The two clamps were the most intricate part of the project and got the most benefit from CNC.

    Helix-milling the seat-bar clamp
    Helix-milling the seat-bar clamp

    The clamp hole must have exactly the same diameter as the seat top tube. I helix-milled the hole to an ordinary 5/8″; I have trouble drilling holes that large precisely in the right spot with the proper final diameter. Milling takes longer, but the results are much better.

    Helix-mill the other block while you have the position set up, then flip and reclamp to drill the pair of holes that match the box extrusion. Drill 10-32 clearance (#9) all the way through.

    Flycutting Clamp Slit
    Flycutting the Clamp Slit

    Bandsaw the blocks in half, paying some attention to getting the cut exactly along the midline, then flycut the cut edge to make it nice & shiny & even. That should result in 1 or 2 mm of slit between the blocks when they’re clamped around the seat rail.

    Finished seat-bar clamps
    Finished seat-bar clamps

    Break those relentlessly sharp edges & corners with a file.

    I finagled the dimensions so a 1-1/2″ socket-head cap screw would have just enough reach to fill a nut, with washers under the screw and nut. Your mileage may vary; I’ve gotten reasonably good at cutting screws to length.

    Normally, you tap one side of each clamp for the screws, but in this situation I didn’t see much point in doing that: the box must attach firmly to the clamps and I was going to need some nuts in there anyway.

    Finished parts
    Finished parts

    With all those parts in hand, assembly is straightforward. Secure the SO-239 with its own thin nut, screw the plastic block in place, hold the clamps around the seat bar, poke the cap screws through, dab some Loctite on the threads, install nuts, and tighten everything. That all goes much easier with four hands!

    The grounding braid fits into a huge solderless connector that must have been made with this application in mind. It originally fit a 1/2″ lug, but with enough meat that I could gingerly file it out to 5/8″ to fit the SO-239 inside the aluminum extrusion. I’ve had those connectors for years without knowing what they were for!

    I eventually came up with a simpler and even more ruthlessly rugged mount that’ll appear in my column in the Autumn 2009 Digital Machinist. More on that later… [Update: There]