Bluetooth Problems Galore with the Logitech H800 Headset

A month or so ago, I decided to pick up a new headset for gaming and Skype. I wanted to Bluetooth headset that I could use while charging so that I wouldn’t be bound by cords or batteries–at least not at the same time. I’ve had good luck with Logitech products, so I did a bit of research and went with the H800.

Out of the box, everything worked great. I paired it to my PC and–voila–I had sound. Great, right? Not so fast, my friend. I’ve had problems with this thing from day one.

Once I get it to work, I don’t usually have issues. The problem is getting it to work. The thing doesn’t reliably reconnect after being disconnected. Sometimes, I’d turn on the headset, and it would connect right away and work. This would happen, say, 15% of the time. Sometimes it would connect, but it would have unbearably poor audio quality. Sometimes it would connect, but it would have no audio. And sometimes it would simply not connect at all.

Ugh.

I found that my best bet when it didn’t connect and work properly would be to turn the headset off, disable the Bluetooth adapter through Device Manager, enable the Bluetooth adapter, and then turn the headset back on. This lil’ song and dance would get me a successful, high-quality connection pretty regularly. If that didn’t work, a reboot would usually do the trick.

The headset also comes with a USB nano receiver, and I’ve had no problems whatsoever using that. I don’t want to use the USB receiver, though, because it takes up one of three precious USB ports. I didn’t buy the headset to use as a USB device, and I’d be disappointed if I had to use the USB receiver instead of Bluetooth.

I was stumped on this issue. I didn’t think it was my computer because I have a different pair of Bluetooth headphones that I’ve no problems with. I didn’t think it was the headset because I’ve used it with my Surface RT with no problems. Everything that I could find online seemed to indicate that it was a problem with my Broadcom Bluetooth adapter driver, but I couldn’t find any updates anywhere. I’d tried reinstalling drivers for the headset and the Bluetooth adapter and anything else that seemed relevant, but nothing seemed to help.

And so I went on, using my headset by disabling and re-enabling devices in Device Manager until one day last week when I could no longer get the headset to work at all through Bluetooth. So annoying!

Since nothing I had tried up to that point had done anything, I thought I’d try upgrading to Windows 8. This is something that I’ve been putting off doing on this computer, anyway, and maybe the OS refresh is just what I needed. I felt encouraged when Windows 8 Setup told me that Broadcome Bluetooth Software was an incompatible program that needed to be removed before I could upgrade.

I did what needed to be done and upgraded to Windows 8, but I was no better off than I was with Windows 7. I could pair the device, but I could not get it to connect. It worked fine with its USB receiver. GAH!

Finally, I stumbled upon this forum post: Bluetooth headset is not working in Windows 8. The accepted answer said that the problem was solved by copying the Broadcom Bluetooth 4.0 driver from a working computer. I headed over to Google and searched for “Broadcom Bluetooth 4.0.” I found the Lenovo download page for it and installed it on my computer even though my ThinkPad W510 was not listed as a “Supported ThinkPad System.” When the install finished, I turned on my headset and guess what? It connected!

Despite my success, I’m not convinced that I’m in the clear. I turned off the headset and turned it back on. I had the same poor quality problem that I’ve had before. I turned it off and back on again. This time it connected, but I had no audio. I went to Windows 8’s wireless devices control panel, and turned the adapter off and back on. Now my headset connected and had good quality audio.

I love the headset when it’s working, but I’m really disappointed with the number of connection problems I’ve had. At the end of the day, I’m content to get them working by disabling and enabling the Bluetooth adapter, but it’s a step that I wish I didn’t shouldn’t have to do. I’m going to pretend that everything works how I think it should by disabling my Bluetooth adapter when I’m not using the headset.

This article was meant to be more of a, “Hey, here’s what got me past the issue!” for other folks troubleshooting similar issues. It has somewhat of a gadget review feel to it, though, doesn’t it? So I’ll wrap up by giving you my opinion of the H800 headset from Logitech. It’s a nice headset. The audio quality is good, and it connects quickly and reliably through the included USB receiver. However, because of the problems I’ve had with the headset on my Lenovo ThinkPad W510, I would not recommend this as a Bluetooth headset, although it works flawlessly with my Surface RT. Based on my experience, you’ve only got a 50/50 shot for satisfaction with the headset as an exclusively Bluetooth peripheral.

Advertisements

Call Method Overloads Based on Derived Type

I was creating a data access component that performed different operations based on the type of request that it received. In order to accommodate this, I have an abstract base request type defined, and handled requests derive from this type. Without getting too deep into why I had to do it this way, I had overloaded methods to which I needed to “route” an instance of the abstract class.

.NET 4 gives us an easy way to do this with the dynamic keyword. Consider the following example, which will correctly call the correct method overload:

void Main()
{
    MyBase obj = new MyOne();
    var p = new Printer();
    p.Print(obj);
}

public class Printer
{
    public void Print(MyBase item)
    {
        dynamic i = item;
        Print(i);
    }
    
    public void Print(MyOne item)
    {
        Console.WriteLine("Print(MyOne)");
    }
}

public abstract class MyBase
{
}

public class MyOne : MyBase
{
}

dynamic wasn’t introduced until .NET 4, though. So, if you have an older application, it may not be available to you. The good news is that you can accomplish the same goal by using reflection. It’s just as effective, but it’s a bit gnarlier.

public void Print(MyBase item)
{
    this.GetType()
        .GetMethod("Print", new[] { item.GetType() })
        .Invoke(this, new object[] { item });
}

So there you have it–two different ways to call method overloads based on object type!

Parse Camel Case into Words

I was working on a small project that had a list of camel case strings that I wanted to display to users. Displaying values as camel case feels dirty, though, so I wanted to pretty it up by parsing the strings into words. Sounds like a job for regular expressions!

After a few tries, this is what I settled on:

var x = Regex.Replace(value, @"([A-Z][^A-Z])", " $1");
x = Regex.Replace(x, "([a-z])([A-Z])", "$1 $2");
x = x.Trim();

Here are my test cases and the results:

Input:
  HelloWorld
  SuperMB
  SMBros
  OneTWOThree

Results:
  Hello World
  Super MB
  SM Bros
  One TWO Three

Ahh, just what I was hoping for. Thanks again, regular expressions!

Speaking Skills in Engineering Careers

I recently visited a local high school to speak with a teacher friend’s speech class. She’s trying to show her students that the skills they’re learning in her speech class are valuable in most careers. She gets a lot of pushback from her future engineers who believe they’ll be relying predominantly on their technical skills, not giving speeches.

I’m entering my tenth year of developing software. I use the presentation skills and techniques learned from my high school speech class almost every day. To an extent, I agree with my friend’s students: you can get by without these skills, but not having them will surely prove to be a significant career growth inhibitor. You might be an incredible [insert engineering career here], but in order to be fully effective, you must be able to communicate your ideas to others, compare and contrast options, and convince your audience–whether it’s your peers, boss(es), or customers–what’s best. This is where those skills come into play.

When I talked to the class, I gave several examples of how I use speaking skills everyday. I gave examples, starting with the most formal, speech-like events and moving to more common, everyday things.

The biggest and best example I have is presenting at my company’s annual customer conference. Customers pay to come to the conference and spend three days attending sessions presented by all sorts of different people, including developers like myself. This is a formal presentation and a direct application of skills taught in a speech class. Preparation is key. We’re required to submit outlines of our presentations months ahead of the event that are refined and built out as the conference draws nearer. At the conference, I’ll be behind a podium at the front of a room, possibly on a stage, giving a presentation or demo to an audience of 20 to 100+ attendees. I’m letting them know what’s new or how they can use my company’s products better. If I do a good job, customer’s get value from the conference. Their opinion of the company and it’s products improve, and maybe they purchase more software. If I do a poor job, the worst case is that a customer begins to question their decisions.

The conference is a wonderful example, but it only happens once a year. A more common scenario occurs when I have a good idea. I need to socialize that idea with my boss and peers, and that requires lots of small communication. I need to make them understand the value of my idea. If I do a good job, they might talk to others. At some point, I might get a call. “Hey, Adam. Remember that idea you were telling me about? I’ve got some people with me that want to hear more. Can you come talk to us?” That’s all the notice I get. I need to walk into a room with an audience that I don’t know and sell them on my idea. If I can talk about the idea enthusiastically and confidently, I might convince people that it’s worth doing and get it onto a project plan. If I don’t have good energy, or the audience doesn’t believe that I have what it takes to see it to fruition, the idea might die there.

A more common (and less dramatic) situation involves my peers. There could be a team working on a problem, and they need my input. Once I understand what they’re trying to accomplish, I use my technical skills to determine options and decide which will be best. From there, it becomes an ad-hoc presentation. I need to present options with their advantages and disadvantages to help my teammates understand what I’m suggesting and get them to buy into my recommendation. If my message isn’t clear, it could result in a bad solution or the need for rework.

And let’s not forget customers. When we create new products, it’s not uncommon to demo them to customers to get feedback. Good presentation skills help the customer understand the value that you’re delivering, and it gets them excited. Bad presentation skills destroy their confidence in you and the company. The same applies to training and conference calls. When you’re able to “speak their language,” customers will like you more and believe in you. I’ve been on calls with other software vendors that aren’t able to articulate their plans and ideas, and it can be really frustrating for all sides.

I certainly couldn’t do my job without the technical skills that I have, but a large percentage of every day is spent communicating with others. I couldn’t be as effective as I am without strong speaking and presentation skills. Those skills have given me growth and leadership opportunities that I wouldn’t have had without them. Standing in front of your classmates, telling them how to care for your dog may not seem like it’s going to be applicable to your career, but being able to explain a complex process to a group of your technical peers is an invaluable ability!

Events with Return Values

I was working with a team on an interface project that allowed for the transferring of records between N different systems. Once the record was transferred, updates can flow in both directions. I suggested that we use events to begin transactions from source systems, and the event arguments would contain the necessary routing information to help get the data to the correct destination.

Great plan, but we ran into a problem because one of the systems involved uses asynchronous operations for its transactions and another uses synchronous operations. No problem, though. We can get around this with the creative use of callbacks and wait handles.

Let’s look at an example. In the code below, the application calls a method that raises an event. The method needs to return a response, and the event handler produces a response, but there is no way to return the response from the event handler to the method.

class Program
{
    static event EventHandler<SampleEventArgs> Sample;

    static void Main(string[] args)
    {
        Sample += SampleEventHandler;
        var response = RaiseAnEvent();
        Console.WriteLine("Response: {0}", response);
        Console.ReadLine();
    }

    static string RaiseAnEvent()
    {
        if (Sample != null)
        {
            var args = new SampleEventArgs();
            Sample(null, args);
        }
        return null; // need the response!
    }

    static void SampleEventHandler(object sender, SampleEventArgs e)
    {
        string response = "foo";
    }
}

public class SampleEventArgs : EventArgs
{
}

When program runs, the following output is produced:

Response: 

The first problem we need to deal with is that the event handler needs a way to provide its response to the calling code. This could be accomplished by adding a response property to the event argument OR by adding a callback to the event argument. I prefer the latter because the former will require me to know when it is safe to retrieve the value from the event argument whereas the callback is more like a “push.” So, let’s add a callback!

public class SampleEventArgs : EventArgs
{
    public Action<string> SampleCompleted { get; set; }
}

Now that we have the ability to specify a callback to capture the response, guess what the next step is. That’s, right: create the callback method! This is also our opportunity to block execution while we wait for a response. I’ll use a ManualResetEvent to block execution, and I’ll set it in the callback. Perfect, and lambdas make the whole thing a breeze!

static string RaiseAnEvent()
{
    string response = null;
    if (Sample != null)
    {
        var args = new SampleEventArgs();
        var manualResetEvent = new ManualResetEvent(false);
        args.SampleCompleted = r =>
            {
                response = r;
                manualResetEvent.Set();
            };
        Sample(null, args);

        if (!manualResetEvent.WaitOne(1000))
        {
            // timeout waiting for response
        }
    }
    return response;
}

Now that we’ve got our callback created and defined, we just need the event handler to invoke it.

static void SampleEventHandler(object sender, SampleEventArgs e)
{
    string response = "foo";
    if (e.SampleCompleted != null)
    {
        e.SampleCompleted(response);
    }
}

And with that, we’re done! We run the application, and we get the expected output.

Response: foo

Complete sample:

namespace EventsWithReturnValues
{
    using System;
    using System.Threading;

    class Program
    {
        static event EventHandler<SampleEventArgs> Sample;

        static void Main(string[] args)
        {
            Sample += SampleEventHandler;
            var response = RaiseAnEvent();
            Console.WriteLine("Response: {0}", response);
            Console.ReadLine();
        }

        static string RaiseAnEvent()
        {
            string response = null;
            if (Sample != null)
            {
                var args = new SampleEventArgs();
                var manualResetEvent = new ManualResetEvent(false);
                args.SampleCompleted = r =>
                    {
                        response = r;
                        manualResetEvent.Set();
                    };
                Sample(null, args);

                if (!manualResetEvent.WaitOne(1000))
                {
                    // timeout waiting for response
                }
            }
            return response;
        }

        static void SampleEventHandler(object sender, SampleEventArgs e)
        {
            string response = "foo";
            if (e.SampleCompleted != null)
            {
                e.SampleCompleted(response);
            }
        }
    }

    public class SampleEventArgs : EventArgs
    {
        public Action<string> SampleCompleted { get; set; }
    }
}

Group Strings Using LINQ and Regular Expressions

I was working on a problem yesterday where I needed to combine strings that were the same except for one part. Here’s a simplified version of the problem:

Input Array:
"Adam likes apples."
"Adam likes bananas."

Desired Output:
"Adam likes apples and bananas."

It was a no-brainer to use regular expressions to do the matching and parsing, but I couldn’t figure out immediately how to use them in to accomplish my goal. I decided to use LINQ’s ToLookup method to create groups of matching items, and then loop through the groups to implement my combine logic.

The first step is to define a regular expression that lets me do two things. It needs to let me create a group “key,” and it needs to let me extract the data part that I’m ultimately trying to combine. For the simple example above, I can use the following pattern:

^(Adam likes )(.*)\.$

I can create the lookup using the regular expression like so:

var input = new[] 
    {
        "Adam likes apples.",
        "Adam likes bananas.",
    };
var regex = new Regex(@"^(Adam likes )(.*)\.$");
var lookup = input.ToLookup(x => regex.Replace(x, "$1"), x => x);

The final step is to loop through the lookup’s keys and do processing on the groups:

foreach (var key in lookup.Select(x => x.Key).ToList())
{
    if (lookup[key].Count() > 1)
    {
        var items = string.Join(
            " and ",
            lookup[key].Select(x => regex.Replace(x, "$2")).ToArray());
        
        var output = regex.Replace(
            lookup[key].First(),
            string.Format("$1{0}.", items));
        Console.WriteLine(output);
    }
    else
    {
        Console.WriteLine(lookup[key].First());
    }
}

Here’s another example to illustrate how this might be useful:

static void Main(string[] args)
{
    var input = new[] 
        {
            "Adam ate 3 apples.",
            "Adam ate 1 apple.",
            "Adam ate 1 banana.",
            "Adam ate 1 banana.",
            "Adam ate 1 orange.",
        };
    var regex = new Regex(@"^(Adam ate)\s+(\d+)\s+(.*?)s?\.$");
    var lookup = input.ToLookup(x => regex.Replace(x, "$1$3"), x => x);
    foreach (var key in lookup.Select(x => x.Key).ToList())
    {
        if (lookup[key].Count() > 1)
        {
            int sum = 0;
            foreach (var item in lookup[key])
            {
                sum += int.Parse(regex.Replace(item, "$2"));
            }

            var target = regex.Replace(lookup[key].First(), "$3");
            if (sum > 1)
            {
                target += "s";
            }
            var output = regex.Replace(
                lookup[key].First(),
                string.Format("$1 {0} {1}.", sum, target));
            Console.WriteLine(output);
        }
        else
        {
            Console.WriteLine(lookup[key].First());
        }
    }
    Console.ReadLine();
}

// Output:
//   Adam ate 4 apples.
//   Adam ate 2 bananas.
//   Adam ate 1 orange.