Thursday, July 14, 2016

Printing with PC Plus Polycarbonate Filament on a Maker Select v2

Several months ago I purchased a Maker Select 2.  I believe my quote, most recently, was “It’s been a few months and the 3D printer is still the coolest thing I’ve ever owned.”  It’s also, sometimes, one of the most frustrating.

My current project is printing a multi-extruder printer (aiming for 4, but starting with 2) using a mash-up of a few different designs and I’m working on a Bowden extruder.  Since I had the need to print some very strong parts for another project, I picked up some PC-Plus after a bit of research.

This stuff is stronger than I’d imagined

Since I’ve had, now, four failed prints with this material, I’ve had an opportunity to test the physical properties.  My tests indicate the most optimistic of the marketing materials is spot on.  My PLA+ extruder body was able to be cracked pretty easily with a rubber mallet on my cement basement floor.  The ABS and Nylon parts were pretty solid but one of the components was designed in such a way that the flexibility of those filaments was going to be a problem. 

This stuff was hard to break with a full-on metal hammer.  It’s far less flexible than ABS or Nylon and the point it which it will flex is (in my unscientific estimation) about twice the pressure it takes to completely snap a PLA print.  I’ll admit, it was kind of fun hammering the crap out of the part seeing how hard I’d have to hit it to get it to crack.  About the only bad thing I can say is that it did dent pretty well but it dented at well beyond the point other parts would have broken.

This material is the stuff that profanity is made out of

I’ve yet to run into a filament that is more difficult to print properly with.  I’ve printed with PETT, PETG, T-Glase, ABS, PLA, PLA+.  It’s safe to say that it takes all of the difficulties of each of these and combines them into one magnificent package.  It’s very temperamental with regard to moisture as evidenced by the fact that it shipped in a vacuum sealed pack with a zip-lock seal for easy re-packing.  Luckily we run the air conditioner here like it’s the arctic.

It curls.  No, I mean, like 80s perm psychotic curls.  They used to ship it with a square of BuildTak.  The manual and nearly everywhere you read says it is *required*.  Thankfully, it’s not if you’re creative.

To get that strength, you need to run your hot end at 260 degrees or higher (that’s as high as the Maker Select 2 goes, so that’s what I’m stuck with) and you need to print slowly (details below).

The BuildTak Option

The Maker Select v2 shipped with a BuildTak clone of some kind attached to the metal heated bed.  I say “Of Some Kind” because this was one of the first things I removed from the printer since the PLA and Nylon I was printing with seemed to just bounce off of the surface of whatever this 3M product was.  After trying a few things that worked well for me in the past, I gave up and purchased 3 sheets of BuildTak.

Let me just say: I hate this stuff.  Perhaps that’s strong sentiment borne out of hours of frustration with this filament more than it is a scathing rebuke of BuildTak, but I’ll never buy it again. 

The first problem is that it works a little too well.  PC-Plus sticks to it like super glue and removing the part rips the surface off of the BuildTak.  It’s difficult enough getting the bed leveled perfectly to the factory recommendations but now you have to figure out just how higher you need to level it in order to get the part to stick properly, but not too well.  That’s assuming the BuildTak doesn’t just pull itself right off of the glass due to the heated bed weakening the adhesive.  Since I purchased the 127mm by 127mm sheets, I was printing the part right on the edge of the BuildTak and that’s exactly what happened to my second print. 

Second, and this might be a matter of me improperly cleaning the surface, but I was only able to use a non-ripped sheet twice.  After that, it simply stopped sticking no matter how close I printed. 

Third, geez this stuff is expensive!  Three of those tiny sheets was almost $10.00.  The idea that I’d get about 6 prints for that price didn’t sit well with me.

Lastly, I prefer to print directly on the glass because it makes the part look nice.  BuildTak has a rough surface and it shows up in the finished product.  That wasn’t so important for these parts (just looking at my printer with gray, green, clear, pink (!) and black parts indicates I don’t care what it looks like, I just want it to be durable and functional).

 

(Mostly) Ignoring the Manual

I’ll be the first to say that much of the manual’s recommendations worked fine except for the 0.33mm gap between the raft and the part (which resulted in a “3D printed turd” stuck to the hot end since it wouldn’t adhere to the part below).  I’d imagine part of that had to do with the fact that I can’t get it up to a higher temperature with this printer.

I really hate printing rafts.  Watching the filament burn down as it drops a surface on top of a surface that should be sticking already only to throw that part in the trash (or if it’s ABS, store it to make more glue) is wasteful.  Then there’s separating the part from the raft, which, since I rarely print rafts, I haven’t quite gotten right yet.  It’s either sticking so hard that I have to risk breaking the part to remove it or it fails to stick at all.

I was able to get it to stick perfectly, though by throwing out most of the recommendations and using a few settings that I had used with T-Glase and other finicky materials.

First, clean the hell out of your bed (91% alcohol does the trick).  Level your bed to the factory recommendations and make sure it’s absolutely perfect.

Heat up the extruder to 260 and clean any filament from the last seven failed prints off of the hot end so they don’t become a magnet for the stuff it’s already laid down.  This stuff sticks well to virtually nothing except for itself and while printing, if you get any strings, they’ll gob up and start removing portions you’ve already printed.

Heat up the bed to 90 degrees and apply a nice layer of Elmer’s Glue Stick.  Follow that up with a reasonable amount of ABS Glue (google it, it’s easy to make).  Let everything dry.

I used a 0.1mm gap on the raft when I printed with a raft (I’ve not had to since I cracked the formula for getting this to print properly).  Slow your printing down.  I went to 40mm/s with 20mm/s for the bottom layer and outer layer.  I also stuck with a 40% fill, though this was more because the part required it.  I also used four solid layers top, bottom and sides.  It may be overkill on that, but several forum posts recommended it so I started with those settings.

If your printer goes higher than 260 degrees, try going higher.  I had layer adhesion issues under 260 but still occasionally ran into small sections that didn’t adhere properly at that temperature.  That bit about making sure the head is clean is very important.  Every one of my layer adhesion issues occurred because the head picked up a string, which picked up small bits of printed material as it went along until it got large enough to get snagged somewhere in the printed body and was deposited, causing the bed to sink slightly as the head passed over.  This resulted in a small gap in a spot on the print.  Those small gaps are enough to make a very strong part pathetically vulnerable to snapping.  I resolved most of these issues over a few prints by slowing them down to the point where the head was adequately melting any smallish gobs as it passed over them and increasing the retraction by a factor of two.  Many forum posts recommended going as high as 290 degrees, which I’d imagine would allow print faster and let gravity resolve some of the issues when gobs appear but the printer I was using only allows me to get to 260 degrees.

For tall parts, consider taking a few of those Amazon boxes apart and making an enclosure.  This will keep the temperature consistently higher while printing and reduce curling.

Using these settings, and the ABS Glue plus Glue Stick, though, made the part stuck so hard to the glass I had to use a razor blade to separate it.  There was zero curling on a part that had several little finger-like points on it (and failed to print properly on anything else with this stuff) so I’m fairly convinced this is the way to go for me from now on.  YMMV

Things that didn’t work

3D printing is often about experimentation to get the easiest process to produce consistent prints with a material.  The only thing these attempts did was consistently produce curled parts or 3D printed turds.  All of these were attempted directly on glass.

Hairspray

As is common with ABS, hairspray seems to make the curling worse.  It will stick initially, but after several layers, it’ll start to curl upwards.  If you’re lucky, the print will stick somewhere and you might have a salvageable part if you don’t care about the looks and the curling occurs on part of it that doesn’t affect its performance.  I was printing an extruder so there’s very little of it that can be off.

Glue Stick (alone)

Initially it stuck and didn’t curl as much as the hairspray did.  This might have worked were the part much smaller but on the extruder body it failed after about the 20th layer, pulling completely off of the bed.  I tried this twice and I’m fairly certain it’s not a good solution.

Elmers and Water

Performed similarly but worse than the glue stick

BuildTak after Two Prints

The surface might as well have been covered in olive oil.

That 3M BuildTak like thing that Maker Select ships with

They gave me an extra one which I put in a box since the one that it came with performed so poorly but I thought I’d give it a shot.  It worked as well as it ever has which is to say, not at all.

ABS Glue (alone)

I’ve read some forum posts from people claiming they simply applied ABS glue to the glass and were printing successfully with other materials.  Perhaps mine is too diluted or I’ve done something wrong, but it’s never worked for me even with ABS filament.  This was no exception.

I also tried mixing a few variants of these, especially the hairspray since even though it seems to encourage more curling, if it gets a good stick initially, it won’t budge with other filaments I’ve tried.  The only mix that worked was Glue Stick and ABS Glue, though to be fair, I didn’t try Elmers+Water and ABS Glue and I have a feeling this would have worked.  It’s just less convenient waiting on the Elmers to get tacky enough to begin printing.

I’d love to know what anyone else has tried or if there’s a better method/something I’m missing but it’s a relatively new filament, has lots of pain points and isn’t experimented with enough to find great information from the forums so I’ve been at a loss for any solid help (which was one of the motivations for getting off my butt and writing this).  If you’ve had success with this material using other tricks, please comment!

Many thanks!

Saturday, April 2, 2016

Sheraton, Bedbugs and how NOT to do Customer Support

Adventures in Bed Bugs
I've traveled enough to know that bed bugs are always a risk at any hotel stay. Generally, I do a pretty reasonable check of the room on arrival. When I find them, I insist on being put up in another hotel. Finding bed bugs is usually difficult. They hide well and the best approach is to look for fecal matter (little black/brown spots -- blood of past guests -- on the bedding and box springs).
Usually, I won't leave bad feedback on one of the travel sites, tweet, or otherwise publicly shame a hotel. Very few things are more damaging because people have no idea how common of a problem it actually is (if they knew, they might just stay home and skip traveling all together). And usually the property handles the situation well.  This time is different. I've never had a hotel and hotel chain so completely disregard such a serious problem.
Sheraton Lake Beuna Vista Hotel, Orlando, Florida
We failed to notice the problem until our very last day, and considering how bad it was I can only plead laziness on my part. When my wife and I arrived and saw the room adorned with bright white sheets, bedding and even comforter, we were lulled into a false sense of security. We stayed there 4 days and on the final day, my wife shot out of bed after she scratched at her leg and found the small sting had a source -- a bed bug.

It was about 8:00 AM and I had been looking forward to sleeping in a little bit after a hard week of work at a conference. That idea was instantly shattered. My wife grabbed one of the Zip Lock bags we put our toothbrushes in and captured the bugger. We brought it down to the front desk and returned to the room to get some more photos. It didn't take but a few seconds to find the second bug hanging around the head board.

Up came the mattresses. What we discovered was nauseating.


Those "fecal matter" inspections, had I bothered to do them, would have immediately had me leaving the room. On top of fecal matter, we found four bugs that were smashed under both beds' box springs. My assumption is that the infestation had been present in the room when things were being moved around and nobody in housekeeping had noticed. Considering the large, smashed, blood stains and pieces of dead bug that were very easy to see, I'm terribly disappointed that staff paid so little attention, though after my experience dealing with Starwood in general, I can't say I'm surprised. Housekeeping should be trained to identify fecal matter and other secondary evidence of the presence of bed bugs and should never have allowed a guest to occupy a room suspected of having an infestation. Had the hotel been paying any reasonable amount of attention, though (or had I), they would have seen the critters actually walking around.
Working with the hotel
The hotel staff kept our luggage and gave me a new bag to place that I could use to bring the three computers I had traveled with home. They assured me the items would be returned to me via FedEx with the clothes heat treated. They explained that the other items could not be heat treated but did not explain what would be done with them. We had to fly out that morning so I couldn't stick around long to ensure things were handled correctly so we trusted the hotel. In retrospect, I should have been less trusting.
Lesson 1: FedEx doesn't mean fast, anymore
Years ago when someone said "we'll Fedex that to you", it meant overnight. The delivery business has changed a lot--a fact I know well--but that didn't stop my mental picture of receiving my belongings in a reasonable amount of time from kicking in. I mean, obviously, these are my things and I expected to go home with them the night I returned so I assumed the hotel would understand the urgency of returning my belongings quickly. I don't travel enough to warrant buying "two of everything". The hotel sent our luggage back FedEx ground, which took a week. All of my wife's makeup was in the bag as was my shaving products. We had to buy replacements.
Lesson 2: Expect others to treat your stuff with little respect
I kind of expected my suit coat was going to need a pressing after its week-long journey. But I didn't expect my belongings to be destroyed.  Because they placed my wife's makeup, a pen, and the rest of our toiletries in an unsealed bag, we found a mix of interesting stains on many of our clothes.  My suit coat has a large black ink stain and pinkish-brownish sain from hairspray-mixed-with-pen-and-makeup.  Most of the rest of the clothes suffered similar fate.  Worse, being in an unsealed bag and not knowing what was done with those items, I didn't know if they were safe to bring in my home, so the luggage went from the porch to the shed (where it remains today).  I'm out about $500 in destroyed clothes (this doesn't include the original bill for the stay)
Customer Service in an Age Without Humans
It's been about 4 years since I've had to work with a hotel to get something like this resolved. My past experience was with a different chain, so it's possible this is related only to Sheraton, but my sense in dealing with other Customer Service related things is that customer service has suffered greatly in the age of text. My first instinct was to send a message via e-mail. Visiting Sheraton's Web site yields a contact form -- nothing I can attach photographic evidence that truly explains the severity of the situation to. I started there and replied to the auto-reply with 8 photos I had snapped (we took a video also). Both cases yielded an e-mail reply with a reference number (different for the sent and replied). Both assured that I would be contacted. Neither were ever replied to, so after two days I made my first call. I referenced the e-mail and was given a reference number and was told that the team who deals with this sort of problem is being engaged and I'd hear back from them soon. I also received an e-mail stating that I'd receive a reply "in five days" (not business days but I had figured this might be the case). Nine days later, I called back hoping this would get me to someone who could directly address the problem.
I started off the call explaining my situation (which left the CSR speechless for a moment) and asked for a manager. I was passed off to "the manager" and explained what had happened. After a bit of hold time to review the problem (given a reference number I had to hunt down), I was told that it was being handled by Consumer Affairs. Ok, so can hand me off to whomever is handling it at Consumer Affairs? No. They gave me an e-mail to reply to. I explained that I'd now had six different messages ignored by them via e-mail (one directly to the hotel I stayed at) and that I would really like to talk to someone who's job it is to actually solve the problem (I was far more polite than my writing makes it sound like). I asked to speak to her supervisor.
Supervisors In Name Only
It's long been a game in the CSR world that "Manager" and "Supervisor" really means nothing anymore. Most people get frustrated enough to ask for Supervisors and CSRs are already at a disadvantage having to field more calls than they have people to field them. If every call has to be passed to a Supervisor then they have to have a lot of supervisors. This last supervisor was the least helpful, explaining again that there is absolutely nothing she can do and the only option I have is to e-mail the magic, general, e-mail box for Consumer Affairs. No, thanks.
Twitter
Finally, I took to twitter, posting 5 of the photos I had taken and @ing Starwood. I received a reply from SPGassist claiming I'd "gotten their attention" and to DM them my reference number. They failed to follow me, though, so I couldn't. I replied with my reference number immediately after they sent the tweet and asked them to follow so I could DM. I sent my phone number to their twitter account expecting, as had happened with other situations where I'd involved Social Media, to get a call that day. It's been 24 hours and *crickets*.
Contrast with Another Property
I'd experienced this at another property four years ago. This time I discovered the problem when I arrived. I went to the front desk and asked for them to put me up somewhere else. Without even an argument, my request was granted. They, too, took my bags and sanitized them, returning them to me that evening as well as providing me with a new toothbrush and razor. The guy who delivered my luggage hung around while I went through everything to make sure it was all there and done to my satisfaction. They gave me 4 times the points for my stay. When I arrived home, the hotel manager at the first hotel called me to not only check in that everything was in order, but to assure me that they have completely stripped/sanitized the room I stayed in so that future guests would not have the problem I had. To this day they are among the two brands I am loyal to. Look, bad things can happen when you travel and Bed Bugs are one of the common "worst" things that can happen. But when it's handled well it's not going to keep me away -- if anything, I now know that "Another Property" brand not only takes the problem seriously, but should that problem happen to me again I know it'll be addressed in a professional, prompt manner. What I've learned from this experience from Starwood is that even in a serious manner such as Bed Bugs, I can expect to have to chase Customer Service around for a month and ultimately have to write, in vein, about it which tells me there's little-to-no hope should something less serious happen to me. No thanks.  I'll be sending a few more e-mails elsewhere and one snail mail, certified letter, but I'm done with chasing general mailboxes and the non-existant people behind them.

Saturday, March 19, 2016

Fix: Serial TTY Terminal Output on Raspberry Pi 3 is Garbled, Garbage or Otherwise Broken

Problem
You've prepped your Raspbian SD card. You've plugged in your FTDI / RS232 adapter to your shiny new Raspberry Pi 3, set up Putty for 115200, Parity 8, Flow Control None, Stop. You've wired everything correctly, Ground to Ground, Tx to Rx, Rx to Tx, and you plug-in, only to be greeted by garbage. Lots of garbage. Blocks, Corners, non-English characters. It looks like your modem looked when it blew off a BBS connection in 1992. But it was just dandy with your Raspberry Pi 2! What gives?
What's happening
Bear with me since some of this may be inaccurate. I'll be honest, the last time I dealt with troubleshooting a serial terminal connection was easily 18 years ago. This shouldn't have happened, really. In my teen years, I actually coded a FOSSIL COM driver into Bulletin Board System software I had written for my multi-node BBS (get off my lawn!). 18 years and many lines of code later, I'm feeling senile.
So with serial communication, there's always the sensitive issue of timing. Your Pi is trying to send data at 115200bps. It's failing. Somewhere along the mystical way, the CPU clock rate is set in such a way that it doesn't quite deliver at the right speed and the result is the text vomit you're seeing in PuTTY.
The Fix
The fix is simple, but has side-effects. If you're simply setting up the serial terminal in order to login and configure WiFi because you're too lazy to walk 10 feet to another room and plug in an Ethernet cable, it's a perfect solution. If you are interested in using serial communication for some other purpose, it's not.
Simply plug the SD card into your PC. Open up the "config.txt" in the root in something that will understand the line endings properly (Notepad++, Atom, Visual Studio Code, Sublime, ... basically anything other than Notepad). Insert the line "core_freq=250". Save and safely eject the card. Pop it back into your Raspberry Pi 3 with everything plugged in and you should see the majestic, properly formatted, vomit-free boot sequence. Login and you're good!
Once you're done and network connected, remove that line from the config.txt (located in /boot/config.txt if you're editing directly on your RPi) and reboot. You'll be back to the original, faster clock speed (and broken serial communication).

Friday, March 18, 2016

HowTo: Add yourself as a local administrator via DirectAccess only connected PC

Problem
You've just been offline domain joined to your domain and you login with your account only to discover that you're a non-administrator on your laptop! This won't do, so you hop launch Computer Management using a local administrator account or Microsoft Account that's an administrator and try to add your Active Directory ID. You soon discover that though Computer Management thinks it can see the domain, it can't seem to find the account that you're actually logged into the computer with!
Why It Doesn't Work
Honestly, I'm not sure on this one. My hypothesis is that Computer Management launched as a local admin is not able to use the DA tunnel, but it knows you're in a domain and expects that it can get to it. This is backed up by the long (Not Responding) message as you wait for it to fail. Bummer.
The Fix
Use a tool that is so old that it can't possibly fail! Kidding. But it is old. Remember the "net" command?
Launch a Command Prompt (cmd.exe) as a local administrator (or Microsoft Account with Local Administrator access).
Type in:
net localgroup administrators YOURDOMAIN\youraccount /ADD

I believe you're going to have to use your SamAccountName (old style DOMAIN\account) rather than UPN (account@ActiveDirectoryDomain.int), but the latter may work. I didn't try it so I simply don't know. :)

Thursday, February 18, 2016

Monitoring Local Presence Changes in Lync Client SDK

Overview

I’m giving a talk remotely today to the DFW Unified Communications Users Group on Skype for Business development and will be showing some of the code related to my simple Raspberry Pi LED Status tool.  The code behind the project was thrown together in under an hour and really isn’t a great example of best practices, however, it’s a good place to get an idea about how to do some basic development with the Skype for Business Client.

In this post, I’ll go through some of the code used for that project.  This post is based on the initial commit, so make sure you’re referencing that in case I’ve got the bug and decided to update it.

The Lync Client SDK

Yes, Lync.  Unfortunately, it wasn’t updated for the Skype for Business release, however, it works fine with the latest client.  You’ll need to be running the latest Lync 2013 client or Skype for Business client in order to use solutions developed with Lync Client SDK, however, you require no other components to actually run the program—it’s all included with the client.

References

Download the Lync Client SDK (search, I won’t provide a link due to Link Rot regularly wiping them out) and install it.

You’ll need to reference Microsoft.Lync.Model.dll and Microsoft.Lync.Utilities.dll.  They’ll be located in the Office15 folder…somewhere.

A Note about Multi-threaded Code

The Lync Client SDK provides a set of APIs for interacting with the client using multi-threaded code.  This means that you’re going to have to be cautious with certain operations.  Many things you’ll want to work with are fired on events in a background thread and all of the perils of multi-threaded programming will apply.  You’ll see a few things I’ve done to combat this, but the code in the initial commit is by no means fully audited to ensure thread-safety and a lot can go wrong in this area!

Interacting With the Lync Client

In the constructor for the Monitor class, you’ll see everything you need in order to connect to and interact with the Lync client.

// Connect to the current Lync Client
m_client = LyncClient.GetClient();
var contact = m_client.Self.Contact;
if (contact == null) // There's better ways to do this, but this works in a dirty implementation
{
 SimpleLogger.Log("Client is not logged in - Setting Offline", m_gpioController.AllOff());
 throw new InvalidOperationException("Client must be logged in before starting the monitor");
}
// Create a subscription and subscribe to our own contact object
contact.ContactInformationChanged += ContactOnContactInformationChanged;
var contactSubscription = m_client.ContactManager.CreateSubscription();
contactSubscription.Contacts.Add(contact);

The connection occurs at LyncClient.GetClient().  This method will throw if the client is not launched.  I chose not to catch that exception since it effectively renders the application dead.

From there, I subscribe to the ContactInformationChanged event and add a subscription to my local contact (m_client.Self.Contact).  This ensures that when any property of my contact changes, the method “ContactOnContactInformationChanged” will fire (on a background thread).

When Contact Information Changes

I have a pretty simple event handler defined for that:

private void ContactOnContactInformationChanged(object sender, ContactInformationChangedEventArgs e)
{
            if (e.ChangedContactInformation.Contains(ContactInformationType.Availability))
                SetLedState();
}
The "e" property lets us know what specific modification caused the event to fire. It's common for more than one thing to change at a time, but since I only care about the Availability component, I check for it and fire off "SetLedState". The changed information is not included, just the component that changed, so we have to look that up. This is done via the following in SetLedState();
var contact = m_client.Self.Contact;
if (contact == null)
 return;
object availabilityId = contact.GetContactInformation(ContactInformationType.Availability);
var availability = (ContactAvailability) availabilityId;                
In this application, I'm only subscribing to the local contact's presence so I simply grab that contact's Contact object. Availability is an int boxed in an object, not a ContactAvailability enum as one might expect, however it's simple to just cast that to ContactAvailability for easier decoding. From there, I "switch" on the ContactAvailability and set the LEDs using the GpioController class.
What’s up With All The Interlocked Stuff in GpioController

Remember all of that multi-threaded nonsense I mentioned earlier?  I implemented Blinking using a Timer, which is a class that lets you fire off a method on a background thread at a given interval.  Because of this, and because our status changes come on an event handler that fires on a background thread, there’s a few members of our GpioController that could be modified by more than one thread.

Normally I’d use a lock, and that would be fine here, as well, but the requirements for this application were simply to ensure that the variable being read is the latest copy in memory.  Lighter weight patterns work fine in this scenario and I use them enough that I simply go there when the kind of variable fits well.

In addition, the GpioController is disposable because that timer needs to be cleaned up.  The Dispose pattern that’s commonly used is not thread-safe.  I’ve included a class in the Patterns class that handles it in a thread-safe manner.  There’s not going to be a case in the application, as it’s currently written, where the GpioController will be disposed on anything but the main UI thread, however, I anticipate that future changes will introduce this and I’d rather not fix that later.  For the most part, you can ignore that class.  If you’ve not done a lot with the Interlocked static methods, you’ll find it to be confusing.

The GpioController keeps a “current LED state” in a flags enum.  Enums are effectively syntactical sugar over ints with constant fields.  I developed a NuGet package that contains a number of helpers for flags enums and includes a wrapper to provide “safe” access to an enum from multiple threads, providing guarantees that when the “Value” member is set, any getters on another thread will always receive the latest value instead of what happens to be in the cache for the core your code is executing on.

The only other place that needed protection was around the blinking feature.  To protect that, I used an int variable in place of a bool and Interlocked to ensure it’s updated and read properly.  Let’s look at that more closely:

// Check that the light is actually blinking and set it to NOT blinking in a threadsafe manner
if (Interlocked.CompareExchange(ref m_isBlinking, 0, 1) == 1)
{
 m_timer.Change(Timeout.Infinite, -1);
 Thread.Sleep(m_currentBlinkInterval.Milliseconds * 2);
}

The Interlocked bit serves two purposes. First, it ensures that the value of m_isBlinking is both read and written to in a manner that guarantees the latest value will be retrieved. It also ensures that if two threads hit this code at nearly exactly the same time, only one will execute the statements in the if block, modifying our timer and incurring the penalty from sleep.

What the code is actually doing is saying "read what is actually stored in m_isBlinking" and if it's set to "1", set it to "0". Then, check the value that was previously stored in m_isBlinking and continue into the body of the "if" only if the previous value of m_isBlinking was "1".

Summary

The code is pretty thoroughly commented, so I’d encourage you to look at each of the methods in each of the classes for more information.  You’ll see I’ve put an event handler in for detecting power events, which is a good idea when your application is going to run on a laptop/tablet.  It’ll catch the “Suspend” event and let you do anything you need to do to clean up before suspending.  Beware that this code should be simple, since the machine can hit suspend before your code is finished executing.  I use it to turn the LEDs off and catch the Resume to ensure the application doesn’t crash when coming back up (the Lync Client API will fire events before you can actually get at the data contained within the Contact class, but it’s easy to detect and prevent while resuming).