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

  • Avalanche Noise Amp: Sampling

    The relatively low bandwidth of the amplified noise means two successive samples (measured in Arduino time) will be highly correlated. Rather than putz around with variable delays between the samples, I stuffed the noise directly into the Arduino’s MISO pin and collected four bytes of data while displaying a single row:

    unsigned long UpdateLEDs(byte i) {
    	
    unsigned long NoiseData = 0ul;
    	
    	NoiseData |= (unsigned long) SendRecSPI(~LEDs[i].ColB);				// correct for low-active outputs
    	NoiseData |= ((unsigned long) SendRecSPI(~LEDs[i].ColG)) << 8;
    	NoiseData |= ((unsigned long) SendRecSPI(~LEDs[i].ColR)) << 16;
    	NoiseData |= ((unsigned long) SendRecSPI(~LEDs[i].Row))  << 24;
    
    	analogWrite(PIN_DIMMING,LEDS_OFF);			// turn off LED to quench current
    	PulsePin(PIN_LATCH);						// make new shift reg contents visible
    	analogWrite(PIN_DIMMING,LEDS_ON);
    
    	return NoiseData;
    }
    

    The bit timing looks like this:

    SPI Sample - noise data - 01
    SPI Sample – noise data – 01

    The vertical cursors mark the LSB position in the first and last bytes of the SPI clock. The horizontal cursors mark the minimum VIH and maximum VIL, so the sampled noise should produce 0 and 1 bits at the vertical cursors. Note that there’s no shift register on the input: MISO just samples the noise signal at each rising clock edge.

    I picked those two bit positions because they produce more-or-less equally spaced samples during successive rows; you can obviously tune the second bit position for best picture as you see fit.

    Given a pair of sequential samples, a von Neumann extractor whitens the noise and returns at most one random bit:

    #define VNMASK_A 0x00000001
    #define VNMASK_B 0x01000000
    
    enum sample_t {VN_00,VN_01,VN_10,VN_11};
    
    typedef struct {
    	byte BitCount;					// number of bits accumulated so far
    	unsigned Bits;					// random bits filled from low order upward
    	int Bias;						// tallies 00 and 11 sequences to measure analog offset
       unsigned SampleCount[4];	// number of samples in each bin
    } random_t;
    
    random_t RandomData;
    
    ... snippage ...
    
    byte ExtractRandomBit(unsigned long RawSample) {
    	
    byte RetVal;
    
    	switch (RawSample & (VNMASK_A | VNMASK_B)) {
    	case 0:							// 00 - discard
    		RetVal = VN_00;
    		RandomData.Bias--;
    		break;
    	case VNMASK_A:					// 10 - true
    		RetVal = VN_10;
    		RandomData.BitCount++;
    		RandomData.Bits = (RandomData.Bits << 1) | 1;
    		break;
    	case VNMASK_B:					// 01 - false
    		RetVal = VN_01;
    		RandomData.BitCount++;
    		RandomData.Bits  = RandomData.Bits << 1;
    		break;
    	case (VNMASK_A | VNMASK_B):		// 11 - discard
    		RetVal = VN_11;
    		RandomData.Bias++;
    		break;
    	}
    	
    	RandomData.Bias = constrain(RandomData.Bias,-9999,9999);
    	RandomData.SampleCount[RetVal]++;
    	RandomData.SampleCount[RetVal] = constrain(RandomData.SampleCount[RetVal],0,63999);
    
    	return RetVal;
    }
    

    The counters at the bottom track some useful statistics.

    You could certainly use something more complex, along the lines of a hash function or CRC equation, to whiten the noise, although that would eat more bits every time.

    The main loop blips a pin to show when the extractor discards a pair of identical bits, as in this 11 sequence:

    SPI Sample - noise flag - 11
    SPI Sample – noise flag – 11

    That should happen about half the time, which it pretty much does:

    SPI Sample - noise flag - 1 refresh
    SPI Sample – noise flag – 1 refresh

    The cursors mark the same voltages and times; note the slower sweep. The middle trace blips at the start of the Row 0 refresh.

    On the average, the main loop collects half a random bit during each row refresh and four random bits during each complete array refresh. Eventually, RandomData.Bits will contain nine random bits, whereupon the main loop updates the color of a single LED, which, as before, won’t change 1/8 of the time.

    The Arduino trundles around the main loop every 330 µs and refreshes the entire display every 2.6 ms = 375 Hz. Collecting nine random bits requires 9 x 330 µs = 3 ms, so the array changes slightly less often than every refresh. It won’t completely change every 64 x 8/7 x 3 ms = 220 ms, because dupes, but it’s way sparkly.

    In the spirit of “Video or it didn’t happen!”, there’s a low-budget Youtube video about that…

  • Alpha Geek Clock: New Battery

    After the CR123A lithium cell in the Alpha Geek Clock gave out:

    Packaged Alpha-Geek Clock
    Packaged Alpha-Geek Clock

    I duct-taped a pair of D cells onto the case and returned it to the bedroom shelf. According to the date scrawled on the tape, that was five years ago: 26 November 2010.

    Over the last few months, the LED gradually faded from a blink to a steady glow as the battery voltage dropped below 2 V and the WWVB receiver output no longer reached the MOSFET’s threshold.

    We’ll see how long these last:

    Alpha Geek Clock - new batteries
    Alpha Geek Clock – new batteries

    Yeah, I should probably do something involving 3D printing…

  • Sunflowers

    A stray sunflower seed decided that the spot just outside the garden gate was perfect and gave Mary’s garden an attractive marker. It will eventually have a dozen blossoms, each one serving as a buffet for the local bumblebees:

    Sunflower with bumblebee
    Sunflower with bumblebee

    Each bee makes several complete circuits of the florets, draining the nectar and collecting pollen as she goes:

    Sunflower with bumblebee - detail
    Sunflower with bumblebee – detail

    Mary tucks the open gate inside the garden to avoid disturbing the pollinators, as wasps tend to have short fuses and multiple-strike stingers:

    Sunflower with wasp
    Sunflower with wasp

    The bumblebee traveled clockwise and the wasp went counterclockwise, but I don’t know if that’s the general rule. I certainly won’t dispute their choices!

    In a few weeks, long after the petals fall away, a myriad small birds will harvest the dried seeds…

  • Makergear M2: Platform Stability

    After replacing that washer, the last step in the platform alignment required 1/6 turn on the front screw between the top two sets of measurements:

    M2 Alignment measurements - 2015-08-09 - 2
    M2 Alignment measurements – 2015-08-09 – 2

    The last two sets show the sample-to-sample variation with no adjustments, which didn’t amount to much.

    Without changing anything else, I then switched from magenta PETG filament to cyan and ran off two more sets of thinwall hollow boxes (in addition to other doodads) over the next two days:

    M2 Alignment measurements - 2015-08-10
    M2 Alignment measurements – 2015-08-10

    A bit less than a month later, after producing several iterations of unrelated doodads:

    M2 Alignment measurements - 2015-09-07
    M2 Alignment measurements – 2015-09-07

    The variation in the center box height from 4.94 mm to 5.00 mm shows that sensing the platform Z-axis position directly on the glass surface actually works the way it should: ±0.03 mm is as good as it gets. Given that my measurement error / eyeballometric averaging on any given box runs around ±0.02 mm, the far corners also seem rock-stable and certainly don’t justify automatic alignment probing and adjustment.

    Thinwall hollow boxes make good handouts at 3D printing presentations…

    Thinwall Hollow Box collection
    Thinwall Hollow Box collection
  • Monthly Science: Silica Gel Regeneration

    Last month’s basement safe log showed the humidity (blue trace) relentlessly rising:

    Basement Safe - 2015-08-09
    Basement Safe – 2015-08-09

    Replacing that bag emptied the dried silica gel stash, so I piled six saturated bags in the oven for an overnight regeneration with the oven set to “Warm”, which the IR thermometer reported as 140 °F or so at the bag surface. They sat on cooling racks atop cookie sheets that pretty much filled two oven shelves, with good air flow across their tops and minimal flow between bags and cookie sheet.

    The last time around, I spread the beads directly on the cookie sheets. That seemed like a lot of effort, so I wanted to see how the low-labor alternative worked.

    The two upper-left bags in each group had a pair of bulldog clips holding them closed. The larger bags hold 500 g of “dry” silica gel and the center bag in the lower row was a smaller mesh bag:

    Silica Gel drying - 2015-08-12
    Silica Gel drying – 2015-08-12

    The big bags lost a bit under 130 g during 10 hours, call it 12 g/h, and felt slightly damp on their lower surface.

    I cranked the oven to 230 °F, the lowest actual heat setting, for 210 °F on the bag surface. That got rid of the last 30 g in three hours; another hour brought them to pretty nearly their dry weight of 507 g (gross, with bag / staples / clips).

    Drying being an exponential process, it looks like an overnight bake at “230 °F” will do the trick without melting the bags; the lower temperature doesn’t quite get the job done.

  • HP 7475A Plotter: Refilled Pen Performance

    Squirting brightly colored CMY ink mixes into an assortment of not-quite-dead-yet plotter pens produced reasonable results:

    CMYK Refilled Pens - plot overview
    CMYK Refilled Pens – plot overview

    The blotches on the legend in the lower left corner show that a refilled plotter pen can accumulate a droplet of ink around its nib, which should come as no surprise. I wiped off the excess immediately after refilling each pen, let the assortment sit for a few hours to (presumably) let the new ink reach the nib, and wiped them off before inserting them in the plotter’s pen carousel. All I can say is that I used up a bunch of paper towels in the process…

    A closer look at the plot shows Pretty Good If You Ask Me results:

    CMYK Refilled Pens - plot detail
    CMYK Refilled Pens – plot detail

    The two blue-ish pens have less flow than the others, resulting in dotted lines that should be continuous. As nearly as I can tell, that’s a function of how much OEM ink has solidified in the fiber nib and, most likely, the fiber rod that draws ink from the sponge reservoir inside the body.

    And, of course, the colors produced by adding CMY printer ink to the surviving OEM ink aren’t found in any catalog. I’m also blithely ignoring the difference between the inks inside plotter pens intended for paper and those for overhead transparencies; at this late date, that’s defined to Not Matter.

  • Rail Trail Riding, With Road Rash

    The Dutchess Rail Trail sits atop a pipeline carrying water from the treatment plant in the City of Poughkeepsie to the GlobalFoundries (neé IBM East Fishkill) complex. For good engineering reasons, the mid-line pumping station (equipment yard visible to our left) in Page Industrial Park sits directly athwart the pipe, which forced an abrupt S-curve on a relatively steep slope into the rail trail layout.

    T=0.000 s — The lead cyclist just cut in front of her companion and isn’t leaning into the turn, at which point Mary and I both realize this isn’t going to end well:

    Road Rash 2015-08-15 - 131
    Road Rash 2015-08-15 – 131

    T=0.750 s — Newton grabs control of her bike and he’s not gonna let go:

    Road Rash 2015-08-15 - 176
    Road Rash 2015-08-15 – 176

    T=1.633 s — The rear wheel locks as she passes Mary, she’s far off-center and falling to her left, the bike has gone inertial, and it’s obvious we’re about to arrive at the same place at the same time:

    Road Rash 2015-08-15 - 229
    Road Rash 2015-08-15 – 229

    T=2.100 s — Collision Alarm! I’m veering off the pavement, which is the only reason we didn’t have an offset frontal collision:

    Road Rash 2015-08-15 - 257
    Road Rash 2015-08-15 – 257

    T=2.333 s — Impact! I’m stopped and balanced on the bike, with my left foot out of the pedal cleat and heading for the ground. She’s sliding past me, pivoting around her bike’s left pedal skidding on the asphalt:

    Road Rash 2015-08-15 - 271
    Road Rash 2015-08-15 – 271

    She ended up sprawled atop her bike, facing up the slope, with the front wheel just beside the rear wheel of my bike; her foot or some part of her bike whacked my left-side underseat bag in passing, but there was no bike-on-bike collision. No injuries for her, other than perhaps a bit of road rash, but only by sheer raw good fortune.

    Reviewing the video shows she lost control at the transition from the trail to the downward S-curve, a few seconds before the first picture here and about five seconds before she stopped sliding past my bike, but the problem wasn’t obvious until the scene in the first picture. Mary never had a chance to react and, with less than two seconds until the not-quite-collision, my gross-motor reaction time just barely got me out of the way.

    Brake early and always wear a helmet.