<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rssdatehelper="urn:rssdatehelper" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Pete Brown's Blog (POKE 53280,0)</title><link>http://10rem.net</link><pubDate /><description>Pete Brown writes on a variety of topics from XAML with the Windows Runtime (WinRT), .NET programming using C#, WPF, Silverlight, XNA, and Windows Phone, Microcontroller programming with .NET Microframework, .NET Gadgeteer and even plain old C, to raising two children in the suburbs of Maryland, woodworking, CNC and generally "making physical stuff". Oh, and Pete loves retro technology, especially Commodore (C64 and C128). If the content interests you, please subscribe using the subscription link to the right of every page.</description><generator>umbraco</generator><language>en-us</language><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PeteBrown" /><feedburner:info uri="petebrown" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>39.004</geo:lat><geo:long>-76.65264</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license><image><link>http://10rem.net</link><url>http://10rem.net/pub/blog/pmb_headshot_full_square_black_bg_color_150.jpg</url><title>Pete Brown</title></image><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/PeteBrown" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FPeteBrown" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><feedburner:browserFriendly>Sorry Outlook users. The Google Feedburner USM option is broken. You get a second http in there which hoses outlook. Recommend manually adding feed to outlook using the address in the address bar above.</feedburner:browserFriendly><item><title>Maker Geek Roundup 007 for 2/8/2012</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/xUyNcv0-sgw/maker-geek-roundup-007-for-2-8-2012</link><pubDate>Thu, 09 Feb 2012 03:04:34 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/02/08/maker-geek-roundup-007-for-2-8-2012</guid><description>&lt;p&gt;The Maker Geek Roundup aggregates information of interest to
makers everywhere. Topics include .NET Micro Framework, CNC, 3d
Printing, Robotics, Microsoft Robotics Studio, Electronics, General
Maker stuff, and more. If you have something interesting you've
done or have run across, or you blog regularly on the topics
included here, please send me the URL and brief description via the
&lt;a href="http://10rem.net/contact"&gt;contact link&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;3d Printing and CAD/CAM/CNC&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.makerbot.com/blog/2012/02/08/what-if-it-isnt-there/"&gt;
What if it isn't there?&lt;/a&gt; (Makerbot Industries)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=AH4Tg2tIgfg"&gt;
Clockathon #2 - The OpenSCAD clock&lt;/a&gt; (Syvwlch)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;.NET Gadgeteer&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=U93hzPJkFDQ"&gt;Using a
photoresistor to adjust screen contrast&lt;/a&gt; (YouTube:Mr Bildo)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://mikedodaro.net/2012/02/06/gps-module-for-net-gadgeteer-by-seeed-studio/"&gt;
GPS Module for .NET Gadgeteer by Seeed Studio&lt;/a&gt; (Michael
Dodaro)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://threeconstants.wordpress.com/2012/01/28/gadgeteer-binary-clock-part-1/"&gt;
Gadgeteer Binary Clock - Part 1&lt;/a&gt; (Ian Ormesher)&lt;/li&gt;

&lt;li style="list-style: none"&gt;
&lt;ul&gt;
&lt;li&gt;Don't forget &lt;a
href="http://threeconstants.wordpress.com/2012/01/28/gadgeteer-binary-clock-part-2/"&gt;
Part 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;.NET Micro Framework General (Netduino, GHI FEZ, etc.)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://highfieldtales.wordpress.com/2012/02/07/infrared-transmitter-driver-for-netduino/"&gt;
Infrared transmitter driver for Netduino&lt;/a&gt; (Highfield Tales)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Arduino&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://arduino.cc/blog/2012/02/07/tweeting-in-morse-code/"&gt;Tweeting
in morse code&lt;/a&gt; (Arduino Blog)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Other Micro Controllers (PIC, AVR, ARM, BeagleBoard, and
more)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://dangerousprototypes.com/2012/02/08/raspberry-pi-first-batch-will-be-manufactured-by-february-20th/"&gt;
Raspberry Pi first batch will be manufactured by February 20th&lt;/a&gt;
(Dangerous Prototypes)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;General Electronics and Hardware Hacking&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.electronics-lab.com/blog/?p=16824"&gt;Superfast
Rechargable Battery&lt;/a&gt; (Electronics-Lab.com)&lt;/li&gt;

&lt;li&gt;&lt;a href="http://www.electronics-lab.com/blog/?p=16815"&gt;Logic
circuits and computer memory are printed together on a sheet of
plastic&lt;/a&gt; (Electronics-Lab.com)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Robots and Robotics Studio&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://robotgrrl.com/blog/2012/02/03/robobrrd-vs-voltage-regulators/"&gt;
RoboBrrd vs Voltage Regulators&lt;/a&gt; (RobotGrrl)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Clocks&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.breakcontinue.com/2011/12/diy-chronodot-for-bulbdial-clock.html"&gt;
DIY Chronodot for Bulbdial Clock&lt;/a&gt; (Take a Break)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Retro Computing and Commodore!&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.mos6502.com/friday-commodore/a-graphics-booster-for-the-c128/"&gt;
A graphics booster for the C128&lt;/a&gt; (MOS6502)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.mos6502.com/commodore-tech-corner/how-the-c128-was-incompatible-with-the-c128/"&gt;
How the C128 was incompatible… with the C128&lt;/a&gt; (MOS6502)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://soldering-irony.blogspot.com/2012/01/sidboard.html"&gt;The
SIDboard&lt;/a&gt; (Soldering Irony)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://soldering-irony.blogspot.com/2012/02/network-sid-device-protocol.html"&gt;
Network SID Device Protocol&lt;/a&gt; (Soldering Irony)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Bdnjww83rZ084v_HBYn6jb42X0k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bdnjww83rZ084v_HBYn6jb42X0k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Bdnjww83rZ084v_HBYn6jb42X0k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bdnjww83rZ084v_HBYn6jb42X0k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=xUyNcv0-sgw:LGBPK6CbBhY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=xUyNcv0-sgw:LGBPK6CbBhY:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=xUyNcv0-sgw:LGBPK6CbBhY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=xUyNcv0-sgw:LGBPK6CbBhY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=xUyNcv0-sgw:LGBPK6CbBhY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=xUyNcv0-sgw:LGBPK6CbBhY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=xUyNcv0-sgw:LGBPK6CbBhY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=xUyNcv0-sgw:LGBPK6CbBhY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=xUyNcv0-sgw:LGBPK6CbBhY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/xUyNcv0-sgw" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/02/08/maker-geek-roundup-007-for-2-8-2012</feedburner:origLink></item><item><title>Windows Client Developer Roundup 087 for 2/9/2012</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/F41cjYACnZ8/windows-client-developer-roundup-087-for-2-9-2012</link><pubDate>Thu, 09 Feb 2012 02:44:11 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/02/08/windows-client-developer-roundup-087-for-2-9-2012</guid><description>&lt;p&gt;The Windows Client Developer Roundup aggregates information of
interest to Windows Client Developers, including &lt;a
href="http://dev.windows.com/"&gt;WinRT XAML&lt;/a&gt;, &lt;a
href="http://windowsclient.net/"&gt;WPF&lt;/a&gt;, &lt;a
href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;, &lt;a
href="http://msdn.microsoft.com/en-us/visualc/default.aspx"&gt;Visual
C++&lt;/a&gt;, &lt;a href="http://creators.xna.com/"&gt;XNA&lt;/a&gt;, &lt;a
href="http://expression.microsoft.com/"&gt;Expression Blend&lt;/a&gt;, &lt;a
href="http://www.microsoft.com/surface/"&gt;Surface&lt;/a&gt;, &lt;a
href="http://msdn.microsoft.com/en-us/windows/default.aspx"&gt;Windows
7&lt;/a&gt;, &lt;a
href="http://msdn.microsoft.com/en-us/ff380145.aspx"&gt;Windows
Phone&lt;/a&gt;, Visual Studio, &lt;a
href="http://silverlight.net/riaservices/"&gt;WCF RIA Services&lt;/a&gt; and
more. Sometimes I even include a little jQuery and HTML5. If you
have something interesting you've done or have run across, or you
blog regularly on the topics included here, please send me the URL
and brief description via the &lt;a href="http://10rem.net/contact"&gt;contact
link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that I've started breaking the Netduino, Electronics,
Robotics, Synthesizer and similar content into a new roundup series
called the &lt;a href="http://10rem.net/blog?filterby=MakerRoundup"&gt;Maker Geek
Roundup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oh and you'll get Windows 8 Consumer Preview on February
29. Get ready to code (and&lt;/strong&gt; &lt;a
href="http://10rem.net/blog/2012/01/25/now-more-than-ever-you-need-a-designer"&gt;
&lt;strong&gt;design&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;) :)&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Windows 8 and WinRT/Metro General&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/b8/archive/2012/02/07/improving-power-efficiency-for-applications.aspx"&gt;
Improving power efficiency for applications&lt;/a&gt; (Sharif Farag and
Ben Srour)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;XAML Technologies (Silverlight, WPF, WinRT Metro XAML)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://grokys.blogspot.com/2012/02/mvvm-and-multiple-selection-part-iv.html"&gt;
Bad Entropy: MVVM and Multiple Selection - Part IV - DataGrid&lt;/a&gt;
(Bad Entropy)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.sharpgis.net/post/2012/01/23/Overwriting-the-default-WebRequest-used-by-WebClient.aspx"&gt;
Overwriting the default WebRequest used by WebClient&lt;/a&gt; (Morten
Nielsen)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.sharpgis.net/post/2012/01/17/Building-A-Multi-Touch-Photo-Viewer-Control.aspx"&gt;
Building A Multi-Touch Photo Viewer Control&lt;/a&gt; (Morten
Nielsen)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.abhisheksur.com/2012/02/optimizing-inpc-objects-against-memory.html"&gt;
DOT NET TRICKS: Optimizing INPC Objects against memory leaks using
WeakEvents&lt;/a&gt; (Abhishek Sur)&lt;/li&gt;

&lt;li style="list-style: none"&gt;
&lt;ul&gt;
&lt;li&gt;Also see &lt;a
href="http://10rem.net/blog/2012/02/01/event-handler-memory-leaks-unwiring-events-and-the-weakeventmanager-in-wpf-45"&gt;
my post on weak events.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://michaelcrump.net/using-the-live-sdk-in-windows-8-xaml/c-metro-applications"&gt;
Using the Live SDK in Windows 8 XAML/C# Metro Applications -
Michael Crump&lt;/a&gt; (Michael Crump)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.sharpgis.net/post/2012/01/12/Reading-and-Writing-text-files-in-Windows-8-Metro.aspx"&gt;
Reading and Writing text files in Windows 8 Metro&lt;/a&gt; (Morten
Nielsen)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.scottlogic.co.uk/blog/colin/2012/02/a-simple-pattern-for-creating-re-useable-usercontrols-in-wpf-silverlight/"&gt;
A Simple Pattern for Creating Re-useable UserControls in WPF /
Silverlight&lt;/a&gt; (Colin Eberhardt)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;DirectX Technologies (DirectX, XNA, WinRT DirectX, GPU and Game
Programming)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://xna-uk.net/blogs/darkgenesis/archive/2012/01/20/the-starter2d-and-starter3d-tutorials-now-on-the-marketplace.aspx"&gt;
The Starter2D and Starter3D tutorials now on the Marketplace&lt;/a&gt;
(Dark Genesis)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://channel9.msdn.com/coding4fun/blog/Large-Scale-Terrain-Rendering"&gt;
Large Scale Terrain Rendering&lt;/a&gt; (Coding4Fun)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;C++ and Native Development&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://geekswithblogs.net/mikebmcl/archive/2012/02/02/c-to-c-ndash-a-somewhat-short-guide.aspx"&gt;
C# to C++ - A Somewhat Short Guide&lt;/a&gt; (Bob Taco Industries)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/vcblog/archive/2012/02/02/10263304.aspx"&gt;
C++11 Conformance Survey&lt;/a&gt; (Vikas Bhatia)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/vcblog/archive/2012/02/03/10263262.aspx"&gt;
The Microsoft C++ Compiler Turns 20!&lt;/a&gt; (Visual C++ Blog)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/somasegar/archive/2012/02/03/c-amp-open-specification.aspx"&gt;
C++ AMP Open Specification&lt;/a&gt; (Soma)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://channel9.msdn.com/posts/Announcing-the-GoingNative-2012-Full-Schedule"&gt;
GoingNative 2012: All Sessions are now available On-Demand!&lt;/a&gt;
(Channel 9)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Visual Studio and .NET General&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/visualstudio/archive/2012/01/18/announcing-visual-studio-achievements.aspx"&gt;
Bring Some Game To Your Code!&lt;/a&gt; (Visual Studio Blog)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;NUI (Kinect, Surface, More)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://robrelyea.wordpress.com/2012/02/01/k4w-details-of-api-changes-from-beta2-to-v1-managed/"&gt;
Kinect for Windows - Details of API Changes from Beta2 to v1.0
(C#/VB)&lt;/a&gt; (Rob Relyea)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/surface/archive/2012/02/05/microsoft-surface-2-sdk-and-runtime-update.aspx"&gt;
Microsoft® Surface® 2.0 SDK and Runtime Update&lt;/a&gt; (Luis
Cabrera)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://kinecthacks.net/interactive-portfolio/"&gt;Interactive
Portfolio&lt;/a&gt; (Kinect Hacks)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Off-Topic Fun&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=LJSZ1TwjcsQ"&gt;The Karate
Rap&lt;/a&gt; (YouTube)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I leave you with only the one "off-topic" item today, because
after watching that, nothing else will ever suffice. Ever.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dUKTLAul4nj36-R6m4frlK6zSAw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dUKTLAul4nj36-R6m4frlK6zSAw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dUKTLAul4nj36-R6m4frlK6zSAw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dUKTLAul4nj36-R6m4frlK6zSAw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=F41cjYACnZ8:-fEQKrOOMw0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=F41cjYACnZ8:-fEQKrOOMw0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=F41cjYACnZ8:-fEQKrOOMw0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=F41cjYACnZ8:-fEQKrOOMw0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=F41cjYACnZ8:-fEQKrOOMw0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=F41cjYACnZ8:-fEQKrOOMw0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=F41cjYACnZ8:-fEQKrOOMw0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=F41cjYACnZ8:-fEQKrOOMw0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=F41cjYACnZ8:-fEQKrOOMw0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/F41cjYACnZ8" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/02/08/windows-client-developer-roundup-087-for-2-9-2012</feedburner:origLink></item><item><title>Creating Big Silverlight Windows and Getting Monitor Resolutions and Positions with PInvoke</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/LnBVZe8RTLI/creating-big-silverlight-windows-and-getting-monitor-resolutions-and-positions-with-pinvoke</link><pubDate>Wed, 08 Feb 2012 03:59:11 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/02/07/creating-big-silverlight-windows-and-getting-monitor-resolutions-and-positions-with-pinvoke</guid><description>&lt;p&gt;While doing the (long!) tech review for Silverlight 5 in Action,
my friend and former coworker &lt;a
href="http://codemares.blogspot.com/"&gt;Tom McKearney&lt;/a&gt; mentioned
that we should put together some code to make handling windows
across multiple monitors a reasonable task in Silverlight 5. Then,
on a mailing list, I recently saw the question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi all -- I'm wondering if there is a maximum window size for
Silverlight documented anywhere. For example if I had hardware that
could support a 3x3 or 3x4 grid of 1920x1080 displays, can I make
an SL5 OOB window that big? Can I make individual items in the
window that big? Can I get hardware acceleration on all of it? Does
the 3D API have any different limits than XAML? Or maybe
Silverlight has no specific limit, but it's up to the hardware?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Curious about that, I decided to try it myself, and combine this
with what Tom had requested. I don't have a 3x3 array of screens
that size, however. It really is a serious number of pixels.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83370/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83375/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb.png" width="650" height="234" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cost of screens aside, most people don't have the video hardware
to be able to run 6 displays. ATI has some displayport cards which
will do that, but otherwise you're looking at a minimum of three
video cards and a variety of connections. You're also looking at a
shedload of video memory.&lt;/p&gt;

&lt;p&gt;What I do have is a pair of 30" displays each running at
2560x1600. That's quite a bit smaller, but still much larger than
most people have. It ends up being a bit less than half the
requested pixels. I do get almost the right width, but the height
is lacking.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83380/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_4.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83385/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb_1.png" width="650" height="142" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wouldn't want 3x3 of the HD res screens (too much bevel)
unless they were big old TV-style ones and you were doing
relatively low-res graphics. 3x3 of the 2560x1600 though?
*drool*&lt;/p&gt;

&lt;p&gt;In any case, my two combined are still quite a bit larger than
the typical HD res 1920x1080 screen people have, with its 2,073,600
pixels, and is a valid test of creating big windows in
Silverlight.&lt;/p&gt;

&lt;p&gt;My displays are also oriented a little differently than you may
expect:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83390/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_6.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83395/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb_2.png" width="500" height="326" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means that logical 0,0 is in the middle of the combined
display. We'll need to know that for later.&lt;/p&gt;

&lt;h3&gt;Creating the Window&lt;/h3&gt;

&lt;p&gt;If you want to learn how to create out-of-browser windows in
Silverlight 5, &lt;a
href="http://10rem.net/blog/2011/04/13/silverlight-5-working-with-operating-system-windows"&gt;
see my post here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first test is to see if I can create a window that fits the
dimensions of my two screens. All sizes here will be
hard-coded.&lt;/p&gt;

&lt;p&gt;XAML&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;
&amp;lt;UserControl x:Class="PeteBrown.SilverlightBigWindow.MainPage"&lt;br /&gt;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&lt;br /&gt;
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;br /&gt;
    mc:Ignorable="d"&lt;br /&gt;
    d:DesignHeight="175&lt;br /&gt;
             " d:DesignWidth="800"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Grid x:Name="LayoutRoot" Background="White"&amp;gt;&lt;br /&gt;
        &amp;lt;ListBox x:Name="DisplayList"&lt;br /&gt;
                 Margin="126,12,12,12"&amp;gt;&lt;br /&gt;
            &amp;lt;ListBox.ItemTemplate&amp;gt;&lt;br /&gt;
                &amp;lt;DataTemplate&amp;gt;&lt;br /&gt;
                    &amp;lt;Grid&amp;gt;&lt;br /&gt;
                        &amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
                            &amp;lt;ColumnDefinition Width="150" /&amp;gt;&lt;br /&gt;
                            &amp;lt;ColumnDefinition Width="50" /&amp;gt;&lt;br /&gt;
                            &amp;lt;ColumnDefinition Width="150" /&amp;gt;&lt;br /&gt;
                            &amp;lt;ColumnDefinition Width="150" /&amp;gt;&lt;br /&gt;
                            &amp;lt;ColumnDefinition Width="75" /&amp;gt;&lt;br /&gt;
                            &amp;lt;ColumnDefinition Width="75" /&amp;gt;&lt;br /&gt;
                        &amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                        &amp;lt;TextBlock Grid.Column="0"&lt;br /&gt;
                                   Text="{Binding MonitorName}" /&amp;gt;&lt;br /&gt;
                        &amp;lt;TextBlock Grid.Column="1"&lt;br /&gt;
                                   Text="{Binding IsPrimary}" /&amp;gt;&lt;br /&gt;
                        &amp;lt;TextBlock Grid.Column="2"&lt;br /&gt;
                                   Text="{Binding MonitorArea}" /&amp;gt;&lt;br /&gt;
                        &amp;lt;TextBlock Grid.Column="3"&lt;br /&gt;
                                   Text="{Binding WorkArea}" /&amp;gt;&lt;br /&gt;
                        &amp;lt;TextBlock Grid.Column="4"&lt;br /&gt;
                                   Text="{Binding Width}" /&amp;gt;&lt;br /&gt;
                        &amp;lt;TextBlock Grid.Column="5"&lt;br /&gt;
                                   Text="{Binding Height}" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                    &amp;lt;/Grid&amp;gt;&lt;br /&gt;
                &amp;lt;/DataTemplate&amp;gt;&lt;br /&gt;
            &amp;lt;/ListBox.ItemTemplate&amp;gt;&lt;br /&gt;
        &amp;lt;/ListBox&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
     &lt;br /&gt;
        &amp;lt;Button Content="Open Full"&lt;br /&gt;
                Height="23"&lt;br /&gt;
                HorizontalAlignment="Left"&lt;br /&gt;
                Margin="12,12,0,0"&lt;br /&gt;
                Name="OpenWindow"&lt;br /&gt;
                VerticalAlignment="Top"&lt;br /&gt;
                Width="108"&lt;br /&gt;
                Click="OpenWindow_Click" /&amp;gt;&lt;br /&gt;
        &amp;lt;Button Content="Open Primary"&lt;br /&gt;
                Height="23"&lt;br /&gt;
                HorizontalAlignment="Left"&lt;br /&gt;
                Margin="12,41,0,0"&lt;br /&gt;
                Name="OpenPrimary"&lt;br /&gt;
                VerticalAlignment="Top"&lt;br /&gt;
                Width="108"&lt;br /&gt;
                Click="OpenPrimary_Click" /&amp;gt;&lt;br /&gt;
        &amp;lt;Button Content="Open Secondary"&lt;br /&gt;
                Height="23"&lt;br /&gt;
                HorizontalAlignment="Left"&lt;br /&gt;
                Margin="12,70,0,0"&lt;br /&gt;
                Name="OpenSecondary"&lt;br /&gt;
                VerticalAlignment="Top"&lt;br /&gt;
                Width="108"&lt;br /&gt;
                Click="OpenSecondary_Click" /&amp;gt;&lt;br /&gt;
    &amp;lt;/Grid&amp;gt;&lt;br /&gt;
&amp;lt;/UserControl&amp;gt;&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;C# code&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void OpenWindow_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
    w.Width = 5120;&lt;br /&gt;
    w.Height = 1600;&lt;br /&gt;
&lt;br /&gt;
    w.Show();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private void OpenPrimary_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private void OpenSecondary_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This will allow me to click a button and have it open a giant
window on the screen. The window has no content, so it'll appear as
a plain white empty window.&lt;/p&gt;

&lt;p&gt;Run it (remember, must be elevated trust out-of-browser app) and
what do you see? No problem. One giant white window which fits
across my screen.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83400/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_8.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83405/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb_3.png" width="650" height="203" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem is, however, that it starts in the middle of my
displays instead of over at the far left. I had to drag it to the
far left to get it to take up the whole set of displays. How do we
figure out how to position and size the window?&lt;/p&gt;

&lt;h3&gt;Positioning and Sizing the Window&lt;/h3&gt;

&lt;p&gt;On my setup, the monitor to the left is all in negative space.
So, to move the window to the far left, I need to move it to -2560.
Then we can open the window and then tell it to move to the top
left, or to take up just a single display.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void OpenWindow_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
    w.Width = 5120;&lt;br /&gt;
    w.Height = 1600;&lt;br /&gt;
&lt;br /&gt;
    w.Left = -2560;&lt;br /&gt;
    w.Top = 0;&lt;br /&gt;
    w.Show();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private void OpenPrimary_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
    w.Width = 2560;&lt;br /&gt;
    w.Height = 1600;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    w.Left = 0;&lt;br /&gt;
    w.Top = 0;&lt;br /&gt;
    w.Show();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private void OpenSecondary_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
    w.Width = 2560;&lt;br /&gt;
    w.Height = 1600;&lt;br /&gt;
&lt;br /&gt;
    w.WindowStyle = WindowStyle.None;&lt;br /&gt;
&lt;br /&gt;
    w.WindowState = WindowState.Maximized;&lt;br /&gt;
&lt;br /&gt;
    w.Left = -2560;&lt;br /&gt;
    w.Top = 0;&lt;br /&gt;
    w.Show();&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Ok, so we've verified that it can be done. Now we need to make
it work for arbitrary resolutions and monitor configurations.
&lt;strong&gt;Before we do that, though, did you notice that the sizing
was off a bit?&lt;/strong&gt; Both the width and height appear to be off
by the measurements of the window chrome. It turns out this happens
whether or not you're using custom chrome. &lt;strong&gt;I've reported a
bug to the team and they're investigating&lt;/strong&gt;, so for now
we're going to have to ignore the size issues. &lt;strong&gt;If you work
around the sizing in your own code, stick it in an conditional
compilation block&lt;/strong&gt; or something so you can easily change it
if/when the bug is fixed.&lt;/p&gt;

&lt;h3&gt;Getting Display Informatin Using PInvoke&lt;/h3&gt;

&lt;p&gt;We're running in elevated OOB mode anyway, so as long as you
only care about Windows, you can also throw in some P/Invoke. The
main functions we're interested in are &lt;a
href="http://pinvoke.net/default.aspx/user32.EnumDisplayMonitors"&gt;EnumDisplayMonitors&lt;/a&gt;
and &lt;a
href="http://msdn.microsoft.com/en-us/library/dd144901(v=VS.85).aspx"&gt;
GetMonitorInfo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The PInvoke.net example was enough to get me started, but it
lacked a few necessary steps. Of course, it also needed some
changes to work with Silverlight.&lt;/p&gt;

&lt;p&gt;The first addition is the DisplayInfo class. We'll use this to
hold information about a single monitor.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
namespace PeteBrown.SilverlightBigWindow&lt;br /&gt;
{&lt;br /&gt;
    public class DisplayInfo&lt;br /&gt;
    {&lt;br /&gt;
        public string MonitorName { get; internal set; }&lt;br /&gt;
        public Win32Rect MonitorArea { get; internal set; }&lt;br /&gt;
        public Win32Rect WorkArea { get; internal set; }&lt;br /&gt;
        public int Width { get; internal set; }&lt;br /&gt;
        public int Height { get; internal set; }&lt;br /&gt;
        public bool IsPrimary { get; internal set; }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Next, I need a way to populate this class. Here's where all the
PInvoke action happens.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using System.Runtime.InteropServices;&lt;br /&gt;
using System.Collections.ObjectModel;&lt;br /&gt;
&lt;br /&gt;
namespace PeteBrown.SilverlightBigWindow&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    [StructLayout(LayoutKind.Sequential)]&lt;br /&gt;
    public struct Win32Rect&lt;br /&gt;
    {&lt;br /&gt;
        public int Left { get; set; }&lt;br /&gt;
        public int Top { get; set; }&lt;br /&gt;
        public int Right { get; set; }&lt;br /&gt;
        public int Bottom { get; set; }&lt;br /&gt;
&lt;br /&gt;
        public override string ToString()&lt;br /&gt;
        {&lt;br /&gt;
            return string.Format("{0}, {1}, {2}, {3}", Left, Top, Right, Bottom);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]&lt;br /&gt;
    internal struct MonitorInfoEx&lt;br /&gt;
    {&lt;br /&gt;
        public int Size;&lt;br /&gt;
        public Win32Rect Monitor;&lt;br /&gt;
        public Win32Rect WorkArea;&lt;br /&gt;
        public uint Flags;&lt;br /&gt;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DisplayManager.DeviceNameCharacterCount)]&lt;br /&gt;
        public string DeviceName;&lt;br /&gt;
&lt;br /&gt;
        public void Init()&lt;br /&gt;
        {&lt;br /&gt;
            this.Size = 40 + 2 * DisplayManager.DeviceNameCharacterCount;&lt;br /&gt;
            this.DeviceName = string.Empty;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
    public class DisplayManager&lt;br /&gt;
    {&lt;br /&gt;
        // size of a device name string&lt;br /&gt;
        internal const int DeviceNameCharacterCount = 32;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private delegate bool MonitorEnumProcDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref Win32Rect lprcMonitor, uint dwData);&lt;br /&gt;
&lt;br /&gt;
        [DllImport("user32.dll")]&lt;br /&gt;
        private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProcDelegate lpfnEnum, uint dwData);&lt;br /&gt;
&lt;br /&gt;
        [DllImport("user32.dll", CharSet = CharSet.Auto)]&lt;br /&gt;
        private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorInfoEx lpmi);&lt;br /&gt;
&lt;br /&gt;
        private static ObservableCollection&amp;lt;DisplayInfo&amp;gt; _displays = new ObservableCollection&amp;lt;DisplayInfo&amp;gt;();&lt;br /&gt;
        public static ObservableCollection&amp;lt;DisplayInfo&amp;gt; Displays&lt;br /&gt;
        {&lt;br /&gt;
            get { return _displays; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public static void LoadDisplays()&lt;br /&gt;
        {&lt;br /&gt;
            EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, 0);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        [AllowReversePInvokeCalls]&lt;br /&gt;
        internal static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref Win32Rect lprcMonitor, uint dwData)&lt;br /&gt;
        {&lt;br /&gt;
            var monitor = new MonitorInfoEx();&lt;br /&gt;
            monitor.Init();&lt;br /&gt;
&lt;br /&gt;
            bool success = GetMonitorInfo(hMonitor, ref monitor);&lt;br /&gt;
&lt;br /&gt;
            if (success)&lt;br /&gt;
            {&lt;br /&gt;
                var display = new DisplayInfo();&lt;br /&gt;
&lt;br /&gt;
                display.MonitorName = monitor.DeviceName;&lt;br /&gt;
&lt;br /&gt;
                display.Width = monitor.Monitor.Right - monitor.Monitor.Left;&lt;br /&gt;
                display.Height = monitor.Monitor.Bottom - monitor.Monitor.Top;&lt;br /&gt;
&lt;br /&gt;
                display.MonitorArea = monitor.Monitor;&lt;br /&gt;
                display.WorkArea = monitor.WorkArea;&lt;br /&gt;
                display.IsPrimary = (monitor.Flags &amp;gt; 0);&lt;br /&gt;
&lt;br /&gt;
                _displays.Add(display);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;This code calls EnumDisplayMonitors to enumerate the monitors on
the system. For each monitor found, I then call GetMonitorInfo to
pull back the details. From that call, I create a DisplayInfo class
and populate it, ready to be used by the rest of the Silverlight
application. The list of DisplayInfo classes is stored in a
class-scope collection.&lt;/p&gt;

&lt;p&gt;Note the "AllowReversePInvokeCalls" attribute on
MonitorEnumProc. That attribute is required for any callbacks. It
also means we couldn't use a simple anonymous delegate for the
callback, as those can't have attributes.&lt;/p&gt;

&lt;p&gt;Finally, a short call in MainPage.xaml and we're able to get the
display sizes&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
public MainPage()&lt;br /&gt;
{&lt;br /&gt;
    InitializeComponent();&lt;br /&gt;
&lt;br /&gt;
    DisplayManager.LoadDisplays();&lt;br /&gt;
&lt;br /&gt;
    DisplayList.ItemsSource = DisplayManager.Displays;&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Run the application. On my screen, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83410/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_12.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83415/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb_5.png" width="650" height="177" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, so now we know how to position a display using hard-coded
values, and how to get the display list from windows. Now, to
combine the two to help with sizing and positioning.&lt;/p&gt;

&lt;h3&gt;Positioning and Sizing the Window&lt;/h3&gt;

&lt;p&gt;Positioning the window can be tricky. There are any number of
ways that monitors can be configured. Here are just a few
interesting (and common) ones, in addition to the ones mentioned
above:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83420/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_16.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83425/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb_7.png" width="650" height="176" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you look at the teal and the green examples, you can see
where a rectangular pixel mapping puts some logical pixels out into
never-never land. On systems like that, a single window spanning
all displays is not particularly practical. In any case, most
multi-display configurations are two, or at most, three displays
because that's all you can typically drive from a single typical
video card.&lt;/p&gt;

&lt;p&gt;As an aside, I've run with all four examples shown above, plus a
few extras. My current layout is 2x 30" displays side by side with
primary on right and secondary on left, plus a 23" display on top
of the primary. The 23" display is connected to a different
computer, however, and shared using Input Director, so it doesn't
factor into this discussion.&lt;/p&gt;

&lt;p&gt;With just the two displays I have, it's easy to test a number of
different scenarios simply by changing resolution and monitor
position in display settings. First, some code to position the
window on a specific screen.&lt;/p&gt;

&lt;h4&gt;Position Window on Primary Display&lt;/h4&gt;

&lt;p&gt;A PC can have only one primary display. Conveniently, the
display is called out as such via the API.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void PositionWindowOnSingleScreen(DisplayInfo screen, Window window, bool SizeToScreen = true, bool maximize = false)&lt;br /&gt;
{&lt;br /&gt;
    window.Left = screen.MonitorArea.Left;&lt;br /&gt;
    window.Top = screen.MonitorArea.Top;&lt;br /&gt;
&lt;br /&gt;
    if (SizeToScreen)&lt;br /&gt;
    {&lt;br /&gt;
        window.Width = screen.Width;&lt;br /&gt;
        window.Height = screen.Height;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (maximize)&lt;br /&gt;
        window.WindowState = WindowState.Maximized;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
private void OpenPrimary_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    if (DisplayManager.Displays.Count &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        // find primary display&lt;br /&gt;
        DisplayInfo info = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                            where di.IsPrimary&lt;br /&gt;
                            select di).FirstOrDefault();&lt;br /&gt;
&lt;br /&gt;
        if (info != null)&lt;br /&gt;
        {&lt;br /&gt;
            Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
            PositionWindowOnSingleScreen(info, w, true, false);&lt;br /&gt;
&lt;br /&gt;
            w.Show();&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            MessageBox.Show("No primary display. I suppose you won't see this message.");&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MessageBox.Show("Display list not yet loaded.");&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This example uses a little LINQ to find the primary screen and
then a separate function to position the window on that screen. I
can't think of a case where you'd have no primary display, but I
check for it anyway.&lt;/p&gt;

&lt;h4&gt;Position Window on Secondary Display&lt;/h4&gt;

&lt;p&gt;Primary is cool. You can do that without any API calls.
Secondary is normally a little more work, but I have you
covered.&lt;/p&gt;

&lt;p&gt;You can, of course, have more than one secondary display. In my
case, I have only one, so I'm going to position this window in the
first secondary display I have.&lt;/p&gt;

&lt;pre class="brush: csharp; highlight: [7];"&gt;
private void OpenSecondary_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    if (DisplayManager.Displays.Count &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        // find first secondary display&lt;br /&gt;
        DisplayInfo info = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                            where !di.IsPrimary&lt;br /&gt;
                            select di).FirstOrDefault();&lt;br /&gt;
&lt;br /&gt;
        if (info != null)&lt;br /&gt;
        {&lt;br /&gt;
            Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
            PositionWindowOnSingleScreen(info, w, true, false);&lt;br /&gt;
&lt;br /&gt;
            w.Show();&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            MessageBox.Show("No secondary display available.");&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MessageBox.Show("Display list not yet loaded.");&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;In this case, all I needed to change was the error message and
add a little bang in the where clause of the LINQ query.&lt;/p&gt;

&lt;h4&gt;Make a window take up all Display Space&lt;/h4&gt;

&lt;p&gt;This goes specifically to the 3x3 screen scenario. As I
mentioned, we'll need to assume rectangular window space here, as
anything else is going to be pretty application-specific.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void OpenWindow_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    if (DisplayManager.Displays.Count &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        Window w = new Window();&lt;br /&gt;
&lt;br /&gt;
        w.Left = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                  select di.MonitorArea.Left).Min();&lt;br /&gt;
&lt;br /&gt;
        w.Top = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                 select di.MonitorArea.Top).Min();&lt;br /&gt;
&lt;br /&gt;
        w.Width = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                   select di.Width).Sum();&lt;br /&gt;
&lt;br /&gt;
        w.Height = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                    select di.Height).Sum();&lt;br /&gt;
&lt;br /&gt;
        w.Show();&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MessageBox.Show("Display list not yet loaded.");&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Because we're assuming a reasonably logical rectangle, I can
simply take the minimum left and top values and use that to
position the window, and then sum the height and width values in
order to size the window.&lt;/p&gt;

&lt;p&gt;As an aside, Silverlight had no issues opening this window on my
machine. I'm not sure I'd recommend stretching a video across it,
though.&lt;/p&gt;

&lt;p&gt;Well, actually, I can't let that lie out there like that. Let's
try it. Add this code right after the w.Height setting and before
the w.Show() line&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
MediaElement video = new MediaElement();&lt;br /&gt;
video.Width = w.Width;&lt;br /&gt;
video.Height = w.Height;&lt;br /&gt;
video.Source = new Uri("/pub/sl5iA/NetduinoRobot_SmallM.wmv", UriKind.Absolute);&lt;br /&gt;
video.Stretch = Stretch.UniformToFill;&lt;br /&gt;
video.AutoPlay = true;&lt;br /&gt;
&lt;br /&gt;
w.Content = video;
&lt;/pre&gt;

&lt;p&gt;I stretch the video so it takes up all space (UniformToFill) and
clips the video so the aspect ratio stays correct. It works, and
works well, If the the video was high enough resolution, it would
even look good.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83430/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_18.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83435/Windows-Live-Writer_Creating-Big-Silverlight-Windows_123FB_image_thumb_8.png" width="531" height="166" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sweet! Big video. That's almost like IMax or &lt;a
href="http://en.wikipedia.org/wiki/Ultra_High_Definition_Television"&gt;
UHDTV&lt;/a&gt; :)&lt;/p&gt;

&lt;h4&gt;Position Main Window on a Named Display&lt;/h4&gt;

&lt;p&gt;This is particularly useful if you're restoring windows when
starting up a new session. You could store the display device name
and then do some checks on startup and if the device name and
resolution are still valid (they could have swapped displays,
bought new ones, got rid of one, etc.) position the window on that
display. If not, position it on the main display.&lt;/p&gt;

&lt;p&gt;In this case, I'm simply going to position the main Silverlight
window on to the display you click on in the ListBox. The code is
simple enough. First, add a button to the MainPage, under the other
buttons.&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;
&amp;lt;Button Content="Move to Selected"&lt;br /&gt;
        Height="23"&lt;br /&gt;
        HorizontalAlignment="Left"&lt;br /&gt;
        Margin="12,115,0,0"&lt;br /&gt;
        Name="MoveToSelectedButton"&lt;br /&gt;
        VerticalAlignment="Top"&lt;br /&gt;
        Width="108"&lt;br /&gt;
        Click="MoveToSelectedButton_Click" /&amp;gt;&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;Next, the event handler and work function in the code-behind.
&lt;strong&gt;There are many ways I could have done this (especially
using SelectedItem), but I specifically want to show using the
device name&lt;/strong&gt;. I know it's extra work, but I'm doing it
on-purpose; the value you store upon exiting is not going to be an
object instance, it's going to be a screen device name string.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void MoveMainWindowToSelectedDisplay()&lt;br /&gt;
{&lt;br /&gt;
    // see comments in blog post as to why I went with strings&lt;br /&gt;
    string deviceName = ((DisplayInfo)DisplayList.SelectedItem).MonitorName;&lt;br /&gt;
&lt;br /&gt;
    DisplayInfo display = (from DisplayInfo di in DisplayManager.Displays&lt;br /&gt;
                            where di.MonitorName.ToLower() == deviceName.ToLower()&lt;br /&gt;
                            select di).FirstOrDefault();&lt;br /&gt;
&lt;br /&gt;
    var mainWindow = Application.Current.MainWindow;&lt;br /&gt;
&lt;br /&gt;
    // center on the display&lt;br /&gt;
&lt;br /&gt;
    mainWindow.Left = display.MonitorArea.Left + (display.Width - mainWindow.Width) / 2;&lt;br /&gt;
    mainWindow.Top = display.MonitorArea.Top + (display.Height - mainWindow.Height) / 2;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private void MoveToSelectedButton_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    if (DisplayList.SelectedItem != null)&lt;br /&gt;
    {&lt;br /&gt;
        MoveMainWindowToSelectedDisplay();&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MessageBox.Show("Please select a screen from the list");&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The code moves the window to the selected monitor and then
centers in that monitor. Some additional checking to make sure the
window isn't wider than that monitor would be a good idea.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;The intent of this post was to give you the foundation you'll
need in order to do window manipulation in Silverlight. Once you
start doing multi-monitor window manipulation, you probably have a
good idea of what you want to do with it. I'll leave it up to you
to take this code and run with it to suit your specific application
needs.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5XJRz3uKKdDDcZIUIbWdzr_VtmY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5XJRz3uKKdDDcZIUIbWdzr_VtmY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5XJRz3uKKdDDcZIUIbWdzr_VtmY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5XJRz3uKKdDDcZIUIbWdzr_VtmY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=LnBVZe8RTLI:tJgv1pGT0io:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=LnBVZe8RTLI:tJgv1pGT0io:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=LnBVZe8RTLI:tJgv1pGT0io:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=LnBVZe8RTLI:tJgv1pGT0io:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=LnBVZe8RTLI:tJgv1pGT0io:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=LnBVZe8RTLI:tJgv1pGT0io:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=LnBVZe8RTLI:tJgv1pGT0io:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=LnBVZe8RTLI:tJgv1pGT0io:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=LnBVZe8RTLI:tJgv1pGT0io:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/LnBVZe8RTLI" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/02/07/creating-big-silverlight-windows-and-getting-monitor-resolutions-and-positions-with-pinvoke</feedburner:origLink></item><item><title>The Commodore 64 Emulator: Emulating Pointers in a sandbox when the real thing is not allowed</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/p4m7Barcbbw/the-commodore-64-emulator-emulating-pointers-in-a-sandbox-when-the-real-thing-is-not-allowed</link><pubDate>Tue, 07 Feb 2012 00:02:46 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/02/06/the-commodore-64-emulator-emulating-pointers-in-a-sandbox-when-the-real-thing-is-not-allowed</guid><description>&lt;p&gt;Late last week, I cracked open the &lt;a
href="http://silverlightc64.codeplex.com/"&gt;Commodore 64 emulator
code&lt;/a&gt; once again, in preparation to post it. However, I had to
have a change made to the source control on CodePlex, so I had a
few days to make some changes. So far, it's shaping up quite
nicely:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83308/Windows-Live-Writer_1244081fb4e8_EF48_image_16.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83313/Windows-Live-Writer_1244081fb4e8_EF48_image_thumb_7.png" width="320" height="202" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;a
href="http://10rem.net/media/83318/Windows-Live-Writer_1244081fb4e8_EF48_image_18.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83323/Windows-Live-Writer_1244081fb4e8_EF48_image_thumb_8.png" width="320" height="202" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I went back to the latest version of the &lt;a
href="http://www.cebix.net/viewcvs/cebix/Frodo4/Src/"&gt;Frodo C64
emulator source code&lt;/a&gt; and decided to port some of their changes
over to this version. Frodo is written in C and C++, and makes very
heavy use of pointers (and not always safe use of them, as there
was at least one logical overrun). In the previous version, I had
replaced pointers with array manipulation, but I did it in a way
that resulted in an awful lot of array copies floating around. The
arrays were small, so this wasn't a big deal memory-wise, but the
copies all took time in an otherwise time-critical application.&lt;/p&gt;

&lt;p&gt;Silverlight doesn't support pointers or unsafe code. Of course,
in elevated trust mode, with a not-really-supported hack, you can
have pointers in Silverlight. However, I wanted to stay away from
that for now as it only works in Silverlight 5, only on Windows,
and won't port to any other sandboxed XAML platforms.&lt;/p&gt;

&lt;p&gt;So, I decided to finish what I started and build out some decent
almost-pointerish safe analogs in Silverlight. It was a fairly
large amount of effort, but I thought it might also be interesting
to read about here.&lt;/p&gt;

&lt;h3&gt;How Pointers Work&lt;/h3&gt;

&lt;p&gt;If you've never written any C/C++ code, there's a better than
zero chance that you haven't done any explicit pointer manipulation
in your own code. That's not a bad thing, really, as the typical
business application (and many other types) simply doesn't need to
do pointer arithmetic. It's not worth the inherent danger for the
small performance increase. That said, &lt;strong&gt;an understanding of
how pointers work is&amp;nbsp; fundamental computer science, and is
important for all developers to know.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's only when you have to do a lot of memory walking in a
performance-critical application that you run into this. &lt;a
href="http://10rem.net/blog/2012/01/15/gnu-cplusplus-blinkenled-part-1-on-the-avr-atmega1284p-with-mikroelektronika-easyavr6-and-atmel-avr-studio-51"&gt;
Programming for microcontrollers like the AVR&lt;/a&gt; is a great way to
refresh your memory as to how pointers work and what they bring to
the table.&lt;/p&gt;

&lt;p&gt;A pointer is an address in memory and an associated type size.
For example, if we have some fictional 6 byte memory chunk and
declare a pointer to a byte, we end up with something like this
(bonus points if you can figure out the significance of the 5 bytes
starting at 0x01):&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83328/Windows-Live-Writer_1244081fb4e8_EF48_image_8.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83333/Windows-Live-Writer_1244081fb4e8_EF48_image_thumb_3.png" width="650" height="204" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, our byte pointer points to the 8 bits starting at
the address 0x01. You can then manipulate memory using pointer
arithmetic:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
byte* p = 0x01;    // declare pointer to memory address 0x01&lt;br /&gt;
&lt;br /&gt;
*p = 0x30;         // changes value at 0x01 to 0x30 from 0x78&lt;br /&gt;
&lt;br /&gt;
*(p+3) = 0x00;     // changes value at 0x04 to 0x00 from 0x7A&lt;br /&gt;
&lt;br /&gt;
while (p &amp;lt; 0x06)   // clear rest of memory&lt;br /&gt;
  *p++ = 0x00;
&lt;/pre&gt;

&lt;p&gt;This is very fast because there really is no indirection. You're
telling the compiler exactly what address to manipulate - it
doesn't have to look anything up.&lt;/p&gt;

&lt;p&gt;The size of the pointer variable has to do with the architecture
of the system and its addressing scheme (8 bit, 16 bit, 32 bit, 64
bit), as well as compiler options you select. (In the case of the
Commodore 64, it's all 8 bit.).&lt;/p&gt;

&lt;p&gt;You're not limited to the smallest memory unit size, though. If
you wanted to declare a pointer to a 16 bit integer, you'd get this
(assuming "short" is 16 bits on your system):&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83338/Windows-Live-Writer_1244081fb4e8_EF48_image_10.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83343/Windows-Live-Writer_1244081fb4e8_EF48_image_thumb_4.png" width="650" height="204" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, depending on the &lt;a
href="http://en.wikipedia.org/wiki/Endian"&gt;endian-ness&lt;/a&gt; of your
system, the resulting 16 bit number may be 0x7879 (big endian) or
0x7978 (little endian).&lt;/p&gt;

&lt;p&gt;It starts to get really powerful when you consider that a
pointer to a structure could also be considered a pointer to a
number of bytes. That allows you to, for example, read a bunch of
bytes from a disk, look at the first couple bytes to figure out
what you have, and then cast the remaining X bytes as the pointer a
directory structure or something. The original C++ C64 emulator
code does a ton of that.&lt;/p&gt;

&lt;h4&gt;How pointers are used in Frodo&lt;/h4&gt;

&lt;p&gt;In addition to pointers to structures in byte buffers, frodo
does a lot of string parsing using pointers. In particular, the
1541 drive emulation code uses this for command parsing. In that
code, the first character is often some command identifier, the
next is a delimiter (like a colon) and then some number of
comma-separated values.&lt;/p&gt;

&lt;p&gt;In our normal pointer-less code, we'd typically parse the string
and then make copies for each of the individual components. Another
way to deal with it is to simply provide pointers to each of the
sections therefore avoiding making copies of memory. That's
typically how the Frodo code works.&lt;/p&gt;

&lt;p&gt;In my first version of the code, I used array indexes to
simulate this. However, that code got incredibly nasty to work
with. I needed another solution.&lt;/p&gt;

&lt;h3&gt;The Simulated Pointer&lt;/h3&gt;

&lt;p&gt;You can simulate pointers by simply passing around arrays,
making copies, or even using array indexes. But, as I mentioned,
that code tends to get pretty messy as you have lots of dependent
variables. Instead, I needed a way to encapsulate all of this and
provide pointer-like functionality to handle the majority of the
cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The primary goal of this effort is to make it easy to have code
which is close to 1:1 with its C++ counterparts. For example, if
the C++ code increments a pointer and then assigns a value, I want
to be able to do something similar without having to worry about
which array the pointer points to, or what index value is. The code
won't be 1:1, but I want it as close as possible.&lt;/li&gt;

&lt;li&gt;Another goal of this effort is to minimize the number of times
I copy arrays around. Primarily this is for performance reasons as
the emulator code needs to loop at least one million times a second
(1MHz). Minimizing array copies and object instances helps keep GC
under control as well.&lt;/li&gt;

&lt;li&gt;A non-goal of this effort is efficient use of actual memory. In
fact, my pointer structures use more memory than a pointer just to
simulate a pointer. I'm ok with that.&lt;/li&gt;

&lt;li&gt;Another non-goal is the ability to cast a pointer to a
structure or other complex type. I'd love to do that, but that's
not sandbox-friendly and it's not going to happen that way in this
code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The C64 code has a number of places where it has memory
allocated in chunks. The most obvious is the main memory of the
system (64K), but there's also 2K in the VIC-1541 drive. Beyond
those, there are several chunks of ROM code which get loaded up and
then mapped into various address locations (cartridges too). In the
emulator code, these are just large arrays of bytes.&lt;/p&gt;

&lt;p&gt;If you ever had to simulate an operating system in college,
you've done this before.&lt;/p&gt;

&lt;p&gt;Here's an example of two pointers "A" and "B". Pointer A points
to address 0x01 in the memory array. Pointer B points to address
0x05.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83348/Windows-Live-Writer_1244081fb4e8_EF48_image_14.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83353/Windows-Live-Writer_1244081fb4e8_EF48_image_thumb_6.png" width="650" height="272" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code to create these looks something like this:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
SystemRam ram = new SystemRam();&lt;br /&gt;
&lt;br /&gt;
var a = new RamBytePointer(ram, 0x00);&lt;br /&gt;
var b = new RamBytePointer(ram, 0x05);&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;The RamBytePointer structure represents the pointer. It has a
member Value which can be used to get/set the value at that
position. It also has a number of other helper methods to do things
like copy values from arrays, comparisons with other pointers, etc.
Note that the pointer structure takes a reference to the memory it
is allowed to manipulate. A real pointer has pretty much free run
of memory, so you need to keep the RAM pretty broadly defined if
you need that flexibility.&lt;/p&gt;

&lt;p&gt;Here's the current version of the structure. It doesn't do quite
everything I want yet (for example, nothing with comparisons
between pointers, for example), but it does a fair bit.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System.Diagnostics;&lt;br /&gt;
using System.Text;&lt;br /&gt;
using System;&lt;br /&gt;
&lt;br /&gt;
namespace PeteBrown.C64.Core.Memory&lt;br /&gt;
{&lt;br /&gt;
    public struct RamBytePointer&lt;br /&gt;
    {&lt;br /&gt;
        public RamBytePointer(RamBase memory, int address)&lt;br /&gt;
            : this(memory)&lt;br /&gt;
        {&lt;br /&gt;
            _address = address;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public RamBytePointer(RamBase memory)&lt;br /&gt;
        {&lt;br /&gt;
            _memory = memory;&lt;br /&gt;
            _address = 0;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private RamBase _memory;&lt;br /&gt;
        private RamBase Memory&lt;br /&gt;
        {&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            get { return _memory; }&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            set { _memory = value; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private int _address;&lt;br /&gt;
        public int Address&lt;br /&gt;
        {&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            get { return _address; }&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            set { _address = value; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public byte this[int offset]&lt;br /&gt;
        {&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            get { return _memory[_address + offset]; }&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            set { _memory[_address + offset] = value; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public byte Value&lt;br /&gt;
        {&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            get { return _memory[_address]; }&lt;br /&gt;
            [DebuggerStepThrough]&lt;br /&gt;
            set { _memory[_address] = value; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public byte[] GetValues(int length)&lt;br /&gt;
        {&lt;br /&gt;
            return _memory.Read(_address, length);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void SetValues(byte[] values)&lt;br /&gt;
        {&lt;br /&gt;
            _memory.Write(_address, values);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public void CopyFrom(byte[] values, bool incrementPointer)&lt;br /&gt;
        {&lt;br /&gt;
            for (int i = 0; i &amp;lt; values.Length; i++)&lt;br /&gt;
            {&lt;br /&gt;
                _memory[_address + i] = values[i];&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (incrementPointer)&lt;br /&gt;
                _address += values.Length;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void CopyFrom(char[] characters, bool incrementPointer)&lt;br /&gt;
        {&lt;br /&gt;
            for (int i = 0; i &amp;lt; characters.Length; i++)&lt;br /&gt;
            {&lt;br /&gt;
                _memory[_address + i] = (byte)characters[i];&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (incrementPointer)&lt;br /&gt;
                _address += characters.Length;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void CopyFrom(string characters, bool incrementPointer)&lt;br /&gt;
        {&lt;br /&gt;
            for (int i = 0; i &amp;lt; characters.Length; i++)&lt;br /&gt;
            {&lt;br /&gt;
                _memory[_address + i] = (byte)characters[i];&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (incrementPointer)&lt;br /&gt;
                _address += characters.Length;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public RamBytePointer NewPointerAtOffset(int offset)&lt;br /&gt;
        {&lt;br /&gt;
            return new RamBytePointer(_memory, _address + offset);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public static RamBytePointer operator +(RamBytePointer p, int offset)&lt;br /&gt;
        {&lt;br /&gt;
            return new RamBytePointer(p.Memory, p.Address + offset);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public static RamBytePointer operator -(RamBytePointer p, int offset)&lt;br /&gt;
        {&lt;br /&gt;
            return new RamBytePointer(p.Memory, p.Address - offset);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public static RamBytePointer operator ++(RamBytePointer p)&lt;br /&gt;
        {&lt;br /&gt;
            p.Address += 1;&lt;br /&gt;
&lt;br /&gt;
            return p;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public static RamBytePointer operator --(RamBytePointer p)&lt;br /&gt;
        {&lt;br /&gt;
            p.Address -= 1;&lt;br /&gt;
&lt;br /&gt;
            return p;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public int IndexOf(byte value, int count)&lt;br /&gt;
        {&lt;br /&gt;
            return _memory.IndexOf(value, 0, count);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int IndexOf(char value, int count)&lt;br /&gt;
        {&lt;br /&gt;
            return _memory.IndexOf(value, 0, count);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public bool Contains(char value, int count)&lt;br /&gt;
        {&lt;br /&gt;
            return _memory.Contains(value, 0, count);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public bool Contains(byte value, int count)&lt;br /&gt;
        {&lt;br /&gt;
            return _memory.Contains(value, 0, count);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public string ToString(int startIndex, int length)&lt;br /&gt;
        {&lt;br /&gt;
            StringBuilder builder = new StringBuilder();&lt;br /&gt;
&lt;br /&gt;
            for (int i = startIndex; i &amp;lt; length; i++)&lt;br /&gt;
            {&lt;br /&gt;
                builder.Append((char)_memory[i]);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return builder.ToString();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;The memory array itself is always created and maintained outside
of this class. It must be valid when the pointer is created.&lt;/p&gt;

&lt;h4&gt;Operator overloading and Offsets&lt;/h4&gt;

&lt;p&gt;Of interest is the operator overloading. This allows me to do
things like p++ or p += 1 in order to modify the address that the
pointer is pointing to. That's an important part of keeping the C#
code as similar as possible to the C++ code. However, it doesn't
allow everything the C++ code allows. For example, I can't do the
exact equivalent of this code:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
*(p + 5) = 0x05;&lt;br /&gt;
*(p - 7) = 0x0A;
&lt;/pre&gt;

&lt;p&gt;If I try to do the equivalent of that, the compiler will barf at
me as it needs an actual LValue on the left side. Instead, code
like that must use something like this:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
p[5] = 0x05;&lt;br /&gt;
p[-7] = 0x0A;
&lt;/pre&gt;

&lt;p&gt;The code is similar enough that I'm happy with it, although
developers new to the code may raise a few eyebrows at the p[-7]
version.&lt;/p&gt;

&lt;h4&gt;Converting Strings&lt;/h4&gt;

&lt;p&gt;Because much of the C++ code treats characters and bytes as
interchangeable (something you can't really do with arrays in C# on
Windows), I also have a few overloads that can take characters or
bytes. This helps clean up the consuming code so it doesn't have so
many casts.&lt;/p&gt;

&lt;p&gt;I have helper functions in there to copy from strings. This
helps me easily translate code such as this:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
*p++ = 'B';&lt;br /&gt;
*p++ = 'L';&lt;br /&gt;
*p++ = 'O';&lt;br /&gt;
*p++ = 'C';&lt;br /&gt;
*p++ = 'K';&lt;br /&gt;
*p++ = 'S';&lt;br /&gt;
*p++ = ' ';&lt;br /&gt;
*p++ = 'F';&lt;br /&gt;
*p++ = 'R';&lt;br /&gt;
*p++ = 'E';&lt;br /&gt;
*p++ = 'E';&lt;br /&gt;
*p++ = '.';
&lt;/pre&gt;

&lt;p&gt;Into a nice single-liner like p.CopyFrom("BLOCKS FREE.",
true);&lt;/p&gt;

&lt;h4&gt;A Structure, not a Class&lt;/h4&gt;

&lt;p&gt;Note that this is a structure, not a class. Why? Having it as a
structure lets me make copies easily. It's common practice in C/C++
code to have a pointer passed into a function, and then make a copy
of it to increment yourself. For example:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
void DoSomething (byte * baseAddress)&lt;br /&gt;
{&lt;br /&gt;
    byte * p = baseAddress;&lt;br /&gt;
&lt;br /&gt;
    while (p++ != 0x0A)&lt;br /&gt;
        ...&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;In this example C++ function, p starts off at the same address
as "baseAddress", but then increments it. The value for baseAddress
must be left alone.&lt;/p&gt;

&lt;p&gt;Reference types like class in C# are themselves pointers. So,
due to the level of indirection this has, we'd end up modifying the
original value:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
class RamBytePointer { ... }&lt;br /&gt;
&lt;br /&gt;
void DoSomething (RamBytePointer baseAddress)&lt;br /&gt;
{&lt;br /&gt;
    RamBytePointer p = baseAddress;&lt;br /&gt;
&lt;br /&gt;
    p += 5;&lt;br /&gt;
&lt;br /&gt;
    Debug.WriteLine(p.Address);&lt;br /&gt;
    Debug.WriteLine(baseAddress.Address);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ---------------------------------------&lt;br /&gt;
&lt;br /&gt;
struct RamBytePointer { ... }&lt;br /&gt;
&lt;br /&gt;
void DoSomething (RamBytePointer baseAddress)&lt;br /&gt;
{&lt;br /&gt;
    RamBytePointer p = baseAddress;&lt;br /&gt;
&lt;br /&gt;
    p += 5;&lt;br /&gt;
&lt;br /&gt;
    Debug.WriteLine(p.Address);&lt;br /&gt;
    Debug.WriteLine(baseAddress.Address);&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The first example doesn't work like pointers in C++ at all.
Incrementing p also increments baseAddress. The second example,
however, works as we would expect because p is a copy of
baseAddress, not a reference to it.&lt;/p&gt;

&lt;p&gt;The downside of using a struct is there's no inheritance. So, I
instead put a fair bit of the potentially reusable code into the
memory classes instead, and simply call that from the pointer
class.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Simulating pointers in pointer-free sandboxed platforms is a bit
unorthodox, but can make translating code easier.&lt;/p&gt;

&lt;p&gt;This isn't something you're likely to need to do in your own
code, but it an interesting exercise in any case. There's no
downloadable source code yet, as I'm still refining this
implementation. You'll be able to get a version of these classes in
the &lt;a href="http://silverlightc64.codeplex.com/"&gt;SilverlightC64
code&lt;/a&gt; when I post it in the next week or less. It's taking
longer to swap out all this code than I had intended :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you've ever had to do anything like this in your own
code, I'd love to hear about it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/N7m9cxEmnCz9G7I5EEYzl-SPaTM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N7m9cxEmnCz9G7I5EEYzl-SPaTM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/N7m9cxEmnCz9G7I5EEYzl-SPaTM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/N7m9cxEmnCz9G7I5EEYzl-SPaTM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=p4m7Barcbbw:c0ix7zEKhU4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=p4m7Barcbbw:c0ix7zEKhU4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=p4m7Barcbbw:c0ix7zEKhU4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=p4m7Barcbbw:c0ix7zEKhU4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=p4m7Barcbbw:c0ix7zEKhU4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=p4m7Barcbbw:c0ix7zEKhU4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=p4m7Barcbbw:c0ix7zEKhU4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=p4m7Barcbbw:c0ix7zEKhU4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=p4m7Barcbbw:c0ix7zEKhU4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/p4m7Barcbbw" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/02/06/the-commodore-64-emulator-emulating-pointers-in-a-sandbox-when-the-real-thing-is-not-allowed</feedburner:origLink></item><item><title>Event Handler Memory Leaks, Unwiring Events, and the WeakEventManager in WPF 4.5</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/cNCfpxx_N5Y/event-handler-memory-leaks-unwiring-events-and-the-weakeventmanager-in-wpf-45</link><pubDate>Wed, 01 Feb 2012 04:27:14 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/02/01/event-handler-memory-leaks-unwiring-events-and-the-weakeventmanager-in-wpf-45</guid><description>&lt;p&gt;Many developers don't realize that a common source of memory
leaks in .NET applications is the event handler. WPF 4.5 includes
built-in support for weak events to help us do the right thing and
not eat up all the available memory.&lt;/p&gt;

&lt;h3&gt;The Problem&lt;/h3&gt;

&lt;p&gt;Events are ubiquitous in .NET. When you add an event handler
using the &lt;em&gt;EventName += &amp;lt;my event handler delegate&amp;gt;&lt;/em&gt;
syntax, the event source acquires a reference to the listener. This
situation is a circular reference, as the listener had a reference
to the source to begin with.&lt;/p&gt;

&lt;p&gt;These references are "strong references". That is, they are
actual pointers to resources.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/83227/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_9.png" width="650" height="151" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;In the .NET framework, circular references aren't usually a
problem. If the set of objects can't be traced back to the root
object in the application, they are garbage collected. That's
great, but in this case, due to the references from the event
source to the event listener, as long as the event source is
reachable, the listener will also stay around, as the event source
can be traced back to a valid object root.&lt;/p&gt;

&lt;p&gt;This can be a real problem if the event source is long-lived, as
is the case with things like application configuration objects, or
other static or singleton objects. Event handlers are often on the
UI side of things, so the listener can be a resource and memory
heavy Window object.&lt;/p&gt;

&lt;p&gt;Take this scenario: Over the course of an application's
lifetime, the user opens and closes document windows. The document
windows each have a reference to some other object: it could be the
parent window, it could be a static configuration class, it could
be a shared singleton data provider somewhere up the chain. The
important thing is that the windows are listening to an event from
that object: CollectionChanged, some custom DataLoaded or other
event.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/83232/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_17.png" width="650" height="228" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;Now, when the parent window (and your code) releases all
reference to the window instance, the event source still has a
reference to them. And, because the event source also has a
reference from the application (implicit if it's static - man that
lifetime gets ugly), the windows stay around:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/83237/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_20.png" width="650" height="228" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;No GC or disposal for those window instances. Windows tend to
have a lot of resources tied up just to paint (control templates,
controles themselves, data even) so they're not cheap resources. It
gets even nastier, though. If those instances have references to,
say, individual ViewModel instances, and those ViewModels have
references to a cache of data, you can end up with pretty enormous
memory leaks. Open up enough windows and, eventually, your app will
run out of resources.&lt;/p&gt;

&lt;h3&gt;Basis for Comparison&lt;/h3&gt;

&lt;p&gt;Before we look at the problem, here's a profile of the
application opening 200 windows, closing the 200 windows, and then
forcing a GC. I did this three and then closed the app. Each window
allocates a bunch of memory in an array just to give it a payload.
The window code looks like this:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
public partial class TestChildWindow : Window&lt;br /&gt;
{&lt;br /&gt;
    long[] _memoryHog;&lt;br /&gt;
&lt;br /&gt;
    public TestChildWindow()&lt;br /&gt;
    {&lt;br /&gt;
        InitializeComponent();&lt;br /&gt;
&lt;br /&gt;
        Random rnd = new Random();&lt;br /&gt;
&lt;br /&gt;
        string imageName = "Assets/image" + rnd.Next(1, 9) + ".jpg";&lt;br /&gt;
        NeatoImage.Source = new BitmapImage(new Uri(imageName, UriKind.Relative));&lt;br /&gt;
&lt;br /&gt;
        _memoryHog = new long[1024];&lt;br /&gt;
&lt;br /&gt;
        Unloaded += new RoutedEventHandler(TestChildWindow_Unloaded);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void TestChildWindow_Unloaded(object sender, RoutedEventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;In the upcoming examples, the TestChildWindow will have a
reference to the SettingsManager. This is a stub class meant to
represent pretty much any long-lived instance in your
application.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
namespace WpfWeakEventManager&lt;br /&gt;
{&lt;br /&gt;
    class SettingsManager&lt;br /&gt;
    {&lt;br /&gt;
        public event EventHandler SettingsChanged;&lt;br /&gt;
&lt;br /&gt;
        private static SettingsManager _current;&lt;br /&gt;
        public static SettingsManager Current&lt;br /&gt;
        {&lt;br /&gt;
            get&lt;br /&gt;
            {&lt;br /&gt;
                if (_current == null)&lt;br /&gt;
                    _current = new SettingsManager();&lt;br /&gt;
&lt;br /&gt;
                return _current;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;Finally, the Main Window has three buttons that I used to test
the application. The first opens 200 windows. The second closes all
windows (except the main one) being tracked by the application. The
third forces a GC collection. It also has a listbox to show
diagnostic information when I'm not running with an attached
debugger.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
namespace WpfWeakEventManager&lt;br /&gt;
{&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;&lt;br /&gt;
    /// Interaction logic for MainWindow.xaml&lt;br /&gt;
    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
    public partial class MainWindow : Window&lt;br /&gt;
    {&lt;br /&gt;
        private SettingsManager _current;&lt;br /&gt;
&lt;br /&gt;
        public MainWindow()&lt;br /&gt;
        {&lt;br /&gt;
            InitializeComponent();&lt;br /&gt;
&lt;br /&gt;
            // make sure SettingsManager is referenced outside&lt;br /&gt;
            // just the child windows. Normally this would happen&lt;br /&gt;
            // just do to general use of the class. Forcing it here.&lt;br /&gt;
&lt;br /&gt;
            _current = SettingsManager.Current;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void OpenWindowsButton_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
            int openedCount = 0;&lt;br /&gt;
            DebugList.Items.Add("Total Memory Before Opening Windows: " + GC.GetTotalMemory(true));&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; 200; i++)&lt;br /&gt;
            {&lt;br /&gt;
                var window = new TestChildWindow();&lt;br /&gt;
                window.Show();&lt;br /&gt;
                openedCount++;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            DebugList.Items.Add("Opened " + openedCount + " windows.");&lt;br /&gt;
            DebugList.Items.Add("Total Memory After Opening Windows: " + GC.GetTotalMemory(true));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void CloseWindowsButton_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
            int closedCount = 0;&lt;br /&gt;
            foreach (Window window in Application.Current.Windows)&lt;br /&gt;
            {&lt;br /&gt;
                if (window != this)&lt;br /&gt;
                {&lt;br /&gt;
                    window.Close();&lt;br /&gt;
                    closedCount++;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            DebugList.Items.Add("Closed " + closedCount + " windows.");&lt;br /&gt;
            DebugList.Items.Add("App has " + Application.Current.Windows.Count + " window(s) it's holding on to.");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void CollectButton_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);&lt;br /&gt;
            //GC.Collect();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;I experimented with a few variations on GC.Collect and some of
the other notifications before the code that is here. A plain old
GC.Collection will likely work just as well in any case.&lt;/p&gt;

&lt;p&gt;Here's what the window looks like after I opened 200 windows and
then closed them and then opened another 200. &lt;strong&gt;200&lt;/strong&gt;
windows is actually a lot of windows, as it turns out, but if you
consider an application where your user opens up 1 customer record
every 5 minutes (for a phone support person, this is conservative),
over the course of an 8 hour day, that could be as many as 160
forms, and that's assuming they close the application every day
when they leave.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83242/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_32.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83247/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_thumb_12.png" width="650" height="360" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I needed to find a good way to track memory usage. The
profiler in Visual Studio is really good for finding performance
bottlenecks, but not really meant for the real-time memory usage
graphing I wanted to do. So, I downloaded the 10 day trial of .NET
Memory Profiler (an app I used a lot back when I was consulting)
and had it capture data while I performed the above actions.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83252/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_22.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83257/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_thumb_7.png" width="660" height="254" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this graph, the pink line is the active memory in use in
bytes, the green line is the number of root references. (note: none
of the memory graphs include memory from on-window images. I ran
without the cute images, but I left the code in the form and the
images in the screenshot just because)&lt;/p&gt;

&lt;p&gt;Remember, this is without any of the circular reference problems
discussed so far. Now, let's take a look at the same actions when I
have an event handler wired up in the constructor of the
window.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83262/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_24.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83267/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_thumb_8.png" width="660" height="253" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice something about that graph? Yep. Memory just isn't being
returned. It's leaking, and the root references keep on climbing.
The only difference between this profiled version and the previous
was that I added the SettingsManager event handler wireup in the
constructor:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
public partial class TestChildWindow : Window&lt;br /&gt;
{&lt;br /&gt;
    long[] _memoryHog;&lt;br /&gt;
&lt;br /&gt;
    public TestChildWindow()&lt;br /&gt;
    {&lt;br /&gt;
        InitializeComponent();&lt;br /&gt;
&lt;br /&gt;
        Random rnd = new Random();&lt;br /&gt;
&lt;br /&gt;
        string imageName = "Assets/image" + rnd.Next(1, 9) + ".jpg";&lt;br /&gt;
        NeatoImage.Source = new BitmapImage(new Uri(imageName, UriKind.Relative));&lt;br /&gt;
&lt;br /&gt;
        _memoryHog = new long[1024];&lt;br /&gt;
&lt;br /&gt;
        SettingsManager.Current.SettingsChanged += Current_SettingsChanged;&lt;br /&gt;
&lt;br /&gt;
        Unloaded += new RoutedEventHandler(TestChildWindow_Unloaded);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void Current_SettingsChanged(object sender, EventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
        // do something&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void TestChildWindow_Unloaded(object sender, RoutedEventArgs e)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The Unloaded handler is empty, but it is wired up. The key
change here is the SettingsManager.Current.SettingsChanged
wire-up.&lt;/p&gt;

&lt;p&gt;There are a multitude of considerations in this example, but
let's deal with just the topic of this post: the event
handlers.&lt;/p&gt;

&lt;h3&gt;Solution 1: Unwire Your Event Handlers&lt;/h3&gt;

&lt;p&gt;This generally doesn't work if you use anonymous delegates (one
reason to be careful about using them with objects that live
outside the scope of a single method), but in cases where you have
a real event handler method, unhooking them when you're done with
them is definitely a best practice.&lt;/p&gt;

&lt;p&gt;You can remove event handlers in Dispose methods, or in the case
of a window, in the Unload event handler. That's what I did
here.&amp;nbsp; The code is a simple change:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
void TestChildWindow_Unloaded(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    SettingsManager.Current.SettingsChanged -= Current_SettingsChanged;&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;All I did was remove the event handler inside the Unloaded
handler. Take a look at the impact it had on memory:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83272/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_26.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83277/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_thumb_9.png" width="660" height="254" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's much better. The root references and memory both drop
when I hit the "collect" button. Compare this to the previous
example where the memory never went down. As to the differences
between this graph and the first one, chalk it up to sample timing
and my own non-deterministic button pushing.&lt;/p&gt;

&lt;p&gt;So, that's a great approach. In fact, if you can do this, you
should do this. It's simple and highly effective.&lt;/p&gt;

&lt;p&gt;For other situations, perhaps where you don't control all the
code, or when unwiring events is difficult or inconvenient, there's
the Weak Event Pattern.&lt;/p&gt;

&lt;h3&gt;Solution 2: Weak Events&lt;/h3&gt;

&lt;p&gt;It's not always possible or practical to unwire event handlers.
&lt;strong&gt;Actually, let me rephrase that&lt;/strong&gt;: sometimes the
level of effort and thought that needs to go into *where* you put
event handler unwiring is more than developers have time to put
into the app. :)&lt;/p&gt;

&lt;p&gt;Enter the Weak Event Pattern&lt;/p&gt;

&lt;p&gt;The concept of a Weak Event is nothing new. Many others have
created their own various weak event solutions for use with WPF.
Previous versions of .NET and WPF included the WeakEventManager,
but required you to derive your own class and implement
IWeakEventListener interfaces. That was a fair bit of work for
developers who just need to get stuff done. The real news here is
that WPF 4.5 includes the &lt;strong&gt;generic&lt;/strong&gt; WeakEventManager
type to make it easier for you to implement the weak event pattern
in your own code, without all the other ceremony. You can still
derive from WeakEventManager (if you can do the work, it's actually
a good practice due to the performance benefits you'll get from it
via having actual events and not reflection look-ups), but the new
generic class makes it easy enough so that there's no excuse *not*
to do it.&lt;/p&gt;

&lt;p&gt;Here's the memory usage of the application using Weak Events&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83282/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_30.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83287/Windows-Live-Writer_WeakEventManager-in-WPF-4.5_EF5D_image_thumb_11.png" width="660" height="254" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's the code change. I removed the code to unwire the
event, and did the event wireup using WeakEventManager rather than
regular old events.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
namespace WpfWeakEventManager&lt;br /&gt;
{&lt;br /&gt;
    /// &amp;lt;summary&amp;gt;&lt;br /&gt;
    /// Interaction logic for TestChildWindow.xaml&lt;br /&gt;
    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;
    public partial class TestChildWindow : Window&lt;br /&gt;
    {&lt;br /&gt;
        long[] _memoryHog;&lt;br /&gt;
&lt;br /&gt;
        public TestChildWindow()&lt;br /&gt;
        {&lt;br /&gt;
            InitializeComponent();&lt;br /&gt;
&lt;br /&gt;
            Random rnd = new Random();&lt;br /&gt;
&lt;br /&gt;
            string imageName = "Assets/image" + rnd.Next(1, 9) + ".jpg";&lt;br /&gt;
            NeatoImage.Source = new BitmapImage(new Uri(imageName, UriKind.Relative));&lt;br /&gt;
&lt;br /&gt;
            _memoryHog = new long[1024];&lt;br /&gt;
&lt;br /&gt;
            // this version wires up an event handler which causes a hard reference&lt;br /&gt;
            // and, unless it is unwired, a memory leak&lt;br /&gt;
//            SettingsManager.Current.SettingsChanged += Current_SettingsChanged;&lt;br /&gt;
&lt;br /&gt;
            // unwire the event handler. This is a good practice for avoiding leaks&lt;br /&gt;
//            Unloaded += new RoutedEventHandler(TestChildWindow_Unloaded);&lt;br /&gt;
&lt;br /&gt;
            // this version avoids memory leaks without requiring you to&lt;br /&gt;
            // unwire the event.&lt;br /&gt;
            WeakEventManager&amp;lt;SettingsManager, EventArgs&amp;gt;&lt;br /&gt;
                .AddHandler(SettingsManager.Current,&lt;br /&gt;
                            "SettingsChanged",&lt;br /&gt;
                            Current_SettingsChanged);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        void Current_SettingsChanged(object sender, EventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
            // do something&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        void TestChildWindow_Unloaded(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
//            SettingsManager.Current.SettingsChanged -= Current_SettingsChanged;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;This new WeakEventManager is much easier to use than anything we
had before. You take a hit for relying on reflection to resolve the
event name, but in all but the most performance-sensitive cases
(where you probably wouldn't bother with events anyway), it's going
to be worth it.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Event handlers and long-lived objects can be the source of
memory leaks in any .NET application. Whenever you can, you should
unwire your event handlers to help avoid these leaks. When that is
impractical, the Weak Event Pattern using the WPF 4.5
WeakEventManager&amp;lt;TObject, TArgs&amp;gt; is a great way to help save
you from the grief of memory leaks without requiring all the
ceremony we had with the regular WeakEventManager and
IWeakEventListener in the previous versions.&lt;/p&gt;

&lt;p&gt;Now there's no excuse to have leaky event handlers.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vWEdpAaAZUJIGK0nCSdtRm-jICo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vWEdpAaAZUJIGK0nCSdtRm-jICo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vWEdpAaAZUJIGK0nCSdtRm-jICo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vWEdpAaAZUJIGK0nCSdtRm-jICo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cNCfpxx_N5Y:OFmCXGG8D3g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cNCfpxx_N5Y:OFmCXGG8D3g:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cNCfpxx_N5Y:OFmCXGG8D3g:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cNCfpxx_N5Y:OFmCXGG8D3g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=cNCfpxx_N5Y:OFmCXGG8D3g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cNCfpxx_N5Y:OFmCXGG8D3g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=cNCfpxx_N5Y:OFmCXGG8D3g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cNCfpxx_N5Y:OFmCXGG8D3g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=cNCfpxx_N5Y:OFmCXGG8D3g:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/cNCfpxx_N5Y" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/02/01/event-handler-memory-leaks-unwiring-events-and-the-weakeventmanager-in-wpf-45</feedburner:origLink></item><item><title>The .NET Gadgeteer Diaper Alarm Part 1 (Moisture Sensor)</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/ly1EjFTELxs/the-net-gadgeteer-diaper-alarm-part-1-moisture-sensor</link><pubDate>Mon, 30 Jan 2012 22:22:37 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/30/the-net-gadgeteer-diaper-alarm-part-1-moisture-sensor</guid><description>&lt;p&gt;During the .NET Microframework and &lt;a
href="http://www.youtube.com/playlist?list=PL7A0F12DEA2A538C2"
target="_blank"&gt;.NET Gadgeteer code camp talk&lt;/a&gt; that Andrew
Duthie and I gave several weeks back, we tossed around the idea of
using the Gadgeteer and a moisture sensor to alert parents of,
ahhhh, soggy diaper issues.&lt;/p&gt;

&lt;p&gt;Shortly before the holidays, in the mail, I got a package of
goodies from Microsoft Research. That package included one of these
moisture sensors from Seeed Studio. These are meant for checking to
see how wet soil is, but I figure one man's diaper is another man's
soil, so, I can't resist. Must…prototype…solution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WARNING: Science in Progress. Also: diaper jokes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;First Iteration&lt;/h3&gt;

&lt;p&gt;I didn't have any of that handy inoffensive blue liquid
available (the stuff they use to represent *any* bodily fluid on
commercials; pretty sure that's how Smurfs are grown), so lacking
any actual babies (my kids are all potty trained now. Yay!) I'm
using plain old water. The real thing is a &lt;a
href="http://www.bing.com/search?q=conductivity+of+urine&amp;amp;src=ie9tr"
 target="_blank"&gt;bit more conductive&lt;/a&gt;, so you may need to vary
some values I use. Also, I'm dealing with liquids only in this
post. You're on your own with anything more…substantial, but I
might recommend some sort of scale, or for the newborns, perhaps a
blast detector &lt;a
href="http://www.amazon.com/3M-8979N-Performance-Nuclear-Slate/dp/B000NG3ZKI"
 target="_blank"&gt;held on with this&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Hardware&lt;/h4&gt;

&lt;p&gt;I'm using the &lt;a
href="http://www.seeedstudio.com/depot/moisture-module-net-gadgeteer-compatible-p-973.html?cPath=203"
 target="_blank"&gt;Moisture Module from Seeed Studio&lt;/a&gt;. (You can
also &lt;a href="http://www.ghielectronics.com/catalog/category/275/"
target="_blank"&gt;purchase it through GHI&lt;/a&gt; as they have a
partnership.) This module returns back an analog voltage that is
proportional to how wet the area is. As mentioned, it's is really
meant to be used in soil, to tell you if you need to water your
plants, so we'll have to finagle a few things to make it work
here.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://www.seeedstudio.com/depot/moisture-module-net-gadgeteer-compatible-p-973.html?cPath=203"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83158/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_3.png" width="500" height="259" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's wired to socket 9 on my Gadgeteer board. That's one of the
two analog sockets on the GHI Electronics Spider. I had one of the
extra long ribbon cables which was perfect for this. You don't want
the rest of your modules anywhere near what we're doing here. Also,
this probably works best with babies who are relatively sedentary,
preferably sleeping. Otherwise, you'll end up with a miniature Borg
running around the house trailing some sort of dangling box of
electronic goodies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Warning: I'm reasonably certain that none of this is actually
baby-proof.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Yee Old Test Subject&lt;/h4&gt;

&lt;p&gt;Next, I need something to test in. No, don't go there as my wife
would not appreciate getting that kind of laundry from me, not even
in the name of science. I'm pretty sure I could get my almost-6
year old son to cooperate if I offered LEGO or something as a
reward, but that'd also get me on the naughty list. Lacking other
creative solutions, I'm just going to use a small plate and a paper
towel to see how this all works.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83163/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_7.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83168/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_thumb_2.png" width="481" height="448" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll wet the towel, and wait until the moisture starts to hit
the sensor. Then I can adjust for sensitivity. The idea is not to
make the sensor swim, but to get an idea of how we the towel needs
to be for this to work. Remember, the sensor is designed to be
stuck in soil, not placed down on a towel.&lt;/p&gt;

&lt;h4&gt;Software&lt;/h4&gt;

&lt;p&gt;Be sure to &lt;a href="http://www.tinyclr.com/support"
target="_blank"&gt;download the latest Gadgeteer SDK and driver
package&lt;/a&gt;. The latest rev (as of this month) includes support for
all the GHI and Seeed modules on the market, including this one.
Once you'd done that, it's time to create a new project. Open up
Visual Studio and create a new .NET Gadgeteer Project. I named mine
DiaperMonitor.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83173/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_5.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83178/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_thumb.png" width="550" height="387" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, add the main board, if it's not already there. By default,
mine came up with the FEZ Hydra, presumably because that's the last
one I used. I simply removed that and dragged on a FEZ Spider from
the list of main boards in the toolbox.&lt;/p&gt;

&lt;p&gt;Next, I added a Seeed.MoistureSensor module. You can either
connect it automatically, or pick the port yourself and drag the
connection to create the link. I have the moisture sensor on socket
9 as shown here. I also added one of the brand new GHI LED7R
modules just to give us something interesting to light up.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83183/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_11.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83188/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_thumb_3.png" width="650" height="361" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't have one of the new LED7R, you can use any LED
module and simply change the code we'll use for the light up.&lt;/p&gt;

&lt;h4&gt;Le Code&lt;/h4&gt;

&lt;p&gt;The first iteration of code is simply going to check the
moisture level, and light up the LED7R&amp;nbsp; when the moisture
level makes it over a certain threshold. On the Gadgeteer, you
don't want to have a tight loop running from the ProgramStarted
method - doing so would prevent other event handlers from
running.&lt;/p&gt;

&lt;p&gt;The code for the sensor is really simple. If you look at the
sensor itself, it appears to simply send a voltage down one side of
the tongs and checks for conductivity with the other side. The
driver uses a digital output for sending and an analog input for
receiving. I was actually surprised to find a through-hole NPN
transistor (it's a TO-932 package &lt;a
href="http://en.wikipedia.org/wiki/2N2222" target="_blank"&gt;2N2222
amplifier&lt;/a&gt; marked 2N2222 H331) in there, as almost everything
else gadgeteer-related uses surface mount components (including the
two resistors on the board), but I know the 2N2222 itself is
difficult (impossible?) to find in an SMT package.&lt;/p&gt;

&lt;p&gt;I'm far from an electronics expert, but my guess is that one
side of the fork sends the regular (apx) 3.3v signal from pin 3
into the dirt/diaper. The other side will get a very faint amount
of voltage transferred through the medium which it then amplifies
with the transistor in order to make it meaningful to the
microcontroller.&lt;/p&gt;

&lt;p&gt;So, instead of using a polling loop, I kick off a timer to
handle polling the sensor. The timer is set to poll once per second
and compare the returned value to the minimum moisture level. If
the level is passed, then the LED7R animates once and then stays
on. After changing the diaper, you reset the Gadgeteer to restart
the program. Inelegant, but simple.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using Microsoft.SPOT.Presentation;&lt;br /&gt;
using Microsoft.SPOT.Presentation.Controls;&lt;br /&gt;
using Microsoft.SPOT.Presentation.Media;&lt;br /&gt;
using Microsoft.SPOT.Touch;&lt;br /&gt;
&lt;br /&gt;
using Gadgeteer.Networking;&lt;br /&gt;
using GT = Gadgeteer;&lt;br /&gt;
using GTM = Gadgeteer.Modules;&lt;br /&gt;
using Gadgeteer.Modules.Seeed;&lt;br /&gt;
using Gadgeteer.Modules.GHIElectronics;&lt;br /&gt;
&lt;br /&gt;
namespace DiaperMonitor&lt;br /&gt;
{&lt;br /&gt;
    public partial class Program&lt;br /&gt;
    {&lt;br /&gt;
        private GT.Timer _pollingTimer;&lt;br /&gt;
        private int minimumBadMoistureLevel = 200;&lt;br /&gt;
   &lt;br /&gt;
        void ProgramStarted()&lt;br /&gt;
        {&lt;br /&gt;
            Debug.Print("Program Started");&lt;br /&gt;
&lt;br /&gt;
            _pollingTimer = new GT.Timer(1000);&lt;br /&gt;
            _pollingTimer.Tick += OnPollingTimerTick;&lt;br /&gt;
&lt;br /&gt;
            _pollingTimer.Start();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        void OnPollingTimerTick(GT.Timer timer)&lt;br /&gt;
        {&lt;br /&gt;
            int moisture = moistureSensor.GetMoistureReading();&lt;br /&gt;
&lt;br /&gt;
            Debug.Print(moisture.ToString());&lt;br /&gt;
&lt;br /&gt;
            if (moisture &amp;gt; minimumBadMoistureLevel)&lt;br /&gt;
            {&lt;br /&gt;
                AlertParents();&lt;br /&gt;
&lt;br /&gt;
                timer.Stop();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void AlertParents()&lt;br /&gt;
        {&lt;br /&gt;
            lED7R.Animate(10, true, true, true);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This approach is nice, but doesn't do another loud or obvious.
You'd have to keep looking in the room and checking for the lights.
Chances are, the baby's own internal alarm would start sounding
before you noticed the lights. In addition, this doesn't allow for
any configuration of level, so on a hot summer night (thank's to
Sammy Hagar, that song is now stuck in my head), there may be a
general level of damp which doesn't quite meet the bar for a burst
dam.&lt;/p&gt;

&lt;p&gt;So we have two problems: one is configuration, the second is for
meaningful alerts. Let's look at configuration first.&lt;/p&gt;

&lt;h3&gt;Second Iteration - Configuration&lt;/h3&gt;

&lt;p&gt;The next step is to configure that alert level. You can leave it
as a fixed value in code, or you can configure it via any number of
other external inputs. One approach would be to use a potentiometer
to set a threshold. Another would be to sample the current value
and say that value is the "normal" value and anything well above it
would be the "wet" value.&lt;/p&gt;

&lt;p&gt;Either approach would require some input device, like a button,
to enable the timer and possibly to sample the data.&lt;/p&gt;

&lt;p&gt;First, I need to know what the possible values are. I couldn't
find any documentation, so I simply went to the Gadgeteer codeplex
site and &lt;a
href="http://gadgeteer.codeplex.com/SourceControl/changeset/view/14112"
 target="_blank"&gt;looked at the source code&lt;/a&gt;. As I suspected, the
sensor is an extremely simple wrapper around the analog input
class. It returns a value in the range of 0 to 1600, as evidenced
by this code:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
/// &amp;lt;summary&amp;gt;&lt;br /&gt;
/// Gets the current moisture reading.&lt;br /&gt;
/// &amp;lt;/summary&amp;gt;&lt;br /&gt;
/// &amp;lt;returns&amp;gt;An integer value, where 0 is fully dry and 1000 (or greater) is completely wet. &amp;lt;/returns&amp;gt;&lt;br /&gt;
public int GetMoistureReading()&lt;br /&gt;
{&lt;br /&gt;
    return (int) (analogInput.ReadProportion() * 1600.0);&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;It also has a nice comment which isn't surfaced in the compiled
version I have, so I assume that's a somewhat later rev. (Actually,
I just looked in the Object Browser and there it is. I wonder why
intellisense wasn't showing it? Odd.) In any case, it's useful to
know you can always go and inspect the source if you have any
question about how something is working at the Gadgeteer module
driver level.&lt;/p&gt;

&lt;p&gt;So what can we do with that information? Well, let's look at the
potentiometer approach.&lt;/p&gt;

&lt;h4&gt;Potentiometer approach&lt;/h4&gt;

&lt;p&gt;One thing most MCUs don't have is a large number of analog
inputs. In order for a MCU to enable analog input, it has to have a
digital to analog converter channel available. Most MCUs which have
on-board ADC support either 10 bit or 12 bit analog conversion. The
specs for the EMX module used by the Gadgeteer show that it has 7
10 bit analog inputs total. The FEZ Spider surfaces six of them,
but only on two sockets. So, unless you have a multi-input devices
that can use the 3 pins on a type A socket (or you create a
breakout of some sort), you really end up being able to take input
from only two analog modules. That leaves us with our diaper sensor
and a potentiometer.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83193/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_13.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83198/Windows-Live-Writer_The-.NET-Gadgeteer-Diaper-Alarm_13CA5_image_thumb_4.png" width="650" height="269" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this, I added a potentiometer module to the other analog
socket: socket 10. The pot is going to be used to configure the
minimum level at which we'll set off the diaper alarm. In addition,
I added a button module that we'll use to arm the device.&lt;/p&gt;

&lt;p&gt;The new code refactors a few things. Explanation after the
listing.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using Microsoft.SPOT.Presentation;&lt;br /&gt;
using Microsoft.SPOT.Presentation.Controls;&lt;br /&gt;
using Microsoft.SPOT.Presentation.Media;&lt;br /&gt;
using Microsoft.SPOT.Touch;&lt;br /&gt;
&lt;br /&gt;
using Gadgeteer.Networking;&lt;br /&gt;
using GT = Gadgeteer;&lt;br /&gt;
using GTM = Gadgeteer.Modules;&lt;br /&gt;
using Gadgeteer.Modules.Seeed;&lt;br /&gt;
using Gadgeteer.Modules.GHIElectronics;&lt;br /&gt;
&lt;br /&gt;
namespace DiaperMonitor&lt;br /&gt;
{&lt;br /&gt;
    public partial class Program&lt;br /&gt;
    {&lt;br /&gt;
        private GT.Timer _pollingTimer;&lt;br /&gt;
&lt;br /&gt;
        private const int MoistureLevelRangeLow = 50;&lt;br /&gt;
        private const int MoistureLevelRangeHigh = 800;&lt;br /&gt;
        private int _minimumBadMoistureLevel = 200;&lt;br /&gt;
   &lt;br /&gt;
        void ProgramStarted()&lt;br /&gt;
        {&lt;br /&gt;
            Debug.Print("Program Started");&lt;br /&gt;
&lt;br /&gt;
            button.ButtonPressed += button_ButtonPressed;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        void button_ButtonPressed(Button sender, Button.ButtonState state)&lt;br /&gt;
        {&lt;br /&gt;
            Debug.Print("Button Pressed");&lt;br /&gt;
&lt;br /&gt;
            if (_armed)&lt;br /&gt;
            {&lt;br /&gt;
                Disarm();&lt;br /&gt;
&lt;br /&gt;
                // animate counter-clockwise and turn off&lt;br /&gt;
                lED7R.Animate(10, false, true, false);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Arm();&lt;br /&gt;
                lED7R.Animate(10, true, false, false);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void SetTriggerLevel()&lt;br /&gt;
        {&lt;br /&gt;
            // read from the pot&lt;br /&gt;
            double pot = potentiometer.ReadPotentiometerPercentage();&lt;br /&gt;
&lt;br /&gt;
            // calculate the moisture level based on the bounds&lt;br /&gt;
            _minimumBadMoistureLevel = MoistureLevelRangeLow +&lt;br /&gt;
                (int)(pot * (MoistureLevelRangeHigh - MoistureLevelRangeLow));&lt;br /&gt;
&lt;br /&gt;
            Debug.Print("Minimum trigger level: " + _minimumBadMoistureLevel);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        bool _armed = false;&lt;br /&gt;
        private void Arm()&lt;br /&gt;
        {&lt;br /&gt;
            SetTriggerLevel();&lt;br /&gt;
&lt;br /&gt;
            // start the timer&lt;br /&gt;
            _pollingTimer = new GT.Timer(1000);&lt;br /&gt;
            _pollingTimer.Tick += OnPollingTimerTick;&lt;br /&gt;
&lt;br /&gt;
            _pollingTimer.Start();&lt;br /&gt;
&lt;br /&gt;
            _armed = true;&lt;br /&gt;
&lt;br /&gt;
            Debug.Print("Armed.");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void Disarm()&lt;br /&gt;
        {&lt;br /&gt;
            // stop the timer&lt;br /&gt;
            _pollingTimer.Stop();&lt;br /&gt;
            _pollingTimer.Tick -= OnPollingTimerTick;&lt;br /&gt;
&lt;br /&gt;
            _armed = false;&lt;br /&gt;
&lt;br /&gt;
            Debug.Print("Disarmed.");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // event handler for the timer that polls the moisture sensor&lt;br /&gt;
        void OnPollingTimerTick(GT.Timer timer)&lt;br /&gt;
        {&lt;br /&gt;
            int moisture = moistureSensor.GetMoistureReading();&lt;br /&gt;
&lt;br /&gt;
            Debug.Print(moisture.ToString());&lt;br /&gt;
&lt;br /&gt;
            if (moisture &amp;gt; _minimumBadMoistureLevel)&lt;br /&gt;
            {&lt;br /&gt;
                AlertParents();&lt;br /&gt;
&lt;br /&gt;
                Disarm();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // do all the obnoxious alert stuff in here&lt;br /&gt;
        private void AlertParents()&lt;br /&gt;
        {&lt;br /&gt;
            Debug.Print("Diaper Alert!");&lt;br /&gt;
&lt;br /&gt;
            // animate clockwise and leave on&lt;br /&gt;
            lED7R.Animate(10, true, true, true);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;The new workflow is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the potentiometer to some minimum trigger level. There's no
readout or anything at the moment, so you'd just have to eyeball
it.&lt;/li&gt;

&lt;li&gt;Once the pot is set, click the button to arm the diaper alert.
The LEDs will cycle and you know it's armed.&lt;/li&gt;

&lt;li&gt;Wet the diaper (not you, personally, I hope)&lt;/li&gt;

&lt;li&gt;Diaper alert and then the system disarms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When disarming the alarm, to avoid leaks, I remove the event
handler. When arming, I wire it back up. In our particular example,
this doesn't buy you anything, but if you were to pull this code
out into another class, it almost certainly would save you from
eating up all the memory on the device over time.&lt;/p&gt;

&lt;p&gt;This new workflow is pretty good, but the diaper alert leaves
something to be desired. You'd have to get in there to notice the
LEDs (in a dark room they'd be ok), but there's nothing to really
grab your attention. Clearly we can't have a piercing piezo siren
or something, as that would wake up baby before the wet does.&lt;/p&gt;

&lt;p&gt;What other options do we have?&lt;/p&gt;

&lt;p&gt;Well, how about an alert that is sent to a remote device?&lt;/p&gt;

&lt;p&gt;That's the topic of the next post :)&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;Ok, that was fun :)&lt;/p&gt;

&lt;p&gt;For most of us, this is probably not how we'll use the
Gadgeteer. Kids generally have &lt;a
href="http://www.youtube.com/results?search_query=crying+babies&amp;amp;oq=crying+babies&amp;amp;aq=f&amp;amp;aqi=g10&amp;amp;aql=&amp;amp;gs_sm=e&amp;amp;gs_upl=162l1874l0l1978l13l10l0l1l1l0l167l1011l3.6l9l0"
 target="_blank"&gt;pretty good built-in wet diaper alarms&lt;/a&gt; as it
is. However, you can use this sensor for just about anything from
plant moisture detection to water leak detection to more. More
importantly, this post shows how to use an analog sensor of any
type, including how to configure the range and some other useful
NETMF tips.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Sx6v20tMCk4PVkFoe4pcprQO9rk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sx6v20tMCk4PVkFoe4pcprQO9rk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Sx6v20tMCk4PVkFoe4pcprQO9rk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sx6v20tMCk4PVkFoe4pcprQO9rk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ly1EjFTELxs:ArD4Ii1KiHE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ly1EjFTELxs:ArD4Ii1KiHE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ly1EjFTELxs:ArD4Ii1KiHE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ly1EjFTELxs:ArD4Ii1KiHE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=ly1EjFTELxs:ArD4Ii1KiHE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ly1EjFTELxs:ArD4Ii1KiHE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=ly1EjFTELxs:ArD4Ii1KiHE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ly1EjFTELxs:ArD4Ii1KiHE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=ly1EjFTELxs:ArD4Ii1KiHE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/ly1EjFTELxs" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/30/the-net-gadgeteer-diaper-alarm-part-1-moisture-sensor</feedburner:origLink></item><item><title>The n00b filter: Bad UX at its Finest in Eagle PCB</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/a5Pb2Q2n6uQ/the-n00b-filter-bad-ux-at-its-finest-in-eagle-pcb</link><pubDate>Fri, 27 Jan 2012 02:55:54 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/26/the-n00b-filter-bad-ux-at-its-finest-in-eagle-pcb</guid><description>&lt;p&gt;Speaking of UX…&lt;/p&gt;

&lt;p&gt;I finally decided to download and learn to use the
industry-standard PCB and schematic layout software: Eagle. I've
tried a bunch of others, and quite frankly, got tired of always
using "also ran" software. The majority of the info on the web is
for Eagle. It certainly doesn't have the best UI or the best
workflow, but it has absolutely the most amount of information and
the best support from PCB manufacturers. It's the industry
standard, and like most industry-leading technical software (ever
use industry-leading 3d modeling software? Gak!), it has some crazy
issues.&lt;/p&gt;

&lt;p&gt;Here's the workflow. First, while working on the Schematic, you
click this "Add" toolbar button&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83112/Windows-Live-Writer_The-n00b-filter-Bad-UX-at-its-Finest_13D66_image_4.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83117/Windows-Live-Writer_The-n00b-filter-Bad-UX-at-its-Finest_13D66_image_thumb_1.png" width="650" height="428" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you're shown a screen with the libraries on the left, and
the selected part on the right. You can browse the libraries here,
but it is not something I went into with the intent of using it to
manage library entries.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83122/Windows-Live-Writer_The-n00b-filter-Bad-UX-at-its-Finest_13D66_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83127/Windows-Live-Writer_The-n00b-filter-Bad-UX-at-its-Finest_13D66_image_thumb.png" width="649" height="439" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to add the component, but I wasn't sure which button to
press. Silly me, thought maybe "drop" meant to "drop it on the
schematic" because, for whatever reason, "OK" didn't seem
right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrong.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Drop", without so much as a confirmation MessageBox removes the
library from the parts libraries on your computer. Yeah, so now I
need to go find the library which contains every type of diode,
because, umm, I deleted it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;At first, I thought I actually deleted it, but it turns
out Eagle marks it to make it not show up in the Add
dialog.&lt;/strong&gt; I'm still going to finish this post anyway,
because the brick was already passed painfully through the orifice
when the library just went *poof* off the list.&lt;/p&gt;

&lt;p&gt;To restore it, you have to go into their separate Control Panel
application (hint: if your app has a "control panel" app, there's
an issue). That's better than having to reinstall the product, or
download the library from RapidItsNotReallyATrojanWeSwearShare.com,
but it's not entirely intuitive.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83132/Windows-Live-Writer_The-n00b-filter-Bad-UX-at-its-Finest_13D66_image_6.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83137/Windows-Live-Writer_The-n00b-filter-Bad-UX-at-its-Finest_13D66_image_thumb_2.png" width="650" height="432" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This type of feature can only be called a n00b
filter&lt;/strong&gt;, although I'm sure there's a more technical UX
antipattern name for it, probably one which includes a four-letter
word or two.&lt;/p&gt;

&lt;p&gt;I have a lot of experience in software. I rarely need to be
hand-held, and the last time I took a class to learn how to use a
piece of software was to be a Novell 4 CNA in the mid 90s, and I
took that class *after* I had already set up the network. I almost
never read manuals, and use "Help" in apps maybe 5 times a year
total, and only because I'm trying new stuff all the time. All I'm
trying to say here, is I'm not afraid of software, and I very
rarely do something which destroys work or accidentally does a
format c:\ or anything.&lt;/p&gt;

&lt;p&gt;Seriously. No confirmation. It's a button on the "Add Component"
screen.&lt;/p&gt;

&lt;p&gt;No wonder users hate us.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/UM7vrnqiIN3UY0AP7h5tuKbjwVo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UM7vrnqiIN3UY0AP7h5tuKbjwVo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/UM7vrnqiIN3UY0AP7h5tuKbjwVo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UM7vrnqiIN3UY0AP7h5tuKbjwVo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=a5Pb2Q2n6uQ:PyydrwzG00M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=a5Pb2Q2n6uQ:PyydrwzG00M:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=a5Pb2Q2n6uQ:PyydrwzG00M:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=a5Pb2Q2n6uQ:PyydrwzG00M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=a5Pb2Q2n6uQ:PyydrwzG00M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=a5Pb2Q2n6uQ:PyydrwzG00M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=a5Pb2Q2n6uQ:PyydrwzG00M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=a5Pb2Q2n6uQ:PyydrwzG00M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=a5Pb2Q2n6uQ:PyydrwzG00M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/a5Pb2Q2n6uQ" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/26/the-n00b-filter-bad-ux-at-its-finest-in-eagle-pcb</feedburner:origLink></item><item><title>Maker Geek Roundup 006 for 1/25/2012</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/PVD4L9hWMF4/maker-geek-roundup-006-for-1-25-2012</link><pubDate>Wed, 25 Jan 2012 19:08:25 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/25/maker-geek-roundup-006-for-1-25-2012</guid><description>&lt;p&gt;The Maker Geek Roundup aggregates information of interest to
makers everywhere. Topics include .NET Micro Framework, CNC, 3d
Printing, Robotics, Microsoft Robotics Studio, Electronics, General
Maker stuff, and more. If you have something interesting you've
done or have run across, or you blog regularly on the topics
included here, please send me the URL and brief description via the
&lt;a href="http://10rem.net/contact"&gt;contact link&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;3d Printing and CAD/CAM/CNC&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blog.ultimaker.com/2012/01/25/working-3d-printed-helicopter-blades/"&gt;
Working 3D printed helicopter blades&lt;/a&gt; (Ultimaker)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://richrap.blogspot.com/2012/01/slic3r-is-nicer-part-3-how-low-can-you.html"&gt;
Slic3r is Nicer - Part 3 - How low can you go?&lt;/a&gt; (RichRap)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blog.rhino3d.com/2012/01/rhinocam-2012-is-latest-version-of.html"&gt;
RhinoCAM 2012 to Release February 6, 2012&lt;/a&gt; (Rhino News)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blog.thingiverse.com/2012/01/25/the-3d-printing-troubadours-of-pocket-factory/"&gt;
The 3D Printing Troubadours of Pocket Factory!&lt;/a&gt;
(Thingiverse)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://arduino.cc/blog/2012/01/10/circuit-milling-with-roland-imodela-now-available-on-arduino-store/"&gt;
Circuit Milling With Roland iModela, Now Available on Arduino
Store&lt;/a&gt; (Arduino Blog)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;.NET Gadgeteer&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.breakcontinue.com/2012/01/arduino-daisylink-module-for-gadgeteer.html"&gt;
Take a break: Arduino DaisyLink module for Gadgeteer&lt;/a&gt; (Valentin
Ivanov)&lt;/li&gt;

&lt;li&gt;&lt;a href="http://devhammer.net/hardware"&gt;Devhammer's Garage
(Info on the IR LED module Andrew created)&lt;/a&gt; (G. Andrew
Duthie)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;.NET Micro Framework General (Netduino, GHI FEZ, etc.)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.pix6t4.com/"&gt;PIX-6T4 - The PIX-6T4 Game
Console&lt;/a&gt; (Fabien Royer, Bertrand LeRoy)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/netmfteam/archive/2012/01/09/new-netmf-book-out-for-v4-1-and-v4-2.aspx"&gt;
New NETMF Book out for v4.1 and v4.2&lt;/a&gt; (Colin Miller)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://mikedodaro.net/2012/01/21/text-to-speech-for-net-micro-framework/"&gt;
Text-To-Speech for .NET Micro Framework&lt;/a&gt; (Marco Minerva)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://mikedodaro.net/2011/12/14/xml-configuration-files-for-net-micro-framework-applications-english/"&gt;
XML Configuration Files for .NET Micro Framework Applications
(English)&lt;/a&gt; (Marco Minerva)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/laurelle/archive/2012/01/21/using-a-light-transistor-sensor-and-a-led-to-create-a-detector.aspx"&gt;
Using a light transistor sensor and a led to create a detector&lt;/a&gt;
(Laurent Ellerbach)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Arduino&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://arduino.cc/blog/2012/01/16/control-an-lcd-with-a-595-shift-register/"&gt;
Control An LCD with a 595 Shift Register&lt;/a&gt; (Arduino Blog)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Other Micro Controllers (PIC, AVR, ARM and more)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.mikroe.com/eng/news/view/418/easypic-pro-v7-is-released/"&gt;
EasyPIC PRO v7 is released!&lt;/a&gt; (MikroElektronika)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://dangerousprototypes.com/2012/01/25/breakout-board-for-the-44pin-qfn-atxmega-microcontroller/"&gt;
Breakout board for the 44pin QFN ATxmega microcontroller&lt;/a&gt;
(Dangerous Prototypes)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;General Electronics and Hardware Hacking&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blog.ianlee.info/2012/01/quick-tip-making-momentary-buttons.html"&gt;
Making Momentary Buttons Breadboard Friendly&lt;/a&gt; (Software and
Sawdust)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://circuit-zone.com/index.php?electronic_project=659"&gt;555
LED Pulsing Breathing Circuit&lt;/a&gt; (Circuit Zone)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://citizenscientistsleague.com/2012/01/24/a-curiously-low-noise-amplifier/"&gt;
A Curiously Low Noise Amplifier&lt;/a&gt; (Citizen Scientists
League)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://circuit-zone.com/index.php?electronic_project=658"&gt;1.5V
FM Broadcast Transmitter&lt;/a&gt; (Circuit Zone)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://dangerousprototypes.com/2012/01/25/the-phone-box/"&gt;The
phone box&lt;/a&gt; (Dangerous Prototypes)&lt;/li&gt;

&lt;li&gt;&lt;a href="http://www.electronics-lab.com/blog/?p=16394"&gt;LED
brightness controller with 64 taps&lt;/a&gt; (Electronics Lab)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Robotics and Robotics Studio&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://robotgrrl.com/blog/2012/01/23/brrd-brain-board-more-progress-less-zigzags/"&gt;
Brrd Brain Board: More progress &amp;amp; less zigzags&lt;/a&gt;
(RobotGrrl)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Clocks&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://hackaday.com/2012/01/25/tutorial-build-a-manifold-clock-for-10/"&gt;
Tutorial: Build a manifold clock for $10&lt;/a&gt; (Hack a Day)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Synthesizers, MIDI and Electronic Instruments&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://highlyliquid.com/blog/?p=852"&gt;Meng Qi's
Wicki-Hayden MIDI Controller&lt;/a&gt; (Highly Liquid)&lt;/li&gt;

&lt;li&gt;&lt;a href="http://highlyliquid.com/blog/?p=839"&gt;Trojan Chorus:
Pinata as MIDI Controller&lt;/a&gt; (Highly Liquid)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Photography&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.diyphotography.net/diy-small-circular-softboxes"&gt;DIY:
Small Circular Softboxes&lt;/a&gt; (DIY Photography)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.diyphotography.net/super-high-speed-footage-of-a-60d-exposure-cycle"&gt;
Super High Speed Footage Of A 60D Exposure Cycle&lt;/a&gt; (DIY
Photography)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.diyphotography.net/using-a-double-flash-bracket-to-add-modeling-light-to-your-setup"&gt;
Using A Double Flash Bracket To Add Modeling light To Your
Setup&lt;/a&gt; (DIY Photography)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;General Maker&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://brando.ie/tweetsweets/"&gt;Tweet Sweet&lt;/a&gt;
(Brando)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://vonkonow.com/wordpress/2012/01/software-for-home-automation/"&gt;
Software for web controlled home automation&lt;/a&gt; (Johan von
Konow)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Retro Computing and Commodore!&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.mos6502.com/general-blogness/retro-game-fair-the-netherlands/"&gt;
Retro Game Fair, The Netherlands&lt;/a&gt; (MOS6502)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.rgcd.co.uk/2011/12/c64anabalt-c64-2011.html"&gt;C64anabalt
(C64) (2011)&lt;/a&gt; (RGCD)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.mos6502.com/friday-commodore/commodore-inside/"&gt;Commodore
Inside!&lt;/a&gt; (MOS6502)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.rgcd.co.uk/2012/01/hydra-castle-labyrinth-pc.html"&gt;
Hydra Castle Labyrinth (PC)&lt;/a&gt; (RGCD)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Misc Geek&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://vihart.com/blog/spongebob/"&gt;Open Letter to
Nickelodeon, Re: SpongeBob's Pineapple under the Sea&lt;/a&gt; (Vi
Hart)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://this8bitlife.com/this-8-bit-life/2012/1/13/cyberpunk-style-workstation-is-pretty-sexy.html"&gt;
Cyberpunk style Workstation is Pretty Sexy&lt;/a&gt; (This 8 bit
Life)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://this8bitlife.com/this-8-bit-life/2012/1/24/amazing-legend-of-zelda-zora-armor-cosplay.html"&gt;
Amazing Legend of Zelda Zora Armor Cosplay&lt;/a&gt; (This 8 bit
Life)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Just Awesome&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=1wwilCs4Jqg"&gt;
You'll either thank me, or burn my house down for this one. Either
way, those brain cells aren't coming back.&lt;/a&gt; (YouTube)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Clsbo6NvjY3r5PY3v6WfNJlE3fM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Clsbo6NvjY3r5PY3v6WfNJlE3fM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Clsbo6NvjY3r5PY3v6WfNJlE3fM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Clsbo6NvjY3r5PY3v6WfNJlE3fM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PVD4L9hWMF4:odUC5g5Bsdw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PVD4L9hWMF4:odUC5g5Bsdw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PVD4L9hWMF4:odUC5g5Bsdw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PVD4L9hWMF4:odUC5g5Bsdw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=PVD4L9hWMF4:odUC5g5Bsdw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PVD4L9hWMF4:odUC5g5Bsdw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=PVD4L9hWMF4:odUC5g5Bsdw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PVD4L9hWMF4:odUC5g5Bsdw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=PVD4L9hWMF4:odUC5g5Bsdw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/PVD4L9hWMF4" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/25/maker-geek-roundup-006-for-1-25-2012</feedburner:origLink></item><item><title>Now, more than ever, you need a designer</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/KjRU3dOJmeI/now-more-than-ever-you-need-a-designer</link><pubDate>Wed, 25 Jan 2012 06:52:53 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/25/now-more-than-ever-you-need-a-designer</guid><description>&lt;p&gt;Before joining Microsoft, I was a consultant, primarily building
desktop applications using a variety of MS technologies. During my
last couple years there, Silverlight was a large part of that both
for full apps and as parts of larger web sites. Prior to that, it
was WPF, Windows Forms, VB, HTML and even SharePoint.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; The point of this long post is not to
show you examples of good design or pick apart existing designs.
I'm not really qualified to do that. However, I can point out the
need for design and give you some small amount of ammunition when
presenting this to your own management. Visual and UX Design
matters, even for internal apps, often far more than architecture
or the other things we focus on. You'll be more efficient with a
designer on-team, who you can iterate with. The world is evolving
and we need to keep up. Go hire one now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr the tl;dr:&lt;/strong&gt; Hire a UX/Interaction
designer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The company I worked at wouldn't hire a UX/Visual
designer.&lt;/strong&gt; Why? Because they felt they could &lt;strong&gt;never
sell the benefit of good UX and visual design to
customers&lt;/strong&gt;, and couldn't keep a designer busy 100% of the
time. The problem was, without a portfolio of well-designed UI and
sites, it became self-fulfilling. I had contended that if they
hired one, they'd be amazed at just how busy that person would end
up being. Quite frankly, they just didn't see the value.&lt;/p&gt;

&lt;p&gt;It got to the point that when I walked into my management's
office, they'd be like "You're not going to tell us to hire a
designer again, are you?"&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You may even be&lt;/em&gt; &lt;a
href="http://10rem.net/blog/2010/11/19/windows-forms-to-xaml-do-i-really-need-a-designer-for-silverlight-or-wpf-applications"
 target="_blank"&gt;&lt;em&gt;thinking the same thing&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, this
post may see like Déjà vu if you've followed my blog for a few
years :) I took a more conservative approach to the problem in that
2010 post. Basically saying the same types of things&lt;/em&gt; &lt;a
href="http://www.hanselman.com/blog/SkipIntroCSS3IsTheNewFlash.aspx"
 target="_blank"&gt;&lt;em&gt;Scott Hanselman recently pointed out in his
Skip Intro post&lt;/em&gt;&lt;/a&gt;&lt;em&gt;: don't over do it, and don't use
things just because they're there. In that post, I argued that if
you want to just keep making the same old battleship gray
applications, you don't *need* a designer. However, I still think
you can benefit from one in your projects regardless. So, I'm going
to backtrack a little bit and deliver a more absolute form of the
message: yes, you need a designer. Whether it is HTML/JS/CSS, or
XAML/C#/VB, or something else, you should have design talent on
staff.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For a bit, we toyed around with the idea of partnering with an
outside firm. The problem was, there was too much of a "hand off"
approach to the design. Without having the design talent on-staff,
you couldn't iterate during the project. The design was passed in
at the beginning and then slowly destroyed by the developers (or
people like me who had good UX but horrible Graphics design skills)
over time.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://bizarrocomic.blogspot.com/2010/06/tough-guy-ugly-baby-free-show.html"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82999/Windows-Live-Writer_a2371b66e292_D4C8_image_22.png" width="270" height="317" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I likened it to other disciplines, like partnering with a firm
just to design the database. Sure, design it all up-front and then
make the project live with that throughout the rest of the
lifecycle. No one found that to be a sane idea, but still couldn't
see the parallel with UX and Graphics design.&lt;/p&gt;

&lt;p&gt;Now, in their defense, the company primarily worked on
large-scale transaction processing systems. However, the business
had slowly evolved to include more commercial work, and more
intranet and internet sites for these same customers. Also, in
their defense, our customers felt the same way. They wanted really
great UX and graphics, but somehow felt those things simply fell
from the sky. They didn't want to pay for designers on projects
either. &lt;strong&gt;They were still stuck in the team makeup and ideas
that worked for mainframe applications and, as in most cases,
haven't moved on.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One thing the enterprise development community in general has
been slower to adopt is the idea that you really do need visual and
UX design talent on staff. &lt;strong&gt;Application success or failure
rarely comes from architecture, or reuse, or whether or not you use
stored procedures or which ORM you use.&lt;/strong&gt; Those are things
we do to meet other, more internal, goals, most of which users
don't care about in the least, many of which offer more perceived
benefit than actual real project benefit. As Scott mentioned in
another post, &lt;a
href="http://www.hanselman.com/blog/YourUsersDontCareIfYouUseWebSockets.aspx"
 target="_blank"&gt;users don't care if you use Web Sockets&lt;/a&gt;. Sure,
if you really botch the architecture, the app may be unusable, but
beyond that, your investment is better spent elsewhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/binaryape/458758810/"
target="_blank"&gt;&lt;img src="http://10rem.net/media/83004/Windows-Live-Writer_a2371b66e292_D4C8_image_16.png" width="650" height="139" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Knowing Your Limits&lt;/h3&gt;

&lt;p&gt;Yesterday, &lt;a
href="http://www.hanselman.com/blog/SkipIntroCSS3IsTheNewFlash.aspx"
 target="_blank"&gt;Scott Hanselman blogged about the emerging trend
to throw a dog's breakfast of features into HTML5/CSS3/JS
sites&lt;/a&gt;. He and I chatted about it for a little, and felt I
should write something up here as well. Go read his post as
well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's natural for developers to push the boundaries when
a new technology comes out.&lt;/strong&gt; That's how we learn. That's
fine for demo sites in developer echo chambers and &lt;a
href="http://www.youtube.com/results?search_query=c64+compo"
target="_blank"&gt;compos&lt;/a&gt;, but &lt;strong&gt;don't do it in front of
actual users&lt;/strong&gt;. It's too easy to have your app look and
perform like a Pirate's idea of wealth: all money and no style.
Scott has links to a few examples of that in his post. There are a
couple other good ones in the comments.&lt;/p&gt;

&lt;p&gt;How did we get to this point? Why do so many still not even
realize we're here?&lt;/p&gt;

&lt;h3&gt;Modern Development&lt;/h3&gt;

&lt;p&gt;First, a little history:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/83009/Windows-Live-Writer_a2371b66e292_D4C8_image_40.png" width="213" height="155" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;a
href="http://www.flickr.com/photos/vax-o-matic/5625208727/"
target="_blank"&gt;&lt;img src="http://10rem.net/media/83014/Windows-Live-Writer_a2371b66e292_D4C8_image_35.png" width="223" height="155" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;img src="http://10rem.net/media/83019/Windows-Live-Writer_a2371b66e292_D4C8_image_38.png" width="209" height="155" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/83024/Windows-Live-Writer_a2371b66e292_D4C8_image_39.png" width="192" height="245" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;a
href="http://www.amazon.com/Wordperfect-5-1-Toolbox-Keyboard-Template/dp/078211007X/ref=cm_cmu_pg__header"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83029/Windows-Live-Writer_a2371b66e292_D4C8_image_43.png" width="453" height="245" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't wear a suit to work. In fact, I work from home, so what
I wear barely counts as clothing some days. I also don't sit in
front of a highly non-ergonomic greenscreen device, trying to
remember arcane codes (ok, well I do when I'm messing around with
microcontrollers or old computers). Why? Because the world has
moved on from that. Gradually over the years, more and more UX
thought has been given to applications.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When applications were just command-line affairs, the only UX
you really had to worry about was how hard the transaction codes
were to remember. Most of the UX was the huge three-ring binder
manual or the multiple volume boxed sets with textured cloth
covers. Users often spent as much time in that as interacting with
the screen, especially during their first X months.
&lt;strong&gt;Graphics were Escher prints you hung on the wall.&lt;/strong&gt;
Computers were &lt;strong&gt;supposed to be hard&lt;/strong&gt;, for some
unknown reason. Engineering ruled the experience, and we didn't
know any better.&lt;/li&gt;

&lt;li&gt;When they became full-screen character mode applications
(Curses, anyone? No? How about the &lt;a
href="http://www.lanet.lv/simtel.net/msdos/turbo_c.html"
target="_blank"&gt;windowing libraries for DOS TurboC&lt;/a&gt;/C++ apps?
IBM 3270? No? Pah. Youngsters.) there was more UX to worry about,
but the layout and workflow choices were still so limited as to
make it easier for a dev with a good eye to come up with something
decent. &lt;strong&gt;Graphics were things scientists used for data
visualization&lt;/strong&gt;. Design was for &lt;a
href="http://www.thedieline.com/blog/2009/11/17/the-evolution-of-the-coca-cola-contour-bottle.html"
 target="_blank"&gt;companies making physical products customers had
to hold in their hands&lt;/a&gt;. An entire industry was built around
plastic-coated cardboard keyboard templates to help you remember
all the keyboard shortcuts required to navigate important
applications, especially for DOS. I blame WordPerfect.&lt;/li&gt;

&lt;li&gt;When apps became battleship gray forms over data (white 2d
forms first), &lt;strong&gt;UX consisted mainly of making sure you had a
decent tab order and "fit as much as possible" on a single
screen&lt;/strong&gt;. Navigation often resembled those character mode
applications we were upgrading/scraping/rewriting because our users
didn't know any better, and we didn't know how to show them
something else and prove it would be more efficient and/or easier.
Things started to go south here. &lt;strong&gt;Graphics were for games
and maybe 16x16 16 color icons&lt;/strong&gt;. &lt;a
href="http://www.youtube.com/watch?v=lAD6Obi7Cag"
target="_blank"&gt;Animation was for music videos&lt;/a&gt;.&lt;/li&gt;

&lt;li style="list-style: none"&gt;
&lt;ul&gt;
&lt;li&gt;Early on, apps were even just black and white instead of gray.
But when the gray "3d" chiseled look started coming into vogue late
in Win 3.11's lifetime (there was a special common controls library
just for it), developers went nuts and had apps that looked like
Mayan pyramids. Borders within borders within borders. Uuuuugly.
And I did it too. It was new. It was exciting, and it was
abused.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;When the web started making inroads into application
development, UX became further complicated. First, the workflow
options for early web apps really blew. &lt;strong&gt;Many apps had two
buttons "Submit" and "Reset" and a big form above them&lt;/strong&gt;.
Validation and all other processing mostly took place server-side.
Sometimes, we got clever, and sent all the data through an iframe
to avoid a full page refresh. We made excuses because that's how
all the other apps were working, and we didn't take much
inspiration from branded experiences. However, at least they often
looked nicer than those battleship gray apps. That made a real
impression on people. Hmm. Graphics. Colors. Whitespace. Animation
was for dancing hamsters or Pixar.&lt;/li&gt;

&lt;li&gt;And then the proliferation of consumer-oriented smart phones
and tablets with great UX, driven in no small part by Apple,
&lt;strong&gt;really brought UX and visual design to the front&lt;/strong&gt;.
It's not because the platform had a great API or something (I've
never worked on it, but I hear the platform, from a programming and
design standpoint is … interesting), but because it attracted a lot
of designer types. It's no accident that companies like Apple and
Microsoft chose design firms to create the first showcase
prototypes of their new UI technologies. Now, even inside the
enterprise, many customers expect this level of UX in their own
applications. Graphics, colors, whitespace, touch, animation,
easing and more all become important parts of the visual design,
and it's &lt;a
href="http://kellabyte.com/2011/12/19/when-metro-design-falls-off-the-tracks/"
 target="_blank"&gt;very easy to get it wrong&lt;/a&gt; unless you have a &lt;a
href="http://www.riagenic.com/archives/751" target="_blank"&gt;talent
for design&lt;/a&gt;.&lt;/li&gt;

&lt;li style="list-style: none"&gt;
&lt;ul&gt;
&lt;li&gt;Your users now and in the future are ones brought up on this
crop of highly visual applications. What do you think they will
have for expectations?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But now we're stuck, because we have the tools to do whatever we
want, but haven't evolved the teams to effectively make use if
them.&lt;/p&gt;

&lt;p&gt;We've had tools and platforms to build these types of apps for
some time. Flash has been around forever, Silverlight since 2007,
and finally, HTML5/CSS3 and its support in browsers is mostly
catching up to where FutureSplash was in 1996. &lt;strong&gt;The
capabilities are there, we just need to use them for
good.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's not just for consumer-oriented apps, either. As companies
consolidate their development staff, expose more things outside the
firewall, or work to support a large number of internal users, the
line between consumer and enterprise development continues to
thin.&lt;/p&gt;

&lt;p&gt;For grins, here are some apps I wrote in the 90s and early
2000-ish, where I happened to have saved some screen shots (I
really wished I had saved more, especially the dBase/FoxPro apps I
wrote for DOS and the VB3-6 and PowerBuilder ones for Windows
3.11). The first one was written for DOS entirely in Borland C++
(including the database) the others were, as I recall, .NET 1.0
beta versions of VB4 apps I wrote earlier. in the first one, I
mainly just had to worry about tab order. In the second, the users
were most comfortable with filling out an online version of the
paper form (in fact, they'd have the paper form in front of them
while doing this). The third was using the typical "Make it look
like Outlook" model of the time.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83034/Windows-Live-Writer_a2371b66e292_D4C8_image_28.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83039/Windows-Live-Writer_a2371b66e292_D4C8_image_thumb_10.png" width="400" height="188" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That version actually looked quite a bit better on a giant 15"
CRT, perched high enough up to count as neck-stretching exercise.
:)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83044/Windows-Live-Writer_a2371b66e292_D4C8_image_24.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83049/Windows-Live-Writer_a2371b66e292_D4C8_image_thumb_8.png" width="320" height="225" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;a
href="http://10rem.net/media/83054/Windows-Live-Writer_a2371b66e292_D4C8_image_26.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83059/Windows-Live-Writer_a2371b66e292_D4C8_image_thumb_9.png" width="320" height="224" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like so many other developers, I simply copied prevalent design
trends of the time (how many devs have you talked to back in the
day who said they were trying to make their app look like Outlook
or Visual Studio/Visual Basic?). I got away with it, but you can
see that it doesn't 100% work. &lt;strong&gt;I force fit some things due
to the limited palette of visual design patterns at my
disposal&lt;/strong&gt;. Bonus points: battleship gray.&lt;/p&gt;

&lt;h3&gt;Is it Customer-Facing?&lt;/h3&gt;

&lt;p&gt;I've heard many people say that they'll only invest in UX for
customer-facing stuff. But who is the customer?&lt;/p&gt;

&lt;p&gt;It depends on how you define your customer. For many IT shops,
the customer works for the same company. For sales apps, many times
the field laptop/tablet application is seen by both a sales person
and the customer. Many of the same things you'd do in a consumer
application apply to these same customers, but &lt;strong&gt;because
they're forced to use your app, they don't get the same attention
to UX&lt;/strong&gt; that external true consumer apps do.&lt;/p&gt;

&lt;p&gt;Here's a list of some common types of applications being built
today, or in the near future. Tell me where UX doesn't matter?
Which is customer-facing?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call center apps inside an organization&lt;/li&gt;

&lt;li&gt;The departmental day-to-day work application at your
company&lt;/li&gt;

&lt;li&gt;Consumer touch-oriented apps on phones and tablets&lt;/li&gt;

&lt;li&gt;Consumer apps on the desktop&lt;/li&gt;

&lt;li&gt;Enterprise shrink-wrapped products for the desktop&lt;/li&gt;

&lt;li&gt;Your intranet site&lt;/li&gt;

&lt;li&gt;That forms-over-data application everyone in the company
uses&lt;/li&gt;

&lt;li&gt;Time and expense reporting systems&lt;/li&gt;

&lt;li&gt;Your one-off shell script to update a bunch of database
tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, so I through the shell script in there just to have
something where you could get away without UX. Of course, there's
often some design put in there too. Did you take a moment to set up
different command line arguments? UX, just no pretty graphics
:)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many times have you heard "Sorry, the computer is really
slow today" when you talk to someone at a call center? Typically
this is because it takes forever to accomplish anything on their
crappy apps. Sometimes, of course, they have a 9600bps serial
connection from wherever they are to wherever the data is, but most
of the time it's just a crap UI that takes forever to help you, or
they've forgotten how to do a certain thing in the UI because it's
so non-intuitive. I've seen these apps up close. I've seen the
massive amount of training that people have to go through to learn
them. Some of the most horrendous UX I've ever seen was in an
in-house call center application to take outage reports at a power
company - one of their most critical ways to help customers. Are
they not worth better UX?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;UX is important for all those applications&lt;/strong&gt;.
&lt;strong&gt;The more the application gets used, the more good or bad UX
comes into play.&lt;/strong&gt; It's not just about selling the
application and getting 5 stars, it's also about making others more
efficient and making their lives a little less hellish. Making them
feel good while using it is a nice bonus.&lt;/p&gt;

&lt;p&gt;Most developers, let's not kid ourselves, are simply not
well-equipped to make good UX decisions. They're too embedded in
the software, &lt;strong&gt;and too aware of the underlying code and
architecture changes that a change in UX would require&lt;/strong&gt; so
they push back, or don't even consider the things that really
should be done. Or they build the system back-to-front and the UI,
by necessity, resembles the data structures they used throughout
the app. Oh, and changing the UX of an application is one of those
things that becomes becomes far more expensive as you wait. UX is
the entire workflow of the application. It touches just about
everything.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://www.flickr.com/photos/drewmaughan/6425581707/in/photostream/"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83064/Windows-Live-Writer_a2371b66e292_D4C8_image_5.png" width="650" height="127" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What about graphics? In companies, "Designer" often encompasses
both UX and Visual/Graphics design. Often, good UX designers also
have a decent visual design background as well, just as developers
often have more than one related skill.&lt;/p&gt;

&lt;h3&gt;Just go Find Some Free Icons&lt;/h3&gt;

&lt;p&gt;That's something I heard over and over, and you probably hear it
too. "Go find some clipart" or "go find a free icon set". Ugh.
Invariably, the icon set would only have 1/3 of the required icons,
and the remaining ones would have to magically appear. I was able
to do that (Axialis Icon Designer saw a lot of me back then), not
anywhere near as well as the original designer, but well enough.
There were many other applications I saw which had different icons
from various sets, with incompatible styles, all mashed together on
the same toolbar.&lt;/p&gt;

&lt;p&gt;The same thing applies to site themes, css, and more. "Just go
find a template" is almost as bad as "go find some free icons".&lt;/p&gt;

&lt;p&gt;There are more choices today, but you still end up with those
toolbars (or pages, or whatever) where half the icons look good,
and the other half show some bad image with a three letter acronym
over it.&lt;/p&gt;

&lt;p&gt;They all have &lt;a
href="http://www.bing.com/images/search?q=splash+screen"
target="_blank"&gt;splash screens&lt;/a&gt; though, and with clip art. Maybe
even from MS Word. :)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://office.microsoft.com/en-us/images/results.aspx?qu=screenbeans"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83069/Windows-Live-Writer_a2371b66e292_D4C8_image_19.png" width="650" height="68" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In some cases, the UI starts to resemble that PTA fund raising
newsletter sent home with your kid, or that office baby shower
announcement :)&lt;/p&gt;

&lt;p&gt;When I did work on the graphics and visual design of
applications a decade or more ago, I had to do it while hiding in
the corner. I had a customer PM come over and tell me "don't let
anyone see you drawing pictures". Clearly the visual design and
icons and other elements "just appeared" from nowhere. The effort
was not respected, but the outcome was expected.&lt;/p&gt;

&lt;p&gt;The problem here is not that developers don't know their limits
(most do), but that &lt;strong&gt;management doesn't see the UX/Graphics
Designer role as useful. It's not seen as a science, it's art. And
just like in public schools, it's art that gets cut
first&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An introduction to Interaction Design should be a required
subject for all Computer Science and MIS majors. Not because I
would expect them to learn to be great at it, but because they need
good solid exposure to it so they know something's possible, even
if they don't have the required skills/talent. They'll see there's
more science to it than they thought. In fact, Psychology
backgrounds often help in UX design. It helps that most Psychology
majors are otherwise unemployed :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Like I said to Scott "The more freedom and power you have, the
more you need someone to tell you what
&lt;strong&gt;&lt;span&gt;not&lt;/span&gt;&lt;/strong&gt; to do." You need this person on
your team.&lt;/p&gt;

&lt;h3&gt;Who is On Your Team?&lt;/h3&gt;

&lt;p&gt;If you are on a team larger than two people, I bet you have a
project manager, a dedicated DBA/database designer (or someone who
doubles as DBA and database designer while also coding queries and
services and whatnot), a front-end programmer, a back-end
programmer, and maybe even a tester. Maybe you have an analyst or
two, although those seem to be getting scarce. Larger teams tend to
have more finely grained roles.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/83074/Windows-Live-Writer_a2371b66e292_D4C8_image_10.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/83079/Windows-Live-Writer_a2371b66e292_D4C8_image_thumb_3.png" width="650" height="150" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are all seen as specialized skills. Not everyone is great
at designing databases. Not everyone is equally skilled at creating
good services and APIs. Not everyone can line up fields on a form.
With web apps, the division tends to be even stronger due to the
different languages and platforms in use in the different tiers or
sections of the application. Inside the development community we,
and our managers, understand these limitations and try to work
within them.&lt;/p&gt;

&lt;p&gt;But most importantly, not everyone can take a problem and
visualize an appropriate workflow and user experience, low-cost
prototype it, test it with the users, and make the changes required
to make the best UX the project budget will support. It's a
specialized skill like any other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And like any other part of a software project, you don't
want to just do it at the end. No lipstick on a pig. Get a designer
involved form the beginning, and include them in your iteration
plan. You'll be amazed at what you can accomplish.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How have your battles gone on this front? Have you been
able to convince management about the importance of
UX/Interaction/Visual design? If so, how did you go about it? What
worked? What didn't?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KHHu-7N4oo6qJuTl19Z110ijeVg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KHHu-7N4oo6qJuTl19Z110ijeVg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KHHu-7N4oo6qJuTl19Z110ijeVg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KHHu-7N4oo6qJuTl19Z110ijeVg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=KjRU3dOJmeI:k0UEhhFKrnU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=KjRU3dOJmeI:k0UEhhFKrnU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=KjRU3dOJmeI:k0UEhhFKrnU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=KjRU3dOJmeI:k0UEhhFKrnU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=KjRU3dOJmeI:k0UEhhFKrnU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=KjRU3dOJmeI:k0UEhhFKrnU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=KjRU3dOJmeI:k0UEhhFKrnU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=KjRU3dOJmeI:k0UEhhFKrnU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=KjRU3dOJmeI:k0UEhhFKrnU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/KjRU3dOJmeI" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/25/now-more-than-ever-you-need-a-designer</feedburner:origLink></item><item><title>Arduino The Documentary</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/cjfhIcd9A28/arduino-the-documentary</link><pubDate>Tue, 24 Jan 2012 04:48:51 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/24/arduino-the-documentary</guid><description>&lt;p&gt;For anyone interested in open source microcontroller
development, or why boards are named with *duino type names, this
1/2 hour documentary is a great watch.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://vimeo.com/18539129" target="_blank"&gt;&lt;img src="http://10rem.net/media/82982/Windows-Live-Writer_Arduino-the-Documentary_989_image_6.png" width="662" height="382" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://vimeo.com/18539129"
title="http://vimeo.com/18539129"&gt;http://vimeo.com/18539129&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Arduino.TheDocumentary.2010.English explains the origin of the
Arduino in a relatively non-technical interview-based documentary
style, with interviews for people involved in the creation, as well
as key partners and users.&lt;/p&gt;

&lt;p&gt;Spanish version is also available.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MZ6XpYcOxlOmDwl-zBngC-b56Wg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MZ6XpYcOxlOmDwl-zBngC-b56Wg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MZ6XpYcOxlOmDwl-zBngC-b56Wg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MZ6XpYcOxlOmDwl-zBngC-b56Wg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cjfhIcd9A28:TL--vRci44g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cjfhIcd9A28:TL--vRci44g:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cjfhIcd9A28:TL--vRci44g:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cjfhIcd9A28:TL--vRci44g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=cjfhIcd9A28:TL--vRci44g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cjfhIcd9A28:TL--vRci44g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=cjfhIcd9A28:TL--vRci44g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=cjfhIcd9A28:TL--vRci44g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=cjfhIcd9A28:TL--vRci44g:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/cjfhIcd9A28" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/24/arduino-the-documentary</feedburner:origLink></item><item><title>My First Real PIX-6T4 Game: Sixty4Racer</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/ZnhAnsv1yk8/my-first-real-pix-6t4-game-sixty4racer</link><pubDate>Sun, 22 Jan 2012 13:34:30 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/22/my-first-real-pix-6t4-game-sixty4racer</guid><description>&lt;p&gt;After &lt;a
href="http://10rem.net/blog/2012/01/21/assembling-the-pix-6t4-netduino-powered-hand-held-game-system"
 target="_blank"&gt;assembling my Netduino-powered PIX-6T4&lt;/a&gt;, I
wanted to go and write a simple game. This post describes the
construction of that game, including all source code.&lt;/p&gt;

&lt;h3&gt;Concept&lt;/h3&gt;

&lt;p&gt;When you have 64 monochrome red pixels, you need to keep the
graphics simple. I decided on a game inspired by the classic &lt;a
href="http://www.bing.com/images/search?q=river+raid&amp;amp;qs=n&amp;amp;sk=&amp;amp;sc=8-3&amp;amp;form=QBIR"
 target="_blank"&gt;Atari River Raid game&lt;/a&gt;. This is essentially a
vertical scrolling game where you need to dodge obstacles with your
boat. Variations included things like &lt;a
href="http://www.bing.com/images/search?q=commodore+spy+hunter&amp;amp;qs=n&amp;amp;sk=&amp;amp;sc=8-13&amp;amp;form=QBIR"
 target="_blank"&gt;Spy Hunter on the C64&lt;/a&gt; and many many others.
Most of those games also involved shooting and enemies, but that's
a but more complex than you can reasonably do on this board. I
won't enable moving walls like &lt;a
href="http://www.bing.com/images/search?q=laser+gates+atari&amp;amp;qs=n&amp;amp;sk=&amp;amp;form=QBIR"
 target="_blank"&gt;Laser Gates&lt;/a&gt;, but I'll leave things open enough
not to make it impossible to do that in the future.&lt;/p&gt;

&lt;p&gt;The game had to be small enough that I could figure out the API,
and then design, code, and blog about it in a single evening after
my kids went to bed The PIX-6T4 is fun, but I have way too many
projects on my backlog to be able to devote any
&lt;strong&gt;significant&lt;/strong&gt; time to it (&lt;em&gt;here's a taste: a
ShapeOko CNC mill, an AVR MIDI-&amp;gt;CV Converter, the final touches
on the MIDI Thru Box, several MFOS Synth Modules, Several Gadgeteer
Board Concepts, a Win8 XAML book, chapters to review in my
Silverlight 5 book, and much much more&lt;/em&gt;). In fact, that was one
of the &lt;strong&gt;big selling points of this device: simple gameplay
and quick to develop for&lt;/strong&gt;. Combined with the great library
Fabien designed, and my past experience with Netduino and, more
specifically, C#, and this should be an evening project.&lt;/p&gt;

&lt;h3&gt;GamePlay&lt;/h3&gt;

&lt;p&gt;A simple dodge'em racing game. Levels get progressively longer
and faster until you crash. And you will crash. And burn. And
die.&lt;/p&gt;

&lt;p&gt;The joystick lets you control moving your single pixel vehicle
either left or right. You can't move in any other direction.&lt;/p&gt;

&lt;h4&gt;Progression&lt;/h4&gt;

&lt;p&gt;Most good games increase in difficulty as you progress through
the game. I decided that for this one, both the number of screens
in the level and the overall speed would both increase as you
progress through the game.&lt;/p&gt;

&lt;h4&gt;Goals&lt;/h4&gt;

&lt;p&gt;The goal is simple: not die. The longer you last, the more
levels you'll make it through, and the more you'll be able to brag
to your friends.&lt;/p&gt;

&lt;h3&gt;Screen Design&lt;/h3&gt;

&lt;p&gt;Back in the 80s, in 7th grade, I used to design single-color
sprites for the commodore 64. The sprites themselves were 3 bytes
wide, with each pixel represented as a single bit in the byte. I
used to define them on graph paper, but alas, the notebooks I
filled with sprites and BASIC listings have long since
disappeared.&lt;/p&gt;

&lt;p&gt;I used to create my own fonts (programmable characters) as well.
Those were done in a similar way, but on 8x8 graphs, eight bytes
total for each character. Some pretty amazing games were created
just with character graphics (the amazing &lt;a
href="http://www.mobygames.com/game/below-the-root"
target="_blank"&gt;Below the Root on the C64&lt;/a&gt;, as I recall, was one
of them. You can &lt;a
href="http://www.youtube.com/watch?v=zWKpgpHa2Mo"
target="_blank"&gt;see it played here&lt;/a&gt;.). That model is what we
have to work with on the PIX-6T4, but showing the equivalent of one
character at a time.&lt;/p&gt;

&lt;p&gt;Here's an image from the Commodore 64 Programmer's Reference
Manual&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82883/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82888/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_thumb.png" width="369" height="280" alt="image" border="0" style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see there how the letter A is formed by the bit patterns
for the eight bytes. I'm going to use a similar approach for the
level design here. I'll create the "blocks" that make up the play
area and then chain them together to create a playable game
field.&lt;/p&gt;

&lt;p&gt;Here here are the initial screens I created, using notepad. The
only criteria I had was to make sure the middle two spots were open
at the start and end of each screen. Zeroes are safe areas, ones
are walls/shore/hard-deadly-smashy-things.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82893/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_4.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82898/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_thumb_1.png" width="660" height="205" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The more variation in screens you add, the more challenging and
interesting the game can be. So, I'll be sure to leave the design
open enough to allow for other screens to be easily added.&lt;/p&gt;

&lt;p&gt;I don't need to limit myself to 8 bytes high, but I did anyway,
as that will let you do things like use &lt;a
href="http://www.min.at/prinz/software/pixelfont/"
target="_blank"&gt;8x8 pixel font editors&lt;/a&gt; to design the screens.
In fact, here are the same levels (with a couple slight
modifications), plus a bunch more, done using the pixel font
editor. I got a little carried away :)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82903/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_6.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82908/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_thumb_2.png" width="660" height="152" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first entry is the start screen, the second is the end
screen. All the ones after that are random ones which can be shown
at any point during play. There are several "break" screens in
there. That is, screens that aren't particularly difficult. And
then there are a number of hair-pullers, and ones with dead-ends
too :) Black is wall, white is passable space.&lt;/p&gt;

&lt;p&gt;Thanks to Fabien for pointing out this tool in the source code.
It's so much easier to visualize the design when using the font
editor, plus you get to export the bytes automatically. Speaking of
export, here's what the tool generated for me:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
&lt;br /&gt;
// Font: ScreensSource.pf&lt;br /&gt;
&lt;br /&gt;
unsigned char font[2048] =&lt;br /&gt;
{&lt;br /&gt;
    0xC7, 0xC3, 0x83, 0x83, 0x81, 0x00, 0x00, 0x00,    // Char 000 (.)&lt;br /&gt;
    0x00, 0x00, 0x81, 0x81, 0xC3, 0xC3, 0xE7, 0xE7,    // Char 001 (.)&lt;br /&gt;
    0xE3, 0xCF, 0x87, 0xCF, 0x81, 0xF3, 0xC3, 0x87,    // Char 002 (.)&lt;br /&gt;
    0x87, 0xC1, 0xF1, 0xF9, 0xE1, 0x87, 0xC3, 0x81,    // Char 003 (.)&lt;br /&gt;
    0x81, 0xE7, 0x81, 0x99, 0x99, 0x81, 0xE7, 0xC3,    // Char 004 (.)&lt;br /&gt;
    0xE7, 0xE7, 0xF1, 0xC1, 0xCF, 0xE3, 0xF7, 0xE7,    // Char 005 (.)&lt;br /&gt;
    0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,    // Char 006 (.)&lt;br /&gt;
    0xE3, 0xF9, 0xFC, 0xFE, 0xFC, 0xF9, 0xF3, 0xE7,    // Char 007 (.)&lt;br /&gt;
    0xE7, 0xE7, 0xEF, 0xE7, 0xF7, 0xE7, 0xEF, 0xE7,    // Char 008 (.)&lt;br /&gt;
    0xC3, 0xFB, 0xE1, 0xEF, 0xC1, 0xFB, 0x83, 0xE7,    // Char 009 (.)&lt;br /&gt;
    0xE7, 0xC1, 0x81, 0xF9, 0xC0, 0x81, 0x9F, 0x87,    // Char 010 (.)&lt;br /&gt;
    0xE7, 0xC3, 0x00, 0x7E, 0x00, 0xE7, 0xE7, 0x81,    // Char 011 (.)&lt;br /&gt;
    0xE7, 0x81, 0x18, 0x7E, 0x3C, 0x99, 0xC3, 0xE7,    // Char 012 (.)&lt;br /&gt;
    0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x3C, 0x18, 0x00,    // Char 013 (.)&lt;br /&gt;
    0xC3, 0x89, 0x24, 0xB5, 0xA5, 0x2C, 0x81, 0xC3,    // Char 014 (.)&lt;br /&gt;
    0x86, 0x3C, 0x5A, 0x66, 0x3C, 0x28, 0x82, 0xC6,    // Char 015 (.)&lt;br /&gt;
    0x81, 0x00, 0x66, 0x66, 0x00, 0x99, 0x81, 0xA5,    // Char 016 (.)&lt;br /&gt;
    0xE7, 0xC3, 0xDF, 0x83, 0xF7, 0xA1, 0x8D, 0xE7,    // Char 017 (.)&lt;br /&gt;
    0xC3, 0x81, 0x00, 0x18, 0x18, 0x00, 0x81, 0xC3,    // Char 018 (.)&lt;br /&gt;
    0xE7, 0xC3, 0x99, 0x38, 0x1C, 0x99, 0xC3, 0xE7,    // Char 019 (.)&lt;br /&gt;
    0x04, 0x49, 0x02, 0x10, 0x4A, 0x00, 0x44, 0x20,    // Char 020 (.)&lt;br /&gt;
    0xA7, 0x2D, 0x6A, 0x2D, 0x26, 0x55, 0x56, 0x27,    // Char 021 (.)&lt;br /&gt;
    0xE7, 0xF7, 0xE7, 0xF7, 0xC3, 0xDB, 0xC3, 0xE7,    // Char 022 (.)&lt;br /&gt;
    0xE3, 0xCB, 0x9B, 0x3B, 0x89, 0x3D, 0x9D, 0xC5,    // Char 023 (.)&lt;br /&gt;
    0xE7, 0xC3, 0x99, 0xBD, 0x99, 0xC3, 0xE7, 0xE7,    // Char 024 (.)&lt;br /&gt;
    0xC3, 0xCF, 0xC3, 0xF3, 0xC7, 0xE3, 0xCF, 0xC7,    // Char 025 (.)&lt;br /&gt;
    0x65, 0xB6, 0x55, 0xB6, 0x65, 0xAA, 0x6D, 0xA7,    // Char 026 (.)&lt;br /&gt;
    0xE7, 0xC3, 0xE3, 0xF1, 0xF8, 0xF3, 0xC7, 0xE7,    // Char 027 (.)&lt;br /&gt;
    0xE4, 0xF4, 0xF4, 0xF4, 0xE4, 0x69, 0x0B, 0xA7,    // Char 028 (.)&lt;br /&gt;
    0x00, 0x18, 0x66, 0x5A, 0x5A, 0x66, 0x18, 0x00,    // Char 029 (.)&lt;br /&gt;
    0xA5, 0x91, 0x93, 0x97, 0x93, 0xCB, 0xE3, 0xE7,    // Char 030 (.)&lt;br /&gt;
    0x00, 0xDB, 0xC3, 0xE7, 0xE7, 0xC3, 0x99, 0x00,    // Char 031 (.)&lt;br /&gt;
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // Char 032 ( )&lt;br /&gt;
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // Char 033 (!)&lt;br /&gt;
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // Char 034 (")&lt;br /&gt;
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // Char 035 (#)&lt;br /&gt;
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // Char 036 ($)&lt;br /&gt;
    ...&lt;br /&gt;
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00     // Char 255 (.)&lt;br /&gt;
};
&lt;/pre&gt;

&lt;p&gt;I then just needed to prune it to remove the stuff I wasn't
using, and make it work in my app. The font designer certainly took
a lot of the work out of it, though. The end-result can be seen in
the code listing for the Screens class.&lt;/p&gt;

&lt;p&gt;With that in place, it was time to actually start creating the
game.&lt;/p&gt;

&lt;h3&gt;First Iteration: Creating the scrolling playfield&lt;/h3&gt;

&lt;p&gt;I called my project PeteBrown.Sixty4Racer. Just as in the
previous post, I copied over the Program.cs file from another
project and used that as the start. Please &lt;a
href="http://10rem.net/blog/2012/01/21/assembling-the-pix-6t4-netduino-powered-hand-held-game-system"
 target="_blank"&gt;read my previous post&lt;/a&gt; to see what references
you need and whatnot.&lt;/p&gt;

&lt;p&gt;The first class I created was the one that manages the creation
of the screens.&lt;/p&gt;

&lt;h4&gt;The Screens Class&lt;/h4&gt;

&lt;p&gt;The Screens class is responsible for storing all the known
screens, and then assembling them into a level when requested. It
knows how large the screens are, and how large a single level's
full set of screens is.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using netduino.helpers.Imaging;&lt;br /&gt;
&lt;br /&gt;
namespace PeteBrown.Sixty4Racer&lt;br /&gt;
{&lt;br /&gt;
    class Screens&lt;br /&gt;
    {&lt;br /&gt;
        // Font: ScreensSource.pf&lt;br /&gt;
        private const int ScreenCount = 32;&lt;br /&gt;
        private const int ScreenHeight = 8;&lt;br /&gt;
        private readonly byte[] _screenBytes = new byte[ScreenCount * ScreenHeight]&lt;br /&gt;
        {&lt;br /&gt;
            0xC7, 0xC3, 0x83, 0x83, 0x81, 0x00, 0x00, 0x00,    // Start Screen&lt;br /&gt;
            0x00, 0x00, 0x81, 0x81, 0xC3, 0xC3, 0xE7, 0xE7,    // Stop Screen&lt;br /&gt;
            0xE3, 0xCF, 0x87, 0xCF, 0x81, 0xF3, 0xC3, 0x87,    // Char 002 (.)&lt;br /&gt;
            0x87, 0xC1, 0xF1, 0xF9, 0xE1, 0x87, 0xC3, 0x81,    // Char 003 (.)&lt;br /&gt;
            0x81, 0xE7, 0x81, 0x99, 0x99, 0x81, 0xE7, 0xC3,    // Char 004 (.)&lt;br /&gt;
            0xE7, 0xE7, 0xF1, 0xC1, 0xCF, 0xE3, 0xF7, 0xE7,    // Char 005 (.)&lt;br /&gt;
            0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,    // Char 006 (.)&lt;br /&gt;
            0xE3, 0xF9, 0xFC, 0xFE, 0xFC, 0xF9, 0xF3, 0xE7,    // Char 007 (.)&lt;br /&gt;
            0xE7, 0xE7, 0xEF, 0xE7, 0xF7, 0xE7, 0xEF, 0xE7,    // Char 008 (.)&lt;br /&gt;
            0xC3, 0xFB, 0xE1, 0xEF, 0xC1, 0xFB, 0x83, 0xE7,    // Char 009 (.)&lt;br /&gt;
            0xE7, 0xC1, 0x81, 0xF9, 0xC0, 0x81, 0x9F, 0x87,    // Char 010 (.)&lt;br /&gt;
            0xE7, 0xC3, 0x00, 0x7E, 0x00, 0xE7, 0xE7, 0x81,    // Char 011 (.)&lt;br /&gt;
            0xE7, 0x81, 0x18, 0x7E, 0x3C, 0x99, 0xC3, 0xE7,    // Char 012 (.)&lt;br /&gt;
            0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x3C, 0x18, 0x00,    // Char 013 (.)&lt;br /&gt;
            0xC3, 0x89, 0x24, 0xB5, 0xA5, 0x2C, 0x81, 0xC3,    // Char 014 (.)&lt;br /&gt;
            0x86, 0x3C, 0x5A, 0x66, 0x3C, 0x28, 0x82, 0xC6,    // Char 015 (.)&lt;br /&gt;
            0x81, 0x00, 0x66, 0x66, 0x00, 0x99, 0x81, 0xA5,    // Char 016 (.)&lt;br /&gt;
            0xE7, 0xC3, 0xDF, 0x83, 0xF7, 0xA1, 0x8D, 0xE7,    // Char 017 (.)&lt;br /&gt;
            0xC3, 0x81, 0x00, 0x18, 0x18, 0x00, 0x81, 0xC3,    // Char 018 (.)&lt;br /&gt;
            0xE7, 0xC3, 0x99, 0x38, 0x1C, 0x99, 0xC3, 0xE7,    // Char 019 (.)&lt;br /&gt;
            0x04, 0x49, 0x02, 0x10, 0x4A, 0x00, 0x44, 0x20,    // Char 020 (.)&lt;br /&gt;
            0xA7, 0x2D, 0x6A, 0x2D, 0x26, 0x55, 0x56, 0x27,    // Char 021 (.)&lt;br /&gt;
            0xE7, 0xF7, 0xE7, 0xF7, 0xC3, 0xDB, 0xC3, 0xE7,    // Char 022 (.)&lt;br /&gt;
            0xE3, 0xCB, 0x9B, 0x3B, 0x89, 0x3D, 0x9D, 0xC5,    // Char 023 (.)&lt;br /&gt;
            0xE7, 0xC3, 0x99, 0xBD, 0x99, 0xC3, 0xE7, 0xE7,    // Char 024 (.)&lt;br /&gt;
            0xC3, 0xCF, 0xC3, 0xF3, 0xC7, 0xE3, 0xCF, 0xC7,    // Char 025 (.)&lt;br /&gt;
            0x65, 0xB6, 0x55, 0xB6, 0x65, 0xAA, 0x6D, 0xA7,    // Char 026 (.)&lt;br /&gt;
            0xE7, 0xC3, 0xE3, 0xF1, 0xF8, 0xF3, 0xC7, 0xE7,    // Char 027 (.)&lt;br /&gt;
            0xE4, 0xF4, 0xF4, 0xF4, 0xE4, 0x69, 0x0B, 0xA7,    // Char 028 (.)&lt;br /&gt;
            0x00, 0x18, 0x66, 0x5A, 0x5A, 0x66, 0x18, 0x00,    // Char 029 (.)&lt;br /&gt;
            0xA5, 0x91, 0x93, 0x97, 0x93, 0xCB, 0xE3, 0xE7,    // Char 030 (.)&lt;br /&gt;
            0x00, 0xDB, 0xC3, 0xE7, 0xE7, 0xC3, 0x99, 0x00    // Char 031 (.)&lt;br /&gt;
        };&lt;br /&gt;
&lt;br /&gt;
        private RacerGame _parentGame;&lt;br /&gt;
&lt;br /&gt;
        public Screens(RacerGame parentGame)&lt;br /&gt;
        {&lt;br /&gt;
            _parentGame = parentGame;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public int GetLevelScreenCount(int level)&lt;br /&gt;
        {&lt;br /&gt;
            return level * 6 + 2;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int GetLevelPixelHeight(int level)&lt;br /&gt;
        {&lt;br /&gt;
            return GetLevelScreenCount(level) * ScreenHeight;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public Composition GetLevelComposition(int level)&lt;br /&gt;
        {&lt;br /&gt;
            int levelScreenCount = GetLevelScreenCount(level);&lt;br /&gt;
&lt;br /&gt;
            byte[] bytes = new byte[ScreenHeight * levelScreenCount];&lt;br /&gt;
&lt;br /&gt;
            int b = 0;&lt;br /&gt;
            int startIndex = 0;&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; levelScreenCount; i++)&lt;br /&gt;
            {&lt;br /&gt;
                if (i == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    // finish screen. This is the second screen in the array&lt;br /&gt;
                    startIndex = ScreenHeight;&lt;br /&gt;
                }&lt;br /&gt;
                else if (i == levelScreenCount - 1)&lt;br /&gt;
                {&lt;br /&gt;
                    // start screen. First screen in the array&lt;br /&gt;
                    startIndex = 0;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    // regular random screen&lt;br /&gt;
                    int selectedScreen = _parentGame.Random.Next(ScreenCount - 2) + 2;&lt;br /&gt;
&lt;br /&gt;
                    startIndex = ScreenHeight * selectedScreen;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                for (int a = startIndex; a &amp;lt; startIndex + ScreenHeight; a++, b++)&lt;br /&gt;
                {&lt;br /&gt;
                    bytes[b] = _screenBytes[a];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return new Composition(bytes, 8, levelScreenCount * ScreenHeight);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The class has the primary function GetLevelComposition which
builds the background bitmap used to populate all the little red
LEDs. The Composition class is one of the netduino helper classes
in the PIX-6T4 library.&lt;/p&gt;

&lt;p&gt;The next class is the main game class.&lt;/p&gt;

&lt;h4&gt;The RacerGame class&lt;/h4&gt;

&lt;p&gt;The RacerGame class is responsible for all the game-specific
logic. It handles scrolling the level, displaying messages, and
(eventually), moving the player around the screen and handling
collision detection. In this first iteration, all it does is
display the level number and then scroll the level at the
appropriate speed. The first level may seem to scroll painfully
slow, but trust me, throw a player pixel in there and you'll change
your mind.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using netduino.helpers.Fun;&lt;br /&gt;
using netduino.helpers.Imaging;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
&lt;br /&gt;
namespace PeteBrown.Sixty4Racer&lt;br /&gt;
{&lt;br /&gt;
    class RacerGame : Game&lt;br /&gt;
    {&lt;br /&gt;
        private Screens _screens;&lt;br /&gt;
&lt;br /&gt;
        public RacerGame(ConsoleHardwareConfig config)&lt;br /&gt;
            : base(config)&lt;br /&gt;
        {&lt;br /&gt;
            _screens = new Screens(this);&lt;br /&gt;
&lt;br /&gt;
            DisplayDelay = 25;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameEnd()&lt;br /&gt;
        {&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameStart()&lt;br /&gt;
        {&lt;br /&gt;
            base.OnGameStart();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
        private int _currentLevel = 0;&lt;br /&gt;
        private float _currentlevelSpeedIncrement = 0f;&lt;br /&gt;
        private float _exactScrollPosition = 0.0f;&lt;br /&gt;
&lt;br /&gt;
        private int CurrentWorldLine&lt;br /&gt;
        {&lt;br /&gt;
            get { return (int)_exactScrollPosition; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void InitializeLevel()&lt;br /&gt;
        {&lt;br /&gt;
            World = _screens.GetLevelComposition(_currentLevel);&lt;br /&gt;
            _exactScrollPosition = _screens.GetLevelPixelHeight(_currentLevel) - 1;&lt;br /&gt;
            _currentlevelSpeedIncrement = 0.02f * (float)_currentLevel; // tweak this to change speed&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void CompleteLevel()&lt;br /&gt;
        {&lt;br /&gt;
            // TODO: Play some music&lt;br /&gt;
&lt;br /&gt;
            Thread.Sleep(1500);&lt;br /&gt;
            ScrollMessage(" Level Up!");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void IntroduceLevel()&lt;br /&gt;
        {&lt;br /&gt;
            // show the level number&lt;br /&gt;
            Hardware.Matrix.Display(SmallChars.ToBitmap(_currentLevel / 10, _currentLevel % 10));&lt;br /&gt;
            Thread.Sleep(1000);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private bool _firstTime = true;&lt;br /&gt;
        public override void Loop()&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentWorldLine == 0 || _firstTime)&lt;br /&gt;
            {&lt;br /&gt;
                if (!_firstTime)&lt;br /&gt;
                {&lt;br /&gt;
                    CompleteLevel();&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // Next Level&lt;br /&gt;
                _currentLevel++;&lt;br /&gt;
                InitializeLevel();&lt;br /&gt;
                IntroduceLevel();&lt;br /&gt;
&lt;br /&gt;
                _firstTime = false;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                _exactScrollPosition -= _currentlevelSpeedIncrement;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // draw the frame&lt;br /&gt;
            Hardware.Matrix.Display(World.GetFrame(0, CurrentWorldLine));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The RacerGame class knows a level is complete when the top row
of pixels is the first row of pixels in the level. Remember, since
we're scrolling the screen down, we're moving from the bottom to
the top of the rows of pixels. Get to the top, and the level is
done.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Minor But Fatal Bitmap Class Bug&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The GetFrame method in the version of the source code I used has
an incorrect check. Where it says if (x &amp;gt;= 0 &amp;amp;&amp;amp; x +
FrameSize &amp;lt; Width) it should say if (x &amp;gt;= 0 &amp;amp;&amp;amp; x +
FrameSize &amp;lt;= Width). Notice the &amp;lt;= instead of &amp;lt;. The
incorrect check means that any bitmaps that are exactly 8 pixels
wide, like the one here, simply won't display. This bug may be
fixed in the source you get, but you'll want to double-check. I'm
just glad I had the source to refer to (and fix!). Isn't OSS great?
:)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the level is complete, you get the scrolling "Level Up!"
message. Click the joystick button and you're good to try the next
level.&lt;/p&gt;

&lt;p&gt;Now is a good time to run the game and see what it looks like.
You should see a vertically scrolling playfield, but no player just
yet.&lt;/p&gt;

&lt;h3&gt;Second Iteration: Adding in the player&lt;/h3&gt;

&lt;p&gt;The PIX-6T4 libraries have built-in the concept of a
PlayerMissile. This is a single pixel on the playfield. It may
move, so it has X and Y speed. You can show or hide it, so it has
Visibility. And most importantly, it has collision detection with
other PlayerMissile instances. For our game, we're not going to use
that, since we're looking for collision detection with the
background. So, a little manual detection is in order.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bitmap Class Bugs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While coding this game, I found a few more bugs in the Bitmap
class. I've alerted Fabien, so you should see an updated set of
source code soon. The first bug is that the GetPixel and SetPixel
methods do some incorrect bounds checking up front. Y is checked
against width rather than height, and the opposite happens with X.
We're going to use GetPixel in a moment, so fixing this is
important.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's the updated RacerGame class&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using netduino.helpers.Fun;&lt;br /&gt;
using netduino.helpers.Imaging;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
&lt;br /&gt;
namespace PeteBrown.Sixty4Racer&lt;br /&gt;
{&lt;br /&gt;
    class RacerGame : Game&lt;br /&gt;
    {&lt;br /&gt;
        private Screens _screens;&lt;br /&gt;
        private PlayerMissile _ship;&lt;br /&gt;
&lt;br /&gt;
        public RacerGame(ConsoleHardwareConfig config)&lt;br /&gt;
            : base(config)&lt;br /&gt;
        {&lt;br /&gt;
            _screens = new Screens(this);&lt;br /&gt;
&lt;br /&gt;
            DisplayDelay = 25;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameEnd()&lt;br /&gt;
        {&lt;br /&gt;
            ScrollMessage(" Game Over");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameStart()&lt;br /&gt;
        {&lt;br /&gt;
            base.OnGameStart();&lt;br /&gt;
&lt;br /&gt;
            _ship = new PlayerMissile()&lt;br /&gt;
                {&lt;br /&gt;
                    Name = "ship",&lt;br /&gt;
                    IsEnemy = false,&lt;br /&gt;
                    X = 3,&lt;br /&gt;
                    IsVisible = true,&lt;br /&gt;
                    VerticalSpeed = 0,&lt;br /&gt;
                };&lt;br /&gt;
&lt;br /&gt;
            ScrollMessage(" Sixty4Racer!");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
        private int _currentLevel = 0;&lt;br /&gt;
        private float _currentlevelSpeedIncrement = 0f;&lt;br /&gt;
        private const float BaseShipSpeed = 0.25f;           // speed ship moves across the screen&lt;br /&gt;
        private float _exactScrollPosition = 0.0f;&lt;br /&gt;
&lt;br /&gt;
        private int CurrentWorldLine&lt;br /&gt;
        {&lt;br /&gt;
            get { return (int)_exactScrollPosition; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void InitializeLevel()&lt;br /&gt;
        {&lt;br /&gt;
            World = _screens.GetLevelComposition(_currentLevel);&lt;br /&gt;
            World.AddMissile(_ship);&lt;br /&gt;
&lt;br /&gt;
            _exactScrollPosition = _screens.GetLevelPixelHeight(_currentLevel) - 1;&lt;br /&gt;
            _currentlevelSpeedIncrement = 0.02f * (float)_currentLevel; // tweak this to change speed&lt;br /&gt;
&lt;br /&gt;
            _ship.Y = CurrentWorldLine + 7; // always be on bottom line&lt;br /&gt;
            _ship.X = 3;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void CompleteLevel()&lt;br /&gt;
        {&lt;br /&gt;
            // TODO: Play some music&lt;br /&gt;
&lt;br /&gt;
            Thread.Sleep(1500);&lt;br /&gt;
            ScrollMessage(" Level Up!");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void IntroduceLevel()&lt;br /&gt;
        {&lt;br /&gt;
            // show the level number&lt;br /&gt;
            Hardware.Matrix.Display(SmallChars.ToBitmap(_currentLevel / 10, _currentLevel % 10));&lt;br /&gt;
            Thread.Sleep(1000);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private bool CheckForCollision()&lt;br /&gt;
        {&lt;br /&gt;
            return World.Background.GetPixel(_ship.X, _ship.Y);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private bool _firstTime = true;&lt;br /&gt;
        public override void Loop()&lt;br /&gt;
        {&lt;br /&gt;
            _ship.HorizontalSpeed = (float)Hardware.JoystickLeft.XDirection * BaseShipSpeed;&lt;br /&gt;
            _ship.Move();&lt;br /&gt;
&lt;br /&gt;
            if (_ship.X &amp;lt; 0) _ship.X = 0;&lt;br /&gt;
            if (_ship.X &amp;gt; 7) _ship.X = 7;&lt;br /&gt;
&lt;br /&gt;
            if (CurrentWorldLine == 0 || _firstTime)&lt;br /&gt;
            {&lt;br /&gt;
                if (!_firstTime)&lt;br /&gt;
                {&lt;br /&gt;
                    CompleteLevel();&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                // Next Level&lt;br /&gt;
                _currentLevel++;&lt;br /&gt;
                InitializeLevel();&lt;br /&gt;
                IntroduceLevel();&lt;br /&gt;
&lt;br /&gt;
                _firstTime = false;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                _exactScrollPosition -= _currentlevelSpeedIncrement;&lt;br /&gt;
&lt;br /&gt;
                _ship.Y = CurrentWorldLine + 7; // always be on bottom line&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // draw the frame&lt;br /&gt;
            Hardware.Matrix.Display(World.GetFrame(0, CurrentWorldLine));&lt;br /&gt;
&lt;br /&gt;
            if (CheckForCollision())&lt;br /&gt;
            {&lt;br /&gt;
                // game over&lt;br /&gt;
                Stop();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This version of the source adds in the player pixel&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I represent the "This Game is Too Damn Hard"
Party&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At this point, after adding the player and collision detection,
I realized just how hard this game is! If you want to make it
easier, I suggest editing the levels to make them a little more
open, like a minimum of two pixels wide for any path, and no sudden
moves left or right. You may even want to segment the level array
into easy/medium/hard, and then change the mix of screens from
level to level.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With all that in place, now is another great time to try out the
game. It has all the main functionality at this point; anything
else is just polish.&lt;/p&gt;

&lt;h3&gt;Third Iteration: Polishing&lt;/h3&gt;

&lt;p&gt;The first thing I realized was that it was really hard to make
out the player pixel in the sea of red. That's to be expected on a
monochrome display at 8x8 resolution. The approach I came up with
to make it a bit easier is to simply flicker the player pixel. Each
time the game loop executes, I toggle the visibility of the ship
PlayerMissile to give it a nice seizure-inducing flicker.&lt;/p&gt;

&lt;pre class="brush: csharp; highlight: [7];"&gt;
public override void Loop()&lt;br /&gt;
{&lt;br /&gt;
    _ship.HorizontalSpeed = (float)Hardware.JoystickLeft.XDirection * BaseShipSpeed;&lt;br /&gt;
    _ship.Move();&lt;br /&gt;
&lt;br /&gt;
    // make the ship blink so we can see it&lt;br /&gt;
    _ship.IsVisible = !_ship.IsVisible;&lt;br /&gt;
&lt;br /&gt;
    if (_ship.X &amp;lt; 0) _ship.X = 0;&lt;br /&gt;
    if (_ship.X &amp;gt; 7) _ship.X = 7;&lt;br /&gt;
&lt;br /&gt;
    if (CurrentWorldLine == 0 || _firstTime)&lt;br /&gt;
    {&lt;br /&gt;
        if (!_firstTime)&lt;br /&gt;
        {&lt;br /&gt;
            CompleteLevel();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Next Level&lt;br /&gt;
        _currentLevel++;&lt;br /&gt;
        InitializeLevel();&lt;br /&gt;
        IntroduceLevel();&lt;br /&gt;
&lt;br /&gt;
        _firstTime = false;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        _exactScrollPosition -= _currentlevelSpeedIncrement;&lt;br /&gt;
&lt;br /&gt;
        _ship.Y = CurrentWorldLine + 7; // always be on bottom line&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // draw the frame&lt;br /&gt;
    Hardware.Matrix.Display(World.GetFrame(0, CurrentWorldLine));&lt;br /&gt;
&lt;br /&gt;
    if (CheckForCollision())&lt;br /&gt;
    {&lt;br /&gt;
        // game over&lt;br /&gt;
        Stop();&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;h4&gt;Sound Effects&lt;/h4&gt;

&lt;p&gt;The next thing this needed was some sound effects. When you move
left or right a full pixel, it would be helpful to play a little
blip. Maybe that's annoying? Nah! Let's do it.&lt;/p&gt;

&lt;p&gt;This is really easy to do. I simply keep track of the last
position the ship moved to. If the new position is different from
the old one, I call the Beep function to make a noise. The actual
implementation here results in an extra blip on startup, but I'm
cool with that :)&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void Blip()&lt;br /&gt;
{&lt;br /&gt;
    Beep(200, 30);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
private bool _firstTime = true;&lt;br /&gt;
private int _oldShipX = 0;&lt;br /&gt;
public override void Loop()&lt;br /&gt;
{&lt;br /&gt;
    _ship.HorizontalSpeed = (float)Hardware.JoystickLeft.XDirection * BaseShipSpeed;&lt;br /&gt;
    _ship.Move();&lt;br /&gt;
&lt;br /&gt;
    if (_ship.X != _oldShipX)&lt;br /&gt;
    {&lt;br /&gt;
        Blip();&lt;br /&gt;
        _oldShipX = _ship.X;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // make the ship blink so we can see it&lt;br /&gt;
    _ship.IsVisible = !_ship.IsVisible;&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;Next, we need to do a little bit of exploding when you hit the
wall. And yes, you &lt;strong&gt;will&lt;/strong&gt; hit the wall.&lt;/p&gt;

&lt;h4&gt;The Explosion Sprite&lt;/h4&gt;

&lt;p&gt;The final thing was to add a little bit of an explosion when the
player hits the wall. I designed the sprite data using the same
PixelFont editor.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82913/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_8.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82918/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_thumb_3.png" width="660" height="90" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then copied just those 8 x 8 bytes of data into the
initializer for the sprite class. Here's the Sprite class itself
(without the initializer code).&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
&lt;br /&gt;
namespace PeteBrown.Sixty4Racer&lt;br /&gt;
{&lt;br /&gt;
    class Sprite&lt;br /&gt;
    {&lt;br /&gt;
        private readonly byte[] _frames;&lt;br /&gt;
        private const int Width = 8;&lt;br /&gt;
        private const int Height = 8;&lt;br /&gt;
        private int _frameCount;&lt;br /&gt;
&lt;br /&gt;
        public Sprite (byte[] frames)&lt;br /&gt;
        {&lt;br /&gt;
            _frames = frames;&lt;br /&gt;
&lt;br /&gt;
            _frameCount = _frames.Length / Height;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int FrameCount&lt;br /&gt;
        {&lt;br /&gt;
            get { return _frameCount; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public int CurrentFrame&lt;br /&gt;
        {&lt;br /&gt;
            get { return _currentFrame; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void Reset()&lt;br /&gt;
        {&lt;br /&gt;
            _currentFrame = 0;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private int _currentFrame = 0;&lt;br /&gt;
        public byte[] GetNextFrame()&lt;br /&gt;
        {&lt;br /&gt;
            return GetFrame(_currentFrame++);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public byte[] GetFrame(int index)&lt;br /&gt;
        {&lt;br /&gt;
            if (index &amp;gt;= FrameCount)&lt;br /&gt;
                throw new IndexOutOfRangeException("Index must be less than " + FrameCount);&lt;br /&gt;
&lt;br /&gt;
            byte[] b = new byte[Height];&lt;br /&gt;
&lt;br /&gt;
            for (int i = 0; i &amp;lt; Height; i++)&lt;br /&gt;
            {&lt;br /&gt;
                b[i] = _frames[index * Height + i];&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return b;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;(The initialization code will be in the next listing.)&lt;/p&gt;

&lt;p&gt;Next, I added in a little music. How about some Sad Trombone
when you die? Sounds good to me. By looking at the Pac Man music
example, and the source code for the RttlSong class, I was able to
figure out how to build a string of notes to play the sad trombone
sound asynchronously while the explosion happens. Rub it in!&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
Sprite _explosion = new Sprite(new byte[]&lt;br /&gt;
    {&lt;br /&gt;
        0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,&lt;br /&gt;
        0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00,&lt;br /&gt;
        0x08, 0x3C, 0x72, 0x5B, 0xDE, 0x62, 0x3C, 0x08,&lt;br /&gt;
        0x3C, 0xD2, 0xAD, 0xFE, 0x5F, 0xF5, 0x56, 0x28,&lt;br /&gt;
        0x00, 0x3C, 0x56, 0x7A, 0x6E, 0x72, 0x3C, 0x00,&lt;br /&gt;
        0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,&lt;br /&gt;
        0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,&lt;br /&gt;
        0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
protected override void OnGameEnd()&lt;br /&gt;
{&lt;br /&gt;
    var song = new RttlSong("SadTrombone:d=4,o=4,b=40:32d4,32c#4,32c4,4b3");&lt;br /&gt;
    var thread = song.Play(Hardware.Speaker, true);&lt;br /&gt;
&lt;br /&gt;
    for (int i = 0; i &amp;lt; _explosion.FrameCount; i++)&lt;br /&gt;
    {&lt;br /&gt;
        Hardware.Matrix.Display(_explosion.GetNextFrame());&lt;br /&gt;
        Thread.Sleep(200);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ScrollMessage(" Game Over");&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;You can go further, of course, but I'm going to wrap it up at
that.&lt;/p&gt;

&lt;h3&gt;Final Steps&lt;/h3&gt;

&lt;p&gt;The final things to do are to create the manifest file and
bitmap which will be used on the SD card. I'll need to check with
Fabien to see what the exact format of the .bin file is, but I
suspect it's just the 8 bytes of data formatted like all the other
bitmap data in this application. I'm also not sure if he has a nice
little app to write that data out, or convert from a bitmap, or
something else. I ended up just using a hex editor to recreate the
pattern from one of the images I created in the font editor.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82923/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_10.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82928/Windows-Live-Writer_My-First-Real-PIX-6T4-Game_1194A_image_thumb_4.png" width="257" height="198" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The assembly itself needs to be loaded from the SD card as a .pe
file, as Fabien explains in &lt;a
href="http://fabienroyer.wordpress.com/2010/12/29/loading-assemblies-dynamically-from-an-sd-card-with-a-netduino/"
 target="_blank"&gt;his blog post on dynamically loading assemblies
from an SD card&lt;/a&gt;. Be sure to comment out the #define dev before
your final compile. Make sure you take the .pet file from the LE
(little endian) folder, not the BE (big endian) folder. The files
look identical other than byte order, but the BE version will not
work.&lt;/p&gt;

&lt;p&gt;I then created a cartridge.txt manifest file for my game. The
contents of that consist of a single line:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
&lt;br /&gt;
assembly:file=PeteBrown.Sixty4Racer.pe;name=PeteBrown.Sixty4Racer;version=1.0.0.0;class=PeteBrown.Sixty4Racer.Program;method=Run&lt;br /&gt;
&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;They must be in a folder with the same name as the root file
name for the image. So, these go in a PeteBrown.Sixty4Racer
folder.&lt;/p&gt;

&lt;p&gt;Finally, don't forget to reflash the PIX-6T4 with the main
ConsoleBootLoader application from your solution.&lt;/p&gt;

&lt;p&gt;After that, pop the SD card into the PIX-6T4 and have a
blast!&lt;/p&gt;

&lt;h3&gt;What You Can Do&lt;/h3&gt;

&lt;p&gt;This came is completely free and open source. While I'd love
credit for the initial work, it's not a requirement. Go ahead and
do whatever you'd like with the source and have a blast :)&lt;/p&gt;

&lt;p&gt;Here's a video of the game in action.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent"
id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:69c56f9e-f14a-4e1e-9f9f-43d6647494c3"
 style="margin: 0px; display: inline; float: none; padding: 0px;"&gt;
&lt;div id="6da37833-fb66-423f-bda2-cefc06cf5131"
style="margin: 0px; display: inline; padding: 0px;"&gt;&lt;object
width="611" height="343"
data="http://www.youtube.com/v/10FzxWQTzzM?hl=en&amp;amp;hd=1"
type="application/x-shockwave-flash"&gt;&lt;param name="src"
value="http://www.youtube.com/v/10FzxWQTzzM?hl=en&amp;amp;hd=1" /&gt;
&lt;/object&gt;&lt;/div&gt;

&lt;div style="width: 611px; clear: both; font-size: 0.8em;"&gt;PIX-6T4
Netduino Mini Game&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yocakmzHMcesqfhZTMHyJkfAQLk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yocakmzHMcesqfhZTMHyJkfAQLk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yocakmzHMcesqfhZTMHyJkfAQLk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yocakmzHMcesqfhZTMHyJkfAQLk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ZnhAnsv1yk8:vlM6_TNId14:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ZnhAnsv1yk8:vlM6_TNId14:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ZnhAnsv1yk8:vlM6_TNId14:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ZnhAnsv1yk8:vlM6_TNId14:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=ZnhAnsv1yk8:vlM6_TNId14:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ZnhAnsv1yk8:vlM6_TNId14:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=ZnhAnsv1yk8:vlM6_TNId14:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=ZnhAnsv1yk8:vlM6_TNId14:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=ZnhAnsv1yk8:vlM6_TNId14:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/ZnhAnsv1yk8" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/22/my-first-real-pix-6t4-game-sixty4racer</feedburner:origLink></item><item><title>Assembling the PIX-6T4 Netduino-powered Hand-Held Game System</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/8a8bxEqkR_U/assembling-the-pix-6t4-netduino-powered-hand-held-game-system</link><pubDate>Sat, 21 Jan 2012 07:12:51 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/21/assembling-the-pix-6t4-netduino-powered-hand-held-game-system</guid><description>&lt;p&gt;I recently picked up a PIX-6T4 build by Fabien Royer (with games
by Fabien Royer and Bertrand Le Roy). This is a 64 pixel, two
joystick/button, monophonic sound hand-held game device based
around the Netduino Mini from Secret Labs. You create games in C#
using Visual studio.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: I work for Microsoft and I enjoy working in the .NET
Micro Framework as well as C++ on other microcontrollers. I
purchased this product on my own, at full price; this is not a
sample or review unit. Presumably, I got the same package of
goodies everyone else gets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Unboxing&lt;/h3&gt;

&lt;p&gt;The kit came in a regular USPS shipping box inside which were
four bags. Two bags had components, and two had joysticks.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82716/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_9.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82721/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_3.png" width="660" height="316" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything was well-packed in ESD safe bags. The two joysticks
were in their original as-delivered bags.&lt;/p&gt;

&lt;p&gt;What's inside?&lt;/p&gt;

&lt;h4&gt;What the Kit Includes&lt;/h4&gt;

&lt;p&gt;The kit includes just about everything you need to assemble a
working PIX-6T4 handheld game console. The PCB, of course, as well
as a nice laser-cut acrylic bottom.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82726/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_11.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82731/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_4.png" width="660" height="355" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82736/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_13.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82741/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_5.png" width="660" height="423" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can be powered by a 9v battery or a regular 9v power supply.
When using a battery, you solder a barrel jack on the battery lead
to make it easy to switch between the two.&lt;/p&gt;

&lt;p&gt;The entire thing is open source hardware and software from the
Netduino all the way up to the full kit and the software to run
it.&lt;/p&gt;

&lt;h4&gt;What it doesn't Include&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;A USB to Serial converter&lt;/strong&gt;. Many people with
Netduino minis already have one of these cables. You can get them
cheap online, or (worst case) get one at Best Buy or Fry's. I
happened to have one just because my C64-TPC (a connection between
my Commodore and my PC) needed one. Putting on-board USB would have
been nice, but that typically requires a surface-mount FTDI chip
which is very difficult for DIY soldering (or a breakout board from
a place like SparkFun which adds bulk, cost, and complexity). The
&lt;a href="http://www.netduino.com/netduinomini/specs.htm"
target="_blank"&gt;Netduino mini&lt;/a&gt;, unlike the Netduino, doesn't
offer an external USB interface. So, while I'm not a fan of the
serial approach, I do think it was the best choice here.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.netduino.com/netduinomini/specs.htm"
target="_blank"&gt;&lt;img src="http://10rem.net/media/82746/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_3.png" width="253" height="178" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="http://www.pix6t4.com/source"
target="_blank"&gt;play the stock games by just loading them on the SD
card&lt;/a&gt;. However, if you want to do any programming or debugging
of your own, you'll really need the USB converter, as debugging is
impossible without it.&lt;/p&gt;

&lt;p&gt;Speaking of SD card, that's the other things that you'll need:
&lt;strong&gt;A FAT32-formatted SD card&lt;/strong&gt;. You'll need one of
these to store the games you write and also to load the stock
games.&lt;/p&gt;

&lt;h3&gt;Assembly&lt;/h3&gt;

&lt;p&gt;I love the blue board. I've always liked blue, black and red
PCBs. The typical green solder mask just looks too much like some
crap 486 motherboard. I'm glad they went with something attractive
here.&lt;/p&gt;

&lt;p&gt;First step is the most unusual bit of soldering. There's one
surface mount component, but it's stunningly easy to solder. That's
the SD card slot. Make sure you following the video and do not
solder the two pins on the right (although if they're not connected
to anything, as long as you don't short them, I would think they'd
be fine)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82751/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_15.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82756/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_6.png" width="660" height="337" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next up, flip the board over and install the IC socket for the
LED controller, and then a resistor.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82761/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_17.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82766/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_7.png" width="660" height="327" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this particular case, it seems the stencil for the resistor
was sized for a 1/8" watt resistor. The space is also cramped, but
this resistor sticking up like that just breaks my heart. At least,
it's on the bottom side of the board so we can all hide our shame
:)&lt;/p&gt;

&lt;p&gt;Next, up, the LED array and then the Netduino mini socket.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82771/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_19.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82776/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_8.png" width="660" height="400" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A power switch and another resistor standing at attention&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82781/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_21.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82786/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_9.png" width="660" height="313" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, it's the audio trim pot and the power LED. At this
point, I have to mention that the power LED is REALLY bright and in
your face when you're trying to play. I covered mine with a little
bit of black paint, but even that isn't quite enough. I actually
think it would be better to solder that LED upside down, so it is
on the underside of the board. That might even be a cool effect
with the acrylic down there. Fabien mentioned he might bump up the
resistor value, but the more I think about putting it upside down,
the more I like it. I might even desolder mine and put a new LED
underneath :)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82791/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_23.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82796/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_10.png" width="660" height="239" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I did a few more steps before taking another photo. Resistors,
the power connector (underside), and a transistor are all in
place.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82801/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_25.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82806/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_11.png" width="660" height="501" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case you haven't gathered, I'm not a big fan of having
resistors stand up in general. In fact, I hate them in all but the
most cramped design with huge multi-watt resistors. They're easy to
knock over, bend, etc, and they're more difficult to solder in that
configuration. There's tons of spare room on this board, so I'm not
entirely sure why Fabien and folks did that. Just be careful when
soldering the other components so you don't break these off.&lt;/p&gt;

&lt;p&gt;Ceramic capacitor, electrolytic capacitor, and the 3.3v power
regulator in place. If I were designing this board, I think I would
have found a way to position the regulator so it lay flat on the
board with its leads bent at 90 degree angles. That's a pretty
common approach in other builds, like the &lt;a
href="http://10rem.net/blog/2011/10/22/just-completed-my-sammich-sid-build"
target="_blank"&gt;Sammich SID I built&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82811/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_27.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82816/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_12.png" width="660" height="305" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, the joysticks, pin headers, and the ICs themselves.
Before I installed the ICs, I went and cleaned the bottom of the
board with flux remover spray and a cleaning brush. It helps clean
things up quite a bit. You'll see later, it also helped me see a
bad solder joint. Organic Rosin flux isn't super harmful to leave
on, but it's ugly to see on the board.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82821/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_29.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82826/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_13.png" width="660" height="373" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget the one IC that goes on the bottom.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82831/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_31.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82836/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_14.png" width="660" height="225" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Smoke Test&lt;/h3&gt;

&lt;p&gt;Time for a power-on test! After I cleaned it up, dried if off,
and installed the ICs, I powered it up without an SD card. This is
what I saw:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82841/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_33.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82846/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_15.png" width="660" height="275" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sweet! I got the skull and crossbones, which means it's working.
As an aside, you can also see what I was talking about with the
super bright LED. It easily overpowers the playing field. Looks
cool in a photo, though, a bit like a Star Trek II photon
torpedo.&lt;/p&gt;

&lt;p&gt;Next, I copied the three game folders (from the zip file
referenced on the PIX-6T4 site) on to a 512MB SD card and started
it up. I was greeted by the icons of the games I could choose. I
picked a game and then…&lt;/p&gt;

&lt;h3&gt;And…I got nothing.&lt;/h3&gt;

&lt;p&gt;At first I thought it was this bad solder joint (which makes no
sense, but hey, I figured the code was perfect!). It's really hard
to see in this picture (and in fact, it looks ok in this picture),
but when viewed through a lens you can see that I never heated the
pin: the solder goes around the pin but never really joins with
it.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82851/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_5.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82856/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_1.png" width="520" height="330" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I only found this after cleaning the board with flux remover.
Flux can fill in holes like that and make it so you can't see them
without doing a continuity test. I resoldered that pin (and the one
next to it which didn't look much better), and then did a
continuity test between the mini and each of the breakout pins,
just to make sure there were no others.&lt;/p&gt;

&lt;p&gt;Still no go.&lt;/p&gt;

&lt;p&gt;After trying out a few SD cards and getting nothing, and
following some other suggestions from Fabien, I still had nothing.
Finally, Fabien recommended I dig out that usb-&amp;gt;serial cable (I
wasn't able to find it at first) and &lt;a
href="http://www.pix6t4.com/deploy-and-debug"
target="_blank"&gt;compile and re-deploy&lt;/a&gt; the current source from
Codeplex. Guess what? It worked :)&lt;/p&gt;

&lt;p&gt;It turns out I had one of the Netduino Minis that had the old
firmware on it, and the games were built with new firmware. The
deploy got them synchronized.&lt;/p&gt;

&lt;p&gt;Excellent. I have a working PIX-6T4 :)&lt;/p&gt;

&lt;h3&gt;The Test Games&lt;/h3&gt;

&lt;p&gt;I tried the games that come with it. One plays the Pac Man song,
one is a game of pong, and the other is an asteroid avoidance game.
You have only 64 pixels to work with, and they're all the same
color, so like the early days of video games, you need to use your
imagination.&lt;/p&gt;

&lt;p&gt;The stock games are well done. However, since I had the
debugger/programmer connected, I wanted to go and build something
myself.&lt;/p&gt;

&lt;h3&gt;My First Game&lt;/h3&gt;

&lt;p&gt;My first game is going to be a test game. I added a new Netduino
application project named "PeteTestGame". I did this in the same
solution that contains the PIX6T4 source code and the other three
stock games. Next, I added a reference to pix6t4.netduino.helpers
project.&lt;/p&gt;

&lt;p&gt;In the project, I also removed the reference to
SecretLabs.NETMF.Hardware.Netduino and add reference to
SecretLabs.NETMF.Hardware.NetduinoMini&lt;/p&gt;

&lt;p&gt;Next, add a GameOfTest class. I named it this following the
naming conventions Fabien and Bertrand set up, but you can call it
anything. GameOfThrones is an obvious choice ;)&lt;/p&gt;

&lt;h4&gt;The GameOfTest class&lt;/h4&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using netduino.helpers.Fun;&lt;br /&gt;
&lt;br /&gt;
namespace PeteTestGame&lt;br /&gt;
{&lt;br /&gt;
    class GameOfTest : Game&lt;br /&gt;
    {&lt;br /&gt;
        public GameOfTest(ConsoleHardwareConfig config)&lt;br /&gt;
            : base(config)&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameEnd()&lt;br /&gt;
        {&lt;br /&gt;
            base.OnGameEnd();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameStart()&lt;br /&gt;
        {&lt;br /&gt;
            base.OnGameStart();&lt;br /&gt;
&lt;br /&gt;
            ScrollMessage(" Hello World!");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnLeftButtonClick(uint port, uint state, DateTime time)&lt;br /&gt;
        {&lt;br /&gt;
            base.OnLeftButtonClick(port, state, time);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnRightButtonClick(uint port, uint state, DateTime time)&lt;br /&gt;
        {&lt;br /&gt;
            base.OnRightButtonClick(port, state, time);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public override void Loop()&lt;br /&gt;
        {&lt;br /&gt;
       &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}
&lt;br /&gt;
&lt;/pre&gt;

&lt;h4&gt;Program&lt;/h4&gt;

&lt;p&gt;Next, I copied the Program.cs from one of the other projects. I
made three changes to the source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uncomment the #define dev at the top&lt;/li&gt;

&lt;li&gt;Changed the namespace to match the rest of the project&lt;/li&gt;

&lt;li&gt;Changed the class in the Run method to be GameOfTest instead of
the one copied from the other project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The program.cs enables you to deploy your test game as the only
game on the device, without worrying about building up a manifest
and icon and dealing with the SD card and whatnot. Obviously, this
also makes debugging possible.&lt;/p&gt;

&lt;p&gt;Set the game project as startup. Next, right-click and select
project properties and navigate to the .NET Micro Framework tab.
Make sure the deployment is set to Serial and you have the COM port
that your Netduino mini is attached to.&lt;/p&gt;

&lt;p&gt;Once done, you can run the project. In my case, I immediately
saw the scrolling (and repeating) Hello World text. The
ScrollMessage function is doing all the heavy lifting. It's great
that Fabien put in the nifty retro font in there as well.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82861/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_7.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82866/Windows-Live-Writer_Assembling-the-PIX-6T4-Netduino-powered-_102FF_image_thumb_2.png" width="520" height="408" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next step was to add some beeping. Because, well, it's not a
game without beeping.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System;&lt;br /&gt;
using Microsoft.SPOT;&lt;br /&gt;
using netduino.helpers.Fun;&lt;br /&gt;
&lt;br /&gt;
namespace PeteTestGame&lt;br /&gt;
{&lt;br /&gt;
    class GameOfTest : Game&lt;br /&gt;
    {&lt;br /&gt;
        public GameOfTest(ConsoleHardwareConfig config)&lt;br /&gt;
            : base(config)&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameEnd()&lt;br /&gt;
        {&lt;br /&gt;
            base.Beep(440, 500);&lt;br /&gt;
            base.Beep(220, 500);&lt;br /&gt;
            base.Beep(440, 500);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        protected override void OnGameStart()&lt;br /&gt;
        {&lt;br /&gt;
            base.OnGameStart();&lt;br /&gt;
&lt;br /&gt;
            base.Beep(440, 500);&lt;br /&gt;
            base.Beep(220, 500);&lt;br /&gt;
            base.Beep(440, 500);&lt;br /&gt;
&lt;br /&gt;
            ScrollMessage(" Hello World!");&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnLeftButtonClick(uint port, uint state, DateTime time)&lt;br /&gt;
        {&lt;br /&gt;
            base.OnLeftButtonClick(port, state, time);&lt;br /&gt;
&lt;br /&gt;
            base.Beep(440, 500);&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected override void OnRightButtonClick(uint port, uint state, DateTime time)&lt;br /&gt;
        {&lt;br /&gt;
            base.OnRightButtonClick(port, state, time);&lt;br /&gt;
&lt;br /&gt;
            base.Beep(220, 500);&lt;br /&gt;
   &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public override void Loop()&lt;br /&gt;
        {&lt;br /&gt;
       &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;Now it plays a few beeps on startup and then beeps when you
press down on either joystick. Note that that does stop the
scrolling text, however.&lt;/p&gt;

&lt;p&gt;I'll leave the more complex games to a later date :)&lt;/p&gt;

&lt;blockquote&gt;Update 1/22: To see my first real full game, check out
my blog &lt;a
href="http://10rem.net/blog/2012/01/22/my-first-real-pix-6t4-game-sixty4racer"&gt;post
on building Sixty4Racer&lt;/a&gt;.&lt;/blockquote&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;I'm impressed with what Fabien has come up with here, and the
stock games he and Bertrand have done are just perfect. I think the
board and enclosure could use a little more design to make it more
compact and also more hand-friendly, but overall, I think this is
an excellent way to get into Netduino programming using something
fun and exciting. Also, because of the display technology, you are
constrained to creating games with very simple graphics (just LEDs)
so, by necessity, you avoid that common barrier to entry. Sometimes
constraint is a good thing.&lt;/p&gt;

&lt;p&gt;Congratulations Fabien and Bertrand!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/whKP6-ORjtSSDYR-6izmoWJELE0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/whKP6-ORjtSSDYR-6izmoWJELE0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/whKP6-ORjtSSDYR-6izmoWJELE0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/whKP6-ORjtSSDYR-6izmoWJELE0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=8a8bxEqkR_U:03Ulo_ojlQ8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=8a8bxEqkR_U:03Ulo_ojlQ8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=8a8bxEqkR_U:03Ulo_ojlQ8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=8a8bxEqkR_U:03Ulo_ojlQ8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=8a8bxEqkR_U:03Ulo_ojlQ8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=8a8bxEqkR_U:03Ulo_ojlQ8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=8a8bxEqkR_U:03Ulo_ojlQ8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=8a8bxEqkR_U:03Ulo_ojlQ8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=8a8bxEqkR_U:03Ulo_ojlQ8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/8a8bxEqkR_U" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/21/assembling-the-pix-6t4-netduino-powered-hand-held-game-system</feedburner:origLink></item><item><title>WPF 4.5 Cross-Thread Collection Synchronization Redux</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/c2zpPWogWkQ/wpf-45-cross-thread-collection-synchronization-redux</link><pubDate>Fri, 20 Jan 2012 21:59:04 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/20/wpf-45-cross-thread-collection-synchronization-redux</guid><description>&lt;p&gt;In my &lt;a
href="http://10rem.net/blog/2012/01/16/wpf-45-observable-collection-cross-thread-change-notification"
 target="_blank"&gt;post about WPF 4.5 Observable Collection
Cross-thread Change Notification&lt;/a&gt;, I showed the basics of how to
synchronize collection updates in WPF, and how to avoid having to
manually dispatch calls to the UI thread. In the comments, Jonathan
Allen brought up some very good points that I simply didn't know
the answers to (and a lock I was missing in the example). Thanks to
Jonathan for keeping me honest :)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For background, go back and &lt;a
href="http://10rem.net/blog/2012/01/16/wpf-45-observable-collection-cross-thread-change-notification"
 target="_blank"&gt;read that post&lt;/a&gt;, but then come here for some of
the updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, rather than guess at the answers, I went right to the guy
responsible for most (all?) of the design of the binding structure
in WPF: Sam Bent. I also went back to the spec document, and also
dove deeper into what's actually happening.&lt;/p&gt;

&lt;h3&gt;Locking&lt;/h3&gt;

&lt;p&gt;Q: If I'm using collection synchronization, do I need to lock my
own access to the collection?&lt;/p&gt;

&lt;p&gt;A: Yes, you do. The collection won't do any locking by itself (I
had thought that ObservableCollection was doing some, but both
Jonathan and Sam corrected me here. Sam also pointed out this works
with just about any collection).&amp;nbsp; Having the collection handle
any locking internally is "full of pitfalls" (Sam's words, which I
agree with having seen the examples) and was abandoned early in
.NET's development cycle.&lt;/p&gt;

&lt;p&gt;What this does mean, is that my example from the previous post
really needed to lock the collection add call. Here's the updated
viewmodel source.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
class MainViewModel&lt;br /&gt;
{&lt;br /&gt;
    public ObservableCollection&amp;lt;Stock&amp;gt; Stocks { get; private set; }&lt;br /&gt;
&lt;br /&gt;
    private object _stocksLock = new object();&lt;br /&gt;
&lt;br /&gt;
    public MainViewModel()&lt;br /&gt;
    {&lt;br /&gt;
        Stocks = new ObservableCollection&amp;lt;Stock&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
        BindingOperations.EnableCollectionSynchronization(Stocks, _stocksLock);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    private Random _random = new Random();&lt;br /&gt;
    public void AddNewItems()&lt;br /&gt;
    {&lt;br /&gt;
        lock (_stocksLock)&lt;br /&gt;
        {&lt;br /&gt;
            for (int i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
            {&lt;br /&gt;
                var item = new Stock();&lt;br /&gt;
                for (int j = 0; j &amp;lt; _random.Next(2, 4); j++)&lt;br /&gt;
                {&lt;br /&gt;
                    item.Symbol += char.ConvertFromUtf32(_random.Next(&lt;br /&gt;
                        char.ConvertToUtf32("A", 0),&lt;br /&gt;
                        char.ConvertToUtf32("Z", 0)));&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                item.Value = (decimal)(_random.Next(100, 6000) / 100.0);&lt;br /&gt;
                Stocks.Add(item);&lt;br /&gt;
                Debug.WriteLine(item.Symbol);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    public void StartAddingItems()&lt;br /&gt;
    {&lt;br /&gt;
        Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
            while (true)&lt;br /&gt;
            {&lt;br /&gt;
                AddNewItems();&lt;br /&gt;
                Thread.Sleep(500);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Notice how I lock the entire loop in AddNewItems. Depending on
what's going on inside that loop, or how many iterations, that may
simply be too large/long a lock. If you need a smaller/shorter
lock, it would be safe to wrap the Add call instead, like this:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private Random _random = new Random();&lt;br /&gt;
public void AddNewItems()&lt;br /&gt;
{&lt;br /&gt;
    for (int i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
    {&lt;br /&gt;
        var item = new Stock();&lt;br /&gt;
        for (int j = 0; j &amp;lt; _random.Next(2, 4); j++)&lt;br /&gt;
        {&lt;br /&gt;
            item.Symbol += char.ConvertFromUtf32(_random.Next(&lt;br /&gt;
                char.ConvertToUtf32("A", 0),&lt;br /&gt;
                char.ConvertToUtf32("Z", 0)));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        item.Value = (decimal)(_random.Next(100, 6000) / 100.0);&lt;br /&gt;
        lock (_stocksLock)&lt;br /&gt;
        {&lt;br /&gt;
            Stocks.Add(item);&lt;br /&gt;
        }&lt;br /&gt;
        Debug.WriteLine(item.Symbol);&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;I'll leave the choice of which one is appropriate up to
the folks designing individual applications&lt;/strong&gt;. It sounds
like a punt, but it really is up to you guys. Each has merits
(fewer lock acquisitions in first one, more atomic actions and less
thread blocking in second one), but really are very application
dependent. In my particular demo example here, with 100 iterations,
I'm fine with handling the lock outside the loop.&lt;/p&gt;

&lt;h3&gt;About the EnableCollectionSynchronization Overload&lt;/h3&gt;

&lt;p&gt;Here's one question that Sam answered. I'll quote him
directly.&lt;/p&gt;

&lt;p&gt;Q: Why are there two overloads to
EnableCollectionSynchronization?&lt;/p&gt;

&lt;p&gt;A: &lt;em&gt;You pick which overload of
EnableCollectionSynchronization to use based on how your app
synchronizes access to its own collection. If you're using fancy
synchronization primitives - semaphores, ReadWriteLock,
ManualResetEvent, etc. - you'd use the overload with a callback
argument. Whenever WPF needs to touch the collection, it calls the
callback, which uses the fancy primitive to gain the right
permissions. On the other hand, if you're just using&amp;nbsp; "lock(x)
{ … }", you'd use the overload with just a lock object, passing in
x. Whenever WPF needs to touch the collection, it also does
"lock(x) { … }". This saves one level of callback in the common
case.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Also note that you can use
&lt;strong&gt;BindingOperations.DisableCollectionSynchronization(collection)&lt;/strong&gt;
when you want to stop using synchronization.&lt;/p&gt;

&lt;h3&gt;Getting in Before the CollectionView is Created&lt;/h3&gt;

&lt;p&gt;The BindingOperations class provides an event
CollectionRegistering, which lets you register the collection for
cross-thread access before any CollectionView instances are
generated for it. Inside this event handler, you can do the actual
registering of the collection. Here's an example:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
public ObservableCollection&amp;lt;Stock&amp;gt; Stocks { get; private set; }&lt;br /&gt;
&lt;br /&gt;
private object _stocksLock = new object();&lt;br /&gt;
&lt;br /&gt;
public MainViewModel()&lt;br /&gt;
{&lt;br /&gt;
    Stocks = new ObservableCollection&amp;lt;Stock&amp;gt;();&lt;br /&gt;
    BindingOperations.CollectionRegistering += BindingOperations_CollectionRegistering;&lt;br /&gt;
&lt;br /&gt;
    //BindingOperations.EnableCollectionSynchronization(Stocks, _stocksLock);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void BindingOperations_CollectionRegistering(object sender, CollectionRegisteringEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Debug.WriteLine("CollectionRegistering Event");&lt;br /&gt;
    if (e.Collection == Stocks)&lt;br /&gt;
    {&lt;br /&gt;
        BindingOperations.EnableCollectionSynchronization(Stocks, _stocksLock);&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This is actually a good place to handle the registration, as you
know you'll get to register for cross-thread access at the right
time, before any dependent objects are created. In fact, I'd say
this is the &lt;strong&gt;best place to do the
EnableCollectionSynchronization call&lt;/strong&gt;. You can do it in the
constructor for simple apps, but once you start adding views (and
sorting, and datagrids and the like), you'll want to do it
here.&lt;/p&gt;

&lt;h3&gt;What's Happening with Change Notifications&lt;/h3&gt;

&lt;p&gt;Inside the framework, pending change notifications from the
background thread are queued up and then acted on by the UI thread
when it has time. This helps increase responsiveness for
higher-priority events like input (mouse, keyboard, touch).&lt;/p&gt;

&lt;p&gt;This is new for .NET 4.5 as part of this cross-thread collection
work.&lt;/p&gt;

&lt;h3&gt;Fin&lt;/h3&gt;

&lt;p&gt;I hope you've found that this post helps clarify some of the
open questions from the previous post. The work the WPF team has
done to enable cross-thread collections is a fair bit of work, even
though it surfaces through a pretty small API. This is also one of
those features which will simply make your own application code
nicer, with less plumbing gunk in it.&lt;/p&gt;

&lt;p&gt;Updated example code attached.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xpK0io5Brd9EB7uUB9hgei-WUrc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xpK0io5Brd9EB7uUB9hgei-WUrc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xpK0io5Brd9EB7uUB9hgei-WUrc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xpK0io5Brd9EB7uUB9hgei-WUrc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=c2zpPWogWkQ:xz9n4qu29zE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=c2zpPWogWkQ:xz9n4qu29zE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=c2zpPWogWkQ:xz9n4qu29zE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=c2zpPWogWkQ:xz9n4qu29zE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=c2zpPWogWkQ:xz9n4qu29zE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=c2zpPWogWkQ:xz9n4qu29zE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=c2zpPWogWkQ:xz9n4qu29zE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=c2zpPWogWkQ:xz9n4qu29zE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=c2zpPWogWkQ:xz9n4qu29zE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/c2zpPWogWkQ" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/20/wpf-45-cross-thread-collection-synchronization-redux</feedburner:origLink></item><item><title>WPF 4.5: Observable Collection Cross-Thread Change Notification</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/scWqRnw-t04/wpf-45-observable-collection-cross-thread-change-notification</link><pubDate>Mon, 16 Jan 2012 20:54:30 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/16/wpf-45-observable-collection-cross-thread-change-notification</guid><description>&lt;p&gt;WPF 4.5 is available as part of the &lt;a
href="http://msdn.microsoft.com/en-us/vstudio/hh127353"
target="_blank"&gt;Visual Studio 11 Developer Preview&lt;/a&gt; released at
the Build 2011 conference, and is part of the .NET Framework
version 4.5. WPF 4.5 addresses several important customer requests
including the ability to have cross-thread change notification for
collections - the topic of this post.&lt;/p&gt;

&lt;blockquote&gt;&lt;strong&gt;Update 1/20/2012:&lt;/strong&gt; I have &lt;a
href="http://10rem.net/blog/2012/01/20/wpf-45-cross-thread-collection-synchronization-redux"&gt;
posted a set of updates&lt;/a&gt; to this post with additional
information about the details, as well as a few code changes. Be
sure to read that post as well as this one.&lt;/blockquote&gt;

&lt;h3&gt;The Problem&lt;/h3&gt;

&lt;p&gt;As I explained in my post on &lt;a
href="http://10rem.net/blog/2012/01/10/threading-considerations-for-binding-and-change-notification-in-silverlight-5"
 target="_blank"&gt;cross-thread change notification&lt;/a&gt;, Silverlight
and WPF have the concept of the UI thread and background (or
secondary) threads. Code on a background thread is not allowed to
interact with UI elements (controls, etc.) on the foreground
thread. You can find more information about the general problem in
that post.&lt;/p&gt;

&lt;p&gt;What happens when you need to add and remove items from a
collection from that background thread? That's pretty common in
applications which must keep a list updated (stock trading is an
obvious example). When the collection raises the change
notification events, the binding system and listeners, on the UI
thread, have code executed. Remember, an event is just a delegate,
or really, just a function pointer. So, essentially, the collection
is calling a function on the UI thread. That's not allowed, and it
throws an exception.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/82267/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_2.png"/&gt;&lt;/p&gt;

&lt;p&gt;The approach pre-4.5 was to dispatch all calls to add items to
the collection. The diagram from the Silverlight post applies
here.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82660/Windows-Live-Writer_WPF.5-Observable-Collection-Cross-Thread_CD9A_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82665/Windows-Live-Writer_WPF.5-Observable-Collection-Cross-Thread_CD9A_image_thumb.png" width="650" height="265" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If code on the background thread needs to access elements on the
UI thread, set a property for example, it needs to dispatch the
call to the UI thread using the dispatcher or synchronization
context. Get enough of this happening, such as when constantly
updating a collection, and you can run into some real performance
problems.&lt;/p&gt;

&lt;h3&gt;The 4.5 Solution&lt;/h3&gt;

&lt;p&gt;We actually have a good solution for this in WPF 4.5. The
BindingOperations class includes the
EnableCollectionSynchronization function. This function helps the
binding system and the collection intelligently handle change
notification.&lt;/p&gt;

&lt;p&gt;Let's look at an example. The application, when run, will look
like this:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82670/Windows-Live-Writer_WPF.5-Observable-Collection-Cross-Thread_CD9A_image_4.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82675/Windows-Live-Writer_WPF.5-Observable-Collection-Cross-Thread_CD9A_image_thumb_1.png" width="500" height="318" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The stocks in the ListBox are loaded by clicking the "Load"
button. To test the change notification, click the Keep Loading
button. For this example, the Keep Updating button doesn't do
anything (more on that when I cover in-place sorting and updating
in another post)&lt;/p&gt;

&lt;h4&gt;XAML&lt;/h4&gt;

&lt;p&gt;Just for grins, and to show its inclusion in 4.5, I've put the
functionality into another new addition to WPF proper: the Ribbon.
I didn't use commands although they are supported.&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;
&amp;lt;RibbonWindow x:Class="WpfApplication2.MainWindow"&lt;br /&gt;
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;
        xmlns:local="clr-namespace:WpfApplication2"&lt;br /&gt;
        Title="MainWindow" Height="350" Width="525"&amp;gt;&lt;br /&gt;
    &amp;lt;Grid&amp;gt;&lt;br /&gt;
        &amp;lt;Ribbon&amp;gt;&lt;br /&gt;
            &amp;lt;RibbonTab Header="First Tab"&amp;gt;&lt;br /&gt;
                &amp;lt;RibbonGroup Header="Group 1"&amp;gt;&lt;br /&gt;
                    &amp;lt;RibbonButton x:Name="Foo" Label="Foo!" /&amp;gt;&lt;br /&gt;
                    &amp;lt;RibbonButton x:Name="Bar"&lt;br /&gt;
                                  Label="Bar!" /&amp;gt;&lt;br /&gt;
                &amp;lt;/RibbonGroup&amp;gt;&lt;br /&gt;
                &amp;lt;RibbonGroup Header="Group 2"&amp;gt;&lt;br /&gt;
                    &amp;lt;RibbonButton x:Name="Load"&lt;br /&gt;
                                  Click="Load_Click"&lt;br /&gt;
                                  Label="Load" /&amp;gt;&lt;br /&gt;
                    &amp;lt;RibbonButton x:Name="KeepLoading"&lt;br /&gt;
                                  Click="KeepLoading_Click"&lt;br /&gt;
                                  Label="Keep loading" /&amp;gt;&lt;br /&gt;
                    &amp;lt;RibbonButton x:Name="KeepUpdating"&lt;br /&gt;
                                  Label="Keep Updating" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;/RibbonGroup&amp;gt;&lt;br /&gt;
                &amp;lt;RibbonGroup Header="Count"&amp;gt;&lt;br /&gt;
                    &amp;lt;TextBlock Text="{Binding Stocks.Count}" /&amp;gt;&lt;br /&gt;
                &amp;lt;/RibbonGroup&amp;gt;&lt;br /&gt;
            &amp;lt;/RibbonTab&amp;gt;&lt;br /&gt;
            &amp;lt;RibbonTab Header="Second Tab"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;/RibbonTab&amp;gt;&lt;br /&gt;
            &amp;lt;RibbonTab Header="Stuff that doesn't go anywhere else"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;/RibbonTab&amp;gt;&lt;br /&gt;
        &amp;lt;/Ribbon&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &amp;lt;Grid Margin="0,156,0,0"&amp;gt;&lt;br /&gt;
            &amp;lt;TextBlock VerticalAlignment="Top"&lt;br /&gt;
                       FontSize="20"&lt;br /&gt;
                       Text="WPF Rules" /&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;Grid&amp;gt;&lt;br /&gt;
                &amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
                    &amp;lt;ColumnDefinition Width="*" /&amp;gt;&lt;br /&gt;
                    &amp;lt;ColumnDefinition Width="*" /&amp;gt;&lt;br /&gt;
                &amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;ListBox ItemsSource="{Binding Stocks}"&lt;br /&gt;
                         VirtualizingPanel.IsVirtualizing="True"&lt;br /&gt;
                         VirtualizingPanel.CacheLengthUnit="Page"&lt;br /&gt;
                         VirtualizingPanel.CacheLength="2,2"&lt;br /&gt;
                         VirtualizingPanel.ScrollUnit="Item"&amp;gt;&lt;br /&gt;
                    &amp;lt;ListBox.ItemTemplate&amp;gt;&lt;br /&gt;
                        &amp;lt;DataTemplate&amp;gt;&lt;br /&gt;
                            &amp;lt;Grid&amp;gt;&lt;br /&gt;
                                &amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
                                    &amp;lt;ColumnDefinition Width="100" /&amp;gt;&lt;br /&gt;
                                    &amp;lt;ColumnDefinition Width="100" /&amp;gt;&lt;br /&gt;
                                &amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                                &amp;lt;TextBlock Text="{Binding Symbol}"&lt;br /&gt;
                                           Grid.Column="0" /&amp;gt;&lt;br /&gt;
                                &amp;lt;TextBlock Text="{Binding Value}"&lt;br /&gt;
                                           Grid.Column="1" /&amp;gt;&lt;br /&gt;
                            &amp;lt;/Grid&amp;gt;&lt;br /&gt;
                        &amp;lt;/DataTemplate&amp;gt;&lt;br /&gt;
                    &amp;lt;/ListBox.ItemTemplate&amp;gt;&lt;br /&gt;
                &amp;lt;/ListBox&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;/Grid&amp;gt;&lt;br /&gt;
        &amp;lt;/Grid&amp;gt;&lt;br /&gt;
    &amp;lt;/Grid&amp;gt;&lt;br /&gt;
&amp;lt;/RibbonWindow&amp;gt;&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;For this example, the primary pieces to pay attention to are the
ListBox which is bound to the stocks, and the ribbon buttons to
Load and Update the stocks collection. Those use the Stock model
item via the ViewModel.&lt;/p&gt;

&lt;h4&gt;The Model&lt;/h4&gt;

&lt;p&gt;The model consists of a single class, called Stock.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System.ComponentModel;&lt;br /&gt;
&lt;br /&gt;
namespace WpfApplication2.Model&lt;br /&gt;
{&lt;br /&gt;
    class Stock : INotifyPropertyChanged&lt;br /&gt;
    {&lt;br /&gt;
        public event PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;
&lt;br /&gt;
        private string _symbol;&lt;br /&gt;
&lt;br /&gt;
        public string Symbol&lt;br /&gt;
        {&lt;br /&gt;
            get { return _symbol; }&lt;br /&gt;
            set { _symbol = value; NotifyPropertyChanged("Symbol"); }&lt;br /&gt;
        }&lt;br /&gt;
        private decimal _value;&lt;br /&gt;
&lt;br /&gt;
        public decimal Value&lt;br /&gt;
        {&lt;br /&gt;
            get { return _value; }&lt;br /&gt;
            set { _value = value; NotifyPropertyChanged("Value"); }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        protected void NotifyPropertyChanged(string propertyName)&lt;br /&gt;
        {&lt;br /&gt;
            if (PropertyChanged != null)&lt;br /&gt;
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;h4&gt;The ViewModel&lt;/h4&gt;

&lt;p&gt;The ViewModel is where the action is. First the listing, and
then the explanation.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System.Threading;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
using System.Windows.Data;&lt;br /&gt;
using WpfApplication2.Model;&lt;br /&gt;
&lt;br /&gt;
namespace WpfApplication2.ViewModel&lt;br /&gt;
{&lt;br /&gt;
    class MainViewModel&lt;br /&gt;
    {&lt;br /&gt;
        public ObservableCollection&amp;lt;Stock&amp;gt; Stocks { get; set; }&lt;br /&gt;
&lt;br /&gt;
        private object _stocksLock = new object();&lt;br /&gt;
&lt;br /&gt;
        public MainViewModel()&lt;br /&gt;
        {&lt;br /&gt;
            Stocks = new ObservableCollection&amp;lt;Stock&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
            BindingOperations.EnableCollectionSynchronization(Stocks, _stocksLock);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private Random _random = new Random();&lt;br /&gt;
        public void AddNewItems()&lt;br /&gt;
        {&lt;br /&gt;
            for (int i = 0; i &amp;lt; 100; i++)&lt;br /&gt;
            {&lt;br /&gt;
                var item = new Stock();&lt;br /&gt;
                for (int j = 0; j &amp;lt; _random.Next(2, 4); j++)&lt;br /&gt;
                {&lt;br /&gt;
                    item.Symbol += char.ConvertFromUtf32(_random.Next(&lt;br /&gt;
                        char.ConvertToUtf32("A", 0),&lt;br /&gt;
                        char.ConvertToUtf32("Z", 0)));&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                item.Value = (decimal)(_random.Next(100, 6000) / 100.0);&lt;br /&gt;
                Stocks.Add(item);&lt;br /&gt;
                Debug.WriteLine(item.Symbol);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        public void StartAddingItems()&lt;br /&gt;
        {&lt;br /&gt;
            Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;
            {&lt;br /&gt;
                while (true)&lt;br /&gt;
                {&lt;br /&gt;
                    AddNewItems();&lt;br /&gt;
                    Thread.Sleep(500);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;When the MainViewModel is instantiated, the collection is
created. Next, I call the EnableCollectionSynchronization method,
providing it the collection and an object to use as a lock. The
lock object is nothing special, just an instance of the CLR object
type. This single method makes cross-thread collection change
notification possible.&lt;/p&gt;

&lt;p&gt;The StartAddingItems method spins up another thread, using the
Task parallel library, which then loads items into the collection.
The data is randomly generated, but includes a large number of
updates. When you run the application, you'll see that the ListBox
is able to be quickly updated and that there are no cross-thread
exceptions reported.&lt;/p&gt;

&lt;p&gt;If you want to cause the exceptions to happen as normal, comment
out the BindingOperations.EnableCollectionSynchronization call.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;WPF 4.5 includes a number of key targeted performance and
capability features, one of which is cross-thread collection change
notification. Enabling the change notification is as simple as the
inclusion of a lock object and a single function call. Versus the
manual dispatching approach, this can be a real performance win,
not to mention save you some coding time.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xxv0VpPdzRXDjKbdNUBQ_aF8JrU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xxv0VpPdzRXDjKbdNUBQ_aF8JrU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xxv0VpPdzRXDjKbdNUBQ_aF8JrU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xxv0VpPdzRXDjKbdNUBQ_aF8JrU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=scWqRnw-t04:K_OPDAcZ6m8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=scWqRnw-t04:K_OPDAcZ6m8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=scWqRnw-t04:K_OPDAcZ6m8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=scWqRnw-t04:K_OPDAcZ6m8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=scWqRnw-t04:K_OPDAcZ6m8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=scWqRnw-t04:K_OPDAcZ6m8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=scWqRnw-t04:K_OPDAcZ6m8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=scWqRnw-t04:K_OPDAcZ6m8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=scWqRnw-t04:K_OPDAcZ6m8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/scWqRnw-t04" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/16/wpf-45-observable-collection-cross-thread-change-notification</feedburner:origLink></item><item><title>GNU C++ BlinkenLED Part 1 on the AVR (ATmega1284P with MikroElektronika EasyAVR6) and Atmel AVR Studio 5.1</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/UTsWJ5EZz2o/gnu-cplusplus-blinkenled-part-1-on-the-avr-atmega1284p-with-mikroelektronika-easyavr6-and-atmel-avr-studio-51</link><pubDate>Sun, 15 Jan 2012 23:49:40 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/15/gnu-cplusplus-blinkenled-part-1-on-the-avr-atmega1284p-with-mikroelektronika-easyavr6-and-atmel-avr-studio-51</guid><description>&lt;p&gt;In this Part 1 post, I'll show how to interface with ATmega
ports and pins to light up LEDs on a board. The follow-up post will
show how to use the timer to actually blink the LED.&lt;/p&gt;

&lt;p&gt;Most of the Microcontroller code out in the public is C or
Assembly. I have nothing personal against assembly or C (and may
end up using a little assembly in the future), but I decided I
wanted to write C++, as I like its encapsulation and structure when
compared to straight C.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I've written some other posts about getting started with these
boards and environments. Be sure to check them out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://10rem.net/blog/2011/11/05/getting-started-with-avr-studio-5"&gt;Getting
Started with AVR Studio 5&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://10rem.net/blog/2012/01/13/setting-up-for-developing-and-debugging-the-avr-atmega1284p-with-avrstudio-51"&gt;
Setting up for Developing and Debugging the AVR (ATmega1284P) with
AVRStudio 5.1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I don't have a lot of experience
with the AVR. I'm writing as I'm learning. If you find a mistake
below, please point it out in the comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C++ Disclaimer:&lt;/strong&gt; If code size and execution
speed are your primary concerns, you can certain do a bit better in
C or even more so in assembly. C++ does add some overhead,
especially if you go nuts on the class hierarchies. I've tried to
strike a balance between size, speed, and encapsulation in my own
libraries here, and also to show the differences. If you intend to
write for some of the ATtiny chips with their miniscule 2k or 4k
(sometimes a bit more) program memory, write some macro-oriented C
or better yet, break out that assembler. For the larger chips with
a little more headroom, C++ is a fun way to go, and is my
preference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform Disclaimer:&lt;/strong&gt; Most of my readers will be
far more productive on the .NET Micro Framework and the &lt;a
href="http://netduino.com/" target="_blank"&gt;Netduino&lt;/a&gt;, &lt;a
href="http://www.ghielectronics.com/catalog/category/7/"
target="_blank"&gt;FEZ Devices&lt;/a&gt;, or &lt;a
href="http://www.netmf.com/gadgeteer/"
target="_blank"&gt;Gadgeteer&lt;/a&gt;. If you're not doing heavy
speed-critical signal processing, you'll probably have more
&lt;strong&gt;fun with NETMF and get from zero to application much more
quickly&lt;/strong&gt;. For people not using C# but who wish to continue
with C/C++ on the AVR specifically, Arduino has most of these types
of things figured out in its rich library. It's not really C++, but
it's a good approach to developing on a subset of the AVR MCUs. If
you're interested more in just getting something done specifically
on the AVR, I recommend looking at that. Finally, if you want to
write C on the metal, Atmel also makes their own AVR library which
helps abstract away the differences between MCUs. I personally
found that confusing to use, with many different ways to accomplish
the same tasks, and a large number of poorly documented APIs to
learn. They were C as well, and without great naming conventions on
their part, it was next to impossible to get a ful picture of
everything available in a particular problem domain. In my case, I
specifically want to learn MCU programming without all that
baggage, so I'm simply coding on the metal but using C++.&lt;/p&gt;

&lt;h3&gt;Ports and pins&lt;/h3&gt;

&lt;p&gt;This family of MCUs have 8*4 (32) General Purpose Input/Output
(GPIO) pins. They can all be used for GPIO, but some ports can also
be assigned different functions. Here's are the pin configurations
for the PDIP and the TQFP/QFN/MLF surface mount versions from the
data sheet. (There are other pages covering the tiny VFBGA and
DRQFN versions, in case you wanted super tiny surface mount
versions)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82484/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_9.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82489/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_3.png" width="660" height="302" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm using the PDIP version on the left. On that, you can see,
for example, that pins 14 through 21 (port D) have the transmit
(TXD) and receive (RXD) functions for the USARTs. When you use
those pins for the USART, you can't use them for GPIO, so you need
to be smart about which pins you use for which functions. (I've
been doing a lot with port D and MIDI - more on that in a future
post.) You can also see that the entire family of chips ATmega164A,
ATmega164PA, ATmega324A, ATmega644A, ATmega644PA, ATmega1284, and
ATmega1284P all share the same pin configuration and device layout.
(and yeah, I'll admit that listing them all here was for search
engines &amp;lt;g&amp;gt;). Where they differ is in memory. Here's the
table from the same data sheet.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82494/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_10.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82499/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_4.png" width="660" height="282" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, I'll concentrate on using Port A. As I previously
mentioned, the MCU I'm using is the ATmega1284P, so I have a
whopping (in MCU terms) available program size of 128K. That's as
much total memory as the Commodore 128 computer sitting behind me
on my desk, and that doesn't even count the 16K available RAM and
4k available EEPROM. In a nutshell, here's how that memory is
used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flash&lt;/strong&gt;: This is the memory used to store your
program code. When you "program" the MCU, this memory is directly
consumed by the instructions for your application.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;EEPROM&lt;/strong&gt;: This is where you can store persistent
settings, like configuration set by the user of your end
product.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;RAM&lt;/strong&gt;: Allocated variables, arrays etc. You can
blow through 16K very quickly if you try and do things like you
would on the desktop (like a lookup table of 16 bit values to make
SIN calculations faster), so you need to be smart about that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, back to pins and ports. The ATmega and ATxmega MCUs by
Atmel (and possibly the ATtiny and others - I haven't checked)
group their IO pins into ports. The ATmega1284 has four ports A, B,
C and D, each of which has 8 pins. By grouping this way, a single 8
bit register can contain the digital information for each in in the
port.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82504/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_18.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82509/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_8.png" width="650" height="116" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, if you know the base address of Port A's pins data register
is 0x20 (or 0x00, for reasons explained in the data sheet), you can
find out the value of pin 2 using code like this:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
#define PINA_ADDRESS 0x20&lt;br /&gt;
&lt;br /&gt;
isHigh = (*PINA_ADDRESS) &amp;amp; 0b00000100;
&lt;/pre&gt;

&lt;p&gt;You can set pin 2 to high using this code, assuming that all the
pins were low before (this actually *toggles* pin 2):&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
#define PINA_ADDRESS 0x20&lt;br /&gt;
(*PINA_ADDRESS) |= 0b00000100;
&lt;/pre&gt;

&lt;p&gt;After you set it, that bit of PINA will be 1 if the pin is high,
and 0 if it is low, regardless of what your code actually sets it
to when toggling.&lt;/p&gt;

&lt;p&gt;You can see how using preprocessor defines like that makes the
code easier to read, but still results in a really tiny program. By
default, the AVR libraries include even nicer preprocessor macros
to get to individual pins, but we're not using them here. Of
course, I did oversimplify a little, at least in the second
example. There are other things you must consider before just
setting pin values.&lt;/p&gt;

&lt;h4&gt;Direction and Data Registers&lt;/h4&gt;

&lt;p&gt;When you want to use pins on a port, you should configure its
pins as input or output. For Port A, this involves the DDRA (Port A
Data Direction Register). This is another 8 bit register which
defines the direction for each pin: 1 is output, 0 is input.&lt;/p&gt;

&lt;p&gt;Also, when reading and writing values, you don't always use the
same register.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82514/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_46.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82519/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_22.png" width="650" height="261" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You have to read the data sheet about 100 times to make sense of
these groups. When compared to the xmega, I found the uses a bit
opaque. So, here's my summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To mark a pin as input, write a 0 to the appropriate bit in the
DDRx register.&lt;/li&gt;

&lt;li&gt;To mark a pin as output, write a 1 to the appropriate bit in
the DDRx register&lt;/li&gt;

&lt;li&gt;To read the value of a pin, check the appropriate bit in the
PINx register&lt;/li&gt;

&lt;li&gt;To TOGGLE the value of a pin, write to the appropriate bit in
the PINx register 

&lt;ul&gt;
&lt;li&gt;This means you need to read the pin value before you toggle
it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond that, there are some other registers that affect the
entire port. This table is useful for figuring out what they
do.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82524/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_12.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82529/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_5.png" width="660" height="215" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Basic Implementation&lt;/h3&gt;

&lt;p&gt;Let's first look at an implementation that looks like C code in
a CPP file. We'll use that as the benchmark for the rest of the
application.&lt;/p&gt;

&lt;h4&gt;Creating the project&lt;/h4&gt;

&lt;p&gt;First, I assume you have Atmel AVR Studio 5.1 installed on your
machine. If not, please refer to the two previous posts linked at
the top of this post. I'm also going to be using a
JTAGICE-compatible programmer and debugger here, also covered in
that previous post.&lt;/p&gt;

&lt;p&gt;Create a new project in AVR Studio 5.1. If you're running only
5.0, you won't see the C++ options unless you have the C++ add-in.
Also notice how these show up under "C/C++" and not under the
board-specific folders. We won't be using the board templates
here.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82534/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_20.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82539/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_9.png" width="650" height="402" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I named the project AvrBlinkenLed.&lt;/p&gt;

&lt;p&gt;The next step is to pick the processor. Make sure you pick the
one you're using. I'm using the ATmega1284P. The easiest way to
find your processor is to enter its model number in the search box
at the upper right.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82544/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_22.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82549/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_10.png" width="650" height="464" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you select the processor, Visual Studio will load up the
project template and put you right in the main .cpp file. You'll
want to adjust a couple things before you do any real coding,
however.&lt;/p&gt;

&lt;h4&gt;Setting clock speed and Debugger&lt;/h4&gt;

&lt;p&gt;Next, we'll need to set the clock speed. You could leave it at
the default 1Mhz, as we're not doing anything special here.
However, why not bump it up to 8Mhz? To do that, we'll need to make
changes in a few places. First, we'll need to actually set the
value on the chip. In this case, we only need to clear the
multiplier fuse which forces the ship at 1MHz by default.&lt;/p&gt;

&lt;p&gt;Go into Tools | AVR Programming. After a moment, the AVR
Programming tool will come up. It'll look for your JTAG programmer
and, if found, will display it in the tool list at the left and the
found MCU in the Device drop down to its right. If it was not
found, your JTAG programmer/ debugger is not set up correctly, or
your board isn't connected. Refer to the manufacturer instructions
to fix that before going any further.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82554/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_24.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82559/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_11.png" width="650" height="354" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you only have the one JTAG programmer/debugger installed, and
aren't doing any chaining of devices (if you're reading this post,
you almost certainly are not) simply click the "Apply" button to
pull back the MCU information. Click on the "Fuses" tab.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82564/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_26.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82569/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_12.png" width="650" height="398" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: Setting some fuses or lock bits can
&lt;strong&gt;brick your MCU and require special high-power parallel
programming to reset it&lt;/strong&gt;. Be sure you completely understand
the purpose of a given fuse or lock before you do anything with
it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had already cleared the CKDIV8 fuse in my MCU. If you just got
yours, it will be set. What this does is divide the 8MHz clock down
so you get a CPU clock of 1MHz. Clear that fuse, and only that
fuse, and then click the "Program" button on the right. Make sure
if works.&lt;/p&gt;

&lt;p&gt;While there, make sure the JTAGEN fuse is set so you can use the
JTAG debugger. If not set, set it and program that one fuse
setting.&lt;/p&gt;

&lt;p&gt;Next, go into the project properties (right-click the
AvrBlinkenLed project and select "Properties") and click the "Tool"
tab. This is where you set up the programmer/debugger to use.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82574/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_28.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82579/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_13.png" width="650" height="385" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pick the JTAG programmer from the list. Once you do that, change
the interface on the right to JTAG so you can debug. By default, it
is ISP (In System Programmer) which only allows programming. Then
change the JTAG clock so it's some value lower than 8Mhz / 4.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82584/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_30.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82589/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_14.png" width="568" height="178" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we'll define a compiler constant in the main file. The
F_CPU constant is a standard approach you'll see often. In fact, if
you use some of the AVR libraries, they require that specific
constant to be set.&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * AvrBlinkenLed.cpp&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 4:21:24 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
#define F_CPU 8000000&lt;br /&gt;
//#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        //TODO:: Please write your application code&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

That's the default template with the addition of the F_CPU
constant. &lt;strong&gt;Also note that I commented out the io.h include.
We're going to do things from scratch here.&lt;/strong&gt; The code
doesn't do anything yet, though, although it does compile. 

&lt;h4&gt;A few more helpful constants and macros&lt;/h4&gt;

&lt;p&gt;One reason straight C code tends to be so efficient, is that
there are almost no constants, enums, or variables in use for
chip-specific stuff. Instead, most everything is done in the
preprocessor, which ends up resolving down to pointer
manipulation.&lt;/p&gt;

&lt;p&gt;We're not taking that approach here, but we'll still use some
constants to help us out.&lt;/p&gt;

&lt;p&gt;Add a new include file to the project, named ATmega1284P.h&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82594/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_34.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82599/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_16.png" width="650" height="315" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file will contain the processor-specific constants and types
we want to use. In this case, the addresses for the registers.&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * ATmega1284P.h&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 4:41:26 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifndef ATMEGA1284P_H_&lt;br /&gt;
#define ATMEGA1284P_H_&lt;br /&gt;
&lt;br /&gt;
typedef volatile unsigned char register8_t;&lt;br /&gt;
&lt;br /&gt;
#define PINA    (*(register8_t*) 0x20)&lt;br /&gt;
#define DDRA    (*(register8_t*) 0x21)&lt;br /&gt;
#define PORTA   (*(register8_t*) 0x22)&lt;br /&gt;
&lt;br /&gt;
#endif /* ATMEGA1284P_H_ */
&lt;/pre&gt;

&lt;p&gt;Once you do that, we have enough to be able to turn the LEDs on
or off. We're going to light the LEDs in a pattern as shown in this
photo. You can see from the little diagram on the board (under the
RoHS symbol) that the LEDs are configured in current source
configuration, so setting them to 1 will light them up.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82604/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_36.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82609/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_17.png" width="660" height="340" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the code for the main file. Doing this will set the above
pattern for the LEDS.&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * AvrBlinkenLed.cpp&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 4:21:24 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
#define F_CPU 8000000&lt;br /&gt;
&lt;br /&gt;
#include "ATmega1284P.h"&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRA = 0b11111111;&lt;br /&gt;
    PINA = 0b10101010;&lt;br /&gt;
 &lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        //TODO:: Please write your application code&lt;br /&gt;
     &lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;In this code, I set all 8 pins to output, and then set
alternated pins to 1 to set them to high (&lt;strong&gt;it actually
toggles the pin value, but because they were all low (0) to begin
with, this works&lt;/strong&gt;). In a current source configuration,
where the LEDs get their voltage from the MCU and the MCU is the
source of the current, setting the pin to high will cause the LED
to light. If they were in a current sink configuration, where the
MCU provides ground reference, setting them to low (0) would light
the LEDs. The LED class we create will support either
configuration.&lt;/p&gt;

&lt;h4&gt;Deploying and Running&lt;/h4&gt;

&lt;p&gt;To deploy the code, first compile. You'll see output which
states how small the code is (178 bytes total, wow!)&lt;/p&gt;

&lt;pre class="brush: plain;"&gt;
------ Build started: Project: AvrBlinkenLed, Configuration: Debug AVR ------&lt;br /&gt;
Build started.&lt;br /&gt;
Project "AvrBlinkenLed.cppproj" (default targets):&lt;br /&gt;
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').&lt;br /&gt;
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.1\Vs\Compiler.targets" from project "D:\Documents\Docs\Projects\AvrBlinkenLed\AvrBlinkenLed\AvrBlinkenLed.cppproj" (target "Build" depends on it):&lt;br /&gt;
    Task "RunCompilerTask"&lt;br /&gt;
        C:\Program Files (x86)\Atmel\AVR Studio 5.1\make\make.exe all&lt;br /&gt;
AvrBlinkenLed.cpp&lt;br /&gt;
        Invoking: AVR8/GNU C++ Compiler&lt;br /&gt;
        "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1\AVRToolchain\bin\avr-g++.exe" -funsigned-char -funsigned-bitfields -O1 -fpack-struct -fshort-enums -g2 -Wall -c  -mmcu=atmega1284p   -o"AvrBlinkenLed.o" ".././AvrBlinkenLed.cpp"&lt;br /&gt;
        Finished building: .././AvrBlinkenLed.cpp&lt;br /&gt;
        Building target: AvrBlinkenLed.elf&lt;br /&gt;
        Invoking: AVR8/GNU C++ Linker&lt;br /&gt;
        "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1\AVRToolchain\bin\avr-g++.exe" -o AvrBlinkenLed.elf  AvrBlinkenLed.o   -Wl,-Map="AvrBlinkenLed.map" -Wl,-lm   -mmcu=atmega1284p&lt;br /&gt;
        Finished building target: AvrBlinkenLed.elf&lt;br /&gt;
        "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature  "AvrBlinkenLed.elf" "AvrBlinkenLed.hex"&lt;br /&gt;
        "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "AvrBlinkenLed.elf" "AvrBlinkenLed.eep" || exit -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "AvrBlinkenLed.elf" "AvrBlinkenLed.eep" || exit 0&lt;br /&gt;
        "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1\AVRToolchain\bin\avr-objdump.exe" -h -S "AvrBlinkenLed.elf" &amp;gt; "AvrBlinkenLed.lss"&lt;br /&gt;
        "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1\AVRToolchain\bin\avr-size.exe" -C --mcu=atmega1284p  "AvrBlinkenLed.elf"&lt;br /&gt;
        AVR Memory Usage&lt;br /&gt;
        ----------------&lt;br /&gt;
        Device: atmega1284p&lt;br /&gt;
        Program:     178 bytes (0.1% Full)&lt;br /&gt;
        (.text + .data + .bootloader)&lt;br /&gt;
        Data:          0 bytes (0.0% Full)&lt;br /&gt;
        (.data + .bss + .noinit)&lt;br /&gt;
    Done executing task "RunCompilerTask".&lt;br /&gt;
Done building target "CoreBuild" in project "AvrBlinkenLed.cppproj".&lt;br /&gt;
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').&lt;br /&gt;
Target "Build" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.1\Vs\Avr.common.targets" from project "D:\Documents\Docs\Projects\AvrBlinkenLed\AvrBlinkenLed\AvrBlinkenLed.cppproj" (entry point):&lt;br /&gt;
Done building target "Build" in project "AvrBlinkenLed.cppproj".&lt;br /&gt;
Done building project "AvrBlinkenLed.cppproj".&lt;br /&gt;
&lt;br /&gt;
Build succeeded.&lt;br /&gt;
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;The next step is to take the hex file that was created and load
that to the board via the JTAG programmer. Go under Tools | AVR
Programming again, and select the "Memories" tab after hitting
"apply" to pull up the ATmega we're using.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82614/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_38.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82619/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_18.png" width="650" height="439" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the hex file from your project. You can see where it's
located on my file system. The programmer will remember this from
project to project, so always double-check to make sure you're
programming the right code. Once sure, click the "Program" button.
You'll see the following status:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82624/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_40.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82629/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_19.png" width="164" height="74" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should immediately see the output on your test board. If
not, close the AVR Programming tool and hit the Reset button on
your board.&lt;/p&gt;

&lt;p&gt;Now, all of that is wonderfully efficient, but not particularly
friendly or reusable. So, let's look at how to do this another
way.&lt;/p&gt;

&lt;h3&gt;First Implementation in real C++&lt;/h3&gt;

&lt;p&gt;The C code is simple and very tight. However, once you get into
a complex application, the code can get confusing and jumbled. The
nature of a language like C requires extreme discipline to keep the
code compartmentalized and reduce dependencies between the
different modules. Often times, the developer will trade away some
of that for the sake of performance or code size. The AVR libraries
that come with AVR Studio include a fair bit of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To be clear, you can write very good code in C as long
as you have discipline.&lt;/strong&gt; You can also write crap code in
C++, but the compiler and language give you a few more things to
help you do the right thing.&lt;/p&gt;

&lt;h4&gt;The IOPort class&lt;/h4&gt;

&lt;p&gt;In my first version of this code, I created an IOPin class
rather than IOPort. I did this because I wanted to make my library
smell a bit like the NETMF libraries where you code against
DigitalInput and DigitalOutput classes. However, that meant
creating an instance of the class for each pin you wanted to
manipulate - an entire class for 3 bits (literally, bits) worth of
data. It also didn't allow me to group operations at the port
level. So, in the version I'm presenting here, I went at it at the
port level with the IOPort class.&lt;/p&gt;

&lt;p&gt;First, create a header file named IOPort.h&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * IOPort.h&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 5:43:58 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifndef IOPORT_H_&lt;br /&gt;
#define IOPORT_H_&lt;br /&gt;
&lt;br /&gt;
#include "ATmega1284P.h"&lt;br /&gt;
&lt;br /&gt;
enum PinDirection&lt;br /&gt;
{&lt;br /&gt;
    DirectionInput = 0,&lt;br /&gt;
    DirectionOutput = 1&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class IOPort&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
    volatile register8_t* _port;&lt;br /&gt;
    volatile register8_t* _pins;&lt;br /&gt;
    volatile register8_t* _ddr;&lt;br /&gt;
public:&lt;br /&gt;
    IOPort(register8_t* portRegister, register8_t* pinsRegister, register8_t* ddrRegister) :&lt;br /&gt;
        _port(portRegister),&lt;br /&gt;
        _pins(pinsRegister),&lt;br /&gt;
        _ddr(ddrRegister) {}&lt;br /&gt;
         &lt;br /&gt;
    void SetPortDirection(register8_t directionBits); &lt;br /&gt;
    void SetPortValues(register8_t valueBits);&lt;br /&gt;
    void GetPortValues(register8_t &amp;amp;valueBits);&lt;br /&gt;
&lt;br /&gt;
    void SetPinDirection(int pin, PinDirection direction);&lt;br /&gt;
    void SetPinValue(int pin, bool value);&lt;br /&gt;
    void GetPinValue(int pin, bool &amp;amp;value);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#endif /* IOPORT_H_ */
&lt;/pre&gt;

&lt;p&gt;You can see the class has separate methods for working with
individual pins versus the entire port. In that way, we can do bulk
port operations and individual pin operations from the same class.
We can get away with that here, unlike in the .NET Micro Framework,
because we know that all the AVR pinsNow for the implementation.
Create a code file IOPort.cpp&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * IOPort.cpp&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 6:03:06 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#include "IOPort.h"&lt;br /&gt;
&lt;br /&gt;
void IOPort::SetPortDirection(register8_t directionBits)&lt;br /&gt;
{&lt;br /&gt;
    *_ddr = directionBits;&lt;br /&gt;
}&lt;br /&gt;
void IOPort::SetPortValues(register8_t valueBits)&lt;br /&gt;
{&lt;br /&gt;
    *_pins = valueBits;&lt;br /&gt;
}&lt;br /&gt;
void IOPort::GetPortValues(register8_t &amp;amp;valueBits)&lt;br /&gt;
{&lt;br /&gt;
    valueBits = *_pins;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void IOPort::SetPinDirection(int pin, PinDirection direction)&lt;br /&gt;
{&lt;br /&gt;
    // assumes pin is correctly in the range of 0..7&lt;br /&gt;
    if (direction == DirectionOutput)&lt;br /&gt;
        *_ddr |= (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
    else&lt;br /&gt;
        *_ddr ^= (1 &amp;lt;&amp;lt; pin);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void IOPort::SetPinValue(int pin, bool value)&lt;br /&gt;
{&lt;br /&gt;
    // assumes pin is correctly in the range of 0..7&lt;br /&gt;
 &lt;br /&gt;
    // if the pin was already high and we want it high, do nothing.&lt;br /&gt;
    // if the pin was already low and we want it low, do nothing.&lt;br /&gt;
    // if the pin was high, and we're requesting low, toggle it&lt;br /&gt;
    // if the pin was low, and we're requesting high, toggle it&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
    if (*_pins &amp;amp; (1 &amp;lt;&amp;lt; pin))&lt;br /&gt;
    {&lt;br /&gt;
        // pin is currently high&lt;br /&gt;
     &lt;br /&gt;
        if (!value)&lt;br /&gt;
            *_pins = (1 &amp;lt;&amp;lt; pin);    // toggle pin because we want it low&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // pin is currently low&lt;br /&gt;
     &lt;br /&gt;
        if (value)&lt;br /&gt;
            *_pins = (1 &amp;lt;&amp;lt; pin);    // toggle pin because we want it high&lt;br /&gt;
    } &lt;br /&gt;
     &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void IOPort::GetPinValue(int pin, bool &amp;amp;value)&lt;br /&gt;
{&lt;br /&gt;
    value = (bool)(* _pins &amp;amp; (1 &amp;lt;&amp;lt; pin));&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Note how writing a 1 to the pin doesn't set it high, it toggles
it. That means we need to read the current value of the pin, and
then decide whether it needs to be toggled or not.&lt;/p&gt;

&lt;p&gt;This IOPort class doesn't support everything. For example, I
haven't included here the code to set the pull-up resistors. I also
didn't add anything optional to the constructor to set initial
direction or values from that call. However, it works for our
purposes in this example.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Supporting multiple types of processors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the code I'm using for my own projects, I don't include the
processor-specific include file in every class. Instead, I include
a common include file which has a preprocessor constant for the
processor I'm using and then makes a decision as to which
processor-specific include file to pull in. I blatantly stole this
idea from the AVR libraries, as it's a good one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Lighting up some LEDs&lt;/h4&gt;

&lt;p&gt;Now to light up some LEDs. I very slightly changed the pattern
so you can be sure you're seeing the newly flash firmware, and not
the original version. Here's the new code for the main
function.&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * AvrBlinkenLed.cpp&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 4:21:24 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
#define F_CPU 8000000&lt;br /&gt;
&lt;br /&gt;
#include "ATmega1284P.h"&lt;br /&gt;
#include "IOPort.h"&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    //DDRA = 0b11111111;&lt;br /&gt;
    //PINA = 0b10101010;&lt;br /&gt;
 &lt;br /&gt;
    IOPort portA(&amp;amp;PORTA, &amp;amp;PINA, &amp;amp;DDRA);&lt;br /&gt;
 &lt;br /&gt;
    portA.SetPortDirection(0xFF);&lt;br /&gt;
    portA.SetPortValues(0b10101111);&lt;br /&gt;
 &lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        //TODO:: Please write your application code&lt;br /&gt;
     &lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Program it on the MCU and look at the LEDs. You should now see
pins 0-3 lit up, as well as pins 5 and 7. This works because the
pins were, by default, all low. &lt;strong&gt;Calling SetPortValues
toggles all the values for that port&lt;/strong&gt;. If you called it
again with the same pattern, they'd all turn off.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I prefer the ATxmega approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ATxmega (the follow-on to the ATmega) has a couple different
registers to accomplish the task of setting the pin value. One is
OUTSET where any set bits cause the pins to go high. The other is
OUTCLR where any set bits cause the pins to go low. In that way,
you don't have to do a read-compare-modify cycle. If that chip were
available in PDIP so creating DIY kits for other people who don't
want to surface mount solder, I'd be in heaven.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As to size: if I comment out the Pin-specific functionality, in
order to get a fair comparison with our original program, the
program compiles to 320 bytes. Compare that to the 178 bytes of the
macro-version. It's a bit under twice the size for this tiny
program. Whether that's a concern to you is, well, your concern :)
If you leave in the pin-specific functionality, you get around 510
bytes. On a processor with 128K, that's not a big deal, but if
you're looking at a processor with only 2K total memory, that can
certainly be an important distinction. At the different levels of
optimization, I get the following program sizes:&lt;/p&gt;

&lt;table border="1" cellspacing="0" cellpadding="2" width="298"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="208"&gt;Optimization level&lt;/td&gt;
&lt;td valign="top" width="88"&gt;Program Size in Bytes&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="208"&gt;None (-O0)&lt;/td&gt;
&lt;td valign="top" width="88"&gt;856&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="208"&gt;Optimize (-O1) default&lt;/td&gt;
&lt;td valign="top" width="88"&gt;512&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="208"&gt;Optimize more (-O2)&lt;/td&gt;
&lt;td valign="top" width="88"&gt;496&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="208"&gt;Optimize most (-O3)&lt;/td&gt;
&lt;td valign="top" width="88"&gt;496&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td valign="top" width="208"&gt;Optimize for size (-Os)&lt;/td&gt;
&lt;td valign="top" width="88"&gt;484&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The different optimization levels certainly make an impact on
size. Beware, though, as sometimes optimization can make the code
larger, or slower. It can also make it more difficult to debug or
trace. I tend to leave the optimization on the default -O1.&lt;/p&gt;

&lt;p&gt;In addition, you can definitely trim this down a bit by removing
some of the conversions, the enum, and doing a little more
optimization. You can even do a little inline assembly, but I'm not
a big fan of the AVR G++ approach to that, using strings. I used to
write a fair bit of inline assembly in Borland C++ for DOS, and to
do that, you simply had an asm block with statements in it like asm
{ mov AX, AY }.&lt;/p&gt;

&lt;p&gt;Without actually trying it, I suspect that the code to construct
the string would take up more space than the inline assembly would
give us back, so I'm going to leave it out of this example.&lt;/p&gt;

&lt;h3&gt;Abstracting Away LED Behavior&lt;/h3&gt;

&lt;p&gt;LEDs can be connected a two main ways: in current source or
current sink configuration. I would like to create an LED class
which properly works regardless of how you hook up the
LEDs.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Create a header file named Led.h&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * Led.h&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 7:12:19 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#ifndef LED_H_&lt;br /&gt;
#define LED_H_&lt;br /&gt;
&lt;br /&gt;
#include "ATmega1284P.h"&lt;br /&gt;
#include "IOPort.h"&lt;br /&gt;
&lt;br /&gt;
enum LedConfiguration&lt;br /&gt;
{&lt;br /&gt;
    LedCurrentSource,&lt;br /&gt;
    LedCurrentSink &lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Led&lt;br /&gt;
{&lt;br /&gt;
protected:&lt;br /&gt;
    IOPort*                _port;&lt;br /&gt;
    LedConfiguration    _configuration;&lt;br /&gt;
    uint8_t                _pin;&lt;br /&gt;
         &lt;br /&gt;
public:&lt;br /&gt;
    Led(IOPort* port, uint8_t pin, LedConfiguration configuration) :&lt;br /&gt;
        _port((IOPort *)port),&lt;br /&gt;
        _configuration(configuration),&lt;br /&gt;
        _pin(pin) {};&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
    void TurnOn();&lt;br /&gt;
    void TurnOff();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* LED_H_ */
&lt;/pre&gt;

&lt;p&gt;Next, create the implementation file Led.cpp. The code in this
file will set the pin values based on whether or not we're in
Source (1 to light) or Sink (0 to light) mode.&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * Led.cpp&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 7:18:36 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
#include "Led.h"&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void Led::TurnOn()&lt;br /&gt;
{&lt;br /&gt;
    _port-&amp;gt;SetPinValue(_pin, (_configuration == LedCurrentSource));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led::TurnOff()&lt;br /&gt;
{ &lt;br /&gt;
    _port-&amp;gt;SetPinValue(_pin, !(_configuration == LedCurrentSource));&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;To make that work, we're going to need another type, so let's
&lt;strong&gt;add the following to the processor-specific header file
ATmega1284P.h&lt;/strong&gt;. At the same time, we'll change the
definition of register8_t to use this type.&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
typedef unsigned char uint8_t;&lt;br /&gt;
typedef volatile uint8_t register8_t;
&lt;/pre&gt;

&lt;p&gt;I need uint8_t because I'm keeping the pin number in the class,
and don't want to allocate a whole 16 bit int to hold a number
between 0 and 7. Memory on these devices is even more scarce than
program memory so you want to use small types to keep the stack
small and the data (if you allocate any) small.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why no New Operator?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You'll notice that I'm not using the new operator anywhere,
instead I'm allocating everything as local variables. At some
point, I may change that, but at least for now, the price isn't
worth it. Adding in the new operator, and all the malloc stuff it
requires, adds a huge amount of code to your application. By
default, AVR G++ doesn't include it in so you can save that
4-10k.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The new main function looks like this:&lt;/p&gt;

&lt;pre class="brush: cpp;"&gt;
/*&lt;br /&gt;
 * AvrBlinkenLed.cpp&lt;br /&gt;
 *&lt;br /&gt;
 * Created: 1/15/2012 4:21:24 PM&lt;br /&gt;
 *  Author: Peter.Brown&lt;br /&gt;
 */&lt;br /&gt;
#define F_CPU 8000000&lt;br /&gt;
&lt;br /&gt;
#include "ATmega1284P.h"&lt;br /&gt;
#include "IOPort.h"&lt;br /&gt;
#include "Led.h"&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    IOPort portA(&amp;amp;PORTA, &amp;amp;PINA, &amp;amp;DDRA);&lt;br /&gt;
 &lt;br /&gt;
    portA.SetPortDirection(0xFF);&lt;br /&gt;
    //portA.SetPortValues(0b10101111);&lt;br /&gt;
 &lt;br /&gt;
    Led ledA0(&amp;amp;portA, (uint8_t)0, LedCurrentSource);&lt;br /&gt;
    Led ledA1(&amp;amp;portA, (uint8_t)1, LedCurrentSource);&lt;br /&gt;
    Led ledA2(&amp;amp;portA, (uint8_t)2, LedCurrentSource);&lt;br /&gt;
    Led ledA3(&amp;amp;portA, (uint8_t)3, LedCurrentSource);&lt;br /&gt;
    Led ledA4(&amp;amp;portA, (uint8_t)4, LedCurrentSource);&lt;br /&gt;
    Led ledA5(&amp;amp;portA, (uint8_t)5, LedCurrentSource);&lt;br /&gt;
    Led ledA6(&amp;amp;portA, (uint8_t)6, LedCurrentSource);&lt;br /&gt;
    Led ledA7(&amp;amp;portA, (uint8_t)7, LedCurrentSource);&lt;br /&gt;
 &lt;br /&gt;
    ledA0.TurnOn();&lt;br /&gt;
    ledA1.TurnOn();&lt;br /&gt;
    ledA2.TurnOn();&lt;br /&gt;
    ledA3.TurnOn();&lt;br /&gt;
    ledA4.TurnOn();&lt;br /&gt;
    ledA5.TurnOn();&lt;br /&gt;
    ledA6.TurnOn();&lt;br /&gt;
    ledA7.TurnOn();&lt;br /&gt;
&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        //TODO:: Please write your application code&lt;br /&gt;
     &lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Rather than inherit LED from the port, as I did in the pin-based
version in some other code I've written, I decided to have the LED
simply take in an instance of the port. The LED class assumes
you've already configured the LED pin as output, as that is an
operation that is often done an entire port at a time. Again,
another small concession to efficiency without sacrificing the main
benefits of C++.&lt;/p&gt;

&lt;p&gt;If you want to test that the led is properly toggling the
values, uncomment the SetPortValues call there to give the port
some initial values. Or, you can just make the LEDs toggle like we
will in the next post.&lt;/p&gt;

&lt;p&gt;At this point, if you run the application, you should see all
eight LEDs lit&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82634/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_42.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82639/Windows-Live-Writer_C-BlinkenLED-on-the-AVR-and-MikroElektro_B9E5_image_thumb_20.png" width="660" height="263" alt="image" border="0" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next post, we'll learn what it's going to take to blink
these LEDs with a specified time interval.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0eJzNZAu9T8l2z_61oaWPoxzHEo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0eJzNZAu9T8l2z_61oaWPoxzHEo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0eJzNZAu9T8l2z_61oaWPoxzHEo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0eJzNZAu9T8l2z_61oaWPoxzHEo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=UTsWJ5EZz2o:s6fohLwSUss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=UTsWJ5EZz2o:s6fohLwSUss:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=UTsWJ5EZz2o:s6fohLwSUss:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=UTsWJ5EZz2o:s6fohLwSUss:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=UTsWJ5EZz2o:s6fohLwSUss:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=UTsWJ5EZz2o:s6fohLwSUss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=UTsWJ5EZz2o:s6fohLwSUss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=UTsWJ5EZz2o:s6fohLwSUss:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=UTsWJ5EZz2o:s6fohLwSUss:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/UTsWJ5EZz2o" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/15/gnu-cplusplus-blinkenled-part-1-on-the-avr-atmega1284p-with-mikroelektronika-easyavr6-and-atmel-avr-studio-51</feedburner:origLink></item><item><title>Setting up for Developing and Debugging the AVR (ATmega1284P) with AVRStudio 5.1</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/HE-yRR4B7Ss/setting-up-for-developing-and-debugging-the-avr-atmega1284p-with-avrstudio-51</link><pubDate>Fri, 13 Jan 2012 23:31:25 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/13/setting-up-for-developing-and-debugging-the-avr-atmega1284p-with-avrstudio-51</guid><description>&lt;p&gt;In the wee hours of the night, I've been continuing to learn how
to develop for the various AVR family chips from Atmel. I also do a
lot with NETMF, Netduino, and the .NET Gadgeteer, but sometimes
(despite the pain!) it feels good to code right on the metal.&lt;/p&gt;

&lt;p&gt;Introductory/getting started information for the AVR family is
not always the easiest to find, so this post covers a few other
important details I think you'll find helpful.&lt;/p&gt;

&lt;h3&gt;Select the MCU&lt;/h3&gt;

&lt;p&gt;MCUs vary wildly in capabilities. Which MCU you choose for
tinkering isn't hugely important, but if you have any sort of
project in mind, you'll want to try and narrow it down to a family.
The programming model is not identical across different families,
and capabilities can vary in significant ways. Here are a few
things to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I need to limit myself to those offered in a &lt;a
href="http://en.wikipedia.org/wiki/PDIP"&gt;PDIP package&lt;/a&gt; in order
to make it easy for DIY use? Most people in the DIY community are
not able to solder the zillion pins on the smaller surface mount
packages. The more powerful the chip (and I define "powerful" very
loosely here) the harder it will be to find a PDIP package. In
those cases, you may need to rely on a &lt;a
href="http://www.mikroe.com/eng/products/view/83/bigavr-mcu-cards/"&gt;
vendor's own carrier boards&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;How many USARTS (sync/async serial communication) do I need?
Serial is important for microcontroller to device
communication&lt;/li&gt;

&lt;li&gt;How many I/O pins to I need?&lt;/li&gt;

&lt;li&gt;How speed-intensive is my code?&lt;/li&gt;

&lt;li&gt;How much program memory do I expect to require&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this project, I chose the ATmega1284P. I chose this
because&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is offered in a 40 PDIP, so it is DIY friendly&lt;/li&gt;

&lt;li&gt;It is inexpensive at &lt;a
href="http://www.mouser.com/Search/ProductDetail.aspx?R=ATMEGA1284P-PUvirtualkey55650000virtualkey556-ATMEGA1284P-PU"&gt;
under $6 per unit&lt;/a&gt; in very small quantities.&lt;/li&gt;

&lt;li&gt;It has the most memory of any AVR PDIP package MCU&lt;/li&gt;

&lt;li&gt;It has two USARTs for serial communication&lt;/li&gt;

&lt;li&gt;It supports SPI so I'll be able to use the SPI DACs I'm playing
with&lt;/li&gt;

&lt;li&gt;It supports JTAG programming and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that speed wasn't really a concern. You'll be amazed at how
much you can accomplish in native code on an MCU running at just a
couple MHz. Amazing!&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82343/Windows-Live-Writer_b3541542a059_B73E_image_21.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82348/Windows-Live-Writer_b3541542a059_B73E_image_thumb_9.png" width="660" height="261" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whatever microcontroller you choose, make sure you know what
clock speed it's running at. It's not as simple as buying a 20Mhz
MCU and saying it's running at 20Mhz. By default, some of the MCUs
run at 1MHz to make sure you can program them with anything. Beyond
that, you can change the speed using "fuses" (flags set on the chip
outside of your program memory), external clock sources, and code
in your application.&lt;/p&gt;

&lt;p&gt;For example, the development board I use (more on that in a
moment) has an 8MHz crystal oscillator on the board. I had
incorrectly assumed that the chip was running at 8MHz. However, I
stumbled across the following in the datasheet for the chip:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82353/Windows-Live-Writer_b3541542a059_B73E_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82358/Windows-Live-Writer_b3541542a059_B73E_image_thumb.png" width="660" height="110" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aha! So many things rely on you knowing the correct clock speed,
that if you get it wrong, you'll find half your code simply
fails.&lt;/p&gt;

&lt;h3&gt;Get the Data Sheets&lt;/h3&gt;

&lt;p&gt;In the case of Atmel, finding the data sheets is pretty easy.
What's confusing is that there will often be more than one version
floating around, and they're not always updated correctly. In
addition, newer chips like the XMega I played with previously, have
a fair number of errors in the data sheet.&lt;/p&gt;

&lt;p&gt;The way to find the sheet is to go to the Atmel site and browse
for your chip. First pick the architecture&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82363/Windows-Live-Writer_b3541542a059_B73E_image_4.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82368/Windows-Live-Writer_b3541542a059_B73E_image_thumb_1.png" width="492" height="448" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, and the bottom left, pick the family&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82373/Windows-Live-Writer_b3541542a059_B73E_image_6.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82378/Windows-Live-Writer_b3541542a059_B73E_image_thumb_2.png" width="490" height="448" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, I chose "megaAVR" as that's the family the MPU I
chose belongs to. It's next to my awesome MSPaint arrow there on
the left.&lt;/p&gt;

&lt;p&gt;Next, scroll down and pick the model that's written on your
chip.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82383/Windows-Live-Writer_b3541542a059_B73E_image_8.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82388/Windows-Live-Writer_b3541542a059_B73E_image_thumb_3.png" width="500" height="289" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can, of course, simply type your chip's name into
Bing/Google and see what comes up. Just ignore all those
third-party datasheet sites. They're the usual link bait crap you
find on the internet.&lt;/p&gt;

&lt;p&gt;You'll eventually make your way to the MCU's product page on the
Atmel site.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82393/Windows-Live-Writer_b3541542a059_B73E_image_10.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82398/Windows-Live-Writer_b3541542a059_B73E_image_thumb_4.png" width="500" height="627" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These product pages are really nice, especially when you're
doing the initial research to figure out which MCU to choose.&lt;/p&gt;

&lt;p&gt;Finally, clock on the "documents" tab at the top. The first two
documents for any given MCU will typically be a short summary,
useful when investigating capabilities, and then a a full data
sheet.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82403/Windows-Live-Writer_b3541542a059_B73E_image_12.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82408/Windows-Live-Writer_b3541542a059_B73E_image_thumb_5.png" width="500" height="434" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, here comes the fun part with Atmel. Make note of the
various MCUs listed in the data sheet. That means they all follow
the same design, but differ in something relatively trivial like
the amount of program or flash memory on board. Now, look up the
data sheets for a couple of those and see if they're any later than
this one. Atmel doesn't always do a good job of making sure the
data sheets make it out to all the right places on their site.
It'll only take a moment.&lt;/p&gt;

&lt;p&gt;With the MCU chosen, the next step is to buy or build something
to host it.&lt;/p&gt;

&lt;h3&gt;Optionally, Pick up a Development Board&lt;/h3&gt;

&lt;p&gt;When getting started, using a development board is almost always
the easiest approach. Atmel makes a number of nice development
boards for their MCUs. One great thing about them is that the
development environment has templates and examples build around
those.&lt;/p&gt;

&lt;p&gt;You can also find relatively inexpensive development boards on
ebay. My experience with those has been pretty spotty: if it works,
awesome. If it doesn't work, support is pretty non-existent and the
language barrier makes self-help on the sites almost
impossible.&lt;/p&gt;

&lt;p&gt;Despite the lack of direct support for them in AVR Studio, I'm
really partial to the Mikroelektronika boards. They are extremely
well made, and feature-rich without getting in your way. This &lt;a
href="http://www.mikroe.com/eng/products/view/321/easyavr6-development-system/"&gt;
EasyAVR6&lt;/a&gt; is one that I put on my Christmas list and found under
the tree on December 25 :) The board is not tiny, it's about the
size of a mini ATX motherboard. Also note that it does not come
with the two LCD screens, those must be purchased separately from
Mikroelektronika. They're inexpensive enough, though.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://www.mikroe.com/eng/products/view/321/easyavr6-development-system/"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82413/Windows-Live-Writer_b3541542a059_B73E_image_15.png" width="550" height="410" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Considerations when picking a board:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does it support the MCU(s) I plan to use?&lt;/li&gt;

&lt;li&gt;Is there native support for it in my dev environment? It's not
necessary, but it removes some barriers to getting started&lt;/li&gt;

&lt;li&gt;Does it break out all the pins in a way that is easy to use? In
the AVR6, the pins are all broken out in the headers on the
right&lt;/li&gt;

&lt;li&gt;Does it break out key features in ways I plan to use them
(RS-232 connector, display, buttons, LEDs)&lt;/li&gt;

&lt;li&gt;Does it include debug LEDs so I can easily see the status of
any pin? (not necessary, but VERY helpful)&lt;/li&gt;

&lt;li&gt;Is it built well, well-supported, and easy to use?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can go with less expensive boards, of course.
MikroElektronika makes a much smaller &lt;a
href="http://www.mikroe.com/eng/products/view/795/ready-for-avr-board/"
 target="_blank"&gt;Ready for AVR&lt;/a&gt; board which supports the 40 pin
AVR chips like this one. It doesn't have any debug LEDs or buttons,
but it has all the required oscillator circuitry and pin headers.
It also supports USB deployment, but does not include a JTAG header
for debugging. This is not a show-stopper, but I personally
consider it critical for non-trivial work.&lt;/p&gt;

&lt;p&gt;Here's an example of the debug LEDs in use on my board&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82418/Windows-Live-Writer_b3541542a059_B73E_image_23.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82423/Windows-Live-Writer_b3541542a059_B73E_image_thumb_10.png" width="660" height="290" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each LED on the left corresponds to one pin. They're labeled so
I can easily see that Port A, Pin 0 and Pin 4, and Port D pins 2
and 3 are all high. This is incredibly helpful when writing your
applications.&lt;/p&gt;

&lt;p&gt;Whatever development board you choose, you'll ideally want to
make sure it breaks out the interface for debugging the MCU, so you
can attach a debugger to it.&lt;/p&gt;

&lt;h3&gt;Get a Debugger and Programmer&lt;/h3&gt;

&lt;p&gt;Most development boards include nice on-board USB
&lt;strong&gt;programming&lt;/strong&gt;. One thing none of them provide is any
sort of USB &lt;strong&gt;debugging&lt;/strong&gt;. For those of us used to
single-stepping through code and adding breakpoints, inspecting
values, etc., this can be a real step backwards in usability.&lt;/p&gt;

&lt;p&gt;Without a debugger, all you can do is debug using tricks like
blinky lights and (eventually) outputting messages to an LCD (but
that comes MUCH later). It's time-consuming and can be
frustrating.&lt;/p&gt;

&lt;p&gt;For AVR programming in AVR Studio 5.1, one of the best consumer
debuggers is the JTAGICE Mk3 from Atmel. The problem is, this thing
costs $300!&lt;/p&gt;

&lt;p&gt;There is one good chinese clone of this device. It's a reverse
engineering of the protocol, not a blatant copy like some others. I
recommend this one above all else. It's called the JTAGICE mkII-CN
by Mcuzone. Make sure you get the red-case one &lt;strong&gt;branded by
Mcuzone&lt;/strong&gt;, and none of the other copies. It runs around $80.
&lt;strong&gt;Get it shipped DHL, don't use China Post&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82428/Windows-Live-Writer_b3541542a059_B73E_image_17.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82433/Windows-Live-Writer_b3541542a059_B73E_image_thumb_7.png" width="399" height="468" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I did a quick ebay search on JTAGICE and crossed off the ones I
do not recommend getting. Notice how one of those is the red box.
It doesn't say "mcuZone" on it, so it may very well be a clone.
&lt;strong&gt;You want one which says mcuZone and has the serial number
tag on the bottom&lt;/strong&gt;. That version comes build for use with
AVR Studio 4, but includes a firmware update to work with AVR
Studio 5.&lt;/p&gt;

&lt;p&gt;Some of the other units are blatant copies of other people's IP,
so I'd rather not support those.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82438/Windows-Live-Writer_b3541542a059_B73E_image_27.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82443/Windows-Live-Writer_b3541542a059_B73E_image_thumb_12.png" width="660" height="396" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, get it shipped DHL even though that costs a bit more.
It's much faster and far more reliable.&lt;/p&gt;

&lt;p&gt;You'll also need to make sure the test board you use has a debug
port of some sort. For the larger AVR chips, that will almost
always be JTAG, although there are other options.&lt;/p&gt;

&lt;h3&gt;Set up the IDE&lt;/h3&gt;

&lt;p&gt;AVR Studio 5.1 is build on Microsoft Visual Studio 2010 Isolated
Shell. That means current Visual Studio developers will feel pretty
comfortable with the IDE.&lt;/p&gt;

&lt;p&gt;I previously &lt;a
href="http://10rem.net/blog/2011/11/05/getting-started-with-avr-studio-5"
target="_blank"&gt;covered using AVR Studio 5 in this blog post&lt;/a&gt;.
In that one, I used the Ready for XMEGA board. That's a great
board, but the XMEGA is a surface mount device. If surface mount
isn't a concern, I highly recommend it as that chip has a lot of
great capabilities and that board is nice and inexpensive…and
includes a JTAG deployment/debugging report.&lt;/p&gt;

&lt;p&gt;Atmel has released a beta of version 5.1. I found the link to
that on the &lt;a
href="http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewforum&amp;amp;f=23"
 target="_blank"&gt;avrfreaks AVR Studio 5 forum&lt;/a&gt;. Be sure to visit
there to get it, as the links change, and there may be a later
version out by the time you read this.&lt;/p&gt;

&lt;p&gt;Version 5.1 supports C++ right in the box, which was key to what
I want to do. Note, however, that if you go C++, you're pretty much
on your own. All the templates are for C and/or assembly. I was ok
with that, though, as I actually found it easier to learn
everything by discarding the AVR software framework that the
templates use.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82448/Windows-Live-Writer_b3541542a059_B73E_image_31.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82453/Windows-Live-Writer_b3541542a059_B73E_image_thumb_14.png" width="640" height="527" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks familiar, doesn't it? That's a MIDI to CV project I've
been working on. The AVR library I'm building is from scratch,
primarily because I want to learn the chip without someone else's
framework obscuring the details. Oh, and because I want to write
C++ :) Still, the optimized byte size of this app so far is about
2k. In this screen shot, I had turned optimization off as I was
trying to figure out why JTAG wasn't working. Speaking of that…&lt;/p&gt;

&lt;h3&gt;Important IDE Settings for JTAG Debugging&lt;/h3&gt;

&lt;p&gt;The external hardware debuggers are pretty much the only choice
when it comes to actually debugging the chip. It's things like this
that make you realize just how much the .NET Micro Framework is
doing for you behind the scenes.&lt;/p&gt;

&lt;p&gt;JTAG debugging has some important considerations with regard to
the speed it runs at. This one tripped me up for quite a while.
Remember earlier I said you need to know what clock speed you're
running the MCU at? Here's one place where it makes a huge
difference.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82458/Windows-Live-Writer_b3541542a059_B73E_image_29.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82463/Windows-Live-Writer_b3541542a059_B73E_image_thumb_13.png" width="520" height="369" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the JTAG clock slider, and the note under it. If JTAG
debugging isn't working, here's one place to check. By default, the
slider was set at 1MHz. By default, the MCU was also running at
1MHz. So, once I slid the slider down to around 200Mhz (which was
automatically corrected to the multiplied value you see above),
JTAG debugging started working! Yay!&lt;/p&gt;

&lt;p&gt;One you have that, you can set breakpoints and single-step
through your code just like you thought you should. If you bump up
the CPU speed on the processor, be sure to come back here and bump
this up as well, so you get the most speed out it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f3o5C2sgTUWm_GxcuiHZ6krlYuM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f3o5C2sgTUWm_GxcuiHZ6krlYuM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f3o5C2sgTUWm_GxcuiHZ6krlYuM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f3o5C2sgTUWm_GxcuiHZ6krlYuM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=HE-yRR4B7Ss:YNychl2Kvjw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=HE-yRR4B7Ss:YNychl2Kvjw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=HE-yRR4B7Ss:YNychl2Kvjw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=HE-yRR4B7Ss:YNychl2Kvjw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=HE-yRR4B7Ss:YNychl2Kvjw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=HE-yRR4B7Ss:YNychl2Kvjw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=HE-yRR4B7Ss:YNychl2Kvjw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=HE-yRR4B7Ss:YNychl2Kvjw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=HE-yRR4B7Ss:YNychl2Kvjw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/HE-yRR4B7Ss" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/13/setting-up-for-developing-and-debugging-the-avr-atmega1284p-with-avrstudio-51</feedburner:origLink></item><item><title>Windows Client Developer Roundup 086 for 1/11/2012</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/PvD8YY82TMA/windows-client-developer-roundup-086-for-1-11-2012</link><pubDate>Thu, 12 Jan 2012 01:02:35 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/11/windows-client-developer-roundup-086-for-1-11-2012</guid><description>&lt;p&gt;The Windows Client Developer Roundup aggregates information of
interest to Windows Client Developers, including &lt;a
href="http://dev.windows.com/"&gt;WinRT XAML&lt;/a&gt;, &lt;a
href="http://windowsclient.net/"&gt;WPF&lt;/a&gt;, &lt;a
href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;, &lt;a
href="http://msdn.microsoft.com/en-us/visualc/default.aspx"&gt;Visual
C++&lt;/a&gt;, &lt;a href="http://creators.xna.com/"&gt;XNA&lt;/a&gt;, &lt;a
href="http://expression.microsoft.com/"&gt;Expression Blend&lt;/a&gt;, &lt;a
href="http://www.microsoft.com/surface/"&gt;Surface&lt;/a&gt;, &lt;a
href="http://msdn.microsoft.com/en-us/windows/default.aspx"&gt;Windows
7&lt;/a&gt;, &lt;a
href="http://msdn.microsoft.com/en-us/ff380145.aspx"&gt;Windows
Phone&lt;/a&gt;, Visual Studio, &lt;a
href="http://silverlight.net/riaservices/"&gt;WCF RIA Services&lt;/a&gt; and
more. Sometimes I even include a little jQuery and HTML5. If you
have something interesting you've done or have run across, or you
blog regularly on the topics included here, please send me the URL
and brief description via the &lt;a href="http://10rem.net/contact"&gt;contact
link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that I've started breaking the Netduino, Electronics,
Robotics, Synthesizer and similar content into a new roundup series
called the &lt;a href="http://10rem.net/blog?filterby=MakerRoundup"&gt;Maker Geek
Roundup&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Shout-Outs&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/visualstudio/archive/2012/01/04/give-us-your-feedback-on-visual-studio-11-and-receive-a-gift.aspx"&gt;
Give us your feedback on Visual Studio 11 etc. and receive a
gift!&lt;/a&gt; (Visual Studio Blog)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Windows 8 and WinRT/Metro General&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/davedev/archive/2012/01/05/windows-8-first-apps-contest.aspx"&gt;
Windows 8 - First Apps Contest&lt;/a&gt; (Dave Isbitski)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://kellabyte.com/2011/12/19/when-metro-design-falls-off-the-tracks/"&gt;
When Metro design falls off the tracks&lt;/a&gt; (Kelly Sommers)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.sharpgis.net/post/2011/12/11/Make-your-Windows-8-Video-App-use-the-PlayTo-feature.aspx"&gt;
SharpGIS | Make your Windows 8 Video App use the PlayTo feature&lt;/a&gt;
(Morten Nielsen)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;XAML Technologies (Silverlight, WPF, WinRT Metro XAML)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://www.andybeaulieu.com/Home/tabid/67/EntryID/223/Default.aspx"&gt;
"Physamajig" for Windows 8&lt;/a&gt; (Andy Beaulieu)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.sharpgis.net/post/2011/12/07/Building-an-Augmented-Reality-XAML-control.aspx"&gt;
Building an Augmented Reality XAML control&lt;/a&gt; (Morten
Nielsen)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;WinJS / JavaScript and HTML Applications for Windows Metro&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://adamkinney.com/blog/2011/12/07/setting-up-your-first-use-of-the-animation-library-in-winjs/"&gt;
Setting up your first use of the Animation library in WinJS&lt;/a&gt;
(Adam Kinney)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://adamkinney.com/blog/2011/12/05/no-alert-in-winjs-use-console-or-messagedialog-instead/"&gt;
No Alert in WinJS! Use console or MessageDialog instead&lt;/a&gt; (Adam
Kinney)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Direct X Technologies (DirectX, XNA, WinRT DirectX, General GPU
and Game Programming)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://geekswithblogs.net/mikebmcl/archive/2011/12/31/getting-started-with-metro-style-directx.aspx"&gt;
Getting started with Metro style DirectX&lt;/a&gt; (Bob Taco
Industries)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://digitalerr0r.wordpress.com/2011/12/12/xna-4-0-shader-programming-1intro-to-hlsl-ambient-light/"&gt;
XNA 4.0 Shader Programming #1-Intro to HLSL, Ambient light&lt;/a&gt;
(digitalerr0r)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://digitalerr0r.wordpress.com/2011/12/13/xna-4-0-shader-programming-2diffuse-light/"&gt;
XNA 4.0 Shader Programming #2-Diffuse light&lt;/a&gt; (digitalerr0r)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://digitalerr0r.wordpress.com/2011/12/20/xna-4-0-shader-programming-3specular-light/"&gt;
XNA 4.0 Shader Programming #3-Specular light&lt;/a&gt;
(digitalerr0r)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;C++ and Native Development&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/sdl/archive/2011/12/02/security.aspx"&gt;
Compiler Security Enhancements in Visual Studio 11&lt;/a&gt; (SDL
Team)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Visual Studio and .NET General&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/somasegar/archive/2011/12/15/visual-studio-11-platform-tooling-advances.aspx"&gt;
Visual Studio 11 Platform Tooling Advances&lt;/a&gt; (Soma)&lt;/li&gt;

&lt;li style="list-style: none"&gt;
&lt;ul&gt;
&lt;li&gt;Good DirectX content in this one as well&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://blogs.msdn.com/b/delay/archive/2012/01/09/make-things-as-simple-as-possible-but-not-simpler-managedmsiexec-sample-app-shows-how-to-use-the-windows-installer-api-from-managed-code.aspx"&gt;
ManagedMsiExec sample app shows how to use the Windows Installer
API from managed code&lt;/a&gt; (David Anson)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;NUI (Kinect, Surface, More)&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://kinecthacks.net/microsoft-kinect-coming-to-windows-on-february-1st-up-for-pre-order-now/"&gt;
Microsoft Kinect coming to Windows on February 1st, up for
pre-order now!&lt;/a&gt; (KinectHacks)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://robrelyea.wordpress.com/2012/01/11/kinect-apps-ensuring-kinect-runtime-is-installed/"&gt;
Kinect Apps - ensuring Kinect Runtime is installed&lt;/a&gt; (Rob
Relyea)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://robrelyea.wordpress.com/2011/12/17/depth-api-improvements-in-v1/"&gt;
Examples of depth API improvements coming in v1&lt;/a&gt; (Rob
Relyea)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://channel9.msdn.com/coding4fun/kinect/Kinect--3D--Fusion4D"&gt;
Kinect + 3D = Fusion4D&lt;/a&gt; (Greg Duncan)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://channel9.msdn.com/coding4fun/blog/Connecting-your-Netduino-to-your-Kinect"&gt;
Connecting your Netduino to your Kinect&lt;/a&gt; (Greg Duncan)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://digitalerr0r.wordpress.com/2011/12/13/kinect-fundamentals-4-implementing-skeletal-tracking/"&gt;
Kinect Fundamentals #4: Implementing Skeletal Tracking |
digitalerr0r&lt;/a&gt; (digitalerr0r)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://studentguru.gr/b/vangos/archive/2012/01/01/kinect-amp-html5-using-websockets-and-canvas.aspx"&gt;
Kinect &amp;amp; HTML5 using WebSockets and Canvas&lt;/a&gt; (Vangos
Pterneas)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Off-Topic Fun&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://poorlydrawnlines.com/comic/when-its-cold/"&gt;Poorly
Drawn Lines - When It's Cold&lt;/a&gt; (for all the ADD types)&lt;/li&gt;

&lt;li&gt;&lt;a href="http://xkcd.com/1002/"&gt;xkcd: Game AIs&lt;/a&gt; (xkcd)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.smbc-comics.com/index.php?db=comics&amp;amp;id=2470&amp;amp;"&gt;
Benoit Mandelbrot: Master of seduction&lt;/a&gt; (SMBC)&lt;/li&gt;

&lt;li style="list-style: none"&gt;
&lt;ul&gt;
&lt;li&gt;and &lt;a
href="http://www.smbc-comics.com/index.php?db=comics&amp;amp;id=2471&amp;amp;"&gt;
Saturday Morning Breakfast Cereal&lt;/a&gt;&amp;nbsp;&lt;/li&gt;

&lt;li&gt;and &lt;a
href="http://www.smbc-comics.com/index.php?db=comics&amp;amp;id=2475&amp;amp;"&gt;
Saturday Morning Breakfast Cereal&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://www.smbc-comics.com/index.php?db=comics&amp;amp;id=2478"&gt;Grammar!&lt;/a&gt;
(SMBC)&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://moistproduction.blogspot.com/2011/12/lego-skeleton-cross-section-for-purists.html"&gt;
Lego Skeleton inside Mini Figure (for the purists)&lt;/a&gt;
(MoistProduction)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p_8ykcYhniBNnwhBOEzdPxlcqWQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p_8ykcYhniBNnwhBOEzdPxlcqWQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p_8ykcYhniBNnwhBOEzdPxlcqWQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p_8ykcYhniBNnwhBOEzdPxlcqWQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PvD8YY82TMA:ZbVh6LC2cvg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PvD8YY82TMA:ZbVh6LC2cvg:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PvD8YY82TMA:ZbVh6LC2cvg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PvD8YY82TMA:ZbVh6LC2cvg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=PvD8YY82TMA:ZbVh6LC2cvg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PvD8YY82TMA:ZbVh6LC2cvg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=PvD8YY82TMA:ZbVh6LC2cvg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=PvD8YY82TMA:ZbVh6LC2cvg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=PvD8YY82TMA:ZbVh6LC2cvg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/PvD8YY82TMA" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/11/windows-client-developer-roundup-086-for-1-11-2012</feedburner:origLink></item><item><title>Threading Considerations for Binding and Change Notification in Silverlight 5</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/mPgdkOol8xE/threading-considerations-for-binding-and-change-notification-in-silverlight-5</link><pubDate>Tue, 10 Jan 2012 16:48:00 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/10/threading-considerations-for-binding-and-change-notification-in-silverlight-5</guid><description>&lt;p&gt;A reader of &lt;a href="http://manning.com/pbrown2"
target="_blank"&gt;my Silverlight 5 book&lt;/a&gt; recently reached out to
me about threading and why I create some objects on the UI thread
in the examples. We discussed some of the reasons, but I felt this
would be a good topic to share with everyone. In fact, this is one
area where it would have been fun to go into great detail in my
book, but there simply wasn't the space. Threading and cross-thread
exceptions can be a bit of a mystery to new Silverlight and WPF
developers.&lt;/p&gt;

&lt;h3&gt;Background&lt;/h3&gt;

&lt;p&gt;The user interface in Silverlight runs on a thread commonly
known as the UI Thread. Any code you create in the code-behind, and
any code it calls all the way down the chain, unless it explicitly
creates another thread, runs on this same UI thread. It's not at
all uncommon to see Silverlight and WPF applications which never
explicitly create a second thread, but do make calls to other
services which create background threads for processing.&lt;/p&gt;

&lt;p&gt;There are many other examples, but networking is one place where
the Silverlight .NET Framework explicitly creates (or uses)
different threads. Not all calls return on the UI thread.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Threads other than the UI thread are not allowed to
access or manipulate UI objects&lt;/strong&gt;. If they attempt to do so,
the runtime throws an Invalid Cross-Thread Access exception. It
looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82267/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82272/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_thumb.png" width="477" height="277" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But wait! I wasn't accessing any UI objects from my code. What
gives?&lt;/p&gt;

&lt;p&gt;It's not always obvious that you're interacting with UI objects
on the UI thread, though. Here's the stack trace from this
particular exception:&lt;/p&gt;

&lt;pre class="brush: csharp; highlight: [2];"&gt;
{System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---&amp;gt;&lt;br /&gt;
  System.UnauthorizedAccessException: Invalid cross-thread access.&lt;br /&gt;
   at MS.Internal.XcpImports.CheckThread()&lt;br /&gt;
   at MS.Internal.XcpImports.GetValue(IManagedPeerBase managedPeer, DependencyProperty property)&lt;br /&gt;
   at System.Windows.DependencyObject.GetOldValue(DependencyProperty property, EffectiveValueEntry&amp;amp; oldEntry)&lt;br /&gt;
   at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry&amp;amp; newEntry, ValueOperation operation)&lt;br /&gt;
   at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)&lt;br /&gt;
   at System.Windows.Data.BindingExpression.SendDataToTarget()&lt;br /&gt;
   at System.Windows.Data.BindingExpression.SourcePropertyChanged(PropertyPathListener sender, PropertyPathChangedEventArgs args)&lt;br /&gt;
   at System.Windows.PropertyPathListener.ReconnectPath()&lt;br /&gt;
   at System.Windows.Data.Debugging.BindingBreakPoint.&amp;lt;&amp;gt;c__DisplayClass4.&amp;lt;BreakOnSharedType&amp;gt;b__3()&lt;br /&gt;
   --- End of inner exception stack trace ---&lt;br /&gt;
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)&lt;br /&gt;
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)&lt;br /&gt;
   at System.Delegate.DynamicInvokeImpl(Object[] args)&lt;br /&gt;
   at System.Delegate.DynamicInvoke(Object[] args)&lt;br /&gt;
   at MainPagexaml.BindingOperation(Object BindingState, Int32 , Action )}
&lt;/pre&gt;

&lt;p&gt;This stack trace was generated by &lt;strong&gt;trying to raise a
PropertyChangedNotification when I manipulated a model object from
a background thread&lt;/strong&gt;. So, it was obvious that I was working
with an object on the background thread, but it wasn't obvious that
I'd get a cross-thread exception (well it was in this case, as I
contrived the example). If you consider a larger application where
you have division of ownership for different pieces, a client-side
developer may simply work with your viewmodel, but not realize
you're farming some work out to another thread.&lt;/p&gt;

&lt;p&gt;I wrote a blog post back in 2010 ( &lt;a
href="http://10rem.net/blog/2010/04/23/essential-silverlight-and-wpf-skills-the-ui-thread-dispatchers-background-workers-and-async-network-programming"&gt;
Essential Silverlight and WPF Skills: The UI Thread, Dispatchers,
Background Workers and Async Network Programming&lt;/a&gt;) explaining
some of the ways to work with threads and dispatching. I didn't
have SynchronizationContext in there at the time, but it's
something I tend to use a lot these days.&lt;/p&gt;

&lt;p&gt;Let's take a look at a few of the common scenarios and how it
works with threading.&lt;/p&gt;

&lt;h3&gt;Common Scenarios&lt;/h3&gt;

&lt;p&gt;All of these scenarios make use of a simple Customer class with
a single property:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
namespace SilverlightThreadingExample.Model&lt;br /&gt;
{&lt;br /&gt;
    public class Customer : Observable&lt;br /&gt;
    {&lt;br /&gt;
        private string _firstName;&lt;br /&gt;
        public string FirstName&lt;br /&gt;
        {&lt;br /&gt;
            get { return _firstName; }&lt;br /&gt;
            set { _firstName = value; NotifyPropertyChanged("FirstName"); }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The customer is &lt;em&gt;observable&lt;/em&gt; that is, it notifies any
listeners when properties change. While not necessary, I
encapsulated the observable code in this base class. You could,
instead, put the implementation in a partial class if you wanted to
make sure your model object's signature from your ORM or whatever
remains the same as it was on the server.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System.ComponentModel;&lt;br /&gt;
&lt;br /&gt;
namespace SilverlightThreadingExample&lt;br /&gt;
{&lt;br /&gt;
    public class Observable : INotifyPropertyChanged&lt;br /&gt;
    {&lt;br /&gt;
        public event PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;
&lt;br /&gt;
        protected void NotifyPropertyChanged(string propertyName)&lt;br /&gt;
        {&lt;br /&gt;
            if (PropertyChanged != null)&lt;br /&gt;
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This is actually a pretty typical approach to handling
INotifyPropertyChanged. There are even more robust versions out
there which use lambdas and reflection to help avoid passing in
strings, but they ultimately come down to raising the
PropertyChanged event. Many of them also fail to work properly in
cross-thread situations.&lt;/p&gt;

&lt;p&gt;I expose the Customer class and a collection of customers from a
ViewModel class.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
namespace SilverlightThreadingExample.ViewModel&lt;br /&gt;
{&lt;br /&gt;
    public class CustomerEntryViewModel : Observable&lt;br /&gt;
    {&lt;br /&gt;
        private Customer _currentCustomer;&lt;br /&gt;
        public Customer CurrentCustomer&lt;br /&gt;
        {&lt;br /&gt;
            get { return _currentCustomer; }&lt;br /&gt;
            set { _currentCustomer = value; NotifyPropertyChanged("CurrentCustomer"); }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private ObservableCollection&amp;lt;Customer&amp;gt; _customers = new ObservableCollection&amp;lt;Customer&amp;gt;();&lt;br /&gt;
        public ObservableCollection&amp;lt;Customer&amp;gt; Customers&lt;br /&gt;
        {&lt;br /&gt;
            get { return _customers; }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        public void LoadCustomersOnSameThread()&lt;br /&gt;
        {&lt;br /&gt;
            LoadDummyData();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        private void LoadDummyData()&lt;br /&gt;
        {&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Pete" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Jon" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Tim" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Scott" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Andy" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Blaine" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Jesse" });&lt;br /&gt;
            _customers.Add(new Customer() { FirstName = "Rey" });&lt;br /&gt;
&lt;br /&gt;
            _currentCustomer = _customers[0];&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Finally, the UI is bound to those classes. The DataContext for
the UI (which will be set in code-behind) is the ViewModel.&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;
&amp;lt;UserControl x:Class="SilverlightThreadingExample.MainPage"&lt;br /&gt;
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&lt;br /&gt;
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;br /&gt;
    mc:Ignorable="d"&lt;br /&gt;
    d:DesignHeight="400" d:DesignWidth="600"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Grid x:Name="LayoutRoot" Background="White"&amp;gt;&lt;br /&gt;
        &amp;lt;Grid Width="500"&amp;gt;&lt;br /&gt;
            &amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
                &amp;lt;ColumnDefinition Width="*" /&amp;gt;&lt;br /&gt;
                &amp;lt;ColumnDefinition Width="250" /&amp;gt;&lt;br /&gt;
            &amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;ListBox x:Name="CustomerList"&lt;br /&gt;
                     Grid.Column="0" Margin="10"&lt;br /&gt;
                     ItemsSource="{Binding Customers}"&lt;br /&gt;
                     SelectedItem="{Binding CurrentCustomer, Mode=TwoWay}"&amp;gt;&lt;br /&gt;
                &amp;lt;ListBox.ItemTemplate&amp;gt;&lt;br /&gt;
                    &amp;lt;DataTemplate&amp;gt;&lt;br /&gt;
                        &amp;lt;TextBlock Text="{Binding FirstName}" /&amp;gt;&lt;br /&gt;
                    &amp;lt;/DataTemplate&amp;gt;&lt;br /&gt;
                &amp;lt;/ListBox.ItemTemplate&amp;gt;&lt;br /&gt;
            &amp;lt;/ListBox&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;StackPanel Grid.Column="1"&amp;gt;&lt;br /&gt;
                &amp;lt;TextBox x:Name="FirstNameField" Margin="10"&lt;br /&gt;
                         DataContext="{Binding CurrentCustomer}"&lt;br /&gt;
                         Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;Button x:Name="AddCustomer"&lt;br /&gt;
                        Content="Add Customer from UI Thread"&lt;br /&gt;
                        Height="30" Margin="5"&lt;br /&gt;
                        Click="AddCustomer_Click" /&amp;gt;&lt;br /&gt;
                &amp;lt;Button x:Name="AddCustomerSecond"&lt;br /&gt;
                        Content="Add Customer from Second Thread"&lt;br /&gt;
                        Height="30" Margin="5"&lt;br /&gt;
                        Click="AddCustomerSecond_Click" /&amp;gt;&lt;br /&gt;
                &amp;lt;Button x:Name="ChangeNameFromSecondThread"&lt;br /&gt;
                        Content="Change Name from Second Thread"&lt;br /&gt;
                        Height="30" Margin="5"&lt;br /&gt;
                        Click="ChangeNameFromSecondThread_Click" /&amp;gt;&lt;br /&gt;
            &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/Grid&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;/Grid&amp;gt;&lt;br /&gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The code-behind looks like this&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
using System.Windows;&lt;br /&gt;
using System.Windows.Controls;&lt;br /&gt;
using SilverlightThreadingExample.ViewModel;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using SilverlightThreadingExample.Model;&lt;br /&gt;
&lt;br /&gt;
namespace SilverlightThreadingExample&lt;br /&gt;
{&lt;br /&gt;
    public partial class MainPage : UserControl&lt;br /&gt;
    {&lt;br /&gt;
        CustomerEntryViewModel _vm;&lt;br /&gt;
&lt;br /&gt;
        public MainPage()&lt;br /&gt;
        {&lt;br /&gt;
            InitializeComponent();&lt;br /&gt;
&lt;br /&gt;
            CreateViewModelOnUIThread();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private void CreateViewModelOnUIThread()&lt;br /&gt;
        {&lt;br /&gt;
            _vm = new CustomerEntryViewModel();&lt;br /&gt;
&lt;br /&gt;
            _vm.LoadCustomersOnSameThread();&lt;br /&gt;
&lt;br /&gt;
            DataContext = _vm;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private void AddCustomer_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private void AddCustomerSecond_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        private void ChangeNameFromSecondThread_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
        {&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;

&lt;p&gt;The methods are named to keep the context clear in this example.
I wouldn't expect you to name your VM instantiation/locator method
"CreateViewModelOnUIThread", for example.&lt;/p&gt;

&lt;p&gt;Now let's look at those scenarios.&lt;/p&gt;

&lt;h4&gt;Changing a property value from a background thread&lt;/h4&gt;

&lt;p&gt;Often in an application, you have a class which is used in UI
binding (an entity/model object) but still need to modify a
property from code. Sometimes, you need to do that from a
background thread. For example, you make a network call to get an
updated price for an item. You will get a cross-thread access error
when the class raises change notification events from that property
setter. If the class is truly POCO (Plan Old CLR Object) and
doesn't do any change notification or other event raising, you'll
be fine. If, however, change notification is involved, you'll get
the cross-thread exception.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/82277/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_13.png" width="640" height="261" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;Assuming the same Customer and Observable classes defined above,
and the same XAML UI, the following code in the code-behind will
throw that exception.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void ChangeNameFromSecondThread_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Thread t = new Thread((o) =&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
            _vm.CurrentCustomer.FirstName = "UpdatedFromSecondThread";&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    t.Start();&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The exception doesn't happen when you set the property value;
that's perfectly acceptable. It happens here, at the highlighted
line:&lt;/p&gt;

&lt;pre class="brush: csharp; highlight: [4];"&gt;
protected void NotifyPropertyChanged(string propertyName)&lt;br /&gt;
{&lt;br /&gt;
    if (PropertyChanged != null)&lt;br /&gt;
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;So, what are the options for working around this? Let's consider
two common approaches.&lt;/p&gt;

&lt;h5&gt;Approach 1&lt;/h5&gt;

&lt;p&gt;The first approach is to do the whole property change from the
UI thread. To do this, simply wrap the property set code with a
call to the dispatcher. You can use either the Dispatcher object,
or if you keep a copy of the SynchronizationContext around, use
that.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/82282/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_22.png" width="640" height="261" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;Here's some example code which implements this. The code looks a
bit silly because I'm forcing a background thread. However, pretend
that the background thread is a given and you need to work from it
(again, the callback from a network call or something.)&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void ChangeNameFromSecondThread_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Thread t = new Thread((o) =&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt;&lt;br /&gt;
            {&lt;br /&gt;
                _vm.CurrentCustomer.FirstName = "UpdatedFromSecondThread";&lt;br /&gt;
            });&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    t.Start();&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;This approach works well, but requires the calling code to
handle all the dispatching. If you have a number of properties to
change in different bits of code, it gets a bit cumbersome. Let's
look at another approach.&lt;/p&gt;

&lt;h5&gt;Approach 2&lt;/h5&gt;

&lt;p&gt;The real problem is the property change notification, so the the
second approach is to dispatch just the change notification to the
UI thread.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/82287/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_24.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/82292/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_thumb_8.png" width="640" height="261" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can put this code into the Observable base class in order to
avoid repeating it throughout all your classes.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
// Code-behind&lt;br /&gt;
// ----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// this version throws an exception if the Observable base class isn't doing thread checking&lt;br /&gt;
private void ChangeNameFromSecondThread_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Thread t = new Thread((o) =&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
            _vm.CurrentCustomer.FirstName = "UpdatedFromSecondThread";&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    t.Start();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Observable&lt;br /&gt;
// ----------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
using System.ComponentModel;&lt;br /&gt;
using System.Windows;&lt;br /&gt;
&lt;br /&gt;
namespace SilverlightThreadingExample&lt;br /&gt;
{&lt;br /&gt;
    public class Observable : INotifyPropertyChanged&lt;br /&gt;
    {&lt;br /&gt;
        public event PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;
&lt;br /&gt;
        protected void NotifyPropertyChanged(string propertyName)&lt;br /&gt;
        {&lt;br /&gt;
            if (PropertyChanged != null)&lt;br /&gt;
            {&lt;br /&gt;
                if (Deployment.Current.Dispatcher.CheckAccess())&lt;br /&gt;
                {&lt;br /&gt;
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt;&lt;br /&gt;
                    {&lt;br /&gt;
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;
                    });&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Note how I first check to see if we have access to the UI thread
using the CheckAccess call. If we do, there's no reason to incur
the overhead and delay of a dispatcher call. However, if we are
running on the background thread, then the call is dispatched to
the UI thread. In either case, we avoid the errors cause by
cross-thread property change notification.&lt;/p&gt;

&lt;p&gt;Next up: Collections&lt;/p&gt;

&lt;h4&gt;Populating an ObservableCollection from a networking return
call&lt;/h4&gt;

&lt;p&gt;A more robust Observable base class like this won't help with
collection change notification (WPF 4.5 has a great solution for
that using BindingOperations.EnableCollectionSynchronization, but
unfortunately Silverlight does not).&lt;/p&gt;

&lt;p&gt;Most applications make networking calls to get information from
some resource on an intranet or out on the web. In Silverlight (and
WPF), it's common practice to populate an ObservableCollection with
the results from those calls. The ObservableCollection class is
nice because it implements INotifyCollectionChanged and raises an
event whenever items are added to or deleted from the collection,
or when the collection is cleared. It's this notification that
enables the various items controls and grids in the UI to stay in
sync with the items in the collection.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/82297/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_16.png" width="640" height="261" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;This version is very similar to what we saw with individual
properties earlier. That's because, it's really the same problem:
we're trying to notify the binding system across threads.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void AddCustomerSecond_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    Thread t = new Thread((o) =&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        var cust = new Customer() { FirstName = "AddedFromSecondThread" };&lt;br /&gt;
        _vm.Customers.Add(cust);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    t.Start();&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;Note that the problem exists regardless of where you actually
create the customer. For example, this code will also fail:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void AddCustomerSecond_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    var cust = new Customer() { FirstName = "AddedFromSecondThread" };&lt;br /&gt;
&lt;br /&gt;
    Thread t = new Thread((o) =&amp;gt;&lt;br /&gt;
    {&lt;br /&gt;
        _vm.Customers.Add(cust);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    t.Start();&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;The reason is, again, it's not the object access that is causing
the cross-thread exception, it's the collection changed
notification that's full of hate here.&lt;/p&gt;

&lt;p&gt;So, how do you get around this? Unless you want to create your
own ObservableCollection type class for Silverlight, you'll need to
dispatch all collection add calls. Luckily, you'll typically have
fewer of these scattered throughout the application, so it's not
quite so onerous.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://10rem.net/media/82302/Windows-Live-Writer_Threading-Considerations-for-Binding-in-_EF97_image_27.png" width="640" height="261" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/p&gt;

&lt;p&gt;The code to implement this is just another easy call to the
dispatcher (or SynchronizationContext, if you prefer).&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
private void AddCustomerSecond_Click(object sender, RoutedEventArgs e)&lt;br /&gt;
{&lt;br /&gt;
    // you can create customer on any thread&lt;br /&gt;
    var cust = new Customer() { FirstName = "AddedFromSecondThread" };&lt;br /&gt;
&lt;br /&gt;
    Thread t = new Thread((o) =&amp;gt;&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
            // dispatch to UI thread to add it to the collection. You can't&lt;br /&gt;
            // access the observable collection x-thread&lt;br /&gt;
            Deployment.Current.Dispatcher.BeginInvoke(() =&amp;gt;&lt;br /&gt;
                {&lt;br /&gt;
                    _vm.Customers.Add(cust);&lt;br /&gt;
                });&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    t.Start();&lt;br /&gt;
}
&lt;/pre&gt;

&lt;p&gt;If you're going to run from an unknown state, be sure to call
CheckAccess to see if you really need to do the dispatching. In
this case, I know I'm always going to be on a background thread, so
I don't bother.&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;The intent here was to show a few of the common threading
pitfalls in Silverlight (and WPF) applications, specifically in the
context of change notification. In most code, it's easy to tell
when you're accessing objects cross-thread, but change notification
is a somewhat behind the scenes operation, so it's not always
obvious.&lt;/p&gt;

&lt;p&gt;For property change notification, the solutions were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dispatch the entire property change operation to the UI
thread&lt;/li&gt;

&lt;li&gt;Update the NotifyPropertyChanged code to check to see which
thread it's running on, and then dispatch the event as
appropriate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Either way works, but I prefer the update to the
NotifyPropertyChanged method.&lt;/p&gt;

&lt;p&gt;For collection change notifications in Silverlight, the
solutions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create (or find) an implementation of ObservableCollection
which does the cross-thread checking. The reason this isn't
built-in is change notification happens often, and dispatching each
and every change notification can be a real performance drain.
That's also why WPF has a separate and optimized solution. You'd
need to enable batching to avoid the overhead of hundreds of
dispatch calls.&lt;/li&gt;

&lt;li&gt;Dispatch the entire collection update when you're running on a
background thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast to the property change notifications, for collection
change, I prefer to dispatch the entire call. If you're adding 1
object or 100, you'll still get only one dispatch call, so
performance is better.&lt;/p&gt;

&lt;p&gt;The Task Parallel Library in WPF, and the subset of it in
Silverlight also offer some alternative approaches to handling
cross-thread work. Similarly, the async and await keywords in .NET
4.5 and Windows 8 XAML can also come into play. More on those in
the future.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uwQIQJePQRlDzsX961fUfvyocuc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uwQIQJePQRlDzsX961fUfvyocuc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uwQIQJePQRlDzsX961fUfvyocuc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uwQIQJePQRlDzsX961fUfvyocuc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=mPgdkOol8xE:Rd1oCIMrnYU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=mPgdkOol8xE:Rd1oCIMrnYU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=mPgdkOol8xE:Rd1oCIMrnYU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=mPgdkOol8xE:Rd1oCIMrnYU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=mPgdkOol8xE:Rd1oCIMrnYU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=mPgdkOol8xE:Rd1oCIMrnYU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=mPgdkOol8xE:Rd1oCIMrnYU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=mPgdkOol8xE:Rd1oCIMrnYU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=mPgdkOol8xE:Rd1oCIMrnYU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/mPgdkOol8xE" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/10/threading-considerations-for-binding-and-change-notification-in-silverlight-5</feedburner:origLink></item><item><title>Silverlight Reporting Open Source Printing/Reports Example Updated for Silverlight 5</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/9lvuBR5MsTc/silverlight-reporting-open-source-printing-reports-example-updated-for-silverlight-5</link><pubDate>Mon, 09 Jan 2012 20:44:30 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/09/silverlight-reporting-open-source-printing-reports-example-updated-for-silverlight-5</guid><description>&lt;p&gt;I recently posted an updated version of Silverlight reporting on
&lt;a href="http://silverlightreporting.codeplex.com/"
target="_blank"&gt;codeplex&lt;/a&gt;. Here's the overview.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://silverlightreporting.codeplex.com/"
target="_blank"&gt;&lt;img src="http://10rem.net/media/82245/Windows-Live-Writer_Silverlight-Reporting-Open-Source-Printi_EA02_image_5.png" width="490" height="100" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project, a unofficial project by Pete Brown of Microsoft,
provides a a very basic framework for building simple, short,
multi-page reports using Silverlight 5.&lt;/p&gt;

&lt;p&gt;The intent is not to be an all-encompassing reporting solution,
or a solution for large reports. Instead, this is a set of code you
can build upon to create short (2-5 page) reports from your
Silverlight applications.&lt;/p&gt;

&lt;p&gt;Currently the sample consists of the full source code of a
simple report writer. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic pagination&lt;/li&gt;

&lt;li&gt;support for line items of varying height&lt;/li&gt;

&lt;li&gt;total page count&lt;/li&gt;

&lt;li&gt;templating&lt;/li&gt;

&lt;li&gt;page headers and footers&lt;/li&gt;

&lt;li&gt;report footer with support for calculated fields&lt;/li&gt;

&lt;li&gt;events to allow hooking into printing at various stages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Latest Release&lt;/h3&gt;

&lt;p&gt;Version information changed to use semantic versioning. This
vesion is numbered: &lt;a
href="http://silverlightreporting.codeplex.com/releases/view/80092"
target="_blank"&gt;1.0.0-alpha.3&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now targets Silverlight 5&lt;/li&gt;

&lt;li&gt;Added ability to specify postscript (vector) printing. The
selected driver must support PostScript or this setting will have
no effect.&lt;/li&gt;

&lt;li&gt;Fixed issue with not being able to re-print the report. (and
fixed leaky event handlers)&lt;/li&gt;

&lt;li&gt;Added null check on templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://silverlightreporting.codeplex.com/"
target="_blank"&gt;&lt;img src="http://10rem.net/media/82250/Windows-Live-Writer_Silverlight-Reporting-Open-Source-Printi_EA02_image_6.png" width="366" height="468" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is still alpha, and is a minor project. Expect bugs. Report
them when you do. Offer fixes if you can :)&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://silverlightreporting.codeplex.com/releases/view/80092"
target="_blank"&gt;Get the latest release here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sqK4kgMZ8xBG6YpQ-5KAvyU1Ya8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sqK4kgMZ8xBG6YpQ-5KAvyU1Ya8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sqK4kgMZ8xBG6YpQ-5KAvyU1Ya8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sqK4kgMZ8xBG6YpQ-5KAvyU1Ya8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=9lvuBR5MsTc:VL2o9HdVqXw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=9lvuBR5MsTc:VL2o9HdVqXw:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=9lvuBR5MsTc:VL2o9HdVqXw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=9lvuBR5MsTc:VL2o9HdVqXw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=9lvuBR5MsTc:VL2o9HdVqXw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=9lvuBR5MsTc:VL2o9HdVqXw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=9lvuBR5MsTc:VL2o9HdVqXw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=9lvuBR5MsTc:VL2o9HdVqXw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=9lvuBR5MsTc:VL2o9HdVqXw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/9lvuBR5MsTc" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/09/silverlight-reporting-open-source-printing-reports-example-updated-for-silverlight-5</feedburner:origLink></item><item><title>MFOS Synth 7: Front Panel Update (Knobs and started wiring)</title><author>Pete Brown	</author><link>http://feedproxy.google.com/~r/PeteBrown/~3/65hSh0IzLII/mfos-synth-7-front-panel-update-knobs-and-started-wiring</link><pubDate>Sun, 08 Jan 2012 06:19:46 GMT</pubDate><guid isPermaLink="false">http://10rem.net/blog/2012/01/08/mfos-synth-7-front-panel-update-knobs-and-started-wiring</guid><description>&lt;p&gt;Today, I started wiring the front panel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Over the next several months I'll be building what is definitely
my most complex electronics project to date: the MFOS (Music From
Outer Space) &lt;a
href="http://www.musicfromouterspace.com/index.php?MAINTAB=SYNTHDIY&amp;amp;PROJARG=SOUNDLAB_ULTIMATE/page1.html&amp;amp;VPW=1326&amp;amp;VPH=1153"&gt;
Sound Lab Ultimate&lt;/a&gt;, &lt;a
href="http://www.musicfromouterspace.com/index.php?MAINTAB=SYNTHDIY&amp;amp;PROJARG=ULTIMATE_EXPANDER/ultexpanderpg1.html&amp;amp;VPW=1326&amp;amp;VPH=1153"&gt;
Ultimate Expander&lt;/a&gt; and (if Santa brings one) &lt;a
href="http://www.musicfromouterspace.com/index.php?MAINTAB=SYNTHDIY&amp;amp;PROJARG=SOUNDLABMINIMARKII/page1.php&amp;amp;VPW=1326&amp;amp;VPH=1153"&gt;
Sound Lab Mini-Synth Mark II&lt;/a&gt;, likely all in the same home-made
wooden case, side by side. The Ultimate and Expander are together a
3 oscillator monophonic true analog synthesizer with filters,
envelopment generator, ring modulator, sample and hold and more.
You patch between the different logical modules using banana
cables, so it's a bit of a self-contained modular synthesizer. The
Mark II is smaller, newer, and has a few fewer features, but a
sound of its own. You also patch that with banana cables, and can
integrate the two. This blog post is another in the series.
Previous posts include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a
href="http://10rem.net/blog/2011/12/02/mfos-synth-1-built-the-power-supply"&gt;MFOS
Synth 1: Built the Power Supply&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://10rem.net/blog/2011/12/02/mfos-synth-2-some-main-synthesizer-board-work"&gt;
MFOS Synth 2: Some main synthesizer board work&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://10rem.net/blog/2011/12/04/mfos-synth-3-starting-the-front-panel"&gt;MFOS
Synth 3: Starting the Front Panel&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://10rem.net/blog/2011/12/16/mfos-synth-4-resistors-all-soldered"&gt;MFOS
Synth 4: Resistors all soldered&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a
href="http://10rem.net/blog/2011/12/18/mfos-synth-5-trimmers-and-some-capacitors-in-place"&gt;
MFOS Synth 5: Trimmers and some capacitors in place&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="http://10rem.net/blog/2012/01/04/mfos-synth-6-pcb-complete"&gt;MFOS Synth
6: PCB Complete&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I received a shipment from Small Bear Electronics. They had the
&lt;a href="http://www.smallbearelec.com/Detail.bok?no=9"&gt;24mm Alpha
1M and 100K audio taper pots&lt;/a&gt; back in stock, so I ordered a few.
I liked the smaller pots, but not how they wiggled in the holes no
matter how much I tightened the nuts. I didn't feel like making
spacers for them.&lt;/p&gt;

&lt;p&gt;I also decided which control knobs I wanted to use. I was really
torn as I liked the &lt;a
href="http://www.smallbearelec.com/Detail.bok?no=727"&gt;violet
knobs&lt;/a&gt; both in size and style, but I really disliked how they
showed the pot washer and nut. It just looked too DIY with those
showing for each pot. Instead, I went with the other one I liked:
the same style that's on my Moog slim phatty.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/81801/Windows-Live-Writer_aaeffbe643b4_1967_image_2.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/81806/Windows-Live-Writer_aaeffbe643b4_1967_image_thumb.png" width="520" height="344" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Small Bear, these are &lt;a
href="http://www.smallbearelec.com/Detail.bok?no=1112"&gt;Synth
Pointer #4&lt;/a&gt;. I cleaned them out, and actually have a few on
backorder.&lt;/p&gt;

&lt;p&gt;With all the potentiometers in place, I decided to start some of
the front panel wiring. Ray has a good diagram on his site showing
the wiring. I printed that out, and as he recommended in the build
notes, I took a marker and colored each wire as I completed it.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/81811/Windows-Live-Writer_aaeffbe643b4_1967_image_4.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/81816/Windows-Live-Writer_aaeffbe643b4_1967_image_thumb_1.png" width="520" height="396" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the diagram, you can see, I've completed almost 1/2 the
rear panel wiring. Here's the panel.&lt;/p&gt;

&lt;p&gt;&lt;a
href="http://10rem.net/media/81821/Windows-Live-Writer_aaeffbe643b4_1967_image_6.png"
 target="_blank"&gt;&lt;img src="http://10rem.net/media/81826/Windows-Live-Writer_aaeffbe643b4_1967_image_thumb_2.png" width="520" height="396" alt="image" border="0" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see that I have a number of SPDT and DPDT where the
plans call for SPST and DPST switches. I simply couldn't find a
decent price on the latter, and just substituted the double throw
switches. I'll wire them as though they were ST.&lt;/p&gt;

&lt;p&gt;I decided to have all the intra-panel wiring gray. I'll use
other color wires for connecting to the board, but the wires on the
panel are easy to trace by eye (I know, famous last words).&lt;/p&gt;

&lt;p&gt;Before I can do too much more with the front panel, I need to do
the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fabricate and install a few brackets to hold the grounded
aluminum shield in place. Ray did this with the &lt;a
href="http://www.musicfromouterspace.com/index.php?MAINTAB=SYNTHDIY&amp;amp;PROJARG=SOUNDLABMINIMARKII/page6.php&amp;amp;VPW=1521&amp;amp;VPH=1094"&gt;
Mark II build&lt;/a&gt;, and I really like the idea.&lt;/li&gt;

&lt;li&gt;Create a few LED holders (also like Ray did on the Mark
II)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Mark II is Ray's latest creation. Being able to incorporate
some of the ideas from that into the Sound Lab Ultimate is
fortunate. I'll do the same with the expander and the Mark II, both
of which are waiting on my desk to be part of this one large
synthesizer.&lt;/p&gt;

&lt;p&gt;Oh, and tried out some new solder today: the recommended one
from Kester. It smokes a lot more, but seems to let out less flux.
Folks seem to swear by it, but I don't see a lot of difference
right now. We'll see once I use it for component soldering.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/18InE_7OpsSoqNZ5uZNdJyJ-Lu4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/18InE_7OpsSoqNZ5uZNdJyJ-Lu4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/18InE_7OpsSoqNZ5uZNdJyJ-Lu4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/18InE_7OpsSoqNZ5uZNdJyJ-Lu4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=65hSh0IzLII:VYpYEzZ8Ue4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=65hSh0IzLII:VYpYEzZ8Ue4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=65hSh0IzLII:VYpYEzZ8Ue4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=65hSh0IzLII:VYpYEzZ8Ue4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=65hSh0IzLII:VYpYEzZ8Ue4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=65hSh0IzLII:VYpYEzZ8Ue4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=65hSh0IzLII:VYpYEzZ8Ue4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/PeteBrown?a=65hSh0IzLII:VYpYEzZ8Ue4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/PeteBrown?i=65hSh0IzLII:VYpYEzZ8Ue4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeteBrown/~4/65hSh0IzLII" height="1" width="1"/&gt;</description><feedburner:origLink>http://10rem.net/blog/2012/01/08/mfos-synth-7-front-panel-update-knobs-and-started-wiring</feedburner:origLink></item></channel></rss>

