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

  • Squirrel vs. Bird Feeder

    After months of attempts and (occasionally) spectacular failures, one of the backyard squirrels managed to climb aboard the bird feeder:

    Squirrel on bird feeder
    Squirrel on bird feeder

    The shutter closes when more than two cardinals and a titmouse perch on the wood bar, so the squirrel didn’t get anything. However, back in 2008, one of that critter’s ancestors mastered the trick:

    Not a Squirrel-Proof Feeder
    Not a Squirrel-Proof Feeder

    Since then, I’ve raised the feeder about five feet and inverted a big pot over two feet of loose PVC pipe around the pole.

    Given the number of squirrel-training videos on Youtube, however, it’s only a matter of time until the critters put all the tricks together!

  • Monthly Science: Minimal-Woo Cast Iron Pan Seasoning

    After trying several variations on a theme, our daily-use pan now looks like this:

    Cast Iron Pan - after weekly seasoning
    Cast Iron Pan – after weekly seasoning

    Those obvious wiping marks come from an oily rag in a hot pan. What could go wrong?

    The reflected light bar comes from the under-cabinet LED strip.

    The surface withstands stainless utensils, cooks omelets with aplomb, and requires no fussy KP:

    Omelet in cast-iron pan
    Omelet in cast-iron pan

    The low-woo seasoning recipe, done maybe once a week when the bottom has more gunk than usual:

    • Clean the pan as usual, wipe dry
    • Begin heating on medium burner set to High
    • Add 0.2 ml = 10 drops = 1 squirt of flaxseed oil
    • Wipe around pan interior with small cotton cloth
    • Continue heating to 500 °F, about four minutes
    • Carefully wipe oily cloth around pan again
    • Let cool

    Works for us and doesn’t involve any magic.

  • Cheap WS2812 LEDs: Test Fixture

    Given that I no longer trust any of the knockoff Neopixels, I wired the remaining PCB panel into a single hellish test fixture:

    WS2812 4x7 LED test fixture - wiring
    WS2812 4×7 LED test fixture – wiring

    The 22 AWG wires deliver +5 V and Common, with good old-school Wire-Wrap wire passing to the four LEDs betweem them. The data daisy chain snakes through the entire array.

    It seems only fitting to use a knockoff Arduino Nano as the controller:

    WS2812 4x7 LED test fixture - front
    WS2812 4×7 LED test fixture – front

    The code descends from an early version of the vacuum tube lights, gutted of all the randomizing and fancy features. It updates the LEDs every 20 ms and, with only 100 points per cycle, the colors tick along fast enough reassure you (well, me) that the thing is doing something: the pattern takes about 20 seconds from one end of the string to the other.

    At full throttle the whole array draws 1.68 A = 60 mA × 28 with all LEDs at full white, which happens only during the initial lamp test and browns out the supply (literally: the blue LEDs fade out first and produce an amber glow). The cheap 5 V 500 mA power supply definitely can’t power the entire array at full brightness.

    The power supply current waveform looks fairly choppy, with peaks at the 400 Hz PWM frequency:

    WS2812 4x7 array - 200 mA VCC
    WS2812 4×7 array – 200 mA VCC

    With the Tek current probe set at 200 mA/div, the upper trace shows 290 mA RMS. That’s at MaxPWM = 127, which reduces the average current but doesn’t affect the peaks. At full brightness the average current should be around 600 mA, a tad more than the supply can provide, but maybe it’ll survive; the bottom trace shows a nice average, but the minimum hits 4.6 V during peak current.

    Assuming that perversity will be conserved as usual, none of the LEDs will fail for as long as I’m willing to let them cook.

    The Arduino source code as a GitHub Gist:

    // WS2812 LED array exerciser
    // Ed Nisley – KE4ANU – February 2017
    #include <Adafruit_NeoPixel.h>
    //———-
    // Pin assignments
    const byte PIN_NEO = A3; // DO – data out to first Neopixel
    const byte PIN_HEARTBEAT = 13; // DO – Arduino LED
    //———-
    // Constants
    #define UPDATEINTERVAL 20ul
    const unsigned long UpdateMS = UPDATEINTERVAL – 1ul; // update LEDs only this many ms apart minus loop() overhead
    // number of steps per cycle, before applying prime factors
    #define RESOLUTION 100
    // phase difference between LEDs for slowest color
    #define BASEPHASE (PI/16.0)
    // LEDs in each row
    #define NUMCOLS 4
    // number of rows
    #define NUMROWS 7
    #define NUMPIXELS (NUMCOLS * NUMROWS)
    #define PINDEX(row,col) (row*NUMCOLS + col)
    //———-
    // Globals
    // instantiate the Neopixel buffer array
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN_NEO, NEO_GRB + NEO_KHZ800);
    uint32_t FullWhite = strip.Color(255,255,255);
    uint32_t FullOff = strip.Color(0,0,0);
    struct pixcolor_t {
    byte Prime;
    unsigned int NumSteps;
    unsigned int Step;
    float StepSize;
    float TubePhase;
    byte MaxPWM;
    };
    // colors in each LED
    enum pixcolors {RED, GREEN, BLUE, PIXELSIZE};
    struct pixcolor_t Pixels[PIXELSIZE]; // all the data for each pixel color intensity
    unsigned long MillisNow;
    unsigned long MillisThen;
    //– Figure PWM based on current state
    byte StepColor(byte Color, float Phi) {
    byte Value;
    Value = (Pixels[Color].MaxPWM / 2.0) * (1.0 + sin(Pixels[Color].Step * Pixels[Color].StepSize + Phi));
    // Value = (Value) ? Value : Pixels[Color].MaxPWM; // flash at dimmest points
    // printf("C: %d Phi: %d Value: %d\r\n",Color,(int)(Phi*180.0/PI),Value);
    return Value;
    }
    //– Helper routine for printf()
    int s_putc(char c, FILE *t) {
    Serial.write(c);
    }
    //——————
    // Set the mood
    void setup() {
    pinMode(PIN_HEARTBEAT,OUTPUT);
    digitalWrite(PIN_HEARTBEAT,LOW); // show we arrived
    Serial.begin(57600);
    fdevopen(&s_putc,0); // set up serial output for printf()
    printf("WS2812 array exerciser\r\nEd Nisley – KE4ZNU – February 2017\r\n");
    /// set up Neopixels
    strip.begin();
    strip.show();
    // lamp test: run a brilliant white dot along the length of the strip
    printf("Lamp test: walking white\r\n");
    strip.setPixelColor(0,FullWhite);
    strip.show();
    delay(250);
    for (int i=1; i<NUMPIXELS; i++) {
    digitalWrite(PIN_HEARTBEAT,HIGH);
    strip.setPixelColor(i-1,FullOff);
    strip.setPixelColor(i,FullWhite);
    strip.show();
    digitalWrite(PIN_HEARTBEAT,LOW);
    delay(250);
    }
    strip.setPixelColor(NUMPIXELS – 1,FullOff);
    strip.show();
    delay(250);
    // fill the array, row by row
    printf(" … fill\r\n");
    for (int i=0; i < NUMROWS; i++) { // for each row
    digitalWrite(PIN_HEARTBEAT,HIGH);
    for (int j=0; j < NUMCOLS; j++) {
    strip.setPixelColor(PINDEX(i,j),FullWhite);
    strip.show();
    delay(100);
    }
    digitalWrite(PIN_HEARTBEAT,LOW);
    }
    // clear to black, column by column
    printf(" … clear\r\n");
    for (int j=NUMCOLS-1; j>=0; j–) { // for each column
    digitalWrite(PIN_HEARTBEAT,HIGH);
    for (int i=NUMROWS-1; i>=0; i–) {
    strip.setPixelColor(PINDEX(i,j),FullOff);
    strip.show();
    delay(100);
    }
    digitalWrite(PIN_HEARTBEAT,LOW);
    }
    delay(1000);
    // set up the color generators
    MillisNow = MillisThen = millis();
    printf("First random number: %ld\r\n",random(10));
    Pixels[RED].Prime = 11;
    Pixels[GREEN].Prime = 7;
    Pixels[BLUE].Prime = 5;
    printf("Primes: (%d,%d,%d)\r\n",Pixels[RED].Prime,Pixels[GREEN].Prime,Pixels[BLUE].Prime);
    unsigned int PixelSteps = (unsigned int) ((BASEPHASE / TWO_PI) *
    RESOLUTION * (unsigned int) max(max(Pixels[RED].Prime,Pixels[GREEN].Prime),Pixels[BLUE].Prime));
    printf("Pixel phase offset: %d deg = %d steps\r\n",(int)(BASEPHASE*(360.0/TWO_PI)),PixelSteps);
    Pixels[RED].MaxPWM = 127;
    Pixels[GREEN].MaxPWM = 127;
    Pixels[BLUE].MaxPWM = 127;
    for (byte c=0; c < PIXELSIZE; c++) {
    Pixels[c].NumSteps = RESOLUTION * (unsigned int) Pixels[c].Prime;
    Pixels[c].Step = (3*Pixels[c].NumSteps)/4;
    Pixels[c].StepSize = TWO_PI / Pixels[c].NumSteps; // in radians per step
    Pixels[c].TubePhase = PixelSteps * Pixels[c].StepSize; // radians per tube
    printf("c: %d Steps: %5d Init: %5d",c,Pixels[c].NumSteps,Pixels[c].Step);
    printf(" PWM: %3d Phi %3d deg\r\n",Pixels[c].MaxPWM,(int)(Pixels[c].TubePhase*(360.0/TWO_PI)));
    }
    }
    //——————
    // Run the mood
    void loop() {
    MillisNow = millis();
    if ((MillisNow – MillisThen) > UpdateMS) {
    digitalWrite(PIN_HEARTBEAT,HIGH);
    unsigned int AllSteps = 0;
    for (byte c=0; c < PIXELSIZE; c++) { // step to next increment in each color
    if (++Pixels[c].Step >= Pixels[c].NumSteps) {
    Pixels[c].Step = 0;
    printf("Color %d steps %5d at %8ld delta %ld ms\r\n",c,Pixels[c].NumSteps,MillisNow,(MillisNow – MillisThen));
    }
    AllSteps += Pixels[c].Step; // will be zero only when all wrap at once
    }
    if (0 == AllSteps) {
    printf("Grand cycle at: %ld\r\n",MillisNow);
    }
    for (int k=0; k < NUMPIXELS; k++) { // for each pixel
    byte Value[PIXELSIZE];
    for (byte c=0; c < PIXELSIZE; c++) { // … for each color
    Value[c] = StepColor(c,-k*Pixels[c].TubePhase); // figure new PWM value
    // Value[c] = (c == RED && Value[c] == 0) ? Pixels[c].MaxPWM : Value[c]; // flash highlight for tracking
    }
    uint32_t UniColor = strip.Color(Value[RED],Value[GREEN],Value[BLUE]);
    strip.setPixelColor(k,UniColor);
    }
    strip.show();
    MillisThen = MillisNow;
    digitalWrite(PIN_HEARTBEAT,LOW);
    }
    }
    view raw ArrayTest.ino hosted with ❤ by GitHub
  • Cheap WS2812 LEDs: Leak Tests vs. Failures

    Applying the Josh Sharpie Test to three defunct WS2812 LEDs produced one failure:

    Failed WS2812 LED - leak view 2
    Failed WS2812 LED – leak view 2

    The other side shows where the ink stopped seeping under the silicone:

    Failed WS2812 LED - leak view 1
    Failed WS2812 LED – leak view 1

    I don’t know if I melted the side of the LED or if it came that way, but, oddly, there’s no leakage on that side.

    This LED matches the layout of Josh’s “crappy” LEDs, as does the entire lot below, although I suspect that’s more coincidence than anything else; there aren’t that many different layouts around.

    Flushed with success, so to speak, I ran the Sharpie around all the unused LEDs from that order:

    WS2812 LEDs - leak test
    WS2812 LEDs – leak test

    I tested the process on the three LEDs in front, then wiped the ink off with denatured alcohol.

    A closer look shows the ink all around the silicone-to-case border, with plenty of opportunity to seep in:

    WS2812 LEDs - leak test - detail
    WS2812 LEDs – leak test – detail

    After wiping the ink off, none of the 31 unused LEDs showed any sign of poor sealing.

    I haven’t been keeping good records of the failures, but right now I have twelve functional WS2812 LEDs attached to various glass doodads. That leaves 7-ish failed LEDs out of the 15-ish with long term use (not counting four recent replacements).

    In round numbers, that’s a 50% failure rate…

    I should wire up the remaining sheet of LEDs as a test fixture, let them cook for a while, and see what happens.

  • Monthly Image: Turkeys in the Trees

    A turkey flock forages through the bottomlands along the Wappinger Creek and, at night, roosts in the trees at the far end of our driveway:

    Roosting Turkeys - visible
    Roosting Turkeys – visible

    I’m a sucker for that moon:

    Roosting Turkeys - visible
    Roosting Turkeys – visible

    It’s rising into the eastward-bound cloud cover bringing a light snowfall, so we missed the penumbral eclipse.

    If you’re counting turkeys, it’s easier with a contrasty IR image:

    Roosting Turkeys - infra-red mode
    Roosting Turkeys – infra-red mode

    Mary recently counted forty turkeys on the ground, so that’s just part of their flock. I think their air boss assigns one turkey per branch for safety; they weigh upwards of 10 pounds each!

    Taken with the DSC-H5 and DSC-F717, both the the 1.7× teleadapter, hand-held in cold weather.

    Searching the blog for turkey will turn up more pix, including my favorite IR turkey shot.

  • Monthly Science: WWVB Reception Sample

    Further results from the SDR-based WWVB receiver:

    60 kHz Receiver - preamp HIT N3 Pi3 - attic layout
    60 kHz Receiver – preamp HIT N3 Pi3 – attic layout

    Seven hours of mid-January RF, tight-zoomed in both frequency and amplitude, from 0350 to 1050 local:

    WWVB waterfall - N3 - 2017-01-24 1050 - composite
    WWVB waterfall – N3 – 2017-01-24 1050 – composite

    The yellow line of the WWVB carrier comes out 2 ppm high, which means the local oscillator chain is 2 ppm low. We know the WWVB transmitter frequency is exactly 60.000 kHz, translated up by 125 MHz to the N3’s tuning range; you can, ahem, set your clock by it.

    The blue band marks the loop antenna + preamp passaband, which isn’t quite centered around 60.000 kHz. Tweaking the mica compression caps just a bit tighter should remedy that situation.

    Given that input, a very very tight bandpass filter should isolate the WWVB carrier and then it’s all a matter of fine tuning…

  • ATX Lithium Ion 18650 Cell Capacity

    The 2016-11A and 2016-11B cells produced the overlapping red and green curves, with the gritty section due to crappy battery pack connections:

    Li-Ion 18650 cells - ATX prot - bare - Ah scale - 2016-12-17
    Li-Ion 18650 cells – ATX prot – bare – Ah scale – 2016-12-17

    The lower curve comes from an old unprotected cell harvested from a defunct media player and retrieved from the to-be-recycled pile.

    I picked 1 A as a reasonable value for their intended use in flashlights and maybe a helmet camera. Unlike some other cells in the recent past, these deliver 3.0 A·h, reasonably close to their rated 3.4 A·h capacity at a (presumably) lower current.

    Replotting the voltage vs. energy delivered doesn’t show any surprises:

    Li-Ion 18650 cells - ATX prot - bare - Wh scale - 2016-12-17
    Li-Ion 18650 cells – ATX prot – bare – Wh scale – 2016-12-17

    The voltage declines more-or-less linearly, without the relatively flat discharge curve for smaller cells, which explains why the J5 V2 flashlight becomes seriously dim after a few hours. On the upside, that allows a reasonably accurate state-of-charge display.

    Assuming the Sony HDR-AS30V camera burns 0.1 W·h/min while recording (which is a fancy way of saying it dissipates 6 W), then it should run for (10 W·h)/(0.1W·h/min) = 100 min from one of these cells fitted as an outrigger. The best of the NP-BX1 cells for the camera delivers something like 90 minutes from a measured capacity of 4 A·h at 500 mA; I don’t know what to make of those numbers. Perhaps the camera runs the NP-BX1 cells below the 2.8 V cutoff I’ve been assuming?