1

xboxcontroller

The folks developing SharpDX do a fantastic job of a .NET Managed DirectX layer. I’m an impatient person, and I think XBox Controllers are awesome input devices. So, here’s a library available as a NuGet package that builds upon SharpDX and boils it down to super-simple code; scientific studies have shown that the average developer can now use an XBox Controller in under 60 seconds.

Like, if you wanted to find out if Button A was pressed on the first connected controller:

var myController = BrandonPotter.XBox.XBoxController.GetConnectedControllers().FirstOrDefault();
if (myController.ButtonAPressed)
{
// do something if button A is pressed
}

Now that I teased you, go get it off NuGet here:

https://www.nuget.org/packages/XBoxController

… or go fork it and improve it here:

https://github.com/BrandonPotter/XBoxController

But wait, there’s more. XBox controllers are tricky. This little library addresses the following common issues when dealing with them…

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 andTriggerRightPressed. 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 theSnapDeadZoneTolerance 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!

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!

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.