Scott Hanselman

Hanselminutes Podcast 30 - Outlook Add-Ins and Personal Productivity Enhancers

August 25, '06 Comments [4] Posted in Podcast
Sponsored By

My thirtieth Podcast is up. This episode is about 3rd party add-ins for Outlook that can be used to greatly enhance your productivity (and get your Inbox to zero messages!)

We're listed in the iTunes Podcast Directory, so I encourage you to subscribe with a single click (two in Firefox) with the button below. For those of you on slower connections there are lo-fi and torrent-based versions as well.

Subscribe: Feed-icon-16x16 Subscribe to my Podcast in iTunes

This show was FULL of links, so here they are again. They are also always on the show site. Do also remember the archives are always up and they have PDF Transcripts, a little known feature.

We talk about three main Outlook-Addin in this show, Speedfilter, Taglocity, and ClearContext.

  • UPDATE: ClearContext has emailed me with this great information for folks:
    • "Tell your listeners to use the following coupon receive $15 off the purchase price: ZEN15 All purchases made between now and our v3 release date will receive a complimentary upgrade to 3.0 at no extra cost.  This coupon is good through 11/1/2006."
      • Office 2007 – our current product (v2.0.6) works well with 2007.  That said, we’re currently beta testing 3.0 of the product which is intended to support 2007.  We have posted some screen prints of our 2007-specific features here.
      • Additional v3 Enhancements – in addition to our "Made for 2007" features we have implemented some UI enhancements that I think you will find interesting.  In particular:
        - We now have an Unsubscribe from Thread feature that works much like Omar's ThreadKiller
        - We have implemented an advanced Topic Selector UI that makes it easier to assign Topics and file
        - We also have built in a Topic Query on Send function that allows customers to assign Topics as they send messages, which in turn can be used to move sent email from the Sent Messages folder to their respective Topic folders.
        More detail on the 3.0 release can be found here
      • If any of your listeners are interested in checking out the beta of 3.0, drop us a note at beta@clearcontext.com
  • The folks at Taglocity have offered this special 25% ($10) off coupon code for Hanselminutes listeners- "ZEN4647015965" - and it's good until the end of September.
    • UPDATE: "Hi Scott - Thanks for the review of Taglocity. As the 'new kid on the block' it's good to see some healthy competition in this market. So in that spirit, we'll match any other vendors coupon offer - just use the coupon ZEN15 from today and you'll get $15 off the purchase price of $39 for Taglocity Pro! That's a big saving when compared to the 55 dollars others are costing..."

We'll post any additional coupons as they show up. Enjoy!

Links from the Show

Speedfiler (hmw)
David Allen (Getting Things Done)
GTD with OneNote 12 (hms)
Taglocity (hmy)
Offical GTD Addin (no OL2007) (hmu)
Scrial Consistancy (hmr)
ClearContext (hmt)
GTD in Outlook 2007 - Omar (hmo)
Installpad (hmx)
Search vs. Filing vs. Tagging (hmz)
GTD in Outlook 2007 - Simon (hmp)
Write your own Outlook Add-in (hn0)
Time Management in Outlook 2007 (hmq)
GTD Command Line (hmv)

NEW COUPON CODE EXCLUSIVELY FOR HANSELMINUTES LISTENERS: The folks at XCeed are giving Hanselminutes listeners that is Coupon Code "hm-20-20." It'll work on their online shop or over the phone. This is an amazing deal, and I encourage you to check our their stuff. The coupon is good for 20% off any component or suite, with or without subscription, for 1 developer all the way up to a site license.

Our sponsors are XCeed, CodeSmith Tools, PeterBlum and the .NET Dev Journal. There's a $100 off CodeSmith coupon for Hanselminutes listeners - it's coupon code HM100. Spread the word, now's the time to buy.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

  • The basic MP3 feed is here, and the iPod friendly one is here. There's a number of other ways you can get it (streaming, straight download, etc) that are all up on the site just below the fold. I use iTunes, myself, to listen to most podcasts, but I also use FeedDemon and it's built in support.
  • Note that for now, because of bandwidth constraints, the feeds always have just the current show. If you want to get an old show (and because many Podcasting Clients aren't smart enough to not download the file more than once) you can always find them at http://www.hanselminutes.com.
  • I have, and will, also include the enclosures to this feed you're reading, so if you're already subscribed to ComputerZen and you're not interested in cluttering your life with another feed, you have the choice to get the 'cast as well.
  • If there's a topic you'd like to hear, perhaps one that is better spoken than presented on a blog, or a great tool you can't live without, contact me and I'll get it in the queue!

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Performance of System.IO.Ports versus Unmanaged Serial Port Code

August 25, '06 Comments [8] Posted in Programming
Sponsored By

IrboardThis is obscure, but then, what do I end up blogging about that isn't obscure? I wish I knew why this stuff keeps happening to me.

I'm trying to do a little work with an external Infrared Transmitter from Iguanaworks connected to a 9-pin serial port.

I'm trying to pulse the IR to emulate a Sony Remote Control.

I'm using the new System.Diagnostic.Stopwatch class in .NET (a wrapper for the Win32 QueryPerformanceCounter API) that uses Ticks for its unit of measurement. On my system the Frequency was 2992540000 ticks per second.

The Sony remote I'm trying to emulate uses a 40kHz frequency, so it wants to flash the LED one cycle once every 1/40000 of a second. That means every 74814 ticks or every 25µs (microseconds are 1/1000000 of a second.)

I'm trying to send a header pulse of 2.4ms in length and I need to cycle the LED once every 25µs. I turn it on for 8µs and turn if off for 17µs. That means it will cycle 96 (2400µs) times for the header, 24 (1200µs) times for a space or zero, and 48 (600µs)times for a one. An image from San Bergmans illustrates:

The Iguanaworks IR uses DTR (Data Terminal Ready) to turn on the IR LED.

I've started with managed code, because I'm a managed kind of a guy. I started using System.IO.Ports like this:

public class ManagedIRSerialPort : IIRSerialPort

    {

        SerialPort port = null;

 

        public ManagedIRSerialPort(string portString)

        {

            port = new SerialPort(portString);

            port.RtsEnable = true; //needed for power!

            port.BaudRate = 115200;

            port.StopBits = StopBits.One;

            port.Parity = Parity.None;

            port.DataBits = 7;

            port.Handshake = Handshake.None;

        }

        public void Open()

        {

            port.Open();

        }

 

        public void On()

        {

            port.DtrEnable = true;

        }

 

        public void Off()

        {

            port.DtrEnable = false;

        }

 

        public void Close()

        {

            port.Close();

        }

    }

But I just couldn't get it to cycle fast enough. Remember, I need the header to take 2400µs total. In this screenshot, you can see it's taking an average of 30000µs! That sucks.

Managed

So I futzed with this for a while, and then Reflector'd around. I noticed the implementation of set_dtrEnable inside of System.IO.Ports.SerialStream was WAY more complicated than it needed to be for my purposes.

//Reflector'd Microsoft code
internal
bool DtrEnable

{

      get

      {

            int num1 = this.GetDcbFlag(4);

            return (num1 == 1);

      }

      set

      {

            int num1 = this.GetDcbFlag(4);

            this.SetDcbFlag(4, value ? 1 : 0);

            if (!UnsafeNativeMethods.SetCommState(this._handle, ref this.dcb))

            {

                  this.SetDcbFlag(4, num1);

                  InternalResources.WinIOError();

            }

            if (!UnsafeNativeMethods.EscapeCommFunction(this._handle, value ? 5 : 6))

            {

                  InternalResources.WinIOError();

            }

      }

}

All I figured I needed to do was call the Win32 API EscapeCommFunction to set the DTR pin high. One thing I learned quickly was that calling EscapeCommFunction was 4 times faster than calling SetCommState for the purposes of raising DTR.

public class UnmanagedIRSerialPort : IIRSerialPort

{

    IntPtr portHandle;

    DCB dcb = new DCB();

 

    string port = String.Empty;

 

    public UnmanagedIRSerialPort(string portString)

    {

        port = portString;

    }

 

    public void Open()

    {

        portHandle = CreateFile("COM1",

              EFileAccess.GenericRead | EFileAccess.GenericWrite,

              EFileShare.None,

              IntPtr.Zero,

              ECreationDisposition.OpenExisting,

              EFileAttributes.Overlapped, IntPtr.Zero);

 

        GetCommState(portHandle, ref dcb);

        dcb.RtsControl = RtsControl.Enable;

        dcb.DtrControl = DtrControl.Disable;

        dcb.BaudRate = 115200;

        SetCommState(portHandle, ref dcb);

    }

 

    public void On()

    {

        EscapeCommFunction(portHandle, SETDTR);

        //dcb.DtrControl = DtrControl.Enable;

        //SetCommState(portHandle, ref dcb);

    }

 

    public void Off()

    {

        EscapeCommFunction(portHandle, CLRDTR);

        //dcb.DtrControl = DtrControl.Disable;

        //SetCommState(portHandle, ref dcb);

    }

 

    public void Close()

    {

        CloseHandle(portHandle);

    }

 

    #region Interop Serial Port Stuff

   
    [DllImport("kernel32.dll")]

    static extern bool GetCommState(IntPtr hFile, ref DCB lpDCB);

 

    [DllImport("kernel32.dll")]

    static extern bool SetCommState(IntPtr hFile, [In] ref DCB lpDCB);

 

    [DllImport("kernel32.dll", SetLastError = true)]

    public static extern bool CloseHandle(IntPtr handle);

 

    [DllImport("kernel32.dll", SetLastError = true)]

    static extern bool EscapeCommFunction(IntPtr hFile, int dwFunc);

   
    //Snipped so you don't go blind...full file below!

    #endregion

}

Here's the NOT COMPLETE (Remember, it just does DTR) Unmanaged Serial Port class. Thanks PInvoke.NET for the structures to kick start this)!:
File Attachment: UnmanagedIRSerialPort.cs (10 KB)

As you can see I've got it abstracted away with a common interface so I can switch between managed serial and unmanaged serial quickly. I ran the same tests again, this time with MY serial port stuff:

Unmanaged

Sweet, almost 10x faster and darn near where I need it to be. However, it's not consistent enough. I need numbers like 2400, 600, 1200. I'm having to boost the process and thread priority just to get here...

 previousThreadPriority = System.Threading.Thread.CurrentThread.Priority;

 System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Highest;

 System.Diagnostics.Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

...and undo it with...

 System.Threading.Thread.CurrentThread.Priority = previousThreadPriority;

 System.Diagnostics.Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Normal;

...and that's just naughty.

At this point, it's close, but I'm wondering if it's even possible to flash this thing fast enough. I'm at the limit of my understanding of serial ports (Is DTR affected by Baud Rate? Is 115200 the fastest? Would this be faster in C++ (probably not), or is there a faster way to PInvoke?)

Any ideas?

IrimageINTERESTING NOTE: Remember, you can't see IR (it's Infrared, not in our visible spectrum) but you can see it if you point it at a Webcam, which is what I've been doing to debug.

ANOTHER ASIDE: This is a uniquely high-power transmitter, that charges up a capacitor in order to provide a range of up to 10-meters. However, it requires a few minutes to charge up. I had no trouble getting output from it using Winlirc (the only officially supported software) but when I used my application, the transmitter would peter out and eventually go dim.

I fought with it for a while, then decided to RTFS (where "S" is "Schematic). The board layout is here. Notice that the RTS (Serial Port Ready-To-Send) Pin 7 goes straight to VIN. Duh! <slaps forehead>. They are sipping power off the Ready To Send pin and I'm not setting that pin hot.

port = new SerialPort(portString);
port.RtsEnable = true; //needed for power!
port.BaudRate = 115200;
port.StopBits = StopBits.One;
port.Parity = Parity.None;
port.DataBits = 7;
port.Handshake = Handshake.None;

So, if you ever find yourself using the High-Power LIRC Transmitter/Receiver in an unsupported way writing your own program, remember to set RTS high or you won't get any power.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Flip the endian-ness of a long in C#

August 25, '06 Comments [20] Posted in Programming
Sponsored By

Programming challenge:

Write me a function with this signature in C#:

public (unsafe?) long Reverse(long i, int bits)

...to flip the endian-ness (LSB/MSB) of a long, but just the # of significant bits specified.

Example, if the input is 376, with bits=11, the output is 244 (decimal, base 10).

376 = 00000101111000
244 = 00000011110100

Example, if the input is 900, with bits=11, the output is 270.

900 = 00001110000100
270 = 00000100001110

Example, if the input is 900, with bits=12, the output is 540.

900 = 00001110000100
540 = 00001000011100

Example, if the input is 154, with bits=4, the output is 5.

154 = 00000010011010
5   = 00000000000101

And make it FAST...;)

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Citizen Mo

August 25, '06 Comments [11] Posted in Musings
Sponsored By

A big (and long and exhausting) day for the Hanselman family. My wife has just today become a citizen! She took her Civics test (Quick! What amendments to the Constitution specifically address voting rights?) We attended the ceremony this afternoon.

Her thoughts from when this process started (and the previous decade) are on her blog. She says she'll get another essay or two up soon. Congrats to the wife!

UPDATE: Mo has add a new entry to her blog entitled "American By Choice."

RedactedCIMG5734CIMG5715

As an interesting side note, Mo has a featured article in this month's issue of Multilingual Living Magazine (TOC PDF - subscripton required - $12 a year to subscribe) on how we met!

 

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

August 2006 - My spare time

August 24, '06 Comments [11] Posted in Musings
Sponsored By

For some reason, I just thought this screenshot was funny at 1:05AM. Something I'm working on in my spare time.

Irmadness1

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.