Wednesday, 3 July 2013

What I learned about bluetooth with Gadgeteer

The Project

My recent Gadgeteer project was to investigate the Bluetooth module with a view to having a hassle-free way to communicate either between 2 Gadgeteer devices or between Gadgeteer and a Windows client.

I decided the best way to learn how the bluetooth module worked was by using Gadgeteer -> Windows, as it would make debugging easier. I came across the Bluetooth library from 32feet - this is a lovely layer of abstraction over the complexities of the bluetooth protocol, and ultimately gives you access to any serial data via a NetworkStream.

The goal of this experiment was to take a picture with the camera, convert it to a windows-compatible bitmap, and stream that over bluetooth to the client, which would create a bitmap from the bytes and display it on the screen. What could be easier?

This is the gadgeteer project:
The Windows client was not fancy; it consisted of a form with a picture box and progress bar.

What I Learnt

  • You should chunk your data. After some experimenting, I found the most reliable way to transfer a 320x240 pixel bitmap (totalling 230,454 bytes) was to split it into 93 chunks of 2,478 bytes each. I hadn't been able to transfer more than around 8k successfully, and my cut-off for reliably transferring data was around 3k.
  • Base64 encodings change between implementations. Don't assume that the .Net Framework will be able to unencode a Base64 string that was encoded on the .Net MicroFramework; I haven't got to the bottom of this one yet; there'll be another post when [if] I do. ** UPDATE ** I think this was how I was using the Base64 data when I received it, I was trying to extract chars rather than bytes.
  • Bluetooth isn't quick. Transferring a 230k bitmap takes around 90 seconds.
  • The Gadgeteer Bluetooth module needs time to warm up. Standard operating procedure for the bluetooth module is to create a timer that fires after 3 seconds of the modules initialising, so it can then enter pairing mode.

The Code

The code is available on Github. The Gadgeteer code is here and the windows client is here

The Result

Here's a picture showing the Gadgeteer LCD screen and the windows client side-by-side; you'll have to take my word for it that the image was bluetoothed...

Friday, 21 June 2013

Why you should check event delegates for null

The other day I came across some code that was raising an event like this:
    public class Dummy
    {
        public event EventHandler SomethingHappened;
        public void RaiseEvent()
        {
            try
            {
                SomethingHappened(this, EventArgs.Empty);
            }
            catch { }
        }
    }
As opposed to the recognised pattern of
    public class Dummy
    {
        public event EventHandler SomethingHappened;
        public void RaiseEvent()
        {
            if (SomethingHappened != null)
            {
                SomethingHappened(this, EventArgs.Empty);
            }
        }
    }
Chatting to a friend at the pub, I mentioned about this code and the fact that the code was relying on exception handling to control the flow, and he mentioned that it would be a lot slower if there wasn't an event handler defined. I knew it would be slower to create, throw and catch a NullReferenceException than to perform a null check, but I hadn't realised just how much slower.

To prove it, I created a class that contains a single event, and exposed two methods to raise the event - one with a try/catch block and one with a null check
    public class Dummy
    {
        public event EventHandler SomethingHappened;

        public void RaiseWithNullCheck()
        {
            if (SomethingHappened != null)
            {
                SomethingHappened(this, EventArgs.Empty);
            }
        }

        public void RaiseInTryCatch()
        {
            try
            {
                SomethingHappened(this, EventArgs.Empty);
            }
            catch { }
        }
    }
...and a console app to repeatedly run the methods with no event handler defined
        public static void Main(string[] args)
        {
            var dummy = new Dummy();
            var stopwatch = Stopwatch.StartNew();
            var iterations = 10000;

            for (int i = 0; i < iterations; ++i)
            {
                dummy.RaiseWithNullCheck();
            }
            stopwatch.Stop();
            Console.WriteLine("Null check: {0}", stopwatch.ElapsedMilliseconds);

            stopwatch.Restart();
            for (int i = 0; i < iterations; ++i)
            {
                dummy.RaiseInTryCatch();
            }
            stopwatch.Stop();
            Console.WriteLine("Try catch: {0}", stopwatch.ElapsedMilliseconds);

            Console.ReadLine();
        }
This is a screenshot of the output - note the values are milliseconds
That's right. Sub-millisecond for the 10,000 null checks, and over 36 seconds for the 10,000 exceptions.


The remaining question is "what's the difference in timing if there is a handler defined for the event?" Obviously in this case the try/catch will be quicker because there's no overhead of checking for null before invoking the event handler. I had to massage the code a little though, before the difference was noticeable:
        public static void Main(string[] args)
        {
            var dummy = new Dummy();
            // Add an empty event handler
            dummy.SomethingHappened += (s, e) => { };

            var stopwatch = Stopwatch.StartNew();
            var iterations = 10000;

            for (int i = 0; i < iterations; ++i)
            {
                dummy.RaiseWithNullCheck();
            }
            stopwatch.Stop();

            // report in ticks, not milliseconds
            Console.WriteLine("Null check: {0} ticks", stopwatch.ElapsedTicks);

            stopwatch.Restart();
            for (int i = 0; i < iterations; ++i)
            {
                dummy.RaiseInTryCatch();
            }
            stopwatch.Stop();
            Console.WriteLine("Try catch: {0} ticks", stopwatch.ElapsedTicks);

            Console.ReadLine();
        }
Here's a typical output for this one (the timings vary a little between runs). Note that this is in ticks not milliseconds (a tick being 1/10,000 of a millisecond).
Given the tiny numbers when the event handler is defined, there isn't a good reason to rely on a try/catch when a simple null check will do.

Sunday, 16 June 2013

Make your Gadgeteer app testable with the MVP pattern

As Gadgeteer is very much about hardware, it's not always obvious how to write unit tests for the code. This post will go through the mechanics of the MVP pattern. The example app cconsists of a button and a multicolour LED; when the button is pressed, the LED displays a random colour. If you don't believe me, there's a video.

The MVP pattern

The Model-View-Presenter (MVP) pattern is designed to split the UI (View) from the business logic (Model) via a class that sends messages between the two (Presenter). In the implementation I use (Passive View) the view has little or, if possible, no logic. When an event occurs (e.g. a button press), the view raises an event which is handled by the presenter. The presenter then invokes a void method on the model. If required, the model will raise an event to signal that the work is completed. The presenter handles that event too, and calls a method on the view to cause a UI update to occur.

Here's the sequence that occurs in the example app:

The Classes

The solution consists of three projects: the Gadgeteer project, the class library and the test project.
The class library defines the classes and interfaces required to implement the MVP pattern - the model, the presenter and the view interface.
The IView interface declares an event ButtonPressed, to be handled by the presenter, and a method ShowColour that will be called by the presenter:

using Microsoft.SPOT;

namespace ButtonAndLight.Lib
{
    public delegate void ButtonPressedEventHandler(object sender, EventArgs args);

    public interface IView
    {
        // The event that the UI will raise when the button is pressed
        event ButtonPressedEventHandler ButtonPressed;
        
        //The method the presenter will call when the colour needs to change
        void ShowColour(byte r, byte g, byte b);
    }    
}

The Model class declares an event ColourChanged, to be handled by the presenter, and a method CalculateNewColour, to be called by the presenter:
using Microsoft.SPOT;

namespace ButtonAndLight.Lib
{
    public class Model
    {
        public Model()
            : this(new RandomGenerator())
        { }

        public Model(IRandomGenerator randomGenerator)
        {
            _randomGenerator = randomGenerator;
        }

        private IRandomGenerator _randomGenerator;

        // Old school event handler for the Micro Framework
        public delegate void ColourChangedEventHandler(object sender, ColourChangedEventArgs args);

        // The event that will be raised when the colour has changed
        public event ColourChangedEventHandler ColourChanged;

        // This will be called by the presenter
        public void CalculateNewColour()
        {
            var r = _randomGenerator.GetNextColourPart();
            var g = _randomGenerator.GetNextColourPart();
            var b = _randomGenerator.GetNextColourPart();

            OnColourChanged(r, g, b);
        }

        private void OnColourChanged(byte r, byte g, byte b)
        {
            if (ColourChanged != null)
            {
                ColourChanged(this, new ColourChangedEventArgs(r, g, b));
            }
        }
    }

    public class ColourChangedEventArgs : EventArgs
    {
        public byte R { get; private set; }
        public byte G { get; private set; }
        public byte B { get; private set; }
        public ColourChangedEventArgs(byte r, byte g, byte b)
        {
            R = r;
            G = g;
            B = b;
        }
    }
}
The Presenter class stitches the model and view together, by calling the relevant method when an event occurs:
using Microsoft.SPOT;

namespace ButtonAndLight.Lib
{
    public class Presenter
    {
        IView _view;
        Model _model;

        public Presenter(IView view, Model model)
        {
            _view = view;
            _model = model;

            _view.ButtonPressed += new ButtonPressedEventHandler(view_ButtonPressed);
            _model.ColourChanged += new Model.ColourChangedEventHandler(model_ColourChanged);
        }

        void model_ColourChanged(object sender, ColourChangedEventArgs args)
        {
            _view.ShowColour(args.R, args.G, args.B);
        }

        void view_ButtonPressed(object sender, EventArgs args)
        {
            _model.CalculateNewColour();
        }
    }
}
These are the Gadgeteer components:

The program class in the Gadgeteer project needs to implement the IView interface, so it can pass a reference to itself to the presenter. In this example I've also made it responsible for building the presenter:

using ButtonAndLight.Lib;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT;
using Gadgeteer.Modules.GHIElectronics;

namespace ButtonAndLight
{
    public partial class Program : IView
    {
        private Presenter _presenter;

        void ProgramStarted()
        {
            _presenter = new Presenter(this, new Model());

            // Wire up handler for the the physical button press
            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            if (ButtonPressed != null)
            {
                ButtonPressed(this, EventArgs.Empty);
            }
        }

        public event ButtonPressedEventHandler ButtonPressed;

        public void ShowColour(byte r, byte g, byte b)
        {
            var colour = ColorUtility.ColorFromRGB(r, g, b);
            multicolorLed.TurnColor(colour);
        }
    }
}
All that's left now is the test class. As this is the Micro Framework, I've had to do by hand what I'd normally have done with Rhino and NUnit
using System;
using Microsoft.SPOT;

namespace ButtonAndLight.Lib.Test
{
    public class Program
    {
        public static void Main()
        {
            ButtonPressed_ExpectRandomColourGenerated();
        }

        private static void ButtonPressed_ExpectRandomColourGenerated()
        {
            // Create objects
            var view = new FakeView();
            var model = new Model(new FakeRandomGenerator());
            var presenter = new Presenter(view, model);

            // Raise event
            view.RaiseButtonPressEvent();

            // Check result
            if (view.R == 10 && view.G == 20 && view.B == 30)
            {
                Debug.Print("Success");
                return;
            }

            throw new InvalidOperationException("Failure");
        }
    }

    public class FakeView : IView
    {
        // Sensing variables
        public byte R { get; private set; }
        public byte G { get; private set; }
        public byte B { get; private set; }

        // Pretend a button's been pushed
        public void RaiseButtonPressEvent()
        {
            if (ButtonPressed != null)
            {
                ButtonPressed(this, EventArgs.Empty);
            }
        }

        #region IView interface
        public event ButtonPressedEventHandler ButtonPressed;

        public void ShowColour(byte r, byte g, byte b)
        {
            R = r;
            G = g;
            B = b;
        }
        #endregion
    }

    public class FakeRandomGenerator : IRandomGenerator
    {
        byte[] _values = new byte[] { 10, 20, 30 };
        int _valuePointer = 0;

        public byte GetNextColourPart()
        {
            return _values[_valuePointer++];
        }
    }
}
Here's a video of the hardware in action:
The code for this example can be found on GitHub at https://github.com/orangutanboy/MVPExample/

Tuesday, 28 May 2013

Don't write new unit tests during the refactoring phase

If you're doing unit tests, you will be familiar with the Red-Green-Refactor cycle - write a failing test (red), make it pass (green) then drive out the design of the code (refactor).

When it comes to the refactor phase, you shouldn't need to write new tests - the refactor phase is when you change the implementation of the code, not the behaviour.

Take the following green code, which returns the min and max temperatures for three states of water:
using System;
namespace H2OLib
{
    public class H2O
    {
        public enum State
        {
            Gas,
            Liquid,
            Solid
        }

        private readonly State _state;

        public H2O(State state)
        {
            if (state != State.Gas && state != State.Liquid && state != State.Solid)
            {
                throw new ArgumentOutOfRangeException();
            }
            _state = state;
        }

        public int MaxTemp
        {
            get
            {
                switch (_state)
                {
                    case State.Gas:
                        return 374;
                    case State.Liquid:
                        return 100;
                    default:
                        return 0;
                }
            }
        }

        public int MinTemp
        {
            get
            {
                switch (_state)
                {
                    case State.Gas:
                        return 100;
                    case State.Liquid:
                        return 0;
                    default:
                        return -230;
                }
            }
        }
    }
}
This code is tested by the following tests:
    [TestFixture]
    public class H2OTests
    {
        [Test]
        public void GivenGasStateThenExpectCorrectTemps()
        {
            var h2o = new H2O(H2O.State.Gas);
            Assert.That(h2o.MinTemp, Is.EqualTo(100));
            Assert.That(h2o.MaxTemp, Is.EqualTo(374));
        }

        [Test]
        public void GivenLiquidStateThenExpectCorrectTemps()
        {
            var h2o = new H2O(H2O.State.Liquid);
            Assert.That(h2o.MinTemp, Is.EqualTo(0));
            Assert.That(h2o.MaxTemp, Is.EqualTo(100));
        }

        [Test]
        public void GivenSolidStateThenExpectCorrectTemps()
        {
            var h2o = new H2O(H2O.State.Solid);
            Assert.That(h2o.MinTemp, Is.EqualTo(-230));
            Assert.That(h2o.MaxTemp, Is.EqualTo(0));
        }

        [Test]
        public void GivenUnknownStateThenExceptionThrown()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new H2O((H2O.State)99));
        }
    }

The code behaves exactly as planned, but the switch statements are a bit smelly. One solution is to refactor to the State pattern, with a factory to instantiate the correct state class based on the value that is passed to the H2O constructor. So, what's the next thing you do? Is it a) write a test for the StateFactory:
namespace H2OLib.Test
{
    [TestFixture]
    public class StateFactoryTests
    {
        [Test]
        public void ConstructExpectNoError()
        {
            Assert.DoesNotThrow(() => new StateFactory());
        }
    }
}
or b) don't write a test for the StateFactory:
// This line left intentionally blank
If you read the title of the post, you'll probably know that the answer is b. Given the tests that are in place, the code can be refactored to the following with no additional tests required:
using System;

namespace H2OLib
{
    public class H2O
    {
        private static StateFactory _stateFactory = new StateFactory();

        public enum State
        {
            Gas,
            Liquid,
            Solid
        }

        private readonly IState _state;

        public H2O(State state)
        {
            _state = _stateFactory.CreateState(state);
        }

        public int MaxTemp
        {
            get
            {
                return _state.MaxTemp;
            }
        }

        public int MinTemp
        {
            get
            {
                return _state.MinTemp;
            }
        }
    }

    public interface IState
    {
        int MinTemp { get; }
        int MaxTemp { get; }
    }

    public class StateFactory
    {
        public IState CreateState(H2OLib.H2O.State state)
        {
            switch (state)
            {
                case H2O.State.Gas:
                    return new GasState();

                case H2O.State.Liquid:
                    return new LiquidState();

                case H2O.State.Solid:
                    return new SolidState();

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }

    public class GasState : IState
    {
        public int MinTemp
        {
            get { return 100; }
        }

        public int MaxTemp
        {
            get { return 374; }
        }
    }

    public class LiquidState : IState
    {
        public int MinTemp
        {
            get { return 0; }
        }

        public int MaxTemp
        {
            get { return 100; }
        }
    }

    public class SolidState : IState
    {
        public int MinTemp
        {
            get { return -230; }
        }

        public int MaxTemp
        {
            get { return 0; }
        }
    }
}
When you write a new test you're not refactoring; it's a new red phase.

Sunday, 19 May 2013

LongTouch event on single-touch LCD

I have a T35 LCD touchscreen as part of my Gadgeteer kit. I was disappointed to find that although the drivers for the screen suggested gestures, in fact the display is a single-touch and so registers only TouchDown and TouchUp events.

I needed a second gesture for an app I was writing so created a subclass of the Display_T35 class. Here's how it works.

The Class

As it subclasses the Display_T35 class, it implements the public constructors of that class. There's one additional parameter on each constructor; the interval in milliseconds after which the LongTouch event will fire - this defaults to a second. The constructors also register handlers for the TouchDown and TouchUp events of the base class.

    public class GestureEnabledDisplay_T35 : Gadgeteer.Modules.GHIElectronics.Display_T35
    {
        public GestureEnabledDisplay_T35(int socket1, int socket2, int socket3, long longTouchRegisterInterval = 1000)
            : base(socket1, socket2, socket3)
        {
            Initialise(longTouchRegisterInterval);
        }

        public GestureEnabledDisplay_T35(int socket1, int socket2, int socket3, int socket4, long longTouchRegisterInterval = 1000)
            : base(socket1, socket2, socket3, socket4)
        {
            Initialise(longTouchRegisterInterval);
        }

        private void Initialise(long longTouchRegisterInterval)
        {
            base.WPFWindow.TouchDown += new Microsoft.SPOT.Input.TouchEventHandler(WPFWindow_TouchDown);
            base.WPFWindow.TouchUp += new Microsoft.SPOT.Input.TouchEventHandler(WPFWindow_TouchUp);
            LongTouchRegisterInterval = longTouchRegisterInterval;
        }
The subclass needs to expose the new LongTouch event. This is the .Net Micro Framework, so generic event handlers are not available - remember .Net 1.1 anyone?

        public delegate void LongTouchEventHandler(object sender, EventArgs args);
        public event LongTouchEventHandler LongTouch;
        
  private void OnLongTouch()
        {
            if (LongTouch != null)
            {
                LongTouch(this, EventArgs.Empty);
            }
        }
The functionality is fairly simple. When the TouchDown event is raised, the current clock tick is recorded. When the TouchUp event is raised, the number of ticks since TouchDown is calculated and compared with the LongTouchRegisterInterval. If the interval has passed, the LongTouch event is raised.

        public long LongTouchRegisterInterval { get; private set; }

  private long _touchdownTicks;
        private const long NanosecondsInMilliseconds = 10000;

        void WPFWindow_TouchUp(object sender, Microsoft.SPOT.Input.TouchEventArgs e)
        {
            var touchupTicks = DateTime.Now.Ticks;
            if (touchupTicks - _touchdownTicks > (NanosecondsInMilliseconds * LongTouchRegisterInterval))
            {
                OnLongTouch();
            }
        }

        void WPFWindow_TouchDown(object sender, Microsoft.SPOT.Input.TouchEventArgs e)
        {
            _touchdownTicks = DateTime.Now.Ticks;
        }

The Usage

If you use the standard Gadgeteer designer to connect your module...
...you'll have an instance of the Display_T35 defined for you in the generated.cs file:

        private Gadgeteer.Modules.GHIElectronics.Display_T35 display;

        private void InitializeModules()
        {
            this.display = new GTM.GHIElectronics.Display_T35(14, 13, 12, 10);
        }
This will need to be edited to use the new GestureEnabledDisplay_T35 class

        private GestureEnabledDisplay_T35 display;

        private void InitializeModules()
        {
            this.display = new GestureEnabledDisplay_T35(14, 13, 12, 10);
        }
However, this means that each time you edit the diagram in the designer, your changes will be overwritten. And the generated class is called generated for a reason - it's not yours so keep your mitts off. A better way to create the display class is to leave the module unconnected in the designer, and create the class explicitly in your code.

    public partial class Program
    {
        GestureEnabledDisplay_T35 gestureEnabledDisplay;

        void ProgramStarted()
        {
            gestureEnabledDisplay = new GestureEnabledDisplay_T35(14, 13, 12, 10);
            gestureEnabledDisplay.LongTouch += new GestureEnabledDisplay_T35.LongTouchEventHandler(display_LongTouch);
        }
 }

Known Issues

There are a couple of annoyances with the implementation, but not enough to make me swear lots:

  • The TouchDown and TouchUp events are defined in the Display_T35.WPFWindow class, but the LongTouch event is defined in the Display_T35 class.
  • If the WPFWindow.TouchUp event is handled as well as the LongTouch event, both events will still fire - the LongTouch event does not swallow the TouchUp event.

Where's the code?

The code's available as a GitHub Gist, here.

Saturday, 18 May 2013

CLR_E_FAIL in .Net Micro Framework

While porting a library from .Net 4.5 to .Net Micro Framework 4.2, I had a large number of build failures - mainly the expected errors around generics and LINQ, which are not available in the Micro Framework.

Having worked my way through the obvious failures - IEnumerable<T> to arrays, EventHandler<T> to delegate(object, EventArgs), the compiler was reporting this:
I presumed the Micro Framework was having trouble with the foreach keyword, so changed the code to use a standard for loop. Then I received this error:


It turns out that what the Micro Framework doesn't like is multi-dimensional arrays. Where I had Points defined as Point[,] it needed to be defined as Point[][]. It was easy enough to fix, but a meaningful error message would have saved some of Google's bandwidth.

Sunday, 28 April 2013

The DevSouthCoast hacking bee photo-story

I spent a weekend with a bunch of developers and a bunch of electronics hardware. The problem we were trying to solve was to build a "beehive monitoring device". Bees are dying out and nobody knows why. There are many theories: parasites, pesticides, reduced hedgerows, overwork. What's certain is that numbers are dwindling, so the weekend was dedicated to producing a low-cost high-tech one-size-fits-all monitoring device for beehives.

The monitoring equipment was supplied by the Microsoft Gadgeteer team and consisted of a power module, a main board and a bunch of sensors (temperature, humidity, motion, light, colour, GPS), communication devices (low-frequency radio, WiFi, GSM, bluetooth), user input (buttons, touch-screen LCDs, joysticks) and output (LCD displays, coloured LEDs, SD card) and more. I can't remember all of it, there was loads.

The bee knowledge was supplied by a local beekeeper who answered all of our questions about the bees and hives with a great deal of patience, then took us to the on-site beehives for a tour. I like bees, but have discovered I don't like defensive bees so didn't hang around for long.

Back in the sweatshop, the 12 developers neatly split into 3 teams of 4, with a seasoned Gadgeteer user and 3 novices in each. The suggestion of naming the teams "drones", "workers" and "queens" was not taken up.

Each team beavered away trying to solve the problem of non-intrusive bee monitoring and came up with a host of ideas. The three demonstrated solutions had a common core of regularly logging temperature and humidity data to an SD card, but the solutions for publishing the data varied across teams. One team's solution was to use a bluetooth component to download the log file contents to a bluetooth device; one's was to send notifications via RF link to a remote device to display information on an LCD screen; the other's was to use a WiFi connection to upload the data to a website to be displayed on a web page, and to send SMS messages for alerting special conditions.

The lucky members of the winning team (including yours truly) each took home an impressive set of Gadgeteer components. Expect more Gadgeteer-related posts soon as I discover what I can do with them!