Weasley Clock Code

Note: I’ve finally gotten around to a much-needed rewrite for WiFi. You can find that code and another video here.

Back at Veracode’s last Hackathon, I published the video below. People have started discovering this and asking questions about it, so here is the code for it:

/*
  Weasley Clock
  -------------

  Created by Doug "LegoDoug" Wilcox for Veracode Hackathon IX.

  Video of the completed project is at https://www.youtube.com/embed/oRUViFnxKsg.

  "Share and enjoy."

 */

// Arduino SPI (Serial Peripheral Interface) library - https://www.arduino.cc/en/Reference/SPI
#include <SPI.h>             
// Arduino Ethernet library - https://www.arduino.cc/en/Reference/Ethernet
#include <Ethernet.h>        
// Arduino Stepper library - https://www.arduino.cc/en/Reference/Stepper
#include <Stepper.h>         
// Adafruit REST IO library - https://learn.adafruit.com/adafruit-io/arduino
// See also https://www.arduino.cc/en/Tutorial/WebClientRepeating
#include "Adafruit_IO_Client.h"    
                                   

// assign a MAC address for the ethernet controller.
byte mac[] = {
  0x8C, 0xDC, 0xD4, 0x4A, 0xC9, 0xC2
};

// initialize the library instance:
EthernetClient client;

// last time the Arduino connected to the server, in milliseconds
unsigned long lastConnectionTime = 0;        
// delay between retrieving updates, in milliseconds
const unsigned long requestInterval = 5000L; 

// Configure Adafruit IO access. You will need to create your own 
// Adafruit IO account (free), and set up a feed, and provide your
// feed and AIO key in the code below.
#define AIO_FEED   "weasleyclockstatus"
#define AIO_KEY    "XXXXXXXXXXXXXXXXXXXXXXXXXXX"

// Create an Adafruit IO Client instance.  Notice that this needs to take a
// WiFiClient object as the first parameter, and as the second parameter a
// default Adafruit IO key to use when accessing feeds (however each feed can
// override this default key value if required, see further below).
Adafruit_IO_Client aio = Adafruit_IO_Client(client, AIO_KEY);

// Alternatively to access a feed with a specific key:
Adafruit_IO_Feed clockFeed = aio.getFeed(AIO_FEED, AIO_KEY);

// States - These are the codes that correspond to specific clock positions.
const String LD_HOME         = "ld_na";
const String LD_TRAVELING    = "ld_tr";
const String LD_VERACODE     = "ld_of";
const String LD_CHURCH       = "ld_ch";
const String LD_MORTAL_PERIL = "ld_mp";
const String LD_GLOUCESTER   = "ld_gl";

// Steps - How many steps the motor needs to move to point to a specific position 
// on the clock.
const int STEPS_HOME         = 0;
const int STEPS_TRAVELING    = 750;
const int STEPS_VERACODE     = 1600;
const int STEPS_CHURCH       = 2450;
const int STEPS_MORTAL_PERIL = 3350;
const int STEPS_GLOUCESTER   = 4350;

// Someday, I will determine what this actually does. (I don't think, functionally, 
// it has any affect.)
const int stepsPerRevolution = 200;  

long motorPosition = 0L;         // Number of steps the motor has taken.
String fValue = "";              // Feed value.

Stepper clockStepper(stepsPerRevolution, 7, 6, 5, 4, 8);

void setup() {
  // start serial port:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native 
      // USB port only, on certain Arduino models.
  }

  // give the ethernet module time to boot up:
  delay(1000);
  // start the Ethernet connection using a fixed IP address and DNS server:
  //Ethernet.begin(mac, ip, myDns);
  // Or, just start it with dynamic DNS by giving it a MAC address.
  Ethernet.begin(mac);
  // print the Ethernet board/shield's IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());

  clockStepper.setSpeed(20);
}

void loop() {

  // Wait for a bit and read the current feed value.
  Serial.println(F("Waiting ..."));
  delay(requestInterval);
  
  // To read the latest feed value call the receive function on the feed.
  // The returned object will be a FeedData instance and you can check if it's
  // valid (i.e. was successfully read) by calling isValid(), and then get the
  // value either as a text value, or converted to an int, float, etc.
  FeedData latest = clockFeed.receive();
  if (latest.isValid()) {
    Serial.print(F("Received value from feed: ")); Serial.println(latest);
    // By default the received feed data item has a string value, however you
    // can use the following functions to attempt to convert it to a numeric
    // value like an int or float.  Each function returns a boolean that indicates
    // if the conversion succeeded, and takes as a parameter by reference the
    // output value.

    // Want some fun? Learning about "conversion from 'FeedData' to non-scalar 
    // type 'String' requested" the hard way.
    //
    // If I remember correctly, it was a casting error caused by trying to use 
    // the 'latest' variable as a String, directly.
    // The following line casts 'latest' to a string and lets us use it as 'fValue'.
    fValue = latest;
    
    if(fValue == LD_HOME) {
      Serial.println("Nashua");
      stepBySteps(STEPS_HOME);
    }
    
    if(fValue == LD_TRAVELING) {
      Serial.println("Traveling");
      stepBySteps(STEPS_TRAVELING);
    }

    if(fValue == LD_VERACODE) {
      Serial.println("Veracode");
      stepBySteps(STEPS_VERACODE);
    }
    if(fValue == LD_CHURCH) {
      Serial.println("Church");
      stepBySteps(STEPS_CHURCH);
    }
    if(fValue == LD_MORTAL_PERIL) {
      Serial.println("Mortal Peril!");
      stepBySteps(STEPS_MORTAL_PERIL);
    }
    if(fValue == LD_GLOUCESTER) {
      Serial.println("Glostah");
      stepBySteps(STEPS_GLOUCESTER);
    }
    
  } else {
    Serial.print(F("Failed to receive the latest feed value!"));
  }

}

void stepBySteps(int newPosition) {
  if(motorPosition == newPosition) {
    Serial.println("No movement required.");
    return;
  }

  long steps = newPosition - motorPosition;
  
  clockStepper.step(steps);
  motorPosition = newPosition;
  Serial.print("position should now be:" );
  Serial.println(motorPosition);
}

When You Marry a Lawyer’s Daughter …

THE REAL WORLD:

“Darling, you look radiant, today!”

(Woman beams appreciatively.)

WHEN YOU MARRY A LAWYER’S DAUGHTER:

“Darling, you look radiant, today!

(Woman waits. The Speaker continues.)

“The use of the word ‘today,’ should not by any means be interpreted as meaning that I (‘The Speaker’) do not believe you (‘The Addressee’) do not look radiant at every moment. Nor should you feel that subjective beauty is an expectation or requirement of gaining or maintaining the affection of The Speaker. The Speaker acknowledges the numerous beneficial and desirous qualities The Addressee possesses, which include, but are in no way limited to: supreme intelligence, unquestionable moral character, delightful humor, unparalleled business acumen, unassailable logic, perfect sexuality, and infallible parenting. The Addressee is the Speaker’s constant delight, his dearest companion, his partner in all ways. The Addressee is due The Speaker’s complete emotional involvement, financial remuneration, and temporal dedication. In the unlikely event of a disagreement, The Speaker preemptively cedes all possibility of correctness to The Addressee. The Speaker further acknowledges The Addressee is the solitary possessor of his undying affection and his eternal soul, world without end. Amen.”

(Woman nods in nonbinding acceptance.)

Crazy to Get to Space

Remember Scotty’s remark about his nephew in Star Trek II: The Wrath of Khan? (No, of course you don’t.) Scotty explains to Kirk, after an inappropriately emotional response by Midshipman Preston: “My sister’s youngest, Admiral. Crazy to get to space.”

going-to-space
“Come on, R2, we’re going.”

Although I never pursued a career as an astronaut, I certainly remain, “Crazy to get to space,” and the description from Khan still resonates with me. I may yet get there, in my lifetime, especially with companies like SpaceX competing to make the cost of getting to orbit as low as possible.

For now, I’m going to have to settle for a proxy. Eliszabeth* MacDougal, one of the human family members I inherited when I married Sarah Latimer, has a friend, Cian Branco, who offered her the chance to send something small up on the Terrior Improved Orion rocket as part of the RockSat-C program. Eliszabeth realized this would be thrilling to me, and passed along her opportunity.

I ordered a new Lego R2-D2 minifigure, and a few parts to complete another mini-me as an astronaut, and shipped them off to Eliszabeth. They will be going up on Thursday, June 23, 2016, somewhere between 6:00 and 10:00 am, from the NASA facility at Wallops Island, Virginia. (My son, David, and I stood on our roof in the cold in October, 2014, to watch a night launch from Wallops.)

Geeking out!

Thank you, Eliszabeth!

New: I have just learned that my minifigs will have company on this voyage: Benny, from The Lego Movie will also be on this flight.

———————–

*Yes, this is the correct spelling.

————————

Update: (June 23, 2016)

:: sigh :: Postponed until tomorrow.

postponed

————————

Update: (June 24, 2016) I got up early to watch the launch today! In my mind, I was thinking, Saturn V. Long, slow acceleration. This is, uh, quite a bit smaller, and it zoomed upward so quickly I missed the rocket itself in the launch video screen capture. (The video will be posted soon by NASA/Wallops, anyway.) The crew was worried about missing the launch window due to weather, and debated skipping the camera alignment step. In addition to the pad camera, there was a UAV (drone) flying around, as some of the pictures below show.

The rocket got to its apogee of 119.08 km (74.0 miles) almost immediately. The payload detached successfully, and hit splashdown in the Atlantic, where it would be recovered, only 8 or 9 minutes later.

Very exciting! I reiterate my gratitude.

Here’s the official NASA post: NASA Successfully Launches Suborbital Rocket from Wallops.

kdiff3 6242016 60716 AMs

kdiff3 6242016 60327 AMs

kdiff3 6242016 60614 AMs

kdiff3 6242016 60617 AMs

————————

Update: (June 24, 2016, 16:05) Just got the official word from Cian: “Hey Doug, will send pics a bit later, currently wrecked. Your minis all went up and returned fine. I have pics of reintegration. Cheers!”

————————

Here's the recovered payload module, showing where my guys were attached in their Crew Module.
Here’s the recovered payload module, showing where my guys were attached in their “Crew Module.”
The Crew Module was carefully sealed with electrical tape.
The Crew Module was carefully sealed with electrical tape.
 Another view of the Crew Module.
Another view of the Crew Module.
Here's how the minifigures actually traveled.
Here’s how the minifigures actually traveled.
 And here they are, reassembled, along with Benny, who was glued into another part of the payload module
And here they are, reassembled, along with Benny, who was glued into another part of the payload module.

Video of the Launch:

Video from an observer to whom I am grateful.

Here is the launch from the NASA/Wallops feed!

A Republican No More

My voter registration is now undeclared. (Sadly, no exotic options, like “Rational Anarchist” are available in New Hampshire—not even Communist.)

Man with a 1950s style fedora waves goodbye .
Goodbye, sewage-ridden idiocracy.

In a time when a voice of reason is desperately needed, your leadership has proven itself unable to take a stand against an obvious megalomaniac. You continue to propose revoking the victory of universal health care. You have protected and praised racists and worse. You have gone to war without cause, and destroyed our great nation’s international reputation. You have chosen a Presidential candidate who makes Vermin Supreme a rational choice by comparison. You have defended environmental destruction, and embraced ignorance over science.

I am saying goodbye to the sewage-ridden idiocracy the Republican Party has become. You are now, indeed, “Not my circus—not my monkeys.”

Adios.

“Sewage-ridden idiocracy,” is a phrase coined, as far as I know, by Connor Houghton.

Dear QuickBooks:

Dear Intuit/QuickBooks:

When importing an IIF (Intuit Interchange Format) file, you might report “The NAME field in this file is too long” as something other than “Error on line X – You can’t change the type of a name or a add a duplicate name.” (You may recall, this is the same problem that remains unfixed from QuickBooks ’99.)

—A Customer

P.S.: Thank you for removing my online banking support, unless I choose to upgrade for several hundred dollars.

ux_fail

The Lord YOUR God

But Isaac said to his son, “How is it that you have found it so quickly, my son?” He answered, “Because the LORD your God granted me success.” (Gen 27:20, ESV)

(Image: Isaac Blessing Jacob, Govert Flinck, oil on canvas, 1638, currently in the Rijksmuseum, Amsterdam.)
(Image: Isaac Blessing Jacob, Govert Flinck, oil on canvas, 1638, currently in the Rijksmuseum, Amsterdam.)

I find the specific choice of words, “the LORD your God” to be troubling, especially as a parent.

I want my children to have a personal faith of their own. I don’t want them to think of the Lord as “That God my dad worships.”

Actually, I want them to have a more real, personal faith than I had at their ages—living and tempered by both love and righteousness, by faith and reason.

It would be quite a long time before Jacob could truly call the Lord his own God, not merely that of his father.

The Scale of the Solar System (or, the Solar System to Scale)

“Space,” [The Hitchhiker’s Guide to the Galaxy] says, “is big. Really big. You just won’t believe how vastly, hugely, mindbogglingly big it is. I mean, you may think it’s a long way down the road to the chemist’s, but that’s just peanuts to space, listen …

Inspired by this NASA Web page, and Miss Sarah’s work-related interest in space science (too bad she spent all those years not reading science fiction), we decided to lay out our solar system in a manageable scale, complete with to-scale outlines of each planet.

Naomi plants herself just outside the orbit of Mars.
(Naomi plants herself just outside the orbit of Mars.)

Here are the scale sizes and distances, along with the real distances.

Body Diameter (mm) Avg. Distance
(yards)
Distance (in) Avg. Distance
in AUs
km miles
Sun 17.00 0.0 0.0 0.0 0 0
Mercury 0.06 0.8 28.8 0.4 58,000,000 35,000,000
Venus 0.15 1.4 50.4 0.7 108,000,000 67,000,000
Earth 0.16 2.0 72.0 1.0 150,000,000 93,000,000
Mars 0.08 3.0 108.0 1.5 228,000,000 142,000,000
(Asteroids) 0.00 4.0 to 8.0 144.0 to 288.0 2.0 to 4.0 450,000,000 279,000,000
Jupiter 1.75 10.5 378.0 5.2 778,000,000 484,000,000
Saturn 1.47 19.0 684.0 9.5 1,427,000,000 887,000,000
Uranus 0.62 38.0 1,368.0 19.0 2,871,000,000 1,784,000,000
Neptune 0.60 60.0 2,160.0 30.0 4,498,000,000 2,795,000,000
Pluto (avg) 0.03 79.0 2,844.0 39.5 5,906,000,000 3,670,000,000
Voyager 1* See http://voyager.jpl.nasa.gov/where/ 138.4 20,707,634,708 12,867,127,667
Voyager 2* for current locations of Voyager 1 and Voyager 2. 114.2 17,089,103,421 10,618,676,567

*Distances of Voyager 1 and 2 are as of May 2, 2017.

Isaac and Naomi lay out the inner planets.
Isaac and Naomi lay out the inner planets.

I’ve made a Google Sheets spreadsheet with this data publicly available, here.

You can also grab and print this Acrobat/PDF file which has the sun and planets to the same scale as the planetary distances: planets_to_scale.pdf. At this scale, the sun is only 17 mm in diameter, Jupiter is tiny, and the inner planets are nearly invisible.

tiny_planets

DSCN3009
(“It’s cold outside, there’s no kind of atmosphere, I’m all alone, more or less …”)

Now, are you ready to have your mind blown?

Our nearest neighboring star is a binary star, Alpha Centauri. It would be, if we could see it from the northern hemisphere. It’s about 4.3 light years (271,930.8 AUs; 25,277,549,200,000 miles; 40,680,272,100,000 km) away.

At the scales we’re dealing with, how far away do you think Alpha Centauri would be?

Think carefully. When you’re sure, follow this link for the answer.

Space … is … big.

Not a Prayer

When no prayer finds my lips,
And Your blows crush me to the earth,
And the light from above cannot illuminate 
The mire of my sorrow,

Then
   in my torment,
   in my lament,
   in the despair of my soul,

You begin to find me,
Though blackness remains.

(I was inspired to poetry during the Michael Card concert, and jotted this down. It is reminiscent of the utter blackness of what happened 3 years ago, and, thus, autobiographical, but not recent.)

Imponderably Improbable

This weekend’s This American Life program was entitled, “No Coincidence, No Story,” and featured a huge selection of fascinating short stories.

Life is full of coincidences, but I’ve never experienced one that seems more improbable than this:

In 1995, I was visiting the Rondon family in the Dominican Republic, and spent some time looking through their library. A book that caught my eye was, La Ira del Tirano, a book by Miguel Guerrero, about the assassination attempt Trujillo (a truly “wonderful” dictator) made against the then-president of Venezuela, Rómulo Ernesto Betancourt Bello, who had the nerve to support democracy in Latin America.

The Rondon children explained that Guerrero was a friend of the family, and I borrowed the book to read to improve my relatively meager Spanish skills. (It would take me years to get through, but it was, eventually, helpful.)

Later that day, I was passing about a quarter hour of free time when the kids were watching television together, the only time in a full week in which the television was on. They had tuned to the Nickelodeon channel, and a filler program was running, showing on-the-spot interviews conducted with random visitors to Universal Studios, Florida.

In those few minutes of time, among the thousands of visitors to Universal Studios that day, at the only moments we were actually watching television, who was selected for an interview but the book’s author, Miguel Guerrero himself!

Imponderably improbable.