Monday, September 19, 2011

First Thoughts Regarding Windows 8

With all the hubbub around Microsoft's BUILD conference and the developer preview of Windows 8, I thought I'd grab a copy to check it out. This is what I found; it's going to be pretty short...

Installation

I downloaded a copy of Windows 8,[1] created a new machine in VirtualBox, attached the downloaded ISO to the CD and booted the machine.[2] It started the install OK and then hung part way through. After waiting awhile, I powered off the VM. On restart, it tried to do an install restart but this time give me a failure message. So I powered it down again and then back up. This time during the restart it showed me the partitions on the drive. I deleted all the previously created partitions and it finally ran through the install to the end. When it finished, it did the typical Windows reboot but hung during the reload. I turned the machine off, detached the ISO image from the CD and turned it back on. This time it booted just fine. It asked me a couple of standard questions, like user name and password and took me to a phone/tablet looking screen.

Cursor problems

At this point the cursor pretty much went wonky. Yes, that's a technical term. When moving the cursor from the host OS to the Windows 8 machine, the cursor would jump to an odd place and then jump back off the guest screen back to the host. It was pretty much unusable. I tried installing VirtualBox's guest additions. The installer asked all the startup questions but then stopped when I told it to begin the actual install saying it didn't support that version of Windows. I suppose that's not too surprising. As a last ditch effort, I moved the virtual screen off my large secondary screen to the laptop's smaller main screen and all of a sudden the cursor started working correctly. At this point I'm not sure if it's a problem with VirtualBox on the secondary screen or if it's a Windows 8 incompatibility or perhaps some of each. In any case, the cursor problem doesn't show up on the main screen and the mouse/keyboard capturing works as I'd expect; i.e. once the guest OS has control, you have to hit the Host button to get back out.

Operation

Once the cursor started working correctly, I played around with a bit. IE10 works pretty much like you'd expect a browser to although the UI is somewhat different in keeping with the Metro design. The biggest thing is the address bar is at the bottom of the screen. Other than that, it worked OK. Google returned search results. GMail showed me my mail. However, when I went to YouTube, it needed the Flash plug-in. I knew the Metro version of IE didn't support plug-ins, so I wasn't sure what would happen. But everything worked, sort of: clicking the link took me to Adobe's web site, downloading and installing worked just fine. Yet when I went back to YouTube, it still complained about no plug-in. I went to the desktop (one of the many tiles on the "start page"), clicked on the IE icon there and then navigated to YouTube. It worked. This is one of those differences between the Metro version and the desktop version. However, I had to know that going in, otherwise it would have simply looked like it didn't work. There was no indication saying the Metro version didn't support plug-ins or that the desktop version did.

I tried clicking on some of the other tiles on the start page and didn't get too far. Most of them seem to need features unique to mobile devices. Word Hunt wanted me to "bump" with a friend's device to initiate the connection. I assume that's some sort of bluetooth thing. Labyrinth simply sat there staring at me. No instructions. Clicking, click-dragging and other random character presses yielded no results. I'm guessing it wanted some sort of tilt sensor input. The last thing I tried was BitBox. I had high hopes of getting somewhere since it actually started with a mini-tutorial. My hopes were dashed on about the third step when told to do a pinch operation to continue. Um, how do you do multi-touch with a mouse?

At that point I pretty much gave up and turned the thing off. That was a bit of an adventure itself. First I tried sending the power off signal from VirualBox. This is equivalent to pressing the power button on a typical PC/Laptop. Nothing happened. I looked around a bit for a shutdown option. All I could find was logout. I ended up going to the desktop and pressing Alt-F4. That has worked since at least Windows 3.1, and it still does. I got a familiar "what do you want to do? shutdown, restart" type dialog. (I have subsequently learned there is a power button that's available after you logout.)

Opinions

My first impression after about an hour of playing with it is that it seems fairly comparable to the iPad and Android regarding user experience. (I've played around with both these about as much as I have Windows 8.) Basically there are big squares that slide around and you can click on them. The applications open in full screen mode. Shrug. I guess some people might get excited about it. To me, it seems about the same as everything else on the market.

What I find interesting about these devices is the infrastructure, development environment and community support that grows up around them. The iPad and Android ecosystems both have their strengths and weaknesses. I think it's too early to tell much about what will happen with the ecosystem around Windows 8. Will Microsoft learn from both their previous successes and mistakes, as well as those of Apple and Google, to become a market leader? Will they become another fairly equal player? Or will they become an also ran in this race?

From an internal design perspective, I like the direction Microsoft is going better than Apple or Google. Apple has a split between the desktop/laptop OS X and the mobile device iOS. Google is trying to scale the mobile/browser experience to the desktop in ChromeOS. I think both these are weak strategies.

Apple has two, separate code bases to maintain, much of which could probably be combined. I think long term this is going to cause compatibility problems much like Microsoft has had between the mobile/embedded Windows and the desktop version and more lately between WPF and Silverlight. Very similar systems with differing code bases have made the developer community pretty aggravated at times.

Google has a similar problem with the bifurcation between Android and ChromeOS. Android probably has the potential for making a pretty nice desktop OS. Give some development effort, it'd be pretty comparable, from a design perspective, as Windows 8. The high-level design documents for both would look very similar. However, Google has decided to try to expand the browser into an operating system. I've experimented with ChromeOS and it works acceptably if all you want to do is available on the web. But frequently I want to use my computer off-line and the whole ecosystem is not up to this task. Perhaps in 5 years everything will be a web app. I doubt it though.

Microsoft is pairing down the core of Windows and then placing different layers on top of it. From a design perspective this seems like the best long term solution. It has always appeared that desktop Windows was the first-class citizen and the embedded/phone OS by the same name (which only had passing resemblance to its big brother) was second-class. By putting a desktop UI on the same core as the mobile device UI, they can both become equal products, just for different markets. As a desktop developer, the biggest fear I have is, instead of raising the mobile UI to be equal to the desktop's, they are going to push the desktop down to second-class status. As it stands with this preview, the first and primary experience is the Metro look and feel. It works great on a tablet. I have yet to see it work well on a desktop. Without major changes to the current experience, I predict Windows 8 will work well on mobile devices but will not be adopted in the desktop world. Hmm, will Windows 8 make the year of the Linux desktop finally a reality?

Updates

The above all happened on Friday. Monday morning, I started the Windows 8 virtual machine. It hung during boot. I turned it off and tried again. Again it hung (at a different place) during boot. I deleted the image. Too much hassle at this point.

Monday evening: I created a VirtualBox machine hosted on my MacBook Pro. Pretty much the same configuration as I had on the other one hosted in Windows 7: 50GB hard drive with about 2.5GB of memory. It installed perfectly the first time and so far has worked flawlessly. (Well, other than the weirdnesses of a touch based interface driven by a keyboard/mouse.)


2. This is not intended to be a tutorial. There are already good tutorials to install onto a hard drive and into a virtual machine available.

Thursday, July 14, 2011

LINQ and set notation

So I learned something today.

It's been a long time since I had any classes dealing with sets. I vaguely remember discussions including Venn diagrams and odd notation that didn't have any relevance to any other context that I was familiar with, but they were also pretty cool to study and get to know. However, they're the types of things that have a highly technical, mathematically rigorous side to them and also the day-to-day intuitive side that I use. Not needing it on a regular basis, the finer points of set algebra quickly sink into the background and aren't easily recalled.

Intersection
Today I needed to do some set manipulation. I knew LINQ had some set related methods in it, such as Intersect which gives only the items that are in both lists.

Union
And I knew it had the Union that gives all the items in both lists, without duplicates.

Needing to find the differences between two lists, I suspected there was something to do that easily. I had two string lists and needed the items from both lists that were only in one of the two lists. In other words, I needed the inverse of Intersect. First I looked at the options in the code completion list. Nothing jumped out at me. I couldn't recall the technical name so I did a web search for "LINQ intersect inverse" and found the Except method. The description sounded promising but, when I tried it, I didn't get what I expected. It only gave the things that were in the first list but not in the second list. In other words, it did not include the things in the second list that weren't in the first. Figuring the people who wrote these methods probably knew something about what they were doing, I went digging a little deeper.

The next web search was for "set intersect inverse" that led me to a Wikipedia page on set intersection. Scrolling to the bottom "see also" section, I saw Complement. Ah-ha! That rang a bell from the distant past. Clicking on that link confirmed that Complement was in fact the difference between two sets.

RelativeComplement
And this is where I started to learn something new: there are multiple types of differences in set theory. In general, the Complement refers to things not in a given set. First, there's the relative complement as implemented by LINQ's Except method. This gives the things from one list that are not in the other list. For example, if list1 = new List<string> {"a", "b", "c"} and list2 = new List<string>{"b", "c", "d"} then list1.Except(list2) will return "a".

AbsoluteComplement
Second, there's the absolute complement. This is the universe of all things not in a given set. Hopefully it's obvious that this can't be implemented in software.

SymmetricDifference
Finally, there is the symmetric difference. This is the name of what I needed. It's the list of things that are in only one of two given sets. Thinking in terms of set operations, it's the relative complement between the union of the sets and the intersection of the sets. In LINQ terms it's list1.Union(list2).Except(list1.Intersect(list2)). This got me what I want.

Now that I had a technical term to search on, out of curiosity I tried "symmetric difference LINQ". (It's always easier to find what you're looking for when you know the proper keywords.) This returned a link to a StackOverflow question that not only gave the answer I came up with but also pointed out there's a SymmetricExceptWith method on the HashSet class.

Curiosity now drove me to do a quick benchmark. Knowing LINQ has never been a speed demon, I assumed it probably wouldn't beat out the HashSet implementation. I threw together a quick console app that simply ran both the above LINQ query and HashSet.SymmetricExceptWith call on two short lists a million times and reported the elapsed times. I used three different types of input containers to see if that made much difference. Here's what I found...
Input typeUsing LINQUsing HashSet.SymmetricExceptWith
List<string>2.8 s1.0 s
LinkedList<string>2.9 s1.1 s
HashSet<string>2.7 s0.8 s

Friday, July 8, 2011

Local procedures from Delphi in C#

Pascal has this nifty feature where you can declare procedures inside of procedures. Something like:
procedure procA

    procedure procB
    begin
        // procedure B code here
    end;

begin
    // procedure A code here calling procB
end;

It's not the type of thing I used a lot, but there were times where it came in handy. It was a nice thing to have in the tool belt even if it wasn't pulled out too often. A couple times I have wanted to do this in C# and have resorted to other means.

Today while reading an article by John Cook about C++, I realized this is trivially easy to do in C#: simply use named lambdas. It's one of those things that's so obviously simple and easy, I don't know why it didn't occur to me before.

So, the above Pascal code could be written in C# like so:
public void procA()
{
    Action procB = () => 
        {
            // procedure B code here
        }

    // procedure A code here calling procB()
}

Wednesday, June 8, 2011

Stepper motor references

Recently I have been playing around with stepper motors on my Arduino. (An overview of one project is on my photography blog.) Here's a list of online resources I've found helpful in my education:

How to wire a stepper motor has a good overview of the different types of steppers and how to identify the wires on an unknown motor.

Circuits for Unipolar motors on the Arduino site uses a ULN2003 or ULN2004 chip. One circuit has a couple resistors and a diode to allow two pin control of the motor. The other uses only the chip but requires four pins. I built the two pin configuration and it worked flawlessly. Note: the ULN2003 will only source up to 500mA. Higher current motors will cause its magic smoke to escape.

Stepper motor controller circuit uses two logic chips, four each of resistors, transistors and diodes and is controlled by two pins. Since it uses discrete components, it's easily modified for higher current motors than the ULN2003/ULN2004 can support. I haven't built this one, but have the components to do so in the future.

The 28BYJ-48 stepper motor is a really cheap, high resolution stepper motor that comes in both 5V and 12V ratings. Not sure how reliable it is, but so far in my experiments it has worked well. It has a 64:1 reduction gear head built into it, so it is pretty high torque for the current draw (I think it's spec'd to be around 250ma) and a whole lot of steps per revolution.

Stepper Motors and Control is a good overview tutorial. It includes logic charts for different ways of driving stepper motors for different purposes: lower power, higher torque and higher number of steps. It also talks about identifying different types of steppers and how to select a current limiting resistor.

I'll update this list if I find anything else that seems like it'd be good to have here.

Thursday, May 26, 2011

There and back again: A Cursor's tale

I've been working on UI code recently and have run into this quite a bit:
Cursor = Cursors.Wait;
SomeLongRunningTask();
Cursor = Cursors.Default;
Pretty straight forward code. I see this type of thing a lot, not just in the C# code I'm working on now, but I've seen this in the past. In other languages. On other platforms. It's a common practice. The problem is it only works in some cases.

This will have problems if any method in the "long running task" does the same thing. The cursor will be set back to default prematurely. Of course, this is easily solved by saving the old value prior to setting the new one.
var oldCursor = Cursor;
Cursor = Cursors.Wait;
SomeLongRunningTask();
Cursor = oldCursor;
This is an improvement but will still fail if an exception is raised. This can be fixed with a try/finally.
var oldCursor = Cursor;
Cursor = Cursors.Wait;
try
{
    SomeLongRunningTask();
}
finally            
{
    Cursor = oldCursor;
}
Ok. So now we have some code that works reasonably well. The issue now is one of code maintainability and clarity. Every method that needs to change the cursor needs to add nine lines before it can do any work of its own. It's nine lines where bugs could hide. It's nine lines obscuring the real purpose of the method. There's got to be a better way.

Way back in my Delphi days, I had a small class which handled this chore for me. The constructor took a parameter containing the new cursor. The current cursor was saved in a class field, the cursor was changed and the constructor finished. The destructor simply set the cursor back to the saved value. In that environment, interfaces were reference counted and destroyed when the reference went to zero. The compiler took care of all the bookkeeping automatically. So I could create an instance of this class, store it in a local variable and, when the variable went out of scope, the object was destroyed, resetting the cursor. It worked really well. One line to change the cursor to whatever I wanted and it automatically reset to the original value when done. Pretty sweet.

Unfortunately, C# does not have any deterministic way of handling object lifetimes. This is one of my biggest frustrations with the language. The closest thing we have is the hack that is the using statement. Since this is the best we have, I have put together a class, shown below, similar to the one I had before. The constructor takes the new cursor value and control whose cursor should be changed, saves the current one and, in the Dispose method, resets it back. Now we can have three simple lines with one code block rather than the nine lines with two blocks. It's a big improvement although still not the single line like I'd prefer.

In use, it looks like this:
using ChangeCursor(this, Cursors.Wait)
{
    SomeLongRunningTask();
}
Arguably, this is a bit cleaner than even the first code snippet we started with.

Since this takes a FrameworkElement, it's WPF specific. It'd be easy enough to change the type to work with WinForms, if needed. The same technique could be used to handle other things where a state needs to be set to one value and then reset when some unit of work is done. For example, if using TreeViews with BeginUpdate/EndUpdate pairs.

Hope this helps someone.
using System;
using System.Windows;
using System.Windows.Input;

namespace CursorResourceProtection
{
    public class ChangeCursor : IDisposable
    {
        private FrameworkElement Context { get; set; }
        private bool Disposed { get; set; }
        private Cursor OriginalCursor { get; set; }

        public ChangeCursor(FrameworkElement context, Cursor newCursor)
        {
            Disposed = false;
            Context = context;
            OriginalCursor = context.Cursor;
            context.Cursor = newCursor;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(Disposed)
                return;

            Context.Cursor = OriginalCursor;
            Disposed = true;
        }

        ~ChangeCursor()
        {
            Dispose(false);
        }
    }
}

Wednesday, May 11, 2011

Non-int array indexes from Delphi in C#

In Delphi, array indexes can be any type that resolves to an integer, not just integers. So for example, enum and bool types can be array indexes. This can be handy in many situations to reduce a if-then or switch construct to a simple assignment. A simple, contrived example:


MyEnum = (item1, item2, item3);
...
function enumToString(value: MyEnum): string
begin
switch(value)
case item1: result = "Item one";
case item2: result = "Item two";
case item3: result = "Item three";
end;
end;
...
SomeLabel.Caption = enumToString(value);
...

becomes something like this:


MyEnum = (item1, item2, item3);
enumToString[MyEnum]: string = ("Item one", "Item two", "Item three");
...
SomeLabel.Caption = enumToString[value];
...
Not only does it reduce code, it also reduces possible bugs. Consider what happens when a value is added to MyEnum. The first example will simply return an empty string creating a possible silent failure that hopefully will be caught when tests are run. The second will generate a compiler error, forcing the programmer to intentionally decide what to do.

In C#, array indexes must be one of the four integer types: int, uint, long or ulong. I really miss the ability to use bools and enums. While lamenting this lack as I looked at some code today similar to the original switch statement, I realized I could use a generic dictionary. The new code looks like this:

MyEnum = (item1, item2, item3);
enumToString = new Dictionary = {{item1, "Item one"}, {item2, "Item two"}, {item3, "Item three")};
...
SomeLabel.Contents = enumToString[value];
...
On one hand, it is a bit more wordy than the Delphi array; on the other, it's clearer how things are associated in the initializer. The biggest drawback is it doesn't have the compiler error when things are added to the enum. This is mitigated a bit by the runtime exception generated by a missing key; it's not quite as silent as just returning nothing in the original code. However, it still depends on good test coverage to find it.

Friday, May 6, 2011

Arduino notebook: 16x2 LCD display (Part 2)

How to change the default behavior

Prologue

My last article in this series talked about why I chose Sparkfun's Serial Enabled LCD display kit and how to build it. One of the reasons it caught my eye was because it uses an Arduino as the controller for the display. I figured it was pretty busy doing nothing most of the time and thought it could be used for other purposes in addition to driving the display. Upon further investigation, it turns out I was right.

Nicole, a friend of mine, recently e-mailed me about a photography project she was interested in doing but didn't want to spend the money for a professional rig to do some of the things involved. She asked if I had any ideas. I'd already given some thought to the problem, the investigation of which led me to the Arduino platform in the first place. This project was one I had stewing on the back burner for quite a while and it was now time to turn up the heat on it.

One of the requirements was to be stand-alone. It had to allow for some user configuration at the time of use in battery mode, without any other devices attached. This ruled out the obvious easy solution of setting the parameters via USB through a computer. Also, it involved controlling a stepper motor. I immediately thought of the LCD kit. I knew I would at least use it for the display, and hopefully some toggle switches. I had a distant hope I could also use it for the motor control. Since this was going to be a pretty permanent build, I immediately ordered another LCD to use specifically for this project.

After getting a new display on the way, I pulled out my first kit to take a look at it. Sure enough, it had a handful of empty holes on the PCB labeled with both digital and analog pin assignments. Cool. It had enough extra pins to accomodate everything I needed to do. So, I started work on the rest of the project while I waited for the LCD to arrive. (The other details of this project I'll write about in future articles here and on my photography blog Hooked On Light.)

First thing after getting the new kit, I assembled it. It went much faster this time with no of the frustrations I experienced on the first one. It actually worked the first time I applied power.

One of the biggest things I did differently was to use ribbon cable between the display and controller boards. In some ways this made things easier and in other ways it was harder. I think on the next project I'll probably put the header pins that come with the kit in one board and get a socket to solder onto the other board. That will give me a cleaner build like the first one, but with the ability to separate the boards for easier access like I have with the ribbon cable on the second one.

The web site to order the kit indicates the firmware can be reprogrammed with an FTDI Basic Breakout board. I had ordered one with the first kit, but hadn't had a chance to use it prior to this project. Knowing I needed to use this, I also purchased some 90 degree header pins from my local electronics parts supplier and soldered them into the holes on one end of the board designed for the purpose. This allowed the FTDI board to plug onto the controller board, providing a plug for a USB cable to be plugged in.

Now I started looking for instructions on how to actually reprogram the thing. The order page indicated you needed to change a setting in the Arduino IDE and referenced the github page for further instructions. Well, the github page had no other instructions on programming the thing. All it talked about was how to use the board through the serial interface. The software for the firmware was also hosted there. Besides the one sentence on the order page, I couldn't find any other instructions either on those two sites or anywhere else via web searches on how to reprogram this kit.

Reprograming the kit

I figured, no guts, no glory and decided to experiment some. I downloaded the source code from github, loaded it in the Arduino IDE and made a simple change to the splash screen text. Since the splash screen is the first thing you see, I thought this would be an easy way to verify if my changes worked or not. In the IDE, as instructed on the order page, I changed the target machine to Arduino Duemilanove or Nano w/ ATmega328 and hit the upload button.

It compiled.

It uploaded.

And when it reset after the upload, there was my new splash screen text.

Amazing. That was all there was to reprogram the kit's default software. The reason I couldn't find any other instructions was, there weren't any other instructions needed.

Epilogue

After this success, it was simply a matter of changing things to do what I needed it to do for this project. Essentially, I ripped out everything the existing software does and replaced it with what I needed. There are a few lines to initialize the LCD and one function to write characters to the screen that are the same, but everything else is completely new.

Now that I've found how easy this is to repurpose, I think I'll probably use it for other projects in the future too. It's an easy way to get an entire Arduino system up and running in a clean package with a simple user interface and minimal external support circuitry needed.