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: Science

If you measure something often enough, it becomes science

  • Tour Easy: Cracked Fork Autopsy

    A look inside the cracked fork lug from my Tour Easy shows that it really did fracture at the top of the fork blade:

    Tour Easy - cracked fork - interior flash
    Tour Easy – cracked fork – interior flash

    Minus the flash, plus contrast enhancement:

    Tour Easy - cracked fork - interior
    Tour Easy – cracked fork – interior

    Looks rather grotendous in there, doesn’t it? Yeah, show me the interior of your fork…

    The front is at the top, blade on the left and crown on the right. The little shiny rectangle at 1 o’clock on the crown was probably the last fragment holding the blade in place.

    Finished!

  • Random LED Dots: Startup Lamp Test

    I should mention the lamp test in case it comes in useful later on…

    	digitalWrite(PIN_HEARTBEAT,LOW);	// turn off while panel blinks
    	
    	analogWrite(PIN_DIMMING,LEDS_ON);	// enable LED array
    
    	for (byte i=0; i<NUMROWS; i++) {
    		for (byte j=0; j<NUMCOLS; j++) {
    			LEDs[i].ColR = LEDs[i].ColG = LEDs[i].ColB = 0x80 >> j;
    			for (byte k=0; k<NUMROWS; k++) {
    				UpdateLEDs(k);
    				delay(25);
    				if (GeigerTicked) {
    					GeigerTicked = false;
    					TogglePin(PIN_HEARTBEAT);
    				}
    			}
    		LEDs[i].ColR = LEDs[i].ColG = LEDs[i].ColB = 0;
    		}
    	}
    	UpdateLEDs(NUMROWS-1);			// clear the last LED
    

    Updating / multiplexing all the rows inside the inner loop with a 25 ms pause produces distinct flashes and demonstrates that each LED operates separately from all the others:

    Lamp Test
    Lamp Test

    The lamp test ends with all the LEDs turned off, but having the array gradually fill with light looked odd.

    After some tinkering, I added the GeigerTicked conditional to handshake with the Geiger pulse interrupt handler, thus producing a nice random time at the end of the loop. Feed that mostly random time into the hash function, use the hash as the random number seed, then set all the LEDs using random(2) function calls:

    	randomSeed(jenkins_one_at_a_time_hash((char *)GeigerTime,4));
    	
    	for (byte Row=0; Row<NUMROWS; Row++) {
    		for (byte Col=0; Col<NUMCOLS; Col++) {		// Col runs backwards, but we don't care
    			LEDs[Row].ColR |= random(2) << Col;
    			LEDs[Row].ColG |= random(2) << Col;
    			LEDs[Row].ColB |= random(2) << Col;
    		}
    		UpdateLEDs(Row);
    	}
    	
    	GeigerTicks = 0;				// reset counter
    	GeigerTicked = false;			// resume capture
    

    Which produced a more-or-less random fill that looked better:

    Random Preload - bright
    Random Preload – bright

    Underexposed to reduce the burnout (after a few Geiger events):

    Random Preload - dim
    Random Preload – dim

    There should be about eight of each color and, hey, it’s close enough.

    After the preload, it ticks along like it should…

  • Random LED Dots: Radioactive Noise

    In need of a quick-and-easy way to generate interesting data that would make an LED array do something and, what with radioactivity being the canonical source for random numbers, an ancient Aware Electronics RM-60 (*) emerged from the heap. The manual will get you up to speed on radiation detection, if you can read past the DOS-era program description.

    It produces a 100 µs (-ish) pulse for each detection:

    Aware RM-60 Geiger Pulse
    Aware RM-60 Geiger Pulse

    The minimum period seems to be around 500 µs, but I lack a sufficiently fierce radioactive source to verify that in any finite amount of time.

    Seeing as how all we need is a little randomness, measuring the time when a pulse occurs will suffice; we’re not talking hardcore crypto.

    With the pulse arriving on the Arduino D2 input, define an interrupt handler that sets a flag, bumps a counter, and records the current time in microseconds:

    void GeigerHandler(void) {
    	if (!GeigerTicked) {				// stop recording until loop() extracts the data
    		GeigerTicked = true;
    		GeigerTicks++;
    		GeigerTime = micros();
    	}
    }	
    

    Define D2 as an input, turn on the pullup, and trigger that handler on the falling edge of the pulse:

    pinMode(PIN_GEIGER,INPUT_PULLUP);	// RM-60 has its own pullup, but add this one, too
    
    attachInterrupt((PIN_GEIGER - 2),GeigerHandler,FALLING);	
    

    Because an absolute timestamp of each event will produce an obviously non-random sequence of monotonically increasing numbers, I ran each four byte timestamp through a simple hash function to whiten the noise:

    //------------------
    // Jenkins one-at-a-time hash
    // From http://en.wikipedia.org/wiki/Jenkins_hash_function
    
    uint32_t jenkins_one_at_a_time_hash(char *key, size_t len)
    {
        uint32_t hash, i;
        for(hash = i = 0; i < len; ++i)
        {
            hash += key[i];
            hash += (hash << 10);
            hash ^= (hash >> 6);
        }
        hash += (hash << 3);
        hash ^= (hash >> 11);
        hash += (hash << 15);
        return hash;
    }
    

    Then the only thing left to do is spin around the loop() while waiting for a particle to arrive:

    	if (GeigerTicked) {
    		digitalWrite(PIN_HEARTBEAT,HIGH);				// show a blip
    		analogWrite(PIN_DIMMING,LEDS_OFF);				// turn off LED array to prevent bright glitch
    
    		Hash = jenkins_one_at_a_time_hash((char *)&GeigerTime,4);	// whiten the noise
    		
    		GeigerTicked = false;							// flag interrupt handler to resume recording
    //			printf("%9ld %08lx %08lx ",GeigerTicks,GeigerTime,Hash);
    		SetLED(Hash);
    	}
    

    The Heartbeat LED gets turned off every 25 ms.

    In the spirit of “video or it didn’t happen”: there’s a movie about that.

    (*) Circuit Cellar readers of long memory will recognize the RM-60 as the McGuffin for the Radioactive Randoms column in 1990 that explained features of interrupt-driven code in a Micromint BASIC-52 board. Decades later, the hardware & software served as Prior Art in a patent suit that forced me to write some Rules of Engagement. Selah.

  • Bicycle GPS Track: Diggin’ Deep and Flyin’ High!

    At first glance, I thought Mary had taken a tour of The Great Swamp south of the Vassar Farm gardens:

    APRS Bicycle Tracking - Flying High
    APRS Bicycle Tracking – Flying High

    Having helped put the fence up, I’m absolutely certain nothing growing in the garden could get her to 4373 feet, much less boost the bike that high.

    Before that, it seems she did some high-speed tunneling:

    2015-05-10 18:17:31 EDT: KF4NGN-9>T1TP4X,WIDE1-1,WIDE2-1,qAR,KB2ZE-4:`eP}nAIb/"/k}
       type: location
       format: mice
       srccallsign: KF4NGN-9
       dstcallsign: T1TP4X
       latitude: 41.67466666666667 °
       longitude: -73.88283333333334 °
       course: 345 °
       speed: 42.596 km/h
       altitude: -371 m
       symboltable: /
       symbolcode: b
       mbits: 101
       posresolution: 18.52 m
       posambiguity: 0
    

    The bike’s altitude began falling while she was on the way to the garden, from a reasonable 66 meters on the entrance road, bottoming out at -371 m as she hit 42.6 km/h (!), rising to 1341 meters with the bike leaning against a fence post, and returning to 53 meters as she started riding home.

    Obviously, you shouldn’t trust consumer-grade GPS tracks without verification: it can get perfectly bogus numbers from fixes with poor satellite geometry. Altitude values tend to be only close, at best, even when you’re not too fussy about accuracy.

    We experienced small-scale jitter in New Jersey and a friend carrying a commercial satellite link experienced similar randomization. Trust, but verify.

  • Monthly Science: Well Pit Winter Minimum

    Combining all the records so far into one giant lump:

    Well Pit Air Temperature - 2014-10 to 2015-04
    Well Pit Air Temperature – 2014-10 to 2015-04

    Yes, the air temperature really did hover around freezing for two weeks in mid-February. If it didn’t require hoisting a four-inch concrete slab with a rusted lift ring, I’d affix a logger to the copper water pipe running across the pit for some direct samples of the actual water temperature.

    It hasn’t ever frozen in the last half-century or so; I’m not going to start worrying now…

  • HP 7475A Plotter: Full-up Sakura Micron Pen Tests

    The HP 7475A plotter comes with a transparent smoke-brown plastic flip-up lid covering the carousel and pen holder, presumably to keep dust and fingers out of the moving parts. That lid also has has the side effect of limiting the pen length, presumably because HP didn’t want the 7475A to eat into their large-format plotter market. In any event, removing the lid leaves another barrier to longer pens: the rugged plastic case between the carousel and the pen holder.

    Well, seeing as how this puppy has been fully depreciated, a bit of pull saw work opened that opportunity:

    HP 7475A - long pen case cut
    HP 7475A – long pen case cut

    Despite appearances, all six Sakura Micron pens emerge vertical & parallel from their adapters in the carousel:

    HP 7475A - Sakura 01 and 005 pens in carousel
    HP 7475A – Sakura 01 and 005 pens in carousel

    They pass neatly through the new channel:

    HP 7475A - cover mod for long pens
    HP 7475A – cover mod for long pens

    And produce reasonable lines, with motion blur catching the pen holder in the midst of a pen-up / pen-down twitch:

    HP7475A - Sakura Micro Pen Adapter - self-test plot
    HP7475A – Sakura Micro Pen Adapter – self-test plot

    That’s from an earlier test, before I sawed the slot in the case, with all the machinery behind the pen holder in full view.

    The test plot, with the proper pen colors and widths loaded in the carousel, looks pretty good:

    HP7475A - Sakura Micro Pens - self-test plot
    HP7475A – Sakura Micro Pens – self-test plot

    The pen holder wasn’t intended to support a long pen, so that shaft tends to torque the pen tip out of position, particularly while drawing characters:

    HP 7475A - long black pen - misalignment
    HP 7475A – long black pen – misalignment

    The various pen tips don’t all point to the same place:

    HP 7475A - long RGBK pen misalignment
    HP 7475A – long RGBK pen misalignment

    That could be non-concentric pen adapters, misalignment in the pen holder, or slightly off-center pen nibs. The offsets between the colors remains consistent in all the bar-chart columns, so the pen adapters aren’t shifting in the holder.

    The worst-case error between bar-chart rectangles amounts to 0.5 mm parallel to the pen holder motion and 0.8 mm parallel to the paper motion. In round numbers, the pen tip is 30 mm from the flange, so moving it 0.5 mm to the side tips the pen 1°. The flange is 17 mm OD, which means a 1° tilt raises one edge by 0.3 mm or both edges by ±0.15 mm. Given a 0.25 mm 3D printed thread thickness, that’s certainly within reach of a random plastic blob.

    Looking closely at the printed-and-glued flange shows plenty of room for misunderstanding betwixt pen and holder, even after cleaning off all that PETG hair:

    HP7475A - Sakura Micro Pen Adapter - vs HP pen
    HP7475A – Sakura Micro Pen Adapter – vs HP pen

    Given that the Sakura pens aren’t intended for this application, a slight tip misalignment due to body molding tolerances isn’t unreasonable; a perfect adapter might not solve the problem.

    The HP maintenance manual lists a BASIC program to produce a test plot that verifies pen alignment, although the prospect of transliterating 2+ pages of quoted strings from a scanned document doesn’t fill me with desire.

  • MakerGear M2: Platform Z-axis Switch Repeatability

    Having run off four quick prints with identical settings, I measured the thickness of the skirt threads around each object:

    Skirt Thread Consistency
    Skirt Thread Consistency

    They’re all slightly thicker than the nominal 0.25 mm layer thickness, but centered within ±0.02 mm of the average 0.27 mm. Tweaking the G92 offset in the startup G-Code by 0.02 would fix that.

    The 0.29 mm skirt surrounded the first object, which had a truly cold start: 14 °C ambient in the Basement Laboratory. After that, they’re pretty much identical.

    Some informal measurements over a few days suggests the actual repeatability might be  ±0.05 mm, which is Good Enough for layers around 0.20 to 0.25 mm.

    The larger skirt suggests that the platform has a slight tilt, but the caliper resolution is only 0.01 mm.

    When I realigned everything after installing the V4 hot end, the last set of thinwall boxes looked like this:

    Thinwall Calibration Cubes - 5 copies
    Thinwall Calibration Cubes – 5 copies

    Their heights were:

    4.96 5.01
    4.98
    4.91 4.92

    Not enough to worry about, in any event, sez I…