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.

Category: Recumbent Bicycling

Cruisin’ the streets

  • APRS Position Error

    So there I was, riding along Thornwood Drive in Poughkeepsie, minding my own business, when I teleported into Vassar Farm… and back!

    APRS data error - 2012-10-21 15:20:20
    APRS data error – 2012-10-21 15:20:20

    The aprs.fi database shows these packets around that glitch:

    2012-10-21 15:43:55 EDT: KE4ZNU-9>T1TP3T,WA2YSM-15,WIDE1*,WIDE2-1,qAR,WB2ZII-15:`eSllA=b/"4Q}
    2012-10-21 15:48:41 EDT: KE4ZNU-9>T1TP4U,WA2YSM-15,WIDE1,W2VER-15,WIDE2*,qAR,WB2ZII-15:`eS0mAQb/"4X}
    2012-10-21 15:49:53 EDT: KE4ZNU-9>T1TP5W,WA2YSM-15,WIDE1*,WIDE2,qAR,WB2ZII-15:`eS$l{1b"4U}
    2012-10-21 15:50:20 EDT: KE4ZNU-9>T1TP5V,WA2YSM-15,WIDE1,K2PUT-15*,WIDE2,qAR,WB2ZII-15:`eR lzlb/"4V}
    2012-10-21 15:50:20 EDT: KE4ZNU-9>T1TP5V,WA2YSM-15,WIDE1,K2PUT-15*,WIDE2,qAR,KC2DHU:`eR<0x7f>lzlb/"4V} [Rate limited (< 5 sec)]
    2012-10-21 15:52:31 EDT: KE4ZNU-9>T1TP8T,W2LW-15,W2LV,WIDE2*,qAR,W2GSA:`eR|lz:b/"4T}
    2012-10-21 15:52:53 EDT: KE4ZNU-9>T1TP8S,WA2YSM-15,WIDE1*,WIDE2,qAR,N2MH-12:`eRsm*ub/"4S}
    2012-10-21 15:59:52 EDT: KE4ZNU-9>T1TQ3X,WA2YSM-15,WIDE1*,WIDE2,qAR,K2DLS:`eQ}lz\b/"4N}
    

    The two packets at 15:50:20 represent two different paths from the WA2YSM-15 digipeater to the APRS database: one through WB2ZII-15 and the other through KC2DHU. The “Rate limited” message indicates that the database regarded the two as different packets, which they are: the position data differs by one character. The database discards identical packets without comment, because the network must handle all the packets generated by a single RF transmission from one GPS tracker to multiple receivers, but rejects what it sees as deliberate (or inadvertent) attempts to overwhelm it.

    Decoding the packets provides a bit more information:

    2012-10-21 15:49:53 EDT: KE4ZNU-9>T1TP5W,WA2YSM-15,WIDE1*,WIDE2,qAR,WB2ZII-15:`eS$l{1b/"4U}
       type: location
       format: mice
       srccallsign: KE4ZNU-9
       dstcallsign: T1TP5W
       latitude: 41.67616666666667 °
       longitude: -73.91800000000001 °
       course: 121 °
       speed: 16.668 km/h
       altitude: 62 m
       symboltable: /
       symbolcode: b
       mbits: 101
       posresolution: 18.52 m
       posambiguity: 0
    
    2012-10-21 15:50:20 EDT: KE4ZNU-9>T1TP5V,WA2YSM-15,WIDE1,K2PUT-15*,WIDE2,qAR,WB2ZII-15:`eR lzlb/"4V}
       type: location
       format: mice
       srccallsign: KE4ZNU-9
       dstcallsign: T1TP5V
       latitude: 41.676 °
       longitude: -73.90066666666667 °
       course: 80 °
       speed: 16.668 km/h
       altitude: 63 m
       symboltable: /
       symbolcode: b
       mbits: 101
       posresolution: 18.52 m
       posambiguity: 0
    
    2012-10-21 15:50:20 EDT: KE4ZNU-9>T1TP5V,WA2YSM-15,WIDE1,K2PUT-15*,WIDE2,qAR,KC2DHU:`eR<0x7f>lzlb/"4V} [Rate limited (< 5 sec)]
       type: location
       format: mice
       srccallsign: KE4ZNU-9
       dstcallsign: T1TP5V
       latitude: 41.676 °
       longitude: -73.9165 °
       course: 80 °
       speed: 16.668 km/h
       altitude: 63 m
       symboltable: /
       symbolcode: b
       mbits: 101
       posresolution: 18.52 m
       posambiguity: 0
    
    2012-10-21 15:52:31 EDT: KE4ZNU-9>T1TP8T,W2LW-15,W2LV,WIDE2*,qAR,W2GSA:`eR|lz:b/<4T}
       type: location
       format: mice
       srccallsign: KE4ZNU-9
       dstcallsign: T1TP8T
       latitude: 41.68066666666667 °
       longitude: -73.916 °
       course: 30 °
       speed: 16.668 km/h
       altitude: 61 m
       symboltable: /
       symbolcode: b
       mbits: 101
       posresolution: 18.52 m
       posambiguity: 0
    
    

    Feeding the coordinates into Google Maps shows that the first packet (to WB2ZII-15) at 15:50:20 carries the damaged data. The second (to KC2DHU) has the correct position, but was rejected because it arrived just after the first and wasn’t an exact duplicate.

    AX.25 packets carry a checksum and it’s a convolutional code, not a simple XOR, so I think it’s safe to say the packets were received as transmitted; you’ll find an intro to that whole topic, with further references, in the N1VG OpenTracker project. The database doesn’t store complete AX.25 packets, so we can’t run their headers and data through the checksum algorithm to see if they both produce good results. Here’s the raw packet payload:

    2012-10-21 15:50:20 EDT KE4ZNU-9: 75 bytes
    0x00 K E 4 Z N U - 9 > T 1 T P 5 V , W A 2 Y S M - 1 5 , W I D E 1 ,
         4b45345a4e552d393e5431545035562c57413259534d2d31352c57494445312c
    0x20 K 2 P U T - 1 5 * , W I D E 2 , q A R , W B 2 Z I I - 1 5 : ` e
         4b325055542d31352a2c57494445322c7141522c5742325a49492d31353a6065
    0x40 R   l z l b / " 4 V }
         52206c7a6c622f2234567d
    
    2012-10-21 15:50:20 EDT KE4ZNU-9: 72 bytes [Rate limited (< 5 sec)]
    0x00 K E 4 Z N U - 9 > T 1 T P 5 V , W A 2 Y S M - 1 5 , W I D E 1 ,
         4b45345a4e552d393e5431545035562c57413259534d2d31352c57494445312c
    0x20 K 2 P U T - 1 5 * , W I D E 2 , q A R , K C 2 D H U : ` e R 7fl
         4b325055542d31352a2c57494445322c7141522c4b43324448553a6065527f6c
    0x40 z l b / " 4 V }
         7a6c622f2234567d
    

    So it seems the TinyTrak3+ sent out a packet containing bad position data, wrapped with a correct checksum.

    The NMEA-format 4800 baud 8N1 serial data from the GPS receiver puck to the TT3+ has no parity error detection, so I suspect a character or two got clobbered (by RFI?) and produced a bad position. NMEA messages have a simple XOR checksum that’s susceptible to that kind of error. Note that the Mic-E encoded message shown above is not passed from the GPS receiver to the TT3+; we never see the raw GPS data.

    Our TinyTraks use SmartBeaconing to transmit only on significant course changes, so the sequence of events probably went like this:

    • The TT3+ decodes a damaged NMEA message from the GPS receiver
    • It notices an abrupt position change and sends that incorrect position
    • The next NMEA message arrives correctly
    • The TT3+ sees another abrupt jump and sends that position
    • The aprs.fi database rejects the message due to rate limiting
    • The TT3+ remains silent until the next turn

    The map doesn’t show all the turns, because that’s a hilly area and not all RF packets make their way from my bike to an APRS receiver.

    For what it’s worth, although we were riding at a fairly steady pace, I don’t believe the five-significant-figure accuracy of those speeds, either.

  • Tour Easy + BOB YAK Trailer = More Cargo Hauling

    A trailer load of 62 pounds of sweet potatoes from the Vassar Farms plot:

    Tour Easy - BOB Yak - sweet potatoes
    Tour Easy – BOB Yak – sweet potatoes

    Followed by 42 pounds of apples from Prospect Hill, a PYO orchard across the Hudson:

    Tour Easy - BOB Yak - with 42 pounds of apples
    Tour Easy – BOB Yak – with 42 pounds of apples

    Folks haul heavier loads than those across the continent and around the world, but … a dozen miles or so is enough for me!

    And, yes, those are rather large sweet potatoes. The biggest one, a Korean Purple, weighed 6 pounds:

    6 pound sweet potato
    6 pound sweet potato
  • Bicycle Mobile: New Windscreen Mic Ball

    The bikes stand upright inside the van and the helmets ride on the floor with all their stalks sticking up. This usually works out well, but on our last trip my helmet rolled under my bike and rubbed the foam ball surrounding its mic against the chain, producing a result so awful that I had to install new foam.

    For posterity, here’s the current state of the electret mic and its mount:

    Electret mic on bike helmet boom
    Electret mic on bike helmet boom

    The foam comes from a sheet of Sonex acoustic foam baffle, snipped into a reasonable approximation of a ball, with a slit deep enough to surround the mic, and a cable tie holding it closed:

    Foam mic ball on bike helmet boom
    Foam mic ball on bike helmet boom

    For what it’s worth, I’ve found that excessive wind noise correlates with too much mic gain. The mic rides about a finger’s width from the corner of my mouth, I talk at a normal volume, the amp supplies about 20 dB of gain, and we have no trouble with wind noise. The amp gain depends on the mic sensitivity, so your results will certainly differ; these mics came from the heap with no specs whatsoever.

    I suppose wind noise also depends on the bike’s speed, but when I’m going that fast I don’t have enough brain or lungs left over to hold a conversation…

  • Wouxun PTT Voltage Limit

    TinyTrak3+ D6 - SMD Schottky diode
    TinyTrak3+ D6 – SMD Schottky diode

    It seems that Wouxun KG-UV3D HTs require nearly 0 V to activate the PTT input, which I discovered after the radio on Mary’s bike began acting intermittently. The TinyTrak3+ would transmit correctly, but the PTT button on the handlebar began to not work at all / work intermittently / work perfectly. The switch and cable were OK, pushing the button produced nearly 0 Ω at the 3.5 mm plug, the connections seemed solid, but the radio didn’t transmit reliably.

    I finally got the thing to fail on the bench, which led to the discovery that:

    • Shorting the PTT input to the GPS+voice adapter PCB to ground didn’t make the radio transmit and
    • Data bursts from the TinyTrack3 worked perfectly

    Gotcha!

    TT3 PTT In-Out
    TT3 PTT In-Out

    The TT3+ pulls its PTT OUT pin down from +5 V using a 2N2222A NPN transistor (off to the right in the schematic snippet), but, for reasons having to do with ESD, the input from the PTT switch on the handlebars goes through a 100 Ω series resistor, then passes to the TT3 board through PTT IN to D6 before joining the TT3 transistor collector. The low-active diode-ORed signal heads off through PTT OUT to a 10 Ω series resistor, thence to the KG-UV3D PTT input. D6 is an ordinary 1N4148, with the net result that the PTT input voltage at the radio dropped to 630 mV with the PTT button pressed.

    Not finding anything else wrong, I replaced D6 with a BAT54 Schottky diode that pulled the PTT voltage down to 300 mV and the radio worked fine.

    Of course, a BAT54 is a surface-mount diode, so I clipped off the unused no-connect lead (it’s the only way to be sure it doesn’t do anything) and tacked it down slaunchwise between the PCB thru-hole pads. If I had a BAT54C with common cathodes, I could replace both D5 and D6 in one shot, but D5 just pulls down a PIC input that has an ordinary logic-level threshold voltage.

    I don’t know why the KG-UV3D PTT is so fussy, although it may really be a current-driven signal that requires more current than can flow through the 110 Ω + diode forward drop in series with the PTT button. Wouxun presents no specifications that I can find.

    The identical circuitry on my bike works fine with the stock D6 diode and a presumably identical KG-UV3D. I should replace that diode before it gives me any trouble, but I’ll wait until I must take the box apart for some other reason.

  • Tour Easy + BOB YAK Trailer = Cargo Hauling

    Friends of ours planted a few dozen Liriope spicata as a border around their nicely trimmed flower garden. This did not work out well, as the stuff spreads like a weed and duplicated beyond their wildest imagination. However, this part of the description caught our attention:

    No serious diseases or pests occur for creeping lilyturf. […] Lilyturf is reported to have little wildlife value.

    Translation: nothing kills the stuff and deer don’t eat it. Sounds like exactly what we need for the section of the front yard that slopes down to the road, where mowing poses a threat to life & limb.

    We said we’d take it, they dug it out and bagged it, I hitched up the bike trailer, and we paid them a visit:

    YAK Bike Trailer - 55 lb of grass
    YAK Bike Trailer – 55 lb of grass

    They’re a few miles off the south end of the Dutchess Rail Trail, which is (by definition) pretty much dead flat and made the trip a lot easier: that load of grass added up to 55 pounds! They dropped off a few bags on their next trip past our house, which tells you how much they wanted to get rid of it.

    I wielded the post-hole digger to prepare about 100 sites, shook the dirt off the existing grass roots to backfill the holes, we divided the new clumps by chopping them with a shovel, and a day later we had everything installed and watered down:

    Liriope spicata planting
    Liriope spicata planting

    I’m liking it already…

  • Cutting Music Wire

    It should go without saying, but you do not cut music wire with diagonal cutters intended for electrical wire or the low-carbon steel shears built into wire strippers. I use a bicycle cable cutter that easily slices through the hard wire used in brake cables and their housing:

    Bicycle cable cutter
    Bicycle cable cutter

    I’ve owned this one forever, but those cutters from Park should work just as well; the odd protrusions behind the pivot crimp aluminum caps on stranded cable. I also have diagonal cutters with hardened jaws, but they’re too bulky for fine work and tend to fire the stub ends across the Basement Laboratory.

    Every now and again I touch up the jaws with a diamond file to get rid of small dings; despite being hardened, those fine points seem particularly prone to burrs.

    When you see an ordinary wire cutter with matching half-moons in each blade, you know what happened…

  • Nike Cycling Shoe Latches: Resprung

    The Nike cycling shoes I bought some years ago (at a steep discount when they got out of the cycling shoe biz) close with a ratcheting plastic strap rather than laces, so I bought a spare set of straps: the plastic part always breaks first. As it turned out, a coil spring inside each latch failed and the stub end (on the right side here) gradually worked its way between the latch tab and the frame:

    Cycling shoe latch - broken spring
    Cycling shoe latch – broken spring

    Eventually this got to the point where the latches jammed and I had to do something. The first step was to drill out the rivet holding the spring and tab in place:

    Drilling latch rivet - magnetized bit
    Drilling latch rivet – magnetized bit

    You’ll note the rich collection of swarf clinging to the drill bit, which indicates this one hasn’t been used since a lightning strike magnetized all the steel in the house. A pass through that demagnetizer shook off the swarf and prepared the bit for the next time.

    Releasing all the parts shows the problem:

    Nike cycling shoe latch - broken spring
    Nike cycling shoe latch – broken spring

    The OEM springs used 24 mil spring wire that, surprisingly, matched a box of music wire in the Basement Laboratory Warehouse Wing. The spring coils have 5 turns that just clear the 3 mm rivet that I recycled as a mandrel; I think a 2.5 mm pin would produce a better fit. Not being a fan of rivets, I replaced them with 4-40 machine screws, even though the threads probably won’t do the aluminum frame any good at all.

    A protracted bending and wrapping session produced a reasonable approximation of the OEM spring:

    Latch spring - formed
    Latch spring – formed

    It’s worth noting that each of those coils uses up about 55 mm of wire: 5 × 3.5 mm × π. Cut an excessively long piece from the music wire coil!

    Trimming and shaping the ends to fit through the notches and around the outside of the frame shows that my wire-bending skills need considerably more practice. This spring (the second one I made) also shows that my beginner’s luck with the first coils wore off all too quickly:

    OEM springs with homebrew replacement
    OEM springs with homebrew replacement

    But both springs fit and work fine, so I’ll call it done for now:

    Repaired latch - nut side
    Repaired latch – nut side

    Will a replacement spring break before the plastic strap?

    Obviously, I need a CNC spring bender