A list of the most influential conservatives

On February 17, 2016, in General, by Neil Stevens

Dan McLaughlin was talking about the most influential conservatives of his lifetime. So I got to thinking about who I think the most influential modern conservatives were.

It’s not 100% “in my lifetime” as Goldwater’s direct influence had waned substantially by the time I was born, but the effects of his Presidential run were still being felt.

The list, in order:

  • Reagan – Presidency changed the GOP
  • Buckley – Founded the modern conservative movement
  • Scalia – His wit inspired countless conservative legal minds
  • Goldwater – Presidential run grew what Buckley started
  • Rehnquist – The Lone Ranger paved the way for Scalia
  • Gingrich – Shrank the government in a way few ever have
  • DeMint – Forerunner of the TEA party anti-establishment revolt
  • Erickson – Champion of the TEA party revolt, outsider’s voice
  • Helms – Senator No, tireless warrior in the Senate
  • Thomas – Much quieter than Scalia, but heroically withstands the left’s arrows
 

World Cup Zelda 2 Tournament

On October 28, 2015, in General, by Neil Stevens

You can’t please everyone with any tournament structure. No matter what you do, there are going to be unbalanced matchups, or people who absolutely cannot win the tournament.

A straight double-elimination, Personal Best-seeded tournament (such as used in the Zeldaone tournament) I think works very well once you get over 32 people. I think it gives the most people a genuine shot to win a game, while still giving the top runners a showdown at the end.

However for reasons I won’t go into (I’m not going to put words in people’s mouths), this is a tournament structure that is disliked by many of the top Zelda 2 runners. So, in trying to find a compromise structure, I outlined a World Cup of Zelda 2. Here’s how it works.

Continue reading »

 

My clock is done

On October 26, 2015, in General, by Neil Stevens

It’s minimalist, but it’s done.

Clock Completed

I posted this earlier on Twitter but after that I decided I needed to tape up the set of plugs connecting the display for ease of plugging/unplugging. That turned out to matter when I realized I’d assembled the case inside out, weirdly enough. So I had to take it all apart and put it back together, which meant unplugging and replugging the display!

I ended up putting no buttons on it. I wrote a little python program for setting the time.

Following is the final code for the Arduino sketch, which drives the display, which is a row of four 8×8 LED grids, driven by an array of four MAX7219 chips. The code also drives the DS3231-based Real Time Clock daughterboard with battery backup.

Though while I’m listing components, the case is a neat little acrylic thing, and the main board is a SainSmart Arduino Uno clone.

On the software end I used the Bounce2, LedControl, and RTClib libraries, with RTClib depending on the Wire library. Well, I had use Bounce2 until I took out the buttons, then just commented all of that out.

/*
#include "Bounce2.h"
*/
#include "LedControl.h"
#include "RTClib.h"
#include "Wire.h"

const byte lowA[8] = {B00000000, B00000000, B00000000, B01111100, B10000010, B10000010, B10000010, B01111101};
const byte capB[8] = {B11111110, B10000001, B10000001, B10000001, B11111110, B10000001, B10000001, B11111110};
const byte lowE[8] = {B00000000, B00000000, B00000000, B01111110, B10000001, B11111111, B10000000, B01111110};
const byte lowG[8] = {B00000000, B00000000, B01111110, B10000001, B10000001, B01111110, B00000001, B01111110};
const byte capH[8] = {B10000001, B10000001, B10000001, B11111111, B10000001, B10000001, B10000001, B10000001};
const byte lowR[8] = {B00000000, B00000000, B00000000, B01111111, B10000000, B10000000, B10000000, B10000000};
const byte lowS[8] = {B00000000, B00000000, B00000000, B01111111, B10000000, B01111110, B00000001, B01111110};
const byte lowU[8] = {B00000000, B00000000, B00000000, B10000001, B10000001, B10000001, B10000011, B01111101};
const byte capW[8] = {B10000001, B10000001, B10000001, B10010001, B10010001, B10010001, B10010001, B01111110};
const byte space[8] = {0, 0, 0, 0, 0, 0, 0, 0};

const byte digits[10][8] = {
	{ B0111110, B1100011, B1100111, B1101011, B1110011, B1100011, B0111110, 0},
	{ B0001110, B0011110, B0001110, B0001110, B0001110, B0001110, B0001110, 0},
	{ B0111110, B1100011, B0000011, B0011110, B0110000, B1100000, B1111111, 0},
	{ B0111110, B1100011, B0000011, B0011110, B0000011, B1100011, B0111110, 0},
	{ B1100110, B1100110, B1100110, B1100110, B1111111, B0000110, B0000110, 0},
	{ B1111111, B1100000, B1111110, B0000011, B0000011, B1100011, B0111110, 0},
	{ B0111110, B1100011, B1100000, B1111110, B1100011, B1100011, B0111110, 0},
	{ B1111111, B0000011, B0000110, B0001100, B0011100, B0011100, B0011100, 0},
	{ B0111110, B1100011, B1100011, B0111110, B1100011, B1100011, B0111110, 0},
	{ B0111110, B1100011, B1100011, B0111111, B0000011, B1100011, B0111110, 0}
};

const unsigned twentyFourHour = false;
LedControl lc = LedControl(11 /* data */, 12 /* clk */, 10 /* cs */, 4);
RTC_DS1307 RTC;
/*
Bounce brightnessButton = Bounce();
Bounce *buttonArray[1] = {&brightnessButton};
*/
boolean firstLoop = true;

void clearAll(LedControl lc) {
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.clearDisplay(i);
	}
}

void setAll(LedControl lc, const int x, const int y)
{
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.setRow(i, x, y);
	}
}

void writeLetter(LedControl lc, const int digit, const byte letter[8], const boolean colon = false)
{
	for(int i = 0; i < 8; ++i) {
		int bits = letter[i];
		if(colon && (i == 2 || i == 4)) {
			bits |= B10000000;
		}
		lc.setRow(digit, i, bits);
	}
}

void setIntensity(LedControl lc, const int brightness) {
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.setIntensity(i, brightness);
	}
}

void setup()
{
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.shutdown(i, false);
		lc.setIntensity(i, 0x0f);
		lc.clearDisplay(i);
	}

/*
	pinMode(1, INPUT_PULLUP);
	brightnessButton.attach(1);
*/

	writeLetter(lc, 3, capB);
	writeLetter(lc, 2, lowA);
	writeLetter(lc, 1, lowG);
	writeLetter(lc, 0, lowU);

	Serial.begin(9600);

	RTC.begin();
}

// returns array {hourTens, hourOnes, minuteTens, minuteOnes}
const byte *timeDigits(DateTime now) {
	static byte ret[4] = {9,9,9,9};
	byte hour = now.hour();
	if(twentyFourHour) {
		hour %= 24;
	} else {
		hour %= 12;
		if(hour == 0) {
			hour = 12;
		}
	}
	byte min = now.minute();

	ret[0] = hour / 10;
	ret[1] = hour % 10;
	ret[2] = min / 10;
	ret[3] = min % 10;
	return ret;
}

void loop()
{
	while(!RTC.isrunning()) {
		Serial.println("RTC not running.");
	}
	static unsigned short brightness;

	if(firstLoop) {
		brightness = 0xf;
		firstLoop = false;
	}

	while(Serial.available() > 0) {
		String cmd = Serial.readString();
		cmd.trim();
		if(cmd == "SET") {
			Serial.println("Reading date");

			while(Serial.available() < = 0) {
				delay(1);
			}
			String d = Serial.readString();
			d.trim();

			Serial.print("Setting date to '");
			Serial.print(d.c_str());
			Serial.println("'");

			Serial.println("Reading time");

			while(Serial.available() <= 0) {
				delay(1);
			}
			String t = Serial.readString();
			t.trim();

			Serial.print("Setting time to '");
			Serial.print(t.c_str());
			Serial.println("'");

			RTC.adjust(DateTime(d.c_str(), t.c_str()));
		} else if(cmd == "SEIZE") {
			Serial.println("YOU");
		}
	}

/*
	for(byte i = 0; i < 2; ++i) {
		buttonArray[i]->update();
	}

	if(brightnessButton.fell()) {
		brightness = (brightness + 1) % 0x10;
		setIntensity(lc, brightness);
	}
*/

	DateTime now = RTC.now();
	const byte *currentDigits = timeDigits(now);

	// Write the clock
	if(currentDigits[0] == 0) {
		writeLetter(lc, 3, space);
	} else {
		writeLetter(lc, 3, digits[currentDigits[0]]);
	}
	writeLetter(lc, 2, digits[currentDigits[1]]);
	writeLetter(lc, 1, digits[currentDigits[2]], (now.second() % 2) == 1);
	writeLetter(lc, 0, digits[currentDigits[3]]);
}
 

Clock update

On October 25, 2015, in General, by Neil Stevens
So I decided to be lazy and just have my clock’s interface be a computer program:
import datetime
import glob
import serial
import sys
import time

if len(sys.argv) > 1:
	port = sys.argv[1]
else:
	port = glob.glob('/dev/tty.usbmodem*')[0]

print "Writing to %s" % port

arduino = serial.Serial(port, 9600)
time.sleep(3)
arduino.write("SEIZE\n")

result = arduino.readline().strip()
if not result == "YOU":
	print("Clock not found\n")
	sys.exit(1)

print("Clock found, setting to current time.")

arduino.write("SET\n");
print(arduino.readline().strip());

arduino.write("%s\n" % time.strftime('%b %d %Y'));
print(arduino.readline().strip());

arduino.write("%s\n" % time.strftime('%H:%M:%S'));
print(arduino.readline().strip());
 

So I built a clock

On October 6, 2015, in General, by Neil Stevens

Here’s a video of it in action:

Parts used:

Libraries used:

My code:

#include "Bounce2.h"
#include "LedControl.h"

const byte lowA[8] = {B00000000, B00000000, B00000000, B01111100, B10000010, B10000010, B10000010, B01111101};
const byte capB[8] = {B11111110, B10000001, B10000001, B10000001, B11111110, B10000001, B10000001, B11111110};
const byte lowE[8] = {B00000000, B00000000, B00000000, B01111110, B10000001, B11111111, B10000000, B01111110};
const byte lowG[8] = {B00000000, B00000000, B01111110, B10000001, B10000001, B01111110, B00000001, B01111110};
const byte capH[8] = {B10000001, B10000001, B10000001, B11111111, B10000001, B10000001, B10000001, B10000001};
const byte lowR[8] = {B00000000, B00000000, B00000000, B01111111, B10000000, B10000000, B10000000, B10000000};
const byte lowS[8] = {B00000000, B00000000, B00000000, B01111111, B10000000, B01111110, B00000001, B01111110};
const byte lowU[8] = {B00000000, B00000000, B00000000, B10000001, B10000001, B10000001, B10000011, B01111101};
const byte capW[8] = {B10000001, B10000001, B10000001, B10010001, B10010001, B10010001, B10010001, B01111110};
const byte space[8] = {0, 0, 0, 0, 0, 0, 0, 0};

const byte digits[10][8] = {
	{ B0111110, B1100011, B1100111, B1101011, B1110011, B1100011, B0111110, 0},
	{ B0001110, B0011110, B0001110, B0001110, B0001110, B0001110, B0001110, 0},
	{ B0111110, B1100011, B0000011, B0011110, B0110000, B1100000, B1111111, 0},
	{ B0111110, B1100011, B0000011, B0011110, B0000011, B1100011, B0111110, 0},
	{ B1100110, B1100110, B1100110, B1100110, B1111111, B0000110, B0000110, 0},
	{ B1111111, B1100000, B1111110, B0000011, B0000011, B1100011, B0111110, 0},
	{ B0111110, B1100011, B1100000, B1111110, B1100011, B1100011, B0111110, 0},
	{ B1111111, B0000011, B0000110, B0001100, B0011100, B0011100, B0011100, 0},
	{ B0111110, B1100011, B1100011, B0111110, B1100011, B1100011, B0111110, 0},
	{ B0111110, B1100011, B1100011, B0111111, B0000011, B1100011, B0111110, 0}
};

const unsigned long maxTicks = 0xFFFFFFFF;
const unsigned twentyFourHour = false;
LedControl lc = LedControl(11, 12, 10, 4);
Bounce hourButton = Bounce();
Bounce minuteButton = Bounce();
Bounce tenMinuteButton = Bounce();
Bounce brightnessButton = Bounce();
Bounce *buttonArray[4] = {&hourButton, &minuteButton, &tenMinuteButton, &brightnessButton};
boolean firstLoop = true;

void clearAll(LedControl lc) {
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.clearDisplay(i);
	}
}

void setAll(LedControl lc, const int x, const int y)
{
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.setRow(i, x, y);
	}
}

void writeLetter(LedControl lc, const int digit, const byte letter[8], const boolean colon = false)
{
	for(int i = 0; i < 8; ++i) {
		int bits = letter[i];
		if(colon && (i == 2 || i == 4)) {
			bits |= B10000000;
		}
		lc.setRow(digit, i, bits);
	}
}

void setIntensity(LedControl lc, const int brightness) {
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.setIntensity(i, brightness);
	}
}

void setup()
{
	for(int i = 0; i < lc.getDeviceCount(); ++i) {
		lc.shutdown(i, false);
		lc.setIntensity(i, 0);
		lc.clearDisplay(i);
	}

	pinMode(1, INPUT_PULLUP);
	brightnessButton.attach(1);
	pinMode(2, INPUT_PULLUP);
	hourButton.attach(2);
	pinMode(3, INPUT_PULLUP);
	tenMinuteButton.attach(3);
	pinMode(4, INPUT_PULLUP);
	minuteButton.attach(4);
}

// returns array {hourTens, hourOnes, minuteTens, minuteOnes}
const byte *timeDigits(const unsigned long seconds) {
	static byte ret[4] = {9,9,9,9};
	byte hour = seconds / 3600;
	if(twentyFourHour) {
		hour %= 24;
	} else {
		hour %= 12;
		if(hour == 0) {
			hour = 12;
		}
	}
	byte min = (seconds % 3600) / 60;

	ret[0] = hour / 10;
	ret[1] = hour % 10;
	ret[2] = min / 10;
	ret[3] = min % 10;
	return ret;
}

unsigned long secondsFromTime(byte hourTens, byte hourOnes, byte minuteTens, byte minuteOnes)
{
	return hourTens * 36000 +
	       hourOnes * 3600 +
	       minuteTens * 600 +
	       minuteOnes * 60;
}

void loop()
{
	boolean reset = false;
	static unsigned long ticks;
	static unsigned long offsetSeconds;
	static unsigned long lastSeconds;
	static unsigned long offsetTicks;
	static unsigned long lastTicks;
	static unsigned short brightness;

	ticks = millis();

	if(hourButton.fell()) {
		const byte *currentDigits = timeDigits(lastSeconds % 86400);
		long hours = currentDigits[0] * 10 + currentDigits[1];
		hours += 1;
		if(twentyFourHour) {
			hours %= 24;
		} else {
			hours %= 12;
			if (hours == 0) {
				hours = 12;
			}
		}
		offsetSeconds = secondsFromTime(hours / 10,
		                                hours % 10,
		                                currentDigits[2],
		                                currentDigits[3]) % 86400;
		reset = true;
	}

	if(tenMinuteButton.fell()) {
		const byte *currentDigits = timeDigits(lastSeconds % 86400);
		offsetSeconds = secondsFromTime(currentDigits[0],
		                                currentDigits[1],
		                                (currentDigits[2] + 1) % 6,
		                                currentDigits[3]) % 86400;
		reset = true;
	}

	if(minuteButton.fell()) {
		const byte *currentDigits = timeDigits(lastSeconds % 86400);
		offsetSeconds = secondsFromTime(currentDigits[0],
		                                currentDigits[1],
		                                currentDigits[2],
		                                (currentDigits[3] + 1) % 10) % 86400;
		reset = true;
	}

	if(brightnessButton.fell()) {
		brightness = (brightness + 1) % 0x10;
		setIntensity(lc, brightness);
	}

	if(firstLoop) {
		brightness = 0;
		firstLoop = false;
		offsetSeconds = 0;
		reset = true;
	}
	
	if(reset) {
		offsetTicks = 0;
		lastTicks = ticks;
		offsetTicks = -ticks;
		lastSeconds = offsetSeconds;
	} else {
		if(lastTicks > ticks) {
			offsetSeconds = lastSeconds;
			offsetTicks = maxTicks - lastTicks;
		}
	}

	for(byte i = 0; i < 4; ++i) {
		buttonArray[i]->update();
	}

	lastSeconds = offsetSeconds + (ticks + offsetTicks) / 1000;
	const byte *currentDigits = timeDigits(lastSeconds % 86400);

	// Write the clock
	if(currentDigits[0] == 0) {
		writeLetter(lc, 3, space);
	} else {
		writeLetter(lc, 3, digits[currentDigits[0]]);
	}
	writeLetter(lc, 2, digits[currentDigits[1]]);
	writeLetter(lc, 1, digits[currentDigits[2]], (lastSeconds % 2) == 1);
	writeLetter(lc, 0, digits[currentDigits[3]]);
}
 
Tech at Night

I know, it’s not Monday, but Monday was Labor day so we’re doing it Tuesday. Besides, I’ve only done one a week lately anyway, so does it really matter?

Time and again we see people going on the Internet and dealing with shady folks, seeking to profit, only to find out those shady folks operated in shady ways, and hurt them instead! Ha.

Continue reading »

Tagged with:
 
Tech at Night

BitTorrent is a technology that distributes data faster by enlisting the bandwidth of downloaders in order to serve more downloads. That’s well and good for legitimate users, however the technology has been used heavily by copyright infringement rings.

The latest scheme, “Popcorn Time”, is under heavy attack as copyright holders and the law strike back.

Continue reading »

Tech at Night

Yeah, terrorism is terrible, and we need to run Islamic State folks into prison, but the idea that a retweet is criminal, given the nature of how Twitter works, is kind of silly. It’s clear to me the Obama administration is just out of touch, as much as its FBI under James Comey is ridiculously power hungry.

Continue reading »

Tagged with:
 

Tech at Night: Catching up before the Gathering

On August 4, 2015, in General, by Neil Stevens
Tech at Night

So the Red State Gathering is this week, and it’s going to be fun. Hopefully you’re coming.

Since Wednesday night I’ll be packing to go, and Friday I’ll be in Atlanta, so this is probably the one shot I have this week to look over Tech nuews, so let’s go.

Continue reading »

Tagged with:
 
Tech at Night

So the Local Radio Fairness Act is purely an act of picking winners and losers, a corrupt means of trying to curry favor with local media stations, come re-election time. I normally hate arguments like that but look, what legitimate reason is there to hand out copyright exemptions?

Continue reading »