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

  • Fly6 Video Compression: Blur to Sharpen?

    So I stuck a snippet of ordinary “transparent” (it’s actually translucent) adhesive tape across the top of the Cycliq Fly6 camera lens:

    Cycliq Fly6 Camera - blur tape
    Cycliq Fly6 Camera – blur tape

    That smoothly blurs the top third of the frame:

    Fly6 - Tape-blurred frame
    Fly6 – Tape-blurred frame

    The motivation for using translucent tape: it should maintain roughly the same brightness and color balance across the whole image. Opaque tape would burn out the remaining image as the camera desperately tries to maintain an average gray level.

    Fast-forwarding VLC with the video stopped forces it to display the inter-frame compression blocks spanning several seconds of video:

    Fly6 - Forced compression artifacts
    Fly6 – Forced compression artifacts

    The upper third of the frame has big, simple blocks that pegged the files at a uniform 475 MB per ten minute file, somewhat lower than the un-blurred 500 to 700 MB. So the compression definitely isn’t working nearly as hard.

    I hoped that simplifying the uninteresting part of the image would leave more bits for license plates and other interesting details, which might be the case. New York has two main licence plate color schemes (the obsolete high-contrast blue-on-white and the current low-contrast blue-on-orange “Empire Gold”) and both the Fly6 and the Sony AS30V cameras do much better with white plates in full sun.

    Some samples at full size:

    Fly6 - License Plates
    Fly6 – License Plates

    Those were chosen based on:

    • Similar range / angle: just over the center line
    • Same-size crop box: 350 x 197
    • Sun vs. shade

    I think those are somewhat sharper than the plates from un-blurred frames, but it’s not like the camera suddenly woke up smarter and started paying attention to the important stuff.

    Time for more riding, minus the tape…

  • Tour Easy: New Front Fork

    A view from the wheel side shows the crack in my Tour Easy’s fork lug had opened a bit more to the rear, which is about what you’d expect from the forces involved:

    Tour Easy - cracked fork lug
    Tour Easy – cracked fork lug

    Removing the handlebar stem from the fork steerer tube requires removing the fairing, its mounting brackets, the fender, a speed sensor, then snipping cable ties to release all the cables and wires. Minus the prep work, removing the fork from the bike isn’t anything special.

    The lower bearing (a YST 8311N in black) has rollers, not balls. The headset has J.I.S. 1 inch dimensions, captured in a screen grab to forestall link rot:

    YST 8311N headset data
    YST 8311N headset data

    Which means cheap & readily available ISO standard headsets aren’t a drop-in replacement. The incomparable Harris Cyclery has J.I.S. ball-bearing headsets in stock and their Tange Levin CDS HD1002 needs just 1.6 mm of additional washer to match the YST’s 35 mm stack height…

    The front side of the crown got rather graunched over the last 14 years, but I punted the problem by rotating the race half a turn to put the eroded spots toward the rear, where they’ll be under minimal stress:

    Tour Easy crown bearing - damage
    Tour Easy crown bearing – damage

    Re-seating the race brought an ancient Headsetter tool from the drawer:

    Tour Easy fork with Headsetter
    Tour Easy fork with Headsetter

    It’s basically galvanized pipe, chamfered on one end, with a set of nuts & washers on a length of all-thread rod just slightly too short for the occasion: this might be the second time I’ve used the thing and I had to supply my own all-thread & nuts. Ah, well, it probably predates the Tour Easy’s design by a decade.

    The lower headset race looked to be in pretty good shape, so I left it alone. Normally, such bearing damage gives you indexed steering, but Tour Easy handlebars provide so much lever arm that nothing interferes with the bike’s steering.

    The new fork didn’t have a notch for the keyed washer isolating the locknut from the upper bearing race. The usual advice is to file off the key and apply threadlocker, which makes adjusting the two nuts tedious, so I restored the notch in the steerer threads:

    Tour Easy - filed steerer tube key slot
    Tour Easy – filed steerer tube key slot

    Yes, that’s a lethally sharp steel shaving from the not-very-well-reamed ID curling up in the middle of the notch.

    The fender mount bridge on the new fork sits half an inch higher in relation to the brake bosses, putting the fender against the V-brake cable hardware.  Anything touching the V-brake messes up the pad-to-rim alignment, so I conjured a snippet of aluminum to lower the fender just enough to clear the brakes:

    Tour Easy - new fork - fender extender
    Tour Easy – new fork – fender extender

    I think that calls for a nice 3D printed bracket, too, but the snippet got me back on the bike faster. When I preemptively replace the fork on Mary’s bike, then I’ll do a proper bracket for both of us.

    The garish red silicone tape replaces the previous black cable ties. It matches the tube paint surprisingly well and doesn’t look good on the fork, so I’ll replace it with cable ties in due course.

    A few miles of shakedown riding settled the crown race against the fork, another 1/6 turn of the upper race / lock nut snugged up the bearings, and it’s all good again.

    Wow, it’s great to be back on the bike!

    (Due to the vagaries of writing this stuff up ahead of time, there’s actually two weeks of realtime between the post that appeared on Monday and this one.)

  • Kenmore 158: Largest Spool Holder, Now With Eye Protection

    A tip o’ the cycling helmet to Mike for catching this oversight:

    Large spool holder - added bead and guide
    Large spool holder – added bead and guide

    I’d rounded the end of that steel rod, it stands behind the sewing machine, and blah blah blah. He was right: it needed a bead. That’s a fancy one pilfered from our Larval Engineer’s stash, held in place by a blob of fast-cure epoxy.

    Selah.

    The safety pin atop the bobbin on the left spool pin feeds the thread into the machine’s upper thread guide at the proper angle to make it all work; a direct line from the spool holder hook isn’t quite right.

  • Always Sign Your Work

    Quite some years ago, I added a wire shelf to the bottom of the “pantry” closet to hold odds-and-ends. The most recent deep-cleaning cycle required removing the shelf, which required removing the mounting brackets to get the fool thing out of the closet.

    The backside of one bracket shows I had a bit of trouble matching the mounting holes to the wall anchors:

    Pantry wire shelf brackets - overview
    Pantry wire shelf brackets – overview

    The lower bracket bears some advice from my Shop Assistant:

    Pantry wire shelf brackets - detail
    Pantry wire shelf brackets – detail

    Check thrice
    Measure twice
    Cut once

    From what little we hear these days, she’s learned the value of always checking her work…

    And she signs it, too.

  • HP 7475A Plotter: Hacking Chiplotle For Hardware Handshaking

    Chiplotle seems like a good way to drive the HP 7475A plotter, but some preliminary tinkering showed that the plotter pen paused quite regularly while drawing. The plotter wakes up with hardware handshaking enabled, Chiplotle has a config file that lets you specify hardware handshaking, the cable has all the right connections for hardware handshaking, but peering at Der Blinkenlights showed hardware handshaking never happened: the data didn’t overrun, the buffer never filled up, and DTR remained solidly on.

    Come to find out that Chiplotle sends data in half-buffer-size chunks (all code from baseplotter.py):

    class _BasePlotter(object):
       def __init__(self, serial_port):
          self.type = '_BasePlotter'
          self._logger = get_logger(self.__class__.__name__)
          self._serial_port = serial_port
          self._hpgl = commands
          self._margins = MarginsInterface(self)
          self.maximum_response_wait_time = get_config_value('maximum_response_wait_time')
    
          #this is so that we don't pause while preparing and sending
          #full buffers to the plotter. By sending 1/2 buffers we assure
          #that the plotter will still have some data to plot while
          #receiving the new data
          self.buffer_size = int(self._buffer_space / 2)
          self.initialize_plotter( )
    

    Every time something goes out to the plotter, this happens:

       def _write_string_to_port(self, data):
          ''' Write data to serial port. data is expected to be a string.'''
          #assert type(data) is str
          if not isinstance(data, basestring):
             raise TypeError('string expected.')
          data = self._filter_unrecognized_commands(data)
          data = self._slice_string_to_buffer_size(data)
          for chunk in data:
             self._sleep_while_buffer_full( )
             self._serial_port.write(chunk)
    

    In order to figure out whether the plotter has enough room, Chiplotle must ask it:

       def _sleep_while_buffer_full(self):
          '''
             sleeps until the buffer has some room in it.
          '''
          if self._buffer_space < self.buffer_size:
             while self._buffer_space < self.buffer_size:
                time.sleep(0.01)
    

    The self._buffer_space method contains the complete handshake:

       def _buffer_space(self):
          self._serial_port.flushInput()
          self._serial_port.write(self._hpgl.B().format)
          bs = self._read_port()
          return int(bs)
    

    Assuming that Python can actually meter out a 0.01 second sleep, that’s a mere 10 ms; call it 10 character times at 9600 b/s. By and large, Chiplotle hammers away at the poor plotter while the buffer drains.

    Now, that would be just ducky, except that the HP 7475A plotter dates back to slightly after microcontrollers were invented. The MC6802 trundles along at 1 MHz from a 4 MHz crystal, because it needed a quadrature clock, and takes a while to get things done. Responding to the buffer space request (a three-character sequence: ␛.B) requires the plotter to:

    • Stop plotting 
    • Answer the phone
    • Figure out what to do
    • Compose a reply
    • Drop it in the serial buffer
    • Resume plotting

    Which take enough time to produce a distinct hitch in the gitalong. Some crude print debugging showed most of the delay happens between the write() and the read() tucked inside _buffer_space.

    Linux handles serial port hardware handshaking far below the Python level, so the simplest fix was to rip out the line that checks for enough buffer space:

       def _write_string_to_port(self, data):
          ''' Write data to serial port. data is expected to be a string.'''
          #assert type(data) is str
          if not isinstance(data, basestring):
             raise TypeError('string expected.')
          data = self._filter_unrecognized_commands(data)
          data = self._slice_string_to_buffer_size(data)
          for chunk in data:
    #         self._sleep_while_buffer_full( )
             self._serial_port.write(chunk)
    

    And then the plotter races along without pauses, drawing as fast as it possibly can, with the DTR output blinking like crazy as Chiplotle dumps the character stream into the output buffer and the serial port hardware (*) managing the data flow. Apparently, detecting a buffer-full situation and dropping the DTR output requires only a few 6802 CPU cycles, which is what makes hardware handshaking such a good idea.

    There’s a movie about that…

    Hooray for Der Blinkenlights!

    HP 7475A - serial port adapters - hardcore
    HP 7475A – serial port adapters – hardcore

    (*) Which is, of course, a USB-to-RS232 converter. I paid extra to get one that reports an FTDI chipset, which may mean the counterfeiters have upped their game since the Windows driver disaster. I actually tried it on the Token Windows box and it still works, so maybe it’s Genuine FTDI.

  • HP 7475A Plotter: Serial Cable for Hardware Handshaking

    The HP 7475A wakes up with hardware handshaking enabled: DTR starts high and goes low when the internal 1 KB buffer has less than 80 bytes remaining. The plotter also supports XON/XOFF handshaking, a sad software thing you’d use only if you had no other choice.

    The Chiplotle doc provides a wiring diagram for a suitable 9-to-25 pin cable, so I printed one and doodled on it while pondering the Great Cable Stash:

    HP7475A Plotter - Serial Cable
    HP7475A Plotter – Serial Cable

    The color codes over on the left of the top diagram match a prebuilt cable I hoped to repurpose, but it had only five conductors, none of which were DSR or CTS. Pfui!

    So I used a hank of gorgeous flexy 9-conductor cable (which came with premolded DE-9 ends of the wrong gender, now amputated into pigtails and back in the GCS), which supported the connections redrawn on the bottom in proper numeric order, used the obvious color sequence (Bn R O Y G Bl V W K), then soldered suitable connectors on each end:

    HP 7475A Plotter - serial cable
    HP 7475A Plotter – serial cable

    And it worked the first time…

  • Bird Box Cleanout

    The effort those little birds put into their nests never ceases to amaze me:

    Bird box cleanout - old nests
    Bird box cleanout – old nests

    Last year it was the same story. Of course, if we didn’t clean out the boxes, the birds would do it on their own, so perhaps we help them get started earlier.