Advertisements

Archive for November, 2015

Time Warner RoadRunner vs. SSH: Help Wanted

So Time Warner updated the infrastructure upstream of Mary’s folks and installed a new cable modem / router, which killed my remote access using ssh (with RSA keys, passphrases, nonstandard ports, fixed internal IP addresses, port forwarding, port triggers, and all the Right Stuff). I just spent a harried pair of days trying and failing to figure out how to make this work again.

My laptop can ssh into my file server from our house network, both wired and wireless. Ditto when it’s on the Squidwrench Operating Table. Ditto from the low-quality Hampton Inn WiFi near her folks. Plunked on their desk and jacked into their router, however, that outbound ssh times out somewhere between their bits and my basement.

I dinked with the TW Surfboard modem / router, added the appropriate port forwarding & triggers, dialed back the firewall intensity, and ssh flat out doesn’t work in either direction from any PC (all running various Linus flavors). No diagnostics, no logs, nothing that I could find.

From the outside (our house or the Hampton), there’s no response from the PCs inside (on their desk). I’m not trying a loopback from inside to inside, which I know doesn’t work with consumer-grade routers. I’d planned to ssh from there to my basement file server, then ssh back to verify that the connections worked, but the outbound connection doesn’t work.

Probably unrelated, but equally frustrating: trying to configure Thunderbird’s outbound SMTP with their email server flat-out doesn’t work. Either the username / password isn’t valid (it is), various combination of ports / security / encryption (including the ones in the TW FAQs) don’t survive the configuration test, or a seemingly valid configuration doesn’t actually transmit email. Incoming email works only in IMAP mode, not POP3.

I finally set up outbound TW email to bankshot through his Gmail account, which will probably have unforeseen side effects.

The usual Google searches were unavailing, other than several notes suggesting that if you have any other choice of ISP or email provider than TW, do that. But it’s not like they have any choice; Verizon provides 1 Mb/s (!) DSL in that area and satellite Internet isn’t going to happen in an apartment.

Obviously, I’m doing several things wrong, but I have no idea what else to try. I’ve set up email and remote access often enough to get a whole bunch of things right, but that sure didn’t help with TW.

Any suggestions?

Advertisements

21 Comments

Why Friends Don’t Let Friends Run Windows

Perhaps this is not nearly as motivational as it’s supposed to be:

Win 10 Upgrade Popup

Win 10 Upgrade Popup

A friend sent that along after reading my efforts to squelch the Windows 10 nagware on an off-lease Dell Optiplex that will never, ever be updated.

She just turned off automatic updates, which means she must examine all the updates and manually install ones that don’t download Win 10 (which she doesn’t want), forevermore. Unfortunately, that means she won’t automatically get all the security updates that help make current versions of Windows much less hazardous then in The Bad Old Days.

Talk about a Hobson’s Choice: in practical terms, you must decide between automatic updates or not getting regular updates. OK, that’s actually a false dilemma, but you get the idea.

If you run automatic updates the way Microsoft recommends, you’ll soon be running a free operating system that tracks and reports your every move, so as to deliver precisely targeted advertisements right on your desktop. What could possibly be better?

Come the middle of next year, we may see an uptick in the number of people using Linux or running unpatched Windows boxes to cut down on nagware.

5 Comments

Traffic Signal Timing: Burnett Blvd. at Rt 55, Redux

Just in case you think reporting a problem to NYSDOT will actually produce any action:

Burnett at Rt 55 2015-11-08 - Yellow 5 s after green

Burnett at Rt 55 2015-11-08 – Yellow 5 s after green

Apparently, NYSDOT’s bicycle safety criteria allow greenlighting opposing vehicles onto bicyclists in the middle of intersections, so there’s no particular urgency to fix this non-problem.

They’ve been “studying” that situation, without contacting me for any further information, since July, so you can decide how much they’ve accomplished thus far. I know NYSDOT employees get offended when you call them liars to their face, but they have never, ever produced any evidence showing that I’m wrong.

Yeah, call me a cynic.

12 Comments

Neopixel Current vs. Arduino Power Supply Voltage

Just to show why powering Neopixels directly from an Arduino is a Bad Idea, I wired up an Adafruit Jewel thusly (and, BTW, exactly like their lead illustration shows):

dsc00925 - Adafruit Neopixel Jewel with Tek current probe

Makes your skin crawl just to look at it, right?

With all seven Neopixels set to a gray PWM (64,64,64), the average current should be around 90 mA: 21 * 18 mA * 64/255, with another 6% knocked off because the WS2812B controller imposes that much mandatory dark time at PWM 255.

Eyeballometrically, this looks pretty close at 100 mA/div:

Neopixel current 100 mA - 64-64-64 0-7 200 mA peak

Neopixel current 100 mA – 64-64-64 0-7 200 mA peak

But those seven asynchronous PWM oscillators guarantee this will happen every now & again:

Neopixel current 100 mA - 64-64-64 0-7 400 mA peak

Neopixel current 100 mA – 64-64-64 0-7 400 mA peak

The 400 mA peaks happen when all seven Neopixels turn on at once. The broad flat floor means they’re off most of the time and the power supply sees a hefty 400 Hz pulsating load.

The bottom trace shows the effect of those peaks in the top trace (at 200 mA/div) on the Arduino’s VCC pin:

Neopixel current 200 mA - 64-64-64 0-7 400 mA pk w VCC

Neopixel current 200 mA – 64-64-64 0-7 400 mA pk w VCC

That’s at 200 mV/div and AC coupled to remove the 5 VDC supply. Because the board runs from USB power, the on-board regulator doesn’t contribute to the problem, but there’s plenty of problem to go around.

Always use an external power supply and a 5 VDC regulator with Neopixels!

3 Comments

Hard Drive Platter Thicknesses

It should come as no surprise that hard drive platters have different thicknesses:

Hard Drive Platter Thickness

Hard Drive Platter Thickness

The thicker ones measure 1.25 mm, which is near enough to 50 mils to suggest they date back to the Good Old Days. The three thinner ones in the middle are 0.77 mm = 30 mil and could be slightly younger than dirt. There’s more where these came from and I expect more variation on the theme.

The beveled edges make the platters look thinner than they really are; they’re firmly clamped together with no space between them.

As nearly as I can tell, the IBM 350 Disk Storage Unit on the IBM 350 RAMAC had platters about 25 mil thick. Those were two feet in diameter, so they definitely don’t make ’em like they used to!

The thickness wouldn’t matter, except that the OpenSCAD program producing the hub & spacer tabs for the Mood Lights needs to know.

4 Comments

Hard Drive Platter Mood Light: Improved Trigonometry

The original Mood Light firmware used the current time in milliseconds as a factor in the sin() argument, assuming that the Arduino runtime would Do The Right Thing. Having been gently disabused of that notion, here’s another pass that resets the argument after every full cycle to keep the trig from going crazy. Thanks to all of you for helping out… [grin]

The hardware still looks like this, though:

Hard Drive Mood Light - high angle

Hard Drive Mood Light – high angle

Define a structure to hold everything needed to calculate each color, then make an array holding one structure per color:

struct pixcolor_t {
	byte Prime;
	unsigned int NumSteps;
	unsigned int Step;
	float StepSize;
	byte MaxPWM;
	byte Value;
};

enum pixcolors {RED, GREEN, BLUE, PIXELSIZE};

#define RESOLUTION 1000

struct pixcolor_t Pixels[PIXELSIZE];

The general idea is to increment the integer Step from 0 through NumSteps - 1 to create the sine wave, with the total number of steps per cycle being Prime times the RESOLUTION.

The angular argument is Step * StepSize, with the size of each step equal to 2π / NumSteps. Because Step gets reset to zero after reaching NumSteps - 1, the argument never exceeds 2π and the trig never falls off the rails.

Soooo, calculating the PWM value for each color goes like this:

byte StepColor(byte Color) {

    Pixels[Color].Value = (Pixels[Color].MaxPWM / 2.0) * (1.0 + sin(Pixels[Color].Step * Pixels[Color].StepSize));
	
	Pixels[Color].Step = (Pixels[Color].Step >= Pixels[Color].NumSteps) ? 0 : Pixels[Color].Step + 1;
	
	if (0 == Pixels[Color].Step) {
		printf("Color %d cycle end at %d\r\n",Color,Pixels[Color].NumSteps);
	}

    return Pixels[Color].Value;
}

The MaxPWM parameter limits the perceived brightness, although not the peak current. Each Neopixel dissipates 300-ish mW at full throttle, they’re mounted on a plastic structure, and there’s not a lot of air flowing between those platters; running at half power makes a lot of sense.

Initializing the structure values happens in the setup() function, because it’s easier than filling in all the array structure entries by hand:

	Pixels[RED].Prime = 5;
	Pixels[GREEN].Prime = 7;
	Pixels[BLUE].Prime = 11;
	
	for (byte c=0; c < PIXELSIZE; c++) {
		Pixels[c].NumSteps = RESOLUTION * Pixels[c].Prime;
		Pixels[c].Step = random(Pixels[c].NumSteps);
		Pixels[c].StepSize = TWO_PI / Pixels[c].NumSteps;
		Pixels[c].MaxPWM = 128;
		StepColor(c);
	}

The Phase value has Gone Away, because it really didn’t add anything to the proceedings. Instead, I randomize the starting Step, although there’s not a lot of randomness to be had early on in an Arduino program; that needs a bit more work. Adding a little PCB with a random noise source doesn’t seem cost-effective, although a photodetector peering out the side and adjusting the MaxPWM values might be a Good Thing.

Come to think of it, limiting the sum of the PWM values might be more useful than limiting their individual maximum values. That’s a simple matter of software…

The main() loop doesn’t have a lot to do. Every 25 ms it updates the three color PWM values, sets the new values into all 12 LED buffer locations, and sends the whole mess to the Neopixels. The RESOLUTION value acts as a gearshift between the 25 ms update rate and the speed at which complete cycles zip past. Absent the Prime factor, each cycle would require 25 ms * RESOLUTION ms to complete: call it 25 seconds.

The Prime factors slow that down proportionally and push the repetition interval out to the product of all the factors. For the (5, 7, 11) factors shown below, that’s 5x7x11x253 s = 6×106 s = 70 days,

Now it doesn’t matter how often the millis() value wraps. Every now & again, MillisThen will be just under 232 and MillisNow will be just over 0, but their (unsigned) difference will be some huge number, the conditional will trip, and nobody will notice the timing glitch…

The Arduino source code:

// Neopixel mood lighting for hard drive platter sculpture
// Ed Nisley - KE4ANU - November 2015

#include <Adafruit_NeoPixel.h>

//----------
// Pin assignments

const byte PIN_NEO = 6;				// DO - data out to first Neopixel

const byte PIN_HEARTBEAT = 13;		// DO - Arduino LED

//----------
// Constants

const unsigned long UpdateMS = 25ul - 4ul;		// update LEDs only this many ms apart minus loop() overhead

//----------
// Globals

unsigned long MillisNow;
unsigned long MillisThen;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, 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;
	byte MaxPWM;
	byte Value;
};

enum pixcolors {RED, GREEN, BLUE, PIXELSIZE};

#define RESOLUTION 1000

struct pixcolor_t Pixels[PIXELSIZE];								// everything that calculates the pixel colors

byte Map[] = {0,5,6,11, 1,4,7,10, 2,3,8,9};							// pixel numbers around platter, bottom to top.

//-- Figure PWM based on current state

byte StepColor(byte Color) {

    Pixels[Color].Value = (Pixels[Color].MaxPWM / 2.0) * (1.0 + sin(Pixels[Color].Step * Pixels[Color].StepSize));
	
	Pixels[Color].Step = (Pixels[Color].Step >= Pixels[Color].NumSteps) ? 0 : Pixels[Color].Step + 1;
	
	if (0 == Pixels[Color].Step) {
		printf("Color %d cycle end at %d\r\n",Color,Pixels[Color].NumSteps);
	}
	
//	printf("Step: %d Color: %d Value: %d\r\n",Pixels[Color].Step,(word)Color,(word)Pixels[Color].Value);
	
    return Pixels[Color].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("Mood Light with Neopixels\r\nEd Nisley - KE4ZNU - November 2015\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(500);
	
	for (int i=1; i<strip.numPixels(); i++) {
		digitalWrite(PIN_HEARTBEAT,HIGH);
		strip.setPixelColor(i-1,FullOff);
		strip.setPixelColor(i,FullWhite);
		strip.show();
		digitalWrite(PIN_HEARTBEAT,LOW);
		delay(500);
	}
	
	strip.setPixelColor(strip.numPixels() - 1,FullOff);
	strip.show();
	delay(500);
	
// and around the disks
	
	printf(" ... using Map array\r\n");
	
	strip.setPixelColor(Map[0],FullWhite);
	strip.show();
	delay(250);
	
	for (int i=1; i<strip.numPixels(); i++) {
		digitalWrite(PIN_HEARTBEAT,HIGH);
		strip.setPixelColor(Map[i-1],FullOff);
		strip.setPixelColor(Map[i],FullWhite);
		strip.show();
		digitalWrite(PIN_HEARTBEAT,LOW);
		delay(250);
	}
	
	strip.setPixelColor(Map[strip.numPixels() - 1],FullOff);
	strip.show();
	delay(250);
	
	MillisNow = MillisThen = millis();
	randomSeed(MillisNow + analogRead(7));
	printf("First random number: %ld\r\n",random(10));
	
	Pixels[RED].Prime = 5;
	Pixels[GREEN].Prime = 7;
	Pixels[BLUE].Prime = 11;
	
	for (byte c=0; c < PIXELSIZE; c++) {
		Pixels[c].NumSteps = RESOLUTION * Pixels[c].Prime;
		Pixels[c].Step = random(Pixels[c].NumSteps);
		Pixels[c].StepSize = TWO_PI / Pixels[c].NumSteps;
		Pixels[c].MaxPWM = 128;
		StepColor(c);
	}
	printf("Prime scales: (%d,%d,%d)\r\n",Pixels[RED].Prime,Pixels[GREEN].Prime,Pixels[BLUE].Prime);
	printf("Initial step: (%d,%d,%d)\r\n",Pixels[RED].Step,Pixels[GREEN].Step,Pixels[BLUE].Step);
	printf("  ...  color: (%d,%d,%d)\r\n",Pixels[RED].Value,Pixels[GREEN].Value,Pixels[BLUE].Value);
	
	for (int i=0; i<strip.numPixels(); i++) { strip.setPixelColor(Map[i],strip.Color(Pixels[RED].Value,Pixels[GREEN].Value,Pixels[BLUE].Value)); } strip.show(); } //------------------ // Run the mood void loop() { // printf("Loop! %ld %ld\r\n",MillisNow,MillisThen); MillisNow = millis(); if ((MillisNow - MillisThen) > UpdateMS) {
		digitalWrite(PIN_HEARTBEAT,HIGH);

		for (byte c=0; c < PIXELSIZE; c++) {
			StepColor(c);
		}
		
		for (int i=0; i < strip.numPixels(); i++) {
			strip.setPixelColor(i,strip.Color(Pixels[RED].Value,Pixels[GREEN].Value,Pixels[BLUE].Value));
		}
		strip.show();

		MillisThen = MillisNow;
		digitalWrite(PIN_HEARTBEAT,LOW);
	}
	
}

,

2 Comments

Sony HDR-AS30V Camera vs. STK NP-BX1 Batteries

This sheaf of tests shows three of the four STK NP-BX1 batteries deliver about 4 W·h during a constant 500 mA discharge, with battery B trailing behind:

Sony NP-BX1 - Wasabi FG - STK ABCD - Wh scale - 2015-11-03

Sony NP-BX1 – Wasabi FG – STK ABCD – Wh scale – 2015-11-03

After the three most recent bike rides, I popped the partially discharged battery into the tester and used the same test current:

Sony NP-BX1 - STK ABD - charged vs used - Wh scale - 2015-11-22

Sony NP-BX1 – STK ABD – charged vs used – Wh scale – 2015-11-22

The longer curves come from the top chart (with different colors), the shorter ones from the partially discharged batteries. In an ideal world, the shorter curves should give the energy left in the battery after the ride, so subtracting that from the before-ride capacity gives the energy used during the ride.

The results for battery A may not be typical, as the camera turned off before I rolled into the garage. The camera may run with a battery voltage below the 2.8 V cutoff in those tests, so it can extract more energy than the tests. The slope of the curve toward the end suggests it won’t get much, but that will still bias the results.

In round numbers, the bike rides required:

  • A: 3.8 – 0.1 = 3.7 W·h
  • B: 3.6 – 1.4 = 2.2 W·h
  • D: 4.2 – 1.0 = 3.2 W·h

I generally turn the camera off during the mid-ride pause (Protip: never wear a helmet camera into a Port-a-Loo), so at least two of the rides have discontinuous usage. I figured the total run time from the video file sizes at the rate of 22.75 min/4.0 GB, blithely ignoring issues like the battery recovering during the pauses, the effect of ambient temperature vs. camera heating on battery temperature, and so forth and so on.

In an ideal world, dividing the total energy by the run time (converted from minutes to hours and not venturing into pirate·ninja territory) should produce a nearly constant value equal to the camera’s power dissipation:

  • A: 3.7 W·h / 1.25 h = 2.96 W
  • B: 2.2 W·h / 1.0 h = 2.1 W
  • D: 3.2 W·h / 1.4 h = 2.25

Ignoring the suspiciously high result for battery A, it looks like the HDR-AS30V really does dissipate a bit over 2 W while recording 1920×1080@60fps video. That’s with GPS, WiFi, and NFC turned off, of course.

Which turns out to be pretty close to the test conditions: 3.7 V x 500 mA = 1.85 W. I could goose the test current to 600 mA = 2.2 W/3.7 V for the next tests, but maybe long-term consistency is a virtue.

5 Comments