Category Archives: General Development

Implementing Free Two-Factor Authentication in .NET using Google Authenticator

Username/password combinations don’t cut it anymore, and Two-Factor authentication is a great way to help secure user accounts. If you have an account with a system that supports it, you should be using it. Likewise, if you develop systems that require users to log in with a username and password, you should be offering it. By using two-factor authentication, you dramatically reduce the attack footprint – no longer would a nefarious individual have to just guess your password, but they would have to guess your password AND a PIN number that changes every couple of minutes.

We are in the middle of adding two-factor auth to a few of our own systems. There are a few sites (like Authy) that will operate this as a cloud service for you at a monthly or usage cost, but there’s no need. Google offers a completely free solution via the Google Authenticator app for iOS and Android, with an equivalent app just called ‘Authenticator’ for Windows Phone. I was surprised there were no really good libraries to use this method of two-factor authentication in an implementation. So, I made one.

What is two-factor authentication?

Two-factor authentication, as the name implies, requires users to supply normal credentials (a username and password, for example), but adds a second, real-time token to the login to verify the user’s identity.

Old-School Tokens

image

You may have seen these RSA keys floating around in Enterprise IT departments. These have been around forever, but have normally been a pain to implement and support.

Text Tokens

Some forms of two-factor authentication will text you a one-time unique token when needed. And that is fairly easy to implement. However, text tokens have a few drawbacks:

  • Not everyone is within cell carrier service all the time
  • Text costs can still be prohibitive (when traveling internationally, for example)
  • Sending true text/SMS messages costs money, through services like Twilio

Two-Factor Apps

Fortunately, this problem is easily solved by apps, and Google Authenticator and its similar alternatives are my pick.

There are others, but that should cover most users pretty well.

The workflow on this is straightforward, and can be used offline – tokens are algorithm-generated, and do not require a live internet connection on the user’s device.

  1. Your system/web site/app generates a two-factor token for the user. Perhaps a GUID, or any unique identifier string specific to that user.
  2. You give the user a code to add to the Google Authenticator app, or show them a QR code to scan for the easy way.
  3. Google Authenticator then generates a 6-digit PIN code every 30 seconds. Prompt the user for this code during their login, and validate it!

It looks like this on iPhone:

GoogleAuthScreenshot

Try it out!

Go get the app and give it a try to see how it works – I set up a sample workflow here: http://GAuthTwoFactorSample.azurewebsites.net

Scan the QR code into Google Authenticator, and then try validating your PIN code.

Now, on to implementation…

This is supposed to be easy, so start by grabbing the NuGet package GoogleAuthenticator (here’s a link).

image

Present User Setup QR Code / Manual Entry Code with GenerateSetupCode

Users have two options when setting up a new Google Authenticator account. If using a mobile device, they can scan a QR code (easiest), or they can enter or copy/paste a manual code into the app.

Generating this information takes a couple lines of code:

TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
var setupInfo = tfa.GenerateSetupCode("MyApp", "user@example.com", "SuperSecretKeyGoesHere", 300, 300);

string qrCodeImageUrl = setupInfo.QrCodeSetupImageUrl;
string manualEntrySetupCode = setupInfo.ManualEntryKey;

GenerateSetupCode requires a couple arguments:

  1. Issuer ID – this is the issuer ID that will appear on the user’s Google Authenticator app, right above the code. It should be the name of your app/system so the user can easily identify it.
  2. Account Title – this will be displayed to the user in the Google Authenticator app. It cannot have any spaces (if it does, the library will filter them). The user’s e-mail address is appropriate to use here, if that works for your system.
  3. Account Secret Key – this is the unique user key that only your system knows about. A good length for this is 10-12 characters. Don’t show this to the user! Your users should never see it. I exposed it on the demo site just to show what’s going on.
  4. QR Code Width – width (in pixels) of generated QR code image
  5. QR Code Height – height (in pixels) of generated QR code image

It returns an object with a few notable properties:

  1. QrCodeSetupImageUrl – the URL to the QR code image that the user can scan (powered by Google Charts)
  2. ManualEntryKey – if the user can’t scan the QR code, this is the string they will need to enter into Google Authenticator in order to set up the two-factor account.

Validate a user’s PIN with ValidateTwoFactorPIN

Prompt the user for their current PIN displayed in Google Authenticator, and validate it:

TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
bool isCorrectPIN = tfa.ValidateTwoFactorPIN(“SuperSecretKeyGoesHere”, “123456”);

That’s it!

About Clock Drift

Given that this two-factor authentication method is time-based, it is highly likely that there is some time difference between your servers and the user’s device. With these PIN codes changing every 30 seconds, you must decide what an acceptable ‘clock drift’ might be. Using the above code samples, the library will default to a clock drift tolerance of +/- 5 minutes from the current time. This means that if your user’s device is perfectly in sync with the server time, their PIN code will be ‘correct’ for a 10-minute window of time. However, if their device time is more than +/- 5 minutes off from your server’s time, the PIN code displayed on their device will never match up.

If you want to change this default clock drift tolerance, you can use the overloaded version of ValidateTwoFactorPIN, and provide a TimeSpan.

That’s all – hope this library is useful and makes two-factor authentication a no-brainer.

Behind the Scenes with the Kinect Train Build

It’s been a little while since the last Christmas project, so it was time to do something again.

This year, I started out with the following criteria for the Christmas for the City display:

  • Something interactive
  • Something that gets more fun as more people join in
  • Something that lets groups of people compete

Concept

The weekend before, my wife came home with a Nestle model train she got at a toy sale for $20:

NestleTrainSet

ABBButtonThis was great – trains and Christmas go together, and if the train could be driven by some input, we have the beginning of an interactive display. My plan at this point was to mount a series of industrial buttons, and wire them to a Netduino. The faster more kids pushed buttons, the faster the train would go.

However, I was running a little low on time at this point, so I needed something a little simpler. I was thinking of what might be possible while I was watching TV, and noticed my Kinect sitting under the TV. That was perfect. The more motion in front of the depth camera, the faster the train goes.

Measuring Motion

Using the Kinect library, I wrote a small app that grabbed each camera frame and passed it into an AForge.NET motion detection library. This gave me a motion analysis similar to this picture, where red areas represent “things that have moved in the last second or so”.

AForgeMotion

By counting the number of “motion pixels” each second, I ended up with what I coined to be the “motion number”. This could be 0 to 150,000 to 600,000 depending on how much motion was happening. I translated this into a percentage based on the max value seen since application start. So now we have a “motion percentage” from 0-100%. This will more or less serve as the value we need for the train throttle.

Mounting the Train

Trains, sensitive electronics, and anything else not bolted down or secured don’t last very long in front of kids, so in order to keep the train from being kicked, shoved, punched, or stolen, it needed some kind of enclosure.

LHShippingBox

For this I used some Bosch Aluminum Profiles – this stuff is amazing, we use it for just about everything. Our awesome distributor we use at work fabbed/cut pieces for me in a day and then it was off to the assembly area – the area between the couch and the dining room table. Winking smile

TrainFrame

This is also the point where I found out our new puppy hates portable drills..

PixelDeWalt

OK, so one problem.

I set up the Nestle train and… it didn’t work. Either the engine or the controller didn’t work. Still not sure what the issue was, but I had come too far now to abandon this one.

This was Saturday. I had the rest of the night and Sunday to finish this thing. I called The Train Loft in Winston-Salem Saturday evening. They were closing in 15 mins but Jeff stayed late so I could come get another train. They had an amazing display – not something I was going to attempt:

TrainLoftDisplay

Anyway, Jeff hooked me up with a Polar Express train set, and tricked up the track a little bit with a figure-8 instead of just the oval. Project officially over-budget at that point, but hey, Polar Express and Christmas go together, right?

Controlling the Train Throttle

What I thought was the easy part actually became the hardest. Turns out that train voltage is weird in a lot of ways (this train used AC, not DC), and controlling it via a computer is not that easy. I looked at various options for this, even trying to use an AC dimmer limited in software as to not overload the train. This got risky quickly, so I opted for a more simple mechanical control on the actual train controller. I pulled out the Lego Mindstorm NXT programmable controller and modified the train controller handle to attach to NXT…

The before:

LionelController

The after:

LegoController

While it looked cool, the “conveyor track” had a lot of slippage in it. Had to modify it further to couple the servo motor directly to the controller, and then I was in business.

Controller2

Making it into a Game

So, now I had a “motion percentage” to use as a throttle value, a way to control the train via software, and a mounting rig.

Now, I just had to make it into a game. So I wrote an app with this workflow:

  • Plays a Polar Express intro clip with the instructions (“move your body to make the train go”)
  • Gives a 3, 2, 1 countdown
  • For 30 seconds, enables Kinect, plays a Polar Express theme song while the train runs, displays the “motion percentage” in 0-400mph (yes, not really to scale, but hey…), and displays the “distance traveled” by the train
  • After 30 seconds, stop train and display high scores (how far the train went in the 30 seconds)
  • Repeat

Deploy!

I wrapped all that up, and our awesome Christmas for the City volunteers helped set up the rig at the convention center. Here are some pics of what it looked like:

TrainRig1

TrainRig2

TrainRig3

TrainRig5

Overall, this worked out great. It was a self-contained rig most of the time running one “round” every minute. Kids participated in nearly every round in the 6-hour period during the event. We had groups of kids competing, groups of adults competing, and a few “die-hards” with sweat pouring down their faces, and most of all a ton of smiles.

One of my favorite parts of the night was when one kid came over and played a few rounds, and then went to see Santa across the room and asked him for “a Polar Express dance game just like that one”.

All in all, I think I achieved the initial objectives, and combined some great hardware components together in a short amount of time!

Visual Studio tip: Turn off #region when generating interface code

I’ve gotten to the point where I don’t like #region tags in code – it’s what you do when you need to sweep some code under a rug.

As such, it’s really annoying to me when implementing an interface and VS generates nice #region tags all the time.

Props to this StackOverflow question/answer for the solution.

Tools > Options > Text Editor > C# > Advanced > uncheck “Surround generated code with #region”.

image

Dear Adobe: This is NOT okay

According to RIAStats.com, Adobe Flash is installed on over 96% of computers.

That’s why I was astonished at the most recent Flash update to 10.1. This morning I was prompted to update Flash because of a security issue via the latest update of Firefox. No problem, however, this was the first clue that Adobe was starting to abuse their place as a popular browser plugin:

image

See that? By default, “Include in your download” – McAfee Security Scan Plus. I’ve used McAfee. I’m not fond of their software. I don’t want it. I just want Flash. No problem… I unchecked “Include in your download” and downloaded Flash player.

So then I downloaded the Adobe Download Manager (let’s not get into the pet peeve of downloading a downloader), and to my surprise:

image

Flash Player at least asked me to accept the license terms. Not only did McAfee Security Scan Plus download and install automatically when I specifically unchecked that option – it installs quickly and automatically with no confirmation. Almost like they knew I would say no if given the chance.

image

So Adobe, here’s my list of grievances:

  1. Attempting to include third-party software by default, especially when it isn’t related to what I actually want (and you know that), is unethical.
  2. Browser plugin runtimes are to be treated as sacred. We as developers use them to bring great experiences to the web, and in turn, get users to install your product. It is imperative that our users trust your runtime. You have disrespected us, disrespected the users we serve, and destroyed that trust by making such a move.
  3. Waiting until version 10 and 96% browser plugin market penetration to do this is unacceptable. Being the #1 rich content plugin comes with an industry-wide responsibility.
  4. Including the download anyway, when I specifically unchecked the option, turns a previously respected Flash runtime into malware.

Please reconsider this delivery model. This is not about Flash in particular, but it is about users being able to trust the applications we deliver to them. The more we leave users with a bad taste in their mouths after updates, the less they’ll update… and that ultimately hurts us all.

How to: Make a Light Saber from a Wii Remote in .NET (C#)

Here’s a quick and fun project that I just used as a fun coding exercise. I was just walking through Toys R Us the other day, and saw a Light Saber shell designed to enclose a Wiimote. I thought that would be cool, but even though I’m not much of a Star Wars nerd, I do know that most light sabers fall short of a quality audio experience.

So wouldn’t it be cool if my PC could simulate the light saber sound effects from a Wiimote?

Here we go…

Pair The Wiimote with your PC

Your PC needs to be Bluetooth capable (or have a Bluetooth adapter installed). With your Wiimote in hand, press the 1 and 2 buttons until the blue LEDs start flashing. While they’re flashing, you can add it as a Bluetooth device to your PC.

IMG_20100912_222220

If prompted for a pairing code, just select “Pair without using a code”, and the Nintendo input device will appear.

image

image

Plan a little (How to make Light Saber Audio)

A light saber essentially has 2 ongoing sounds. The first is the low, droning “hummmmmmm” that’s always there. So we’ll need a constant “hummmmm” wave file. And the second is a higher-pitched “swing” sound. Our app should just play both in a loop, and increase the volume of the “swing” sound proportional to the amount of motion detected in the Wii controller. Spec – done.

Getting The Code Together

I got the following components to make this come together:

  • WiimoteLib (.NET code library for Wiimote) – http://wiimotelib.codeplex.com/
  • Googled “Light Saber Sound Effect” to find the droning, constant “hum”
  • Found a Sci-Fi electricity sound to be the “swing” (I must admit, this could be better, but it’s good enough for this app)
  • DirectX / DirectSound managed wrappers (Microsoft.DirectX.dll and Microsoft.DirectX.DirectSound.dll)

Use DirectSound and WAV Files

Because we’re looping sounds, we need a bit higher performance than MP3 files and Windows Media Player components. That’s why it’s important to use the DirectSound library with playback loop buffering and uncompressed audio files.

Make sure you compile the application as 32-bit (x86) as DirectX may complain with 64-bit or Any CPU compilation.

Calculating Light Saber Motion

So, I’ve got the following app set up (hit Turn On to enable the Saber sounds, and if you have a Wiimote connected, it will detect it on app startup):

image

To calculate the Wiimote “swing” motion, this gets a little difficult. Wiimotes report what position they’re in (X, Y, and Z) axis, but there’s no way to tell how fast they’re moving through the air (i.e., true acceleration). If you’ve ever been able to trick your Wii and become an accomplished Wii bowler from the couch, then you know what I mean.

So after a few different methods, here’s the way I’ve calculated the Saber “swing” motion:

  • Re-evaluate the Wii controller position no more than every 50 milliseconds
  • Measure the most recent X, Y, and Z positions with the previously reported ones, and calculate the differences
  • Add the differences together (X+Y+Z) to get the cumulative “motion change factor” (I called this the “Saber Force”)
  • Use the “Saber Force” to set the volume of the Swing WAV file.

This works okay, but could probably be improved to make it smoother and more responsive.

Other Notes

I would suggest playing with the “Constant Hum” and “Swing Intensity” sliders after turning the saber on, just to get the feel of how this thing works. Once you hit the “Turn Wiimote into Saber” button, the Swing Intensity slider is disabled and controlled by the Wiimote motion calculations. There’s little to no exception handling or app state management as this is a quick and dirty play application. If you wanted to actually create something with this, it does provide a good starting point with ideas.

Download

Download WiiSaber Source Code (Visual Studio 2010)

The .zip contains the compiled application (if you just want to run it and play), the Visual Studio solution, and the reference DLLs and sound files that I used.

XBox Controller in .NET 3.5 with 3 lines of code

XBox controllers are pretty cool little hardware devices. So why not use them in .NET to control something cool?

XBoxController

The only problem is, there’s not a whole lot of code out there for any recent version of .NET, and nobody really likes learning Managed DirectX for fun… In addition, the bits of code that I did actually find, while useful for getting the hardware connected, felt like hacks to actually use it. So…

I’ve pieced together most of the XBox code into what I hope is a clean, ready-to-use and complete .NET DLL to get connected up to a controller and using it in 3 lines of code. Credit goes to some of the code at MDXInfo for giving me a good head start.

First, download the DLL:

http://static.x9tech.com/XNT/XBoxController/X9Tech.XBox.Input.zip

Add it as a reference to your .NET project. Then, use it like so:

 X9Tech.XBox.Input.XBoxControllerManager xcm = new XBoxControllerManager();
 var controllers = xcm.GetConnectedControllers(); // get the collection of connected controllers
 var controller1 = controllers[0]; // the controller at index 0 will be controller #1
 if (controller1.ButtonAPressed) {
 // do something if Button A is pressed...
 }

 

The XBoxControllerManager class simply has a method to GetConnectedControllers() which gives you a List<XBoxController> collection of connected controllers.

This little library addresses the following common issues when dealing with XBox Controllers…

Percentages instead of raw values – In reality, the thumb pads have values between –32,767 to +32,768. The triggers have values of 0 to 65,000. For all practical purposes, these are pretty meaningless, so these types of ranges are converted to percentages (as a double with crazy precisions). When each thumb pad is at its center position, this is 50% X / 50% Y. So from here on out, we’re going to be talking percentages, mmkay?

Trigger On/Off – Left and right triggers (the little, well, triggers that resemble the trigger of a gun) on the front of the controller) are, in reality, never actually “on” or “off”, they’re in between 0-100%. However, you may notice that the XBoxController class has two boolean properties called TriggerLeftPressed and TriggerRightPressed. These are inferred based on the current trigger percentage value, and two more properties (TriggerLeftPressThreshold / TriggerRightPressThreshold), which define the minimum percentage values the trigger needs to meet in order to be considered pressed. Defaults to 10%, as I found this was a pretty comfortable place to consider it “pressed”.

Dead Zone – The thumb pads do have springs to snap them back to “center”. However, with 65,535 positions on each axis, rarely will “center” ever mean the same thing twice. If you’re counting on 50/50 being “no thumb on the thumbpad”, this will drive you insane. So, I needed some kind of a ‘dead zone’ to go ahead and assume 50/50 when it’s in the “close enough to be considered the center” area. Through sheer trial and error I determined that a reliable center is anywhere from a 40% to 60% position. If you want this to be more or less sensitive, just set the SnapDeadZoneTolerance property. The tolerance is the percentage value that we consider to be in the “dead zone” on either side of 50%. So, for a Dead Zone Tolerance of 10, this means “10% on either side of 50%”, so 40% – 60%. A tolerance of 5 would mean the dead zone is between 55% – 65%, and of course a tolerance of 0 would disable the assumed dead zone.

Controller Polling / Refresh – To get new controller state information, we have to poll the XBox Controller. This little library will handle it automatically, so you can just grab properties and go. By default, this will poll the device a maximum of every 30 milliseconds. This felt comfortable to me, but if you need faster or slower polling, just adjust the RefreshIntervalMilliseconds property.

Controller Connect/Disconnect – At some point, your user will disconnect the controller while your application is using it; nothing should crash, and the controller’s IsConnected property should return false once it’s disconnected with no blow ups. Reconnection happens automagically.

Vibration Motors – The XBox Controller has 2 vibration motors, a left and right. The left motor (let’s call it “the big vibrations”), when set to 100%, will send your XBox controller walking across whatever surface it’s on. The right motor resembles what’s in your cell phone. You can set the motors (again, with percentages here) by calling SetLeftMotorVibrationSpeed() and SetRightMotorVibrationSpeed().

That’s about it. If you use this library and there’s anything I have forgotten, I’d love to hear. Happy coding!

How I made a Giant Walking Piano (with C#)

I had 2 projects this year for Christmas for the City – first, the online streaming, and second, to take my idea of a giant walking piano (like in the movie Big), and turn it into reality. The main purpose of this was twofold – first, to give kids a feature that uses interactive technology to bring a smile to their faces, and second, for me to learn what works and doesn’t work well when it comes to interactive displays for projects down the road.

BigPiano

The basic idea is this: Kids walk across the keys of the piano, activating some kind of a pressure sensor, and the keys light up and the key’s sound plays. Sounds fairly simple, right? In all reality, it’s a lot harder than it looks in the movies. 🙂 I decided to go with a 16-key piano (to give me 2 octaves), and to make the design a lot simpler, just to skip the black keys altogether. While I didn’t expect to end up with something as elaborate as this picture, I did intend to create the same experience for a person walking across it.

The Keys

First, the material for the “keys” needed to be lightweight but strong, and readily available. I settled on a Lexan material from Lowe’s. They come in 18” x 24” rectangles, which, when cut in half, give you a 9” x 24” piano key. CFTCPiano012 feet seemed to be wide enough for my purposes, so the next step is to find the best way to let it ride above some kind of a switch, and let it hit the switch when a few pounds of pressure are added to it (i.e. a child’s foot).

The picture to the right is when I was testing it in my living room. I had a curved plastic stand that some time ago held a cable modem or access point or something, and I experimented with a couple of different types of switches.

The Switches

The most readily available supply of switches came from Radio Shack, but like a lot of things from Radio Shack, not all of them were all that great. The general idea here is that the switches would be recessed into the piano wood just enough to allow them to be pushed, but not damage them.

RSSwitch1

The first contender was a Radio Shack Mini SPST Momentary Pushbutton Switch (275-1556). At less than $3 a piece, this appeared to be what I was looking for, but was actually a massive fail. You have to push these down so hard, and even when pushed down, the “momentary contact” isn’t even that consistent, so I wasn’t comfortable trying to make this actually work.

RSDetectSwitchThe next type of switch I tried was a SPST Detect Switch (275-008).  It’s a little pie shaped switch that gets pushed down into the casing to activate the momentary contact. This had the response I was looking for and took very little travel before the contact was connected. I decided to go ahead and roll with this. The only problem was, most Radio Shacks only stock about 3 of these at a time. It took about a week of visiting Radio Shacks in 3 cities to accumulate enough of these things to wire up 16 keys. At one Radio Shack, someone had stolen all of them and left the plastic packaging behind. Nice.

Now, it was time to make…

The Frame

CFTCPiano02

The idea here was pretty simple. Get a few 14-ft 2×4’s, and space 2×4 supports every 9” where the edges of the keys rest on them. Mount the sensors in the supports and off we go, piece of cake.

I learned a valuable lesson here – measurements are never always exact. I tried to build the frame first, measure it out, attach it, and then put the keys on, expecting everything to line up perfectly. There is apparently a law of woodworking, and a law of Lowe’s lexan products, that measurements don’t always come out like they do on paper. Add in a little bit of warping wood, and I rebuilt this frame twice before I figured out that I should build and fit the frame around the keys, instead of trying to stay in my idealistic happy bubble where everything works out like it does on paper and fairies dance around singing duets with unicorns.

CFTCPiano03

Here is where I got the first few keys fitted, and it starts to look like the top of a keyboard.

 

 

 

CFTCPiano04

To hold the keys in place, I used molding from Lowe’s. Cheap stuff and worked great for keeping the keys from shifting around.

 

 

Wiring It Up

CFTCPiano05

The next step, while the framing was fairly accessible, was to go ahead and get the wiring harness in place. I started out using 1-conductor solid wire, running 2 wires to each key, and after 3 keys, realized this would be a complete and unmanageable mess. I switched over to using A/V 2-conductor + ground install cable (XLR audio cable) that I had left over from an old install. This made things a lot more manageable by keeping it to 1 cable per key.

CFTCPiano06

This added some thickness to the cable that I didn’t really anticipate, so a few extra holes and it worked out fine.

 

 

 

 

 

CFTCPiano07

For the actual switches, I carved out a slot in each key support with a Dremel router bit. I left just enough clearance on top for the sensor switch to stick up above the top of the wood. I also found that chunks of foam weatherstrip (the kind you would stick around your home windows to seal them) worked great for the keys to ride on. It held the weight of the lexan above the switch, but also compressed enough for it to hit the switch with no problem.

CFTCPiano08

Also, these switches had a hole on the left side of them that I used to tack a short nail through. This held it in place quite nicely.

 

 

CFTCPiano09 Once these were in place, I soldered the key cables up to the switches, which completed the wiring for each key. Once stapled and labeled, it ended up looking pretty clean. This part of the design was very solid and worked extremely well.

 

 

 

Once I attached the keys, it ended up looking like this…

CFTCPiano10

The Microcontroller

This piano was to be computer controlled. The main challenge here is how to make the piano talk to the computer. I wanted to do this via USB… so the plan was:

  1. Get enough inputs together on one microcontroller to sense on/off for 16 piano keys.
  2. Write a simple .NET Micro Framework controller OS that will sense these and notify the computer via USB.
  3. Write a host application on the computer that will talk to said microcontroller and take actions (play sound, turn on lights).

I went down this road, looking at Digi Connect, Tahoe, Arduino, etc, and after longer than I care to admit, realized something… what’s a microcontroller that speaks USB, just has a bunch of on/off contacts, is cheap, and readily available? A computer keyboard.

Things just got a LOT simpler, with a $12 Logitech keyboard from Wal-Mart… or so I thought. I didn’t have a whole lot of time to finish this, so this decision was final, and could probably be considered one of the best from a cost/simplicity standpoint, and one of the worst from a design standpoint.

A computer keyboard is actually really, really simple. When you type, your keys simply push two plastic sheets together that are less than a millimeter apart. When certain spots (where the keys are) connect, this connects 2 pins together on the keyboard circuit board. It’s this combination of pins that determines which key value to send to the computer over USB.

ComputerKeyboardCircuitBoard 

The new plan was:

  1. Rip out the controller, and solder cables to the controller contacts.
  2. Wire the piano key switches to a combination of contacts.
  3. In the computer, map certain keys to notes and lights.

There are 2 parts of a keyboard controller that really made this plan suck:

  • These boards aren’t designed to be soldered. The contact surfaces are really, really close together, making it darn near impossible to get soldered cleanly without shorting two contacts together.
  • These boards are cheap and fragile. In all reality, they don’t have to be robust – a plastic sheet lays against them and that’s pretty much it. But once I soldered cables on, the slightest pull and the copper contacts would simply peel off.

It was too late for me to change it by the time I realized these 2 major points (okay, it was the night before the event, because I thought this would be super easy and left it to the last minute), so I rolled with it. After soldering on 20 wires, out of a possible 108 key combinations, I ended up with about 22 working key combinations. Some of these were special keys (tab, shift, etc) that I didn’t want to use, but I ended up with exactly 16 letters. Score. Once connected, I could step on piano keys, and type random letters into Notepad. I was home free on the “input” side of things at this point.

Now on to the software…

Making Sounds

I used MIDI to make the sounds on the piano. I used an open-source library called NAudio to drive MIDI sounds. NAudio is a wrapper for DirectSound and runs as a 32-bit target. There are tons of tutorials on controlling MIDI, so I won’t cover that here.

Controlling Lights

In the hollow space below the keys of the piano, I filled it with Christmas lights. At Wal-Mart, a pack of 100 Christmas Lights was about $1.50, so they became a cost effective lighting medium. I connected these up to DMX-controlled dimmers. For those not familiar with DMX, it stands for Digital MultipleX protocol, and is the standard communication protocol used in production lighting systems today. It is really RS-485 (in essence, RS-232 that can daisy chain to up to 32 devices together and travel 1000 feet without loss) running a constant stream of byte values that represent sequential channels and their current control/intensity value.

Most programmers today don’t often come into contact with lighting control protocols used on large intelligent lighting and dimming systems, so there’s not a whole lot of code out there to work with it. There are really 2 ways of having a normal computer talk to lighting systems:

  1. Through a DMX-over-Ethernet protocol called ARTNet. This requires an Ethernet network, and a converter that will translate Ethernet DMX packets into RS-485 DMX traffic to get to the dimmers. The converters usually run between $300 up to $5,000.
  2. Through a USB DMX device.

My office lights are already controlled via ARTNet, and I already had code for it, but the converter cost was a deterrent for this project. Keeping costs to a minimum, I went the USB DMX device route with a really cheap device – the Enttec Open DMX USB. Enttec has simply taken a chip from FTDI (232BM) that is a USB to RS-485 converter.

The major pain point here is that FTDI only offers unmanaged code DLLs to work with, and a C# wrapper for it that was mediocre and halfway-working at best.

Low-level, byte-by-byte programming using non-managed Interop is pretty much not my cup of tea, but to make a long story short, I decided to stick it out and coded a serial communication wrapper in C# based on the DMX protocol spec, and 6 hours and lots of frustration later, some lights were coming on!

CFTCPiano12

Putting It All Together with Software

The lighting code took a LOT longer than I thought, and truth be told, I still hadn’t written the software to put this all together and actually make the piano come alive an hour before the doors opened for the event.

Using a simple .NET dataset, I constructed a XML file format that looked like this:

<PianoKey>
  <KeyNumber>0</KeyNumber>
  <MIDINote>60</MIDINote>
  <KeyboardCharacter>i</KeyboardCharacter>
  <DMXChannel>0</DMXChannel>
</PianoKey>
<PianoKey>
  <KeyNumber>1</KeyNumber>
  <MIDINote>62</MIDINote>
  <KeyboardCharacter>r</KeyboardCharacter>
  <DMXChannel>1</DMXChannel>
</PianoKey>

I made a very quick Windows Forms application that took the keyboard input (key down / key up events), adjusted the DMX output to light up the key, and played/stopped the specified MIDI note value. This application looked like this:

image

One of the problems I had to solve was key repeat – when you hold a key down in Windows, Windows will automatically repeat the key every few milliseconds. Each repeat is actually fired as a separate KeyDown event on the form. A simple array of “currently pressed keys” solved this pretty quickly, but there was somewhat of a limit on how many keys could be processed at a time because of this.

By the time I finished tweaking, it was literally minutes until the doors opened. The application actually ran in Visual Studio debug mode the first night, until I got it transferred over to a netbook to run the other 2 nights. One of the unintentional but nice side effects of running it straight out of Visual Studio became the ability to update the code whenever a wave of people left the room. 🙂 So, about halfway through the first night, I added a little timer to change the instrument every 30 seconds. Interesting side note here – MIDI bagpipes are a great way to clear out the room quickly to make room for the next wave to come in. There’s not much more annoying than a high-pitched bagpipe note from a kid sitting on one of the keys and not moving.

Below is the video of the finished product in action:

 

Lessons Learned

  1. Find a better microcontroller than a computer keyboard with small solder points.
  2. A giant piano made out of 2×4’s, lexan, and dimmers weighs in at over 350lbs and is very awkward. (Thanks goes to the 8 people who helped get this thing up and down the stairs since it wouldn’t fit in the elevator.)
  3. The weather strip started to wear out after a few nights of beating and some had to be supplemented when keys would start to stick. I would use larger strips next time.

The piano was a great success. It did exactly what it was supposed to do, and brought smiles to a lot of kids faces. Can’t wait to use the experiences gained from this project to make something else.

How we did Christmas for the City Streaming (The Technical Details)

For the past 2 years, my church has hosted an event called Christmas for the City. A few hundred volunteers and about 30 other churches partnered with the event from around the area to take over a downtown building for a few days, providing support and resources for people in hard times in Winston-Salem, and a really unique Christmas experience composed of music, art, dance, literary works, and a ton of other features.

One of the goals for 2009 was to bring the event online in a bigger way with a few online streams that would let a virtual visitor surf through some of the main areas with just a couple of clicks. This blog post describes the process of how we ended up with what we did, and some of the challenges to solve for the next event of this type.

The Stream Team

This year’s streaming was very much a team effort, and everyone involved donated a lot of time and resources into making it happen. It wouldn’t be right in finishing this post without props going to:

  • Sean E. – Sean serves as an engineer for Microsoft and provided vision, hardware, some Windows 7 boot-to-VHD ninja, and way too much effort working with Time Warner Cable.
  • Sammy E. / Triad Tech – Sammy, with Triad Technologies, provided wiring through 3 floors of the Millennium Center, giving us the backbone we needed to establish a real network.
  • Jason H. – Silverlight kung-fu, getting the initial application prototype built and into the wild based on some of my very “loose” specs…
  • Brandon M. – Streaming support throughout the event
  • Dillon M. – Mobile Cam Driver
  • WSF Media Team (Aaron R., Chris E.) – These guys rocked the tech world with some awesome animation, and provided cameras and various other accessories and support.
  • X9 Technologies – X9 provided the network infrastructure, access points, servers, bandwidth, and code to get video out of the building and across the ‘net.

Location, and Wireless Networking

MillenniumCenter-NuclearFalloutShelter The Millennium Center in downtown Winston-Salem is the location of the event. It’s an extremely “historical” building with lots of “character”. We needed a solid wireless network to build on, and it didn’t exist in this building. The “character” (marble floors, walls, solid ceilings, 3-ft thick plaster walls) meant 2 things – first, it was designated as a nuclear fallout shelter, and second, RF doesn’t work like you would expect in there.

 

CiscoAironetSince wiring is pretty difficult and we only really  had one point of access to each floor, the strategy we went with was to cover the “main” area of each floor with one Wireless Access Point. We used three Cisco Aironet AP’s. Power was really not available or not convenient next to the network drops, so we solved this with the magic of Power over Ethernet (PoE). To get the best performance out of these for general internet access (below 5mbit), they were optimized for range instead of speed.

Windows Media vs. Flash

Of the streaming options out there right now, the two most viable options are Windows Media and Flash. When it came time to decide between the two, I was kind of 50/50 on both, with a slight tendency to go toward Flash, just because it had the larger install base and generally “just works” (most people have watched a YouTube video on their computer, so they already have what they need). Sean suggested using Windows Media with Silverlight. While we probably could have accomplished the same thing with Flash, we decided to create the player interface with Silverlight, and be able to pretty carefully control the user’s experience. The decision to go Silverlight over Flash pretty much came down to Silverlight and the underlying .NET stack offering us very rapid development that we could rely on without a whole lot of testing and tweaking. Although we knew some users would need to go through the Silverlight install, it was worth the tradeoff.

The Interface

Here’s a screenshot of what the final looked like:

CFTC Streaming Screenshot

The interface is pretty straightforward. The user can select between 3 different camera streams (originally Party Room, Performing Arts Stage, and Multi-Cultural Room). In the upper right hand corner, a real-time scrolling schedule is kept in sync with the event as it happens, so the user can check out whichever scheduled artist they want. In the lower right hand corner is the Twitter integration, displaying tweets from Twitter’s search API that contain the hashtag #CFTC.

Testing

I had a little bit of dumb luck when it came to testing this application before the event. The Friday before, we had a pretty good snowstorm here in North Carolina (which never happens), so I used that opportunity to set up a camera and turn it into a “snow cam”. This gave people a reason to go and visit the application to see the snowfall, and gave me some valuable feedback via comments and logs of how many people had Silverlight installed, and whether or not everything was working as expected. Surprisingly, not one person had a problem viewing it out of a couple dozen. Success.

Failover Streams

The only problem with Windows Media Services is that when a stream ends (i.e. in the event of a network interruption), it gets pretty ugly. The player usually just freezes on the last frame, or displays an ugly error message, which is obviously not ideal. The first night, I ran out of time to implement a static failover stream, but by the second night I was able to have it in place.

This is a fairly undocumented method in Windows Media Services, but it requires 2 publishing points. First, the publishing points for the “live cams” (we called them CFTCCam1, CFTCCam2, and CFTCCam3), and second, the publishing points for the “broadcasts” with failover (we called them CFTCBroadcast1, CFTCBroadcast2, and CFTCBroadcast3). The “broadcast” publishing points are actually a Windows Media Server Side Playlist (.WSX file) that contains a <switch> statement with a loop. So, the Broadcast publishing point will try to play the “live cam” feed first, but if it’s offline, it will switch over to a static .WMV animation file (the Christmas for the City animation).

The only caveat by doing this is that you really have to keep the “failover” file short, as it must play through all the way until the server attempts to switch back over to the “live” stream. We kept ours down to about 25 seconds (the animation followed by a quick “hang tight!” message), and I considered this acceptable.

Encoding

ExpressionEncoderEncoding was done with Microsoft Expression Encoder 3. This is a fairly new product in Microsoft’s Expression line of design tools, and it’s a fairly slick interface (major improvement over Windows Media Encoder 9).

We had 3 computers (2 desktops and 1 laptop, 2 running Windows 7 and 1 running Vista), with Sony HVR-1 cameras using FireWire for input. This gave us a pretty good video source with the camera audio taking XLR output from the audio console(s) or camera mic.

I have to say, while Expression Encoder is a great interface, it had its share of “isms”. First, after installing it on a clean Windows 7 or Vista machine, using it in Live Encoding mode with our FireWire cameras, it would crash hard every time we pressed “Start Streaming”. This was fixed pretty easily by installing a QFE found here. Also, it generally does not deal with network hiccups very well. Again, we’re 100% wireless in a nuclear fallout shelter, so whenever there was a hiccup, the stream would die, and our only clue would be a little line of red text next to the Publishing Point output with “Unspecified Error”. Also, the “remember password” option when setting up Publishing Points just plain doesn’t appear to be hooked up, so this became an annoyance with our volunteer team that helped set up and maintain the streams throughout the nights. Overall, these were just slightly annoying problems that I’m sure will be fixed in time in an otherwise great piece of software.

Stats

We watched stats in realtime during the event through X9’s Streaming Client Center. This hooks into the backend of the streaming servers and cross-references IP addresses with X9’s Geomap database to give us an idea of our traffic on each of the 3 feeds. We could also overlay the data on top of a Google map to impress people.

 imageimage

The Mobile Random Cam

Watching our stats on Monday, while people were frequenting the Party Room and Performing Arts Stage, we noticed that no one was really watching the “Multi-Cultural Room Cam”, which is a camera in a room with an 8-ft ceiling and is pretty narrow. There was no board audio feed on it, and most of the time it was just people standing around in front of the camera.

Tuesday morning, I was helping unload 25 bags of Chex Mix and 20 gallons of Apple Cider from my wife’s car into the Millennium Center, and was attempting to use a caster plate the production company used to cart around truss. By about the 3rd time everything had fallen off, I got frustrated, and went and found a large catering cart. Pushing the cart around, through the elevator, and on to the second floor, I was thinking “man, wouldn’t it be awesome if people online could just virtually ride around on a cart like this……”, and later that evening… ta-dah:

RandomCamCart

On the back of the cart is a laptop running Expression Encoder, and on the front is the Sony cam. Each laptop would last about 2 hours, so we switched between Sean’s small Lenovo and my personal Dell Precision. We needed something to get the camera lens above the cart handle, so I found a cardboard box. Dillon found a bungee cord in his truck to keep the camera from flying off. The Mobile Random Cam was born.

The stats on the mobile cam were pretty funny. Viewers immediately loved it and started watching it more than the other 2 static feeds. Then we’d go into an elevator, lose our WiFi signal, lose all of our “fans” to the other feeds, and they’d join us back a few minutes later. I think the random-ness combined with the comedy of watching as Dillon and I try to navigate this cart through thousands of people, up and down stairs, and interviewing pretty much everyone we ran into made this stream pretty entertaining. Oh, and we had a blast doing it.

That’s It.

This pretty much sums up the CFTC streaming… by all means, it was a great success, and our team was awesome. We definitely pushed the limits of wireless, Expression Encoder, and put a few miles on a catering cart. Can’t wait to do it again for another event!

Random Contact Data Generation in C# / VB.NET

I wanted to generate random contact data (you know, first names, last names, city/state/zip and phone numbers) in .NET, and I found a few little snippets, but nothing really comprehensive.

I wrote these little methods to do this to save me (and maybe you) some time in the future. It’s obviously very easy to add more data to them depending on your needs. It generates things like this (just a few examples):

Michael Jones
461 Second Dr
Los Angeles, AK 12422
124-851-3783
James Smith
532 Sixth St
Columbus, LA 44714
446-576-5437
Richard Harris
261 Elm Pkwy
Las Vegas, OH 77006
769-302-7091
Patricia Thomas
68218 Maple Pkwy
Boston, NE 62280
944-388-4109
Elizabeth Martinez
332 Ninth Blvd
Sacramento, VT 79846
797-749-8472
Daniel Martin
65363 Elm Blvd
Tucson, CT 22140
221-474-1127
Robert Williams
403 First Dr
Milwaukee, MN 54432
543-200-2781
Joseph Taylor
133 Seventh St
Jacksonville, IA 39706
396-561-7144
David Miller
5542 Eighth Pkwy
Portland, NC 71998
719-286-8798
Linda White
844 Second Dr
Los Angeles, AZ 14291
142-911-1453

In C#… (see VB.NET down further)

        private Random GetRandomizer()
        {
            System.Threading.Thread.Sleep(1);
            return new Random(DateTime.Now.Millisecond);
        }

        private string GenerateName()
        {
            return GenerateFirstName() + " " + GenerateLastName();
        }

        private string GenerateFirstName()
        {
            string[] fNames = { "James", "John", "Robert", "Michael", "Mary", "William", "David", "Richard", "Charles", "Joseph",
                    "Thomas", "Patricia", "Christopher", "Linda", "Barbara", "Daniel", "Paul", "Mark", "Elizabeth", "Jennifer"};

            return GetRandomValueFromStringArray(fNames);
        }

        private string GenerateLastName()
        {
            string[] lNames = { "Smith", "Johnson", "Williams", "Jones", "Brown", "Davis", "Miller", "Wilson", "Moore", "Taylor",
                    "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", "Thompson", "Garcia", "Martinez", "Robinson"};

            return GetRandomValueFromStringArray(lNames);
        }

        private string GenerateStreetNumber()
        {
            Random r = GetRandomizer();

            StringBuilder sB = new StringBuilder();

            for (int i = 0; i <= r.Next(2, 5); i++)
            {
                if (i == 0)
                {
                    // don't use a 0
                    sB.Append(r.Next(1, 9).ToString());
                }
                else
                {
                    sB.Append(r.Next(0, 9));
                }
            }

            return sB.ToString();
        }

        private string GeneratePhoneNumber()
        {
            Random r = GetRandomizer();
            int areaCode = r.Next(100, 999);

            if (areaCode.ToString().EndsWith("11"))
            {
                areaCode = areaCode + 1;
            }

            return areaCode.ToString() + "-" + r.Next(100, 999).ToString() + "-" + r.Next(1000, 9999).ToString();
        }

        private string GenerateStreetName()
        {
            string[] popularStreetNames = { "Second", "Third", "First", "Fourth", "Park", "Fifth", "Main", "Sixth", "Oak", "Seventh",
                            "Pine", "Maple", "Cedar", "Eighth", "Elm", "View", "Washington", "Ninth", "Wall" };
            string[] streetSuffixes = { "Dr", "St", "Pkwy", "Blvd" };

            return GetRandomValueFromStringArray(popularStreetNames) + " " + GetRandomValueFromStringArray(streetSuffixes);
        }

        private string GenerateAptOrSuite()
        {
            Random r = GetRandomizer();

            string[] prefixes = { "Apt", "Ste", "Bldg" };
            string[] suffixes = { "A", "B", "C", "D" };
            int numericalVal = r.Next(1, 300);

            return GetRandomValueFromStringArray(prefixes) + " " + numericalVal.ToString() + GetRandomValueFromStringArray(suffixes);
        }

        private string GenerateCity()
        {
            string[] cities = { "New York", "Los Angeles", "Chicago", "Houston", "Philadelphia", "Phoenix", "San Diego", "San Antonio", "Dallas", "Detroit",
                         "San Jose", "Indianapolis", "Jacksonville", "San Francisco", "Columbus", "Austin", "Memphis", "Baltimore", "Milwaukee", "Fort Worth",
                         "Charlotte", "El Paso", "Boston", "Seattle", "Washington", "Denver", "Portland", "Oklahoma", "Las Vegas", "Tucson",
                         "Long Beach", "Albuquerque", "New Orleans", "Cleveland", "Fresno", "Sacramento", "Mesa", "Atlanta" };

            return GetRandomValueFromStringArray(cities);
        }

        private string GenerateState(bool abbreviationOnly)
        {
            string[] states = { "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida",
                         "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
                         "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire",
                         "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
                         "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin",
                         "Wyoming" };
            string[] stateAbbr = { "AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL",
                         "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KT", "LA", "MN",
                         "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH",
                         "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI",
                         "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA" };

            if (abbreviationOnly)
            {
                return GetRandomValueFromStringArray(stateAbbr);
            }
            else
            {
                return GetRandomValueFromStringArray(states);
            }
        }

        private string GenerateZipCode()
        {
            Random r = GetRandomizer();

            return r.Next(10000, 99999).ToString();
        }

        private string GetRandomValueFromStringArray(string[] sArray)
        {
            Random r = GetRandomizer();

            return sArray[r.Next(sArray.Length)];
        }

Sometimes the ancient way just works better

For an application in .NET Compact Framework, I need to load about 10MB worth of data stored in XML files into datasets. On a desktop, it takes approximately no time to load that data into a dataset, or write it back out to a XML file.

I thought to myself, “since this worked in less than 1 second on a PC, I should be able to do this on a mobile device in maybe 5-10 seconds” – acceptable for an application startup time. Right? Wrong. Try over 4 minutes. Nothing fancy, just a DataSet.ReadXml() and then iterating through and validating data.

Right now, you’re thinking to yourself (because I’m writing this I get to choose), “why not use SQL CE or something?” – because the sole purpose of this data is to get enough data loaded into memory to get a head start on synchronizing it with the server, and SQL CE is not worth getting into as a dependency for this task. It’s supposed to be as simple of a process as possible.

“Oh, that makes sense,” you think. Thank you.

Knowing that 4 minutes for an applicaiton startup was a little bit excessive, I spent a few minutes turning it into a tab-delimited file instead.

The results? All the data loaded in 20 seconds. It’s not fancy, it’s not flexible, but it works. And that’s what I care about at the end of the day.