Friday, June 26, 2015

Building an Interactive SVG Pie Chart with Asp.Net MVC Razor and C#

In one of my recent web development projects I set out to redesign a basic pie chart. The previous implementation was generated by a javascript framework that did more than it was used for, and lacked some of the flexibility that we wanted. So for the rewrite I decided to simplify the code, and take an opportunity to learn more about SVG graphics.

Bear in mind as you read this that it's all still pretty "fresh" ...the code probably can (and should) be refactored. But this should serve as a good basic introduction. There are a number of good tutorials on the web for generating SVG pie charts. This post focuses on my implementation using Asp.Net MVC, C#, and Razor. WHat you'll see below is the combination of various bits of knowledge gathered from around the web and a fair amount of tinkering and troubleshooting. I think the final result looks pretty nice, so I figured it was worth sharing.

Why SVG? Because it's a vector-based image, it can scale up or down and never get pixellated, and looks good on any screen from desktop to mobile. The image data itself is very minimal, and because it can be written inline with your HTML, it doesn't require extra HTTP calls. The SVG code itself is pretty simple as well, so I don't need to rely on more intensive server-side image generation code. There are plenty of reasons why SVG is cool, but those are just a few that come to mind right now. SVG is pretty widely supported now across all major browsers except IE8, which at least for my current project I don't need to worry about.

I started out by writing a basic C# class to hold all the relevant information needed for a simple pie chart:

Having this dedicated PieChart class allows me to generate pie charts throughout my application in a consistent way. In my MVC controller, I can build a view model for the page, and include a PieChart object. Then, in my Razor view, I can add a simple call to "DisplayFor" to generate the inline SVG, using a shared display template.

The bulk of the code lives in the shared razor template in Views/Shared/DisplayTemplates/PieChart.cshtml

To keep everything fairly self-contained, I decided to include the SVG-specific C# code right in the Razor file. While this may not adhere very well to separation of concerns, it certainly helps with manageability and making it easier to follow/understand. A fair tradeoff if you ask me. Here's the entire Razor file. I'll explain each section below:


@functions

Normally I don't put complex functions in my razor views, so I didn't know the "@functions" block existed until now. For this application it was the perfect container for some simple trigonometric calculations.

PieSlicePathDesc

In SVG, we can use the path element to define complex shapes. In this case, we'll need to generate multiple "pie slices". This function does the math to calculate the x/y coordinates of each point, and outputs the path description in SVG's language. Basically the path description boils down to these instructions:

  • Start drawing at the center of our pie chart
  • Move to a point on the outside of the circle
  • Draw an arc with a given radius until we reach the next x/y coordinate
  • Draw a line back to the starting point to complete the shape

With all this logic defined here, we can easily call it in the razor markup later.

startAngle

For my pie chart, I want the first slice to start at the top of the circle. Here I set the starting angle.

svg

With most of the code out of the way, we can start generating the actual SVG tags. For a great reference to all the SVG tags and attributes, check out MDN's SVG Element Reference. The viewBox attribute defines the limits of the image using the SVG's internal coordinate system. I sized this image to have a padding around the outside equal to 10% of the radius. This comes in handy later for our hover effect.

style

Here in the SVG I embedded some CSS styling to apply a consistent style to all the pie slices, mainly to give them all a white outline.

@foreach loop

Using Razor, we can easily enumerate over the collection of PieChartSlice objects and generate the SVG paths.

g (Group) element

This is a basic SVG element to group together other SVG elements together. This allows us to combine the pie slice, as well as a tooltip and some hover animation elements.

title element

In SVG, the title element acts much like the title attribute in HTML. In most browsers this text will appear as a tooltip when the mouse hovers over it. I could have used other elements to write the text on the image, but I decided to keep it hidden to keep the image clean and uncluttered. If the user hovers over the pie slice, they can see the label, the value, and the percentage. The text is also available to screen readers and other web accessibility tools.

circle or path

In the event that our pie chart's data set only contains one item, we only need to draw a full circle, not a slice.  If we are generating multiple slices, the SVG path is used, and calls the PieSlicePathDesc method we defined earlier.

Hover animations with animateTransform

To add a little interactivity, I wanted to add a hover effect to each pie slice, where the slice would expand outward while hovering over it. To do this I added some animateTransform elements to the group containing the pie slice. There is one animation that expands from the center by 5% on mouseover, and another animation that shrinks back down on mouseout.

Finished!

My final implementation was a bit more complex. I added some code for generating the pie slice colors and some other changes specific to my project, but this should give you a basic idea of how it works.

To see the final result, below is some actual inline SVG generated by this code:

Thinking: 0:38:39 (39.3%) Writing Code: 0:34:16 (34.9%) Researching: 0:11:33 (11.8%) Refactoring: 0:09:52 (10%) Getting Distracted: 0:03:54 (4%)

Wednesday, September 24, 2014

My new Wood LED Clock - Sparkfun Clockit Retrofit

I always enjoy a good project; a chance for me to make something new and work with something new in the process. These days I have several longer-term projects in-progress, so once in a while I enjoy working on something smaller that I can finish in a short time. This time it's my new wood LED clock project.


The Inspiration

First off, this is not a new idea by any means. I've seen these kinds of clocks around before, but hadn't considered making one until now. Recently I came across a website and youtube channel called "I Like To Make Stuff". Besides the fact that this statement perfectly describes me, I can also identify with the host/creator Bob Clagett. He's a father, software developer, and creative DIY'er like myself. Not long ago he posted a video on How to make a wooden digital clock that walks through the process.

The main driver for me was that I already has the most important part... a barebones clock. A few years ago I bought the ClockIt kit from Sparkfun when I was first getting into microcontrollers. I soldered it up, and then it sat on my workbench, mostly unused and ignored ever since. So I figured, why not retrofit this into a wood clock and put it up on my desk at work?

Reworking The Clock

The clock itself had a few issues that would make it difficult to place behind a sheet of veneer. There were a number of components on the circuit board that were too tall to make it work. I was able to remove a couple items completely. I wasn't planning on using the alarm feature, so I removed the buzzer and the alarm on/off switch. Both were easily de-soldered. I just replaced the switch with a wire jumper to simulate the alarm being in the off position. I could have bypassed this in code too, but this was simple enough.

There were also some buttons, a capacitor, and some programming headers on the front of the board that were a bit too tall. I was able to move the buttons and capacitor to the back of the board without much issue. I didn't get the buttons pushed back through the holes all the way, so they're a little ugly, but for my purposes it was fine. I decided to keep the programming headers, but just clip them shorter. In the end, my LED display was the tallest item on the front, and everything left on that side was short enough that I could fit a 1/8" board over them.

Ready for rework



Reprogramming

I won't get into too much detail here, but I also tweaked the programming on the clock a bit. I dug out my AVR programmer, downloaded the source code from Sparkfun's website, made some changes, and used WinAVR to reprogram the clock. The main thing I did was disable the am/pm indicator "dot" on the clock, purely for aesthetic reasons. I also increased the brightness a bit since it would be behind a sheet of veneer. Their code is fairly straightforward, so making these changes didn't take much effort.

UPDATE 10/6/2014 - I've reworked the code a bit more and made my version available at GitHub: https://github.com/benbrandt22/TimeBox

Building the Box

The front face was the most complicated part of the build, but wasn't too bad. I measured up the clock and used CAD to draw up some cutouts that I could use that would hold the clock kit. I printed those templates to paper, transferred them to my 1/8" boards, and cut them out with a jigsaw. I also ended up cutting a couple sheets of veneer to give me the height that I wanted (see photos below):

Paper templates & wood cutouts. Since it is a 12-hour clock, not all the display elements will be lit, so it's shifted slightly to the left so the time will appear centered.

Checking the height of my "faceplate"


The rest of the box was cut out of various sheets of plywood and MDF, and glued together with wood glue:


Once dried, I trimmed down all 4 sides on the table saw to make each side smooth:


Applying the Veneer & Finishing

At this point it wasn't much of a show piece (yet), just a bunch of plywood glued together. I hadn't worked with veneer before, so this was a fun new (and relatively easy) experience. I picked up a pack of maple veneer from the local woodworking store, and a small bottle of contact cement from Home Depot.

Each sheet of veneer was glued on with the contact cement. After drying, I used a power sander to knock down the edges to make them flush with the sides of the box. Once I had all the veneer applied, I gave the whole thing a couple coats of polyurethane for a nice finish. The polyurethane caused one minor issue I hadn't expected; it caused the veneer to warp slightly. This wasn't a problem where it was glued down, but the small rectangular area for the display ended up slightly indented. Eventually it flattened out a little bit, so it's not too noticeable anymore, but it's still not nice and flat like I was going for. Regardless, I think it turned out pretty nice.

I left the bottom open, so I can set the time, and remove the clock kit if necessary. I figure it's fun for people to be able to see what's inside to see how it was done, and knowing me, I'll probably want to make future changes, so it's nice having it accessible. I may add a removable base in the future, but for now I like the simplicity of the box in its current form.

Sanding down the edge of a veneer sheet

Applying contact cement

I masked off the area where the display would be, to avoid getting contact cement on it.

Adding polyurethane

The view from the bottom. Mounted in the back is a panel-mount power jack that runs to the clock inside.


The finished product.




Sql query performance monitoring with EF6 through interception

Lately I've been building a web application against a database that I don't have full control over which is used by a variety of other internal applications. If something were to affect the performance of my app (such as a slow database query) I'd like to know before my users start to complain. To that end, I've built out some very basic always-on production monitoring/instrumentation. For example, I set up a Http Module to monitor response times on all Http requests, and log the ones that fall outside of a given threshold.

I've been using NLog, through the Common.Logging interface to handle this sort of thing. I have NLog configured to email me a log dump whenever an error or warning occurs. If I can just log a warning when a sql query takes too long, the rest of the process (logging, emailing, etc) is taken care of.

When I first started looking into it, I was looking at the new DbContext.Database.Log property in Entity Framework 6. I could set it to any action that takes a string, intercept the messages, and parse out the occasional log message that contained the query execution time. This was admittedly a bit messy, but it worked.

I did a little more research and discovered what I really needed... database interception. In particular, this article laid out a simple example of database interception code. However it didn't show any way to actually measure query execution time. I decided to figure out how the EF logger was doing it. After looking at some stack traces and poking around in JustDecompile, I found the System.Data.Entity.Infrastructure.Interception.DatabaseLogFormatter class. This is the class that actually generates the messages sent through the Database.Log action. It works as a database interceptor, and just implements a simple timer that starts and stops with each SQL command that passes through it. Armed with this information, I had enough to build up a proper sql monitoring class for EF6 that logs slow queries and also sql errors:

Thursday, July 17, 2014

Capturing log messages in the MSTest Unit Test Output with Common.Logging

Lately I've been enjoying the abstraction of a logging facade in my .NET apps, specifically the Common.Logging project. This provides me with a simple, standard interface for logging in my code which I can configure to output to a variety of destinations. Typically I send the logging output through NLog to a combination of outputs (file, email, event log, etc), but the beauty of using a logging facade is that you can change how the log messages are handled without changing your production code.

Today I though it would be nice to see what my code was logging during my unit tests, and I didn't want to dig through a log file to find the log from one specific test. Since the unit test runner is a different executing assembly than my web project, it can have it's own configuration for logging separate from the application. Knowing this, I should be able to set up this new logging behavior for my tests without changing anything in my main project's configuration.

So what makes it possible to log messages from Common.Logging to the standard unit test output?
  • Anything written to Console.Out during a unit test will get captured in the unit test Output.
  • Common.Logging ships with a built-in Console.Out logger adapter that we can use without requiring a larger logging framework.
Knowing these two facts, we can implement this easily in a Unit Test Project:
  1. The code being tested should be doing its logging through the Common.Logging log methods.
  2. Using NuGet, install the Common.Logging package into your unit test project
  3. In the unit test project's App.Config file, add the necessary XML to configure the console logger (See XML snippet below)
  4. Run your unit test(s)
  5. See the log messages captured during each test in your test output:
And of course, let's not forget the code and configuration details:

Thursday, July 10, 2014

Running Visual Studio Tests from a Network Drive

This afternoon I ran into an odd issue with Visual Studio 2013 that ate up an unreasonable amount of my time. I recently set up a new project using the built-in Git source control tools. To keep my project safer I put the repository on my network drive, which gets backed-up regularly. In the future we may get a central server, but for now this is good enough. The code was building and running with no problem until I tried running a unit test. No matter what I did Visual Studio couldn't detect any of my tests. The Test output window said:

------ Discover test started ------
Could not load file or assembly 'file:///U:\Repos\Scheduler\Scheduler\Scheduler.Web.Tests\bin\Debug\Scheduler.Web.Tests.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)
========== Discover test finished: 0 found (0:00:00.5040504) ==========

It took some digging, and a few failed attempts at other suggested solutions, but I finally found the workaround:

  • Open a command prompt and type "setx COMPLUS_LoadFromRemoteSources 1"
  • or
  • Create an environment variable named COMPLUS_LoadFromRemoteSources
  • Set the value to 1
  • Restart Studio
Source: https://connect.microsoft.com/VisualStudio/feedback/details/502353/running-unit-tests-from-network-drive

Incidentally, I came across another suggested fix that involved changing a "LoadFromRemoteSources" value in the devenv.exe.config file, but this did not work for me. The Environment Variable did the trick.

Wednesday, July 2, 2014

From Steel Tubing to DIY Monitor Stand

About a month ago I started a new job, developing software for a manufacturing company that makes steel tubing of various shapes and sizes.

So what does a steel tubing manufacturer have an abundance of? Steel tubing. What do they do when they need new shelving, furniture, etc? Open the office supply catalog? Nope... They go to the maintenance department and make their own out of... you guessed it, steel tubing. This is not a knock on the company at all. As a big time DIY guy, I can appreciate this kind of self-sufficiency.

Case and point... this is the desk I inherited, made primarily out of 1" square tubing:


It's been several years since I've been able to work hands-on with metal (I miss the days of having full access to the machine shop at college). So I decided that I wanted to raise up my monitors, and do it myself with steel from the scrap bins. The room next door was being remodeled, and some extra monitor mounts were being taken down from the wall, which I could use in my new setup.

Over the course of a couple weeks, one of my coworkers introduced me to the guys in Maintenance and Quality while I collected, measured, and cut several pieces of sheet steel and square tubing. Our welder helped me weld together a few pieces, and I took care of drilling, cutting, and painting.

What I ended up with was a square tube support across the back, and two adjustable monitor mounts that hung from the bar. With a coat of black Rustoleum, I think it turned out quite nice.




One of my friends from my last job said that he couldn't wait to see all the stuff I would build in my house using steel tubing. While I don't foresee that happening in the near future (especially since I don't own a welder... yet), I have a feeling that this is how it starts. Today a monitor stand, tomorrow the world.

Tuesday, July 1, 2014

Getting Started with LESS CSS in your ASP.Net MVC project

Today one of my coworkers asked me for more information on a CSS preprocessor I had mentioned in one of our weekly meetings. I've been using LESS CSS lately for one of my projects and enjoying it. It simplifies the CSS I have to write, and the language is easy to follow as most of the syntax reads like standard CSS code.

Getting Started with LESS

Here’s the official LESS website that will walk you through how it works:
They have some good documentation and examples to get you started.

This was originally designed to “compile” the CSS in the user's web browser. I prefer to do this before it gets to the client. This offloads some of the work from the client browser, and ensures your CSS will always be generated the same way every time regardless of the client's browser capabilities. This also prevents the chance of making the page “blink” as it converts the LESS to CSS. This is especially applicable to me as my current web application project is running on a "thin client" machine which runs an older browser on a limited processor.

So how do we get from a LESS file to usable CSS? There are a couple ways to generate your CSS from LESS files…

Getting to CSS

The easiest way to get started would be to use the popular Visual Studio extension Web Essentials:
It provides great LESS support in Visual Studio (and lots of other handy features). Every time you save a LESS file, it automatically generates an accompanying CSS file in your project, which you can then reference in your page.

Too many files?

Personally I don’t like managing all the extra CSS files in my project. Part of me worries that my CSS won't always be "in sync" with my LESS file, either from some unseen bug or more likely a mistake I may make. I prefer to let the server automatically generate my CSS on the fly, and cache the generated result. This gets a bit more complex and requires some other packages, but I feel it's worth it.

First, I love the LESS preview function in Web Essentials, but as I mentioned I don't want the CSS files generated. This is easy to disable under Visual Studio's Tools > Options menu. Under Web Essentials > Less, disable "Compile files on save."

I use a NuGet package called dotLess (a .net based LESS compiler):
It handles all requests for .less files and returns the compiled CSS. This way I can put a reference on my page for a .LESS file and the server will return the compiled CSS automatically. The only drawback is that it isn't quite up to date with the LESS spec, so I've run into a few issues with some of the more complicated aspects of the LESS language. Thus far I've been able to work around them so I'm willing the accept the trade off for the convenience it provides.

Bundling & Minification

Generated CSS is great, but it's even better if we can bundle and minify everything to improve the page load time and the overall user experience.

For bundling & minification with dotLess, I use this package:
This gives me a “LessBundle” class that will let me bundle & minify multiple CSS & LESS files. For example, my BundleConfig.cs file in my MVC project has this entry in it:

bundles.Add(new LessBundle("~/Content/styles")
    .Include("~/Content/normalize.css")
    .Include("~/Content/less/Site.less")
);
Now, I can just include a reference to the bundle in my view:
@Styles.Render("~/Content/styles")
In debug mode I get a style tag for each file. The request for the less file will be handled by dotLess
<link href="/Content/normalize.css" rel="stylesheet"></link>
<link href="/Content/less/Site.less" rel="stylesheet"></link>
In Release mode, bundling and minification become enabled, and everything in the LESS Bundle is compiled with dotLess and minified into a single stylesheet link:
<link href="/Content/styles?v=OVSsAe9M_HQdBtQlL5-p9IRWblY32n6g5U4FaGEiUCE1" rel="stylesheet"></link>
More LESS Links:

Monday, November 26, 2012

My 2012 on Two Wheels

We're well into November now, and it's definitely too cold to ride my bike, so this seems the appropriate time to sum up my season of biking, now that my bike is hoisted up in the garage for the winter.

This past spring I was inspired by a coworker to try commuting on my bike. I had always loved biking back in college, as I lived a fair distance from most of the campus. Best of all is that this was a form of exercise I truly enjoyed. Since graduating though I slowly stopped riding and my bike remained in storage. I was already taking the bus to and from work, so I could use the bike rack easily. I decided to take the bike into work on the bus in the mornings (to avoid working up a sweat before work), and then biking home once or twice a week as my schedule and the weather allowed. My coworker was able to provide his tips and advice which helped me get started. I was able to keep it up most weeks, although I cut back in mid-summer due to the high heat. Might have to try morning rides in the future.

I ride a Raleigh mountain bike; a tough (and heavy) piece of equipment that has served me well this year. Going into it I was a little unsure about taking a heavy-duty bike for long distance rides (as opposed to a faster, lighter road bike), but I figured if I could handle that it would only make me stronger, and it was the only bike I owned. I also saw the undertaking as a personal challenge, to see what this former heart patient was really capable of.

Tuning up the bike on my ghetto bike stand (ladder + 2 by 4 board)
One aspect of biking this year which I enjoyed more than I expected was GPS tracking. Using my employer-issued Blackberry, I set myself up with the Endomondo sports tracker app. Before every ride, I start recording on my phone, and when I'm done all my stats are uploaded to the website. From there I can see almost any aspect of my performance for the entire ride: speed, altitude, distance, etc... all laid out on a map. Over the course of the spring, summer, and fall I could see my average speed increasing. It became a fun, engaging competition with myself. Best of all I could see my total miles racking up. From April to October I pedaled 279 miles this year. By the end of the season I definitely noticed that hills had become easier and I had more endurance overall.

My miles per month for 2012
I explored a variety of trails between work and home, which was usually an 8-10 mile trip depending on the route. Thankfully Minneapolis has a great trail system, so only a small portion of my rides were on roads or sidewalks. On a few occasions I went out of my way for a 15+ mile trip to take my favorite trail, the Midtown Greenway, a scenic "bike freeway" of sorts through south Minneapolis. The highlight of the summer was participating in the Minneapolis Bike Tour, a 36 mile ride around the city. Several thousand riders turned out for the event and the weather was perfect. Streets were closed just for the event, and several fun pit stops were provided along the route, providing food and water. It was a blast being part of such a big event, and being free to ride at faster speeds on wide open streets. It was also a fun ego boost to be passing some road-bikers on my mountain bike. I will definitely be doing this again.

The 36-mile Minneapolis Bike Tour (shown in blue), as recorded by GPS/Endomondo
A self-shot of me at the finish line of the Minneapolis Bike Tour, Sept 16, 2012
Next season I plan on stepping up my game, riding more often and aiming for more miles, both overall and per ride. I may not be able to change the length of my commute, but I'd like to take some more long distance rides here and there, and see how far I can go to rack up some more personal victories in 2013.

Thursday, August 9, 2012

Checkerboard Chocolate Chip Cookies

So I was browsing the web the other day, learning about making checkerboard cakes, and in the process came across a video on how to make checkerboard cookies. The recipe was a pretty simple sugar/butter type cookie dough. While this recipe may have worked well for molding/building the checkerboard, it didn't seem particularly appealing. This got me thinking... how about chocolate chip cookies? More specifically, chocolate chip cookies and chocolate cookies with white chips. Two delicious recipes that would contrast well. The checkerboard procedure I saw made a cookie with a 4 by 3 grid, which I didn't care much for... I wanted something more symmetrical, so I decided to work out a way to get a 3 by 3 grid. Here's how it all worked out...

I started out by making a batch of Chocolate Chip Cookies, and a batch of Chocolate Cookies with White Chips. The dough was then placed between sheets of parchment paper on a cookie sheet and pressed into a 1/2" thick rectangular slab. They should be the same size or at least close to the same size. At this point the dough is too soft for holding its shape, so these slabs were refrigerated overnight. You could probably get by with an hour or two. The important thing is that the dough stiffens up so it can maintain its shape and thickness.

Once the dough has been chilled, slice the smallest rectangle into three strips of equal width. Then slice 3 strips from the other slab of the same width. Any extra dough can be set aside to make some non-checkerboard cookies.
Next, stack up the strips so you have one stack of light-dark-light, and another stack of dark-light-dark. Press them together so each layer sticks together. These will provide your alternating checkerboard pattern.
Now we start slicing off strips from the long edge of each "dough sandwich". Each strip should be as wide as the thickness of your original slabs. In my case this was about 1/2 inch. With all of the cold, hard chocolate chips in the dough, it was difficult to cut with a regular knife. I found that an electric knife worked well to cut through all the chips and give a consistent straight cut. For each "cookie log" you'll need a slice of one "sandwich" and two slices of the other.
Press your three strips together to form a checkerboard cookie "log". Note: your next "log" should be opposite of this one, so you don't use up one color pattern faster than the other. In the end I had one extra strip that ended up becoming "striped" cookies.
You can now start slicing off your checkerboard cookies from the cookie dough "log" at about 1/2 inch thickness. A regular knife seemed to work best at this stage. Whenever you're not slicing off cookies, place the checkerboard dough back in the refrigerator so it doesn't get too warm and soft.
Place on your ungreased cookie sheet, and bake at 350 degrees F for about 10 minutes, until the edges start to brown. Once removed from the oven, leave them on the cookie sheet for 10 minutes or so to finish baking while the next batch is in the oven.
Enjoy your cookies!

Thursday, July 26, 2012

The Color Jar - Microcontroller-driven fun for the kids

I finally managed to spend some time on a new electronics project at my workbench. Major credit for the idea goes to Paul, author of the Fangletronics blog. He is also a father and electronics tinkerer, so his blog certainly appealed to me. One post in particular (Pixie-Dust Bottles) stood out as a fun and relatively simple potential project, a good programming exercise, and something I thought my boys would enjoy. Shown at left is the final product, what I've been calling the Color Jar. It's a frosted plastic jar with a knob on top. As you turn the knob, the RGB LED light turns on inside the jar, and it smoothly cycles through all the colors of the rainbow, based on the position of the knob, essentially letting you "dial-in" a color.

The original design was built around an ATTiny13 microcontroller, but it ported over very easily to the ATTiny85 chip which I had on hand, as it has the same pinout but with more memory. I worked out the circuit on a breadboard, and then soldered it up on some proto board, and mounted it to the potentiometer to make it into a nice compact package. I made sure to use a chip socket for easy removal for reprogramming, which came in handy. The other major design change was the battery. Since my plastic jar allowed some more space in the lid, I decided to use a larger 3 volt CR2 "Photo" battery (not a small watch battery) that should last longer.



For the most part, I used the programming from the original pixie dust bottle project, but had to make a couple updates & fixes for my project.

First was a hardware issue. I bought my potentiometer (with switch) from Radioshack, which was convenient, but turns out it was not linear. That is, the voltage change was not directly proportional to the amount of rotation. In practice, this meant that for the first half of the knob's rotation there was almost no voltage change, so for most of the rotation the light would only show red. I took a series of voltage measurements at different degrees of rotation, and used Excel to graph out the signal curve. From there I was able to come up with a formula to take my input signal and adjust it to a more linear value. This allowed me to more evenly spread each color over the full rotation of the knob. The extra-low voltages at the bottom of the range also made it difficult to get consistent readings, which made my light flicker a little. I was able to smooth this out by taking 10 input readings per cycle with a 2 millisecond delay between each and averaging them to get my final input value.

The other issue was a programming bug in the code I was using. At a certain point between green and cyan, the LED would start flashing/flickering red. Looking at the code I had a hunch it was a math error in the way the RGB color was being calculated. To be sure, I did the math and found out it was calculating a Red value of -2, when normally this should be between 0 and 255. It might be fun to refactor the code and come up with my own algorithm for calculating the colors, but for now I just left the main logic in place, and then added a few lines to force any values below zero back to zero, and anything over 255 set back to 255, to keep everything in the appropriate range. This got rid of the flickering, and overall I'm happy with the performance of the Color Jar.

While Nathan may not appreciate the electronics and programming running inside it, he definitely enjoys the Color Jar, and that's the biggest payoff for me :-)

Monday, April 9, 2012

My biggest cake yet... Cruise Ship Cake

Last month, my sisters and I got to put together an over-the-top 60th birthday party for our parents. They love going on cruises, and unfortunately had to cancel their cruise reservation for this year (the first since Dad's original cancer diagnosis) because he was just diagnosed with the same cancer again. With a long road of of treatment ahead of them, we wanted to go all out and throw them a birthday party to remember. To make a long story short, the party was a huge success, and was full of the artistic touches that my family is known for. My main contribution was this nearly 3-foot long cruise ship cake:


The Plan:

I wanted to make a relatively long cake to best represent a typical cruise ship, and have multiple decks. I figured the simplest way to get this shape would be to make 3 9x13 cakes, and cut them down the middle, giving me several 4 1/2" wide cakes which I could cut and stack. I've only worked with fondant once before, and I wasn't that impressed with it, so I wanted to focus on a better tasting cake and use regular frosting instead. This would make it a bit more difficult to make the necessary details to make it look enough like a cruise ship. So I set out to make some good windows...

Windows:

I didn't want to pipe out frosting windows. The idea seemed too tedious and labor intensive, especially since I'd be building the cake the day of the party. I also didn't want a bunch of frosted windows because they would look inconsistent in size and shape. This led me to the idea of making square windows out of white chocolate, colored blue. I did some experimentation ahead of time to get it right, and they turned out great. I melted white chocolate slowly in a double boiler setup, and colored it blue with food coloring. Once it was colored well enough, I poured it out on some wax paper on a cookie sheet, and layered another piece of wax paper on top. At this point I spread out the melted chocolate to an even thickness and put it in the fridge to chill and harden.

Cutting proved to be tricky. You can't just cut all the way through with a knife, otherwise it cracks and breaks in unpredictable ways. What worked best was to score the surface of the chocolate sheet, and then break it along the score-line. This method let me easily break it down into even strips, and then squares. This of course produced a number of irregular pieces which made for some good snacking.

In the end I made a couple hundred little blue windows and kept them in the freezer to prevent any melting or sticking together.

Baking:

I took the cheap and easy route for the cake itself... boxed cake mix and jar frosting. Both of which came from Aldi at a great price and were much tastier than I had originally expected. I went off of Wilton's cake batter recommendations, which said a 9x13 wedding cake should be made with 7 cups of batter (about 1.5 boxes of mix for each). Each cake was baked at 350 F for 35-40 minutes. The biggest thing I learned was how to properly flour a pan. I came across a youtube instructional video that recommended putting a sheet of parchment paper (also greased & floured) in the bottom of the pan. This makes it MUCH easier to remove from the pan. I tried once without this parchment paper bottom layer, and ruined a cake trying to get it out of the pan.

Assembly:

I planned out the design and so I knew how long the cake would be, and cut a plywood board a little larger. This was then wrapped in blue paper from the craft store to serve as my cake board. The first layer was laid out with wax paper strips underneath the edges (to protect the cake board and keep it clean). Between each layer was a mixture of chocolate and white frosting. This was chosen so it would resemble the wood floors on each deck. Mixing chocolate and white frosting is also an easy way to get light brown.

Decorating:

When I started the assembly my cakes were nearly frozen, but eventually warmed up. This made frosting a bit difficult toward the end. I got most of the outside done with a frosting spreader, but had to finish up by piping it on, otherwise the blade would pull off bits of cake and it wouldn't stick.

Last but not least I stuck on the windows, which really made the cake look like a cruise ship, and added a fun chocolate touch to each piece. This was fun to build, and even better to eat.

Best of all, it tasted great, and looked good surrounded by more of our fancy buffet.


Happy Birthday Mom & Dad!

Sunday, January 8, 2012

The Many Reconstructive Surgeries of Bobbleheads


Over the last couple months, our 2-year-old son Nathan has found his favorite new toys (and latest obsession) in the unlikely location of our Twins memorabilia shelf. He took a liking to our MN Twins Bobbleheads, although most of them aren't playing for the Twins anymore. We have Delmon Young, Joe Mauer, Torii Hunter, Joe Nathan, Brad Radke, Justin Morneau, and a small Ron Gardenhire figure that walks when you wind him up. We started lifting up Nathan to the height of the shelf and teaching him the names of each one, which he quickly picked up and could recite them in full to anyone who asked. Eventually we let him get them down and play with them. We like our bobbleheads, but we're no so attached to them that would deny our son the fun of playing with them.

Watching him play with the bobbleheads has been a constant source of entertainment and smiles. He brings them everywhere in the house. He'll stand them in a line in the laundry room, the bathroom, living room, kitchen, dad's workbench, and anywhere else he happens to be. He examines them with his doctor kit. He knows which ones are smiling, and he knows what each one is holding/doing (without looking). He sets them up on the dining room table so they can watch him eat his meals, and he lays them down for naps before he goes down for his own. It's ridiculously cute. To top it off, they seem to act as his conscience, and remember the rules of the house when he cannot. Lately his favorite is Delmon Young. Nathan tells us things like "Delmon Young says not to throw my fork on the floor" and "Delmon Young says don't bother the baby." Of course, you listen to him Nathan.

Knowing our son, we knew he would be careful with them (and he is), but accidents were bound to happen eventually. Joe Nathan's and Brad Radke's heads have come loose, which were easily fixed by re-gluing the spring to the head/body with some good epoxy. That was easy.

Then Delmon Young hit the tile floor. Twice.

The first injury was a decapitation at the base of the neck. While some glue might have held it, it was a spot that would be put under stress regularly and could easily break again. More drastic measures were required. This called for some bobblehead spinal fusion surgery.

Luckily the plastic was hard but wasn't too difficult to drill. I drilled a hole down into the torso and used epoxy to set in the shaft of a screw to act as reinforcement. Then I drilled a larger hole in the neck to give me some room for proper alignment, and filled the cavity with epoxy. Overall I'd say it came together fairly well and should hold strong.


About this time I was feeling pretty proud of my skills as bobblehead repair man and Dad. Delmon's body would sit on the workbench for awhile to let the epoxy properly cure. During this time Nathan was very concerned about Delmon and sad that he was missing from the lineup. We had to go down and check up on him regularly. He felt much better when we let him take care of Delmon's head while the body was under repair. Here's Nathan enjoying a morning snack with Delmon's head:


Sadly, tragedy struck the bobble-Delmon again before he could be put back together completely. Delmon's head fell off a table in the basement, hit the tile floor, and broke open.


This was when I learned the head itself was hollow, and rather thin in some spots. Nathan was devastated, and looked to me with "Daddy fix it" coming out of his mouth as it had so many times before. Challenge accepted.

Knowing how thin the head was, I wasn't comfortable leaving it empty. I wanted to reinforce it so it would hold up better going forward. I proceeded to superglue the big piece back on, and placed it in a small vise to hold it together while I filled the cavity with spray foam. I left the small pieces out so the foam could expand until it dried. This is how Delmon looked for at least a day:


This photo was taken on my workbench the night I started the cranial reconstruction. The next day Nathan wanted to go check on Delmon as soon as we got him out of his crib. He spent the rest of the day up on the mantle in the living room so Nathan could keep an eye on him. All day he would point up to Delmon's foam-extruding head and say things like "I just want to give Delmon a hug" or "when Delmon be all fixed, then I can play with him." Sure thing kiddo, I'll do whatever I can for you (and Delmon).

Tonight I cut away the excess foam, and trimmed back some of the plastic to get everything to fit. The fit wasn't as perfect as when it originally broke. Adding foam, glue, and epoxy kind of messed up the fit, but I think I got everything to come together fairly well. After my work tonight, here's how he looks now, happily bobbling away with his newly reinforced neck and head, ready to play some baseball. I made sure to get photographic evidence of him fully assembled and unbroken, as it may not last forever.


Tomorrow morning Delmon will rejoin his teammates (currently lined up on the Piano in our living room) for more adventures with our son around the house. I like projects & handyman challenges, and I love to make my kids happy. Thanks Nathan. Take care of the guys, I'd hate to see you have to lose one if he got damaged beyond repair.