Monday 11 February 2013

Gadgeteer Ethernet J11D module not working in NETMF 4.2 projects

I had some problems getting an Ethernet module working with my Gadgeteer mainboard in a NetMF 4.2 project last night, so i thought i'd share how i got it working.

I'm using a Fez Spider mainboard and Ethernet J11D module and it seems that the Ethernet module works a bit differently under NetMF 4.2 that what i'm used to.





















Adding the Ethernet module to the Gadgeteer visual designer in the same way as other modules will cause a null reference exception.

We no longer need to add the Ethernet module to the designer. Instead we use the EthernetBuiltIn class and the NetworkInterfaceExtension.AssignNetworkingStackTo method.

You can find some sample code to get the Ethernet module working below.

You'll need to add a reference to GHI.Premium.Net for the EthernetBuiltIn class.

 static readonly EthernetBuiltIn Ethernet = new EthernetBuiltIn();  
   
     void ProgramStarted()  
     {  
       Debug.Print("Program Started");  
   
       Ethernet.Open();  
   
       NetworkInterfaceExtension.AssignNetworkingStackTo(Ethernet);  
   
       Ethernet.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(Ethernet_NetworkAddressChanged);  
   
       Ethernet.NetworkInterface.EnableDhcp();  
     }  
   
     void Ethernet_NetworkAddressChanged(object sender, EventArgs e)  
     {  
       Debug.Print("Network Address Changed");  
       Debug.Print(Ethernet.NetworkInterface.IPAddress);  
     }  

This code should be enough to get you started with the Ethernet module under NETMF 4.2

Friday 1 February 2013

Gadgeteer - Setting system time from the internet


I came across a scenario recently where i needed to get set the system time from an NTP server on my gadgeteer mainboard.

















It's easy enough to set the system time using the Utility.SetLocalTime method, but we still need some way of getting the correct time from the network.

Turns out that we have some built in functionality to do this.


TimeService


The TimeService class provides some helper methods to allow syncing the local system time from an NTP server. We can also specify a time period, after which the TimeService will update from the NTP server again.

The code below gets the current time from time.windows.com syncs the system time and prints it out the the console.

First make sure you have added a reference to Microsoft.Spot.Time


    void SetTime()   
    {   
     Debug.Print("setting time");
   
     TimeService.SystemTimeChanged += new SystemTimeChangedEventHandler(TimeService_SystemTimeChanged);   
     TimeService.TimeSyncFailed += new TimeSyncFailedEventHandler(TimeService_TimeSyncFailed);  
 
     var settings = new TimeServiceSettings();   
     settings.ForceSyncAtWakeUp = true;
   
     // refresh time is in seconds   
     settings.RefreshTime = 1800;
    
     settings.PrimaryServer = GetTimeServerAddress();
   
     TimeService.Settings = settings;   
     TimeService.SetTimeZoneOffset(0);   
     TimeService.Start();   
    }
   
    byte[] GetTimeServerAddress()   
    {   
     IPAddress[] address = Dns.GetHostEntry("time.windows.com").AddressList;   
     if (address != null && address.Length > 0)   
     {   
      return address[0].GetAddressBytes();   
     }   
     throw new ApplicationException("Could not get time server address");   
    }
   
    void TimeService_TimeSyncFailed(object sender, TimeSyncFailedEventArgs e)   
    {   
     Debug.Print("error synchronizing time with NTP server: " + e.ErrorCode);   
    } 
  
    void TimeService_SystemTimeChanged(object sender, SystemTimeChangedEventArgs e)   
    {   
     Debug.Print("network time received. Current Date Time is " + DateTime.Now.ToString());   
    }   
 

Hopefully this will be useful for someone else out there.

Thursday 24 January 2013

HP Z1 Review


About four months ago I swapped my Windows-bootcamped iMac for a new HP Z1 workstation that HP were kind enough to let us test drive. 

First impressions were OK – it's a neat all in one matt black machine, and although not as shiny and pretty as my iMac, it's a really nice looking pc. The 27 inch ips display is stunning.

I've been using the Z1 for a few months now and as a Windows workstation i have to say that i definitely prefer the it to the iMac.

Performance wise, the Z1 is packing a quad core Xeon processor with 8gb ram and a 2gb Nvidia Quadro graphics card, which is probably a bit better than the i5 processor, 8gb ram, and Radeon graphics card in the Mac. It's a great machine on the occasions we decide to play a few games in the office.

One area where the Z1 excels is in it's upgradability. I've added a solid state drive to mine and now it beats the iMac hands down. Windows 8 boots in a matter of seconds and everything feels nice and snappy. On the bootcamped iMac it's around 15-20 seconds boot time and can occasionally feel a bit sluggish. 



I ran PC Mark 07 on both machines. The iMac scored 3205 and the Z1 with ssd scored 4940. 
Obviously it's not a fair comparison. The iMac is running a bootcamped installation of windows on a sata hard disk, whereas the Z1 is a real windows installation on a solid state drive. Unfair maybe, but i know which one I'd prefer to work on.

While it's not a laptop, it's very portable for something that's so powerful. I recently used it on an R&D project (Real Weather) as a server, and I it was really useful to be able to just pick it up and plug it in where we were setting up.   

Overall i'm really happy with the Z1. My only criticism would be aesthetic: although the screen is awesome, overall the shape/look/general shininess of the machine isn't quite as nice as the iMac, and the keyboard and mouse provided with it definitely don't look right.   But that's a relatively minor quibble considering the performance that i can get from the Z1

Tuesday 30 October 2012

Surface Tablet First Impressions

Our office Surface tablet was delivered yesterday and I've the chance to spend a bit of time playing around with it. I thought i'd write a short post about my initial impressions.

I've tried to be as objective as possible. I use Windows as my desktop operating system, however I also own an Ipad and Iphone, both of which I love. This isn't my Surface, it belongs to my employer, so if it sucked, it wouldn't make any difference to me.



The positive.

Build quality is awesome. The surface is a really well made piece of kit.

Touch cover keyboard feels pretty good to type on. With the kickstand out it feels almost like a laptop. Having a track pad is great for doing stuff that requires a higher level of precision.

I've been using Windows 8 on my desktop for the last few months, but it really comes to life on this device. The more I use windows RT on the Surface, the more I prefer it to IOS. Its just a better tablet operating system. Yes there are some flaws. It takes a bit of getting used to the new gestures, but once you do, its amazing.

Multitasking on the surface is amazing. It's liberating to be able to use two apps at the same time with snapped mode. It's easy to keep an eye on twitter while typing up a blog post for example. Switching between apps feels really fluid and natural.

Being able to use Command prompt from the desktop is awesome.

Being able to plug in usb devices is great.

Can add extra storage via the micro sd slot.

The ability to have separate logins for different users of the device is a killer feature. Roaming profile and app data makes for a seamless experience if you use other windows devices.

Much lighter than carrying a laptop around. It feels about the same weight as my Ipad. Maybe just slightly heavier.

This is a device I can actually do some work on without it feeling like a massive chore. I'm writing this post on the surface. I've tried to write blog posts on my Ipad before and it's just a horrible experience.



The negative

Wish the touch cover had a magnetic latch like the ipad

Rotation from landscape to portrait mode feels a little clunky. No transition

Lack of apps at the moment. Its still early days though, hopefully we'll see lots more developers getting on board in the next few months.

Have experienced quite a few crashes in various different apps including the Windows Store. While crashing apps can be blamed on 3rd party developers, there really isn't any excuse for the Windows store crashes I've seen. Sort it out Microsoft!

Windows app store can sometimes be a bit slow.

The mail app is terrible. Again, please sort it out Microsoft.

Having to use IE10 at the moment, although IE10 is actually not so bad. It's still not Chrome. Looking forward to the Chrome metro app.

An out of the box 32gb Surface only has around 17gb disk space free. This is really disappointing. How the hell does Windows RT and Office take up so much space.

The size of the Surface may be off-putting for some people. It's a 10.6 inch tablet. If you primarily use the Ipad in portrait mode, it will definitely feel weird for you. I always use my Ipad in landscape mode so it didn't really bother me.


Overall i'm pretty impressed with the Surface.
It's not perfect but it's definitely got huge potential as a laptop replacement and maybe even an Ipad replacement. Most of the issues I have with it are software based, and can be fixed with updates. It's also important to remember that this is a first generation device. Once there is more app support i'd definitely consider replacing my Ipad with one.

If you want a device purely for content consumption then go buy an Ipad. However if you want a tablet that you can also do some work on then the Surface is a very strong contender.

Sunday 23 September 2012

Real Weather – Digital Sizzle 6 Hackathon Project

Last week i took part in the Digital Sizzle 6 Hackathon, which took place at Mozilla HQ in London.
The event was a 48 hour coffee and beer fuelled event which was organised by the Three Beards.

The brief for the hackathon was relatively simple and open to interpretation. “take publicly accessible data and turn it into something amazing”

The best projects from the hackathon would be displayed at the Whitechapel Gallery in London at an event later in the month.

So on Friday night i headed down to Mozilla HQ along with 3 colleagues from specialmoves. The first night was an opportunity to meet the other developers and creatives at the event and to form a hackathon team ready to start on Saturday. Anyone who had an idea for a project was invited to pitch their idea to the crowd.

Sid Lawrence talks about twilio

After listening to all the pitches my favourite idea actually came from one of my colleagues Gavin Clark
Basically his idea was to get weather data from a public weather api, and recreate a real live weather experience.

Initially in our beer fuelled state we decided that we wanted to build some sort of booth that we could put the user in, and then shower them with water, and blast them with air etc. A few other people were also interested in Gavin’s idea and we had formed a team of 4 within a relatively short space of time.

Unfortunately our ambitions were possibly a little bit too extreme and somewhat scared the Whitechapel gallery representatives who were present (and also the organisers of the hackathon)

In the end we settled on a slightly more conceptual version of the idea.
The hackathon started on Saturday morning at 9am and teams were allowed until 4pm on Sunday to complete their projects.

We spent the first part of the day planning what we were going to build and then a couple of us headed off to get some materials, while the rest stayed to start writing some code.

Basically our plan was to build an internet connected plug socket that we could switch on and off by making http requests. This would allow us to turn on and off the devices that we were using to simulate the weather. A lamp for the sun, a fan for the wind, a pond pump for rain, and a strobe light for lightning.

I used a .Net gadgeteer mainboard with a relay module and ethernet module to build the plug socket.
Gadgeteer is great for events like this as it is a good platform for rapid prototyping. You can build awesome stuff in a very short space of time, and debugging is really simple with visual studio.

Building an internet connected plug socket

We chose 5 cities from around the world that had fairly interesting weather, and to make things a bit more interesting we allowed users to vote for the city they wanted to see by text message using the awesome Twilio api

Weather data was obtained for the next 10 days using the weather underground api, and the idea was to recreate the next 10 days weather for the winning city over 100 seconds, 10 seconds per day.

Real Weather in action

We built a node js server side component to handle the twilio stuff and hosted it on a server kindly provided by event sponsors Wirehive.

We also had  videos of the various different weather types and music which was composed by a composer that we met at the event. This was all handled using an Adobe Flash application which coordinated everything and made the required calls to our http enabled plug socket to switch things on and off.

Tom and Gavin write some code  Tom and Gavin with a sealant gun

Digital Sizzle 6 was one of the most amazing events i’ve ever been too. We had lots of fun building Real Weather and met some really cool people along the way. Really can't wait to attend my next hackathon.

Our project and lots of others from Digital Sizzle 6 will be in an exhibition at the Whitechapel Gallery on the 26th September 2012.

Check out a video i made of Real Weather below.

Friday 24 August 2012

Building .Net 4.5 Projects with Jenkins









In my day job for Specialmoves we use Jenkins as our continuous integration server.

Today, after upgrading one of our projects to target .Net 4.5, a colleague of mine was complaining  that the Jenkins build for the project was failing with the following error.

warning MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed.

He had already tried installing .Net 4.5 on the Jenkins server, which hadn't fixed the problem.
















Chuck Norris was not amused....... 


















(if you haven't installed the Chuck Norris plugin for Jenkins, i suggest you do so immediately. It wont fix your problem, but it will make you laugh)

The first thing we had to do was to install the Windows SDK for Windows 8 on the Jenkins server. This 
includes the .NET Framework 4.5 SDK


After installing the SDK, we kicked off the build again, only to be greeted with a different error.

error MSB4019:  The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk

To fix this error we copied the missing Visual Studio 2012 msbuild folder from a machine that actually had Visual Studio 2012 installed.

So copy C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\ from a machine that has Visual Studio 2012 installed, to the same location on the Jenkins server.

Once you've done this, Jenkins should be able to build the project.

Chuck Norris is happy again.



Tuesday 31 July 2012

Kinect Player Radar Using C# and WPF

In this post i'm going to explain how to make a simple top down player radar for the Kinect using wpf and c#

The radar provides a top down view of user locations relative to the Kinect sensor.


I needed something like this for part of a larger r&d project i'm working on, but wasn't able to find any examples of how to do it. Turns out it's actually pretty simple.

SkeletonStream

The Kinect's SkeletonStream allows us to track the position of a user infront of the Kinect, and also the positions of up to 20 joints on the user's body.

SkeletonStream provides position tracking for up to six users. Full skeletal tracking is only possible for  two users, however for the purposes of this project i only needed the global position of each user.

The Kinect SDK provides a Skeleton Class (Microsoft.Kinect.Skeleton) which is used to contain the data for a tracked user skeleton.

There are three members of the Skeleton Class that we are interested in.

  1. TrackingState : this property tells us the tracking state of the skeleton, either Tracked, PositionOnly, or NotTracked
  2. TrackingId : a unique id for each tracked skeleton
  3. Position : provides the 3d position of a tracked user
Position data is represented by the SkeletonPoint structure which has 3 distance properties, X: which represents the horizontal distance from the sensor, Y: which represents the vertical distance from the sensor, and Z: which represents depth. The values returned are in meters and the Kinect sensor is at position 0,0,0. For this project i was only concerned with the X and Z values as this is a top down view.

For this simple example i'm going to draw a circle on a wcf canvas panel to represent each tracked player. Each player will be represented by a different colored circle.

I'm using a canvas panel with a width of 600px and a height of 1050px
300 pixels on the canvas represents 1 meter in the real world, so the canvas size maps to a 2m x 3.5m area infront of the kinect.
The values i'm using are oriented so that the kinect sensor is effectively at the top center of the canvas

The Code


I'm going to detail some of the code that i used for this project below.
You can find full example code for this article on github

The xaml markup for the radar is very simple. It's pretty much just a canvas panel.

<Window x:Class="KinectPlayerRadar.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="KinectPlayerRadar" Width="600" Height="1050" Loaded="WindowLoaded" Closing="WindowClosing">

    <Canvas Width="600" Height="1050" Name="canvas" Background="Gray">
    </Canvas>
</Window>

Jumping straight into the codebehind. First up we define some variables to contain a reference to the Kinect sensor, and a list of the skeleton ids that we are currently tracking.
We then initialize the Kinect sensor, enable the SkeletonStream, and subscribe to the sensor's SkeletonFrameReady event. This event fires when a new skeleton frame for the SkeletonStream is available.

private KinectSensor _sensor;
private List<int> _skeletonTrackingIds;

const int PixelsPerMeter = 300;
const string BaseMarkerName = "player";

private void WindowLoaded(object sender, RoutedEventArgs e)
{
    if (!KinectSensor.KinectSensors.Any())
    {
        throw new ApplicationException("no kinect sensor detected");
    }

    _sensor = KinectSensor.KinectSensors[0];
            
    _skeletonTrackingIds = new List<int>();
            
    _sensor.SkeletonStream.Enable();
    _sensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(sensor_SkeletonFrameReady);            
    _sensor.Start();
}

SkeletonFrameReady event handler

In the event handler we copy the Skeleton Frame data into a new array. The array will always contain 6  Skeletons, even if nothing is being tracked, so we need to loop through each of the Skeletons and check the TrackingState property. If the Skeleton is being tracked we call the SetMarkerPosition method, passing in the Skeleton and its index in the array as parameters.

Once we have processed each skeleton, the RemoveUnusedMarkers method is called to remove any markers for players that are no longer being tracked.


void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
    Skeleton[] skeletons = new Skeleton[0];

    using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
    {
        if (skeletonFrame != null)
        {
            skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
            skeletonFrame.CopySkeletonDataTo(skeletons);
        }
    }

    var index = 0;

    foreach (Skeleton skeleton in skeletons)
    {
        if (skeleton.TrackingState != SkeletonTrackingState.NotTracked)
        {
            SetMarkerPosition(skeleton, index);
        }

        index++;
    }

    RemoveUnusedMarkers(skeletons);
}

SetMarkerPosition 

In this method we get the X and Z positions of the tracked skeleton and calculate the top and left values  for our player marker on the canvas.

The X position is negative if the player is to the right of the sensor, and positive if the user is to the left of the sensor. The Y value will always be positive. So for example an X value of -0.8 and a Y value of 1.5 would mean that the user is 0.8 meters to the left of the sensor, and 1.5 meters back from the sensor.

Given these position values we can easily calculate the position of the marker on the canvas.

Since our sensor is assumed to be at the top center of the canvas, the "top" value for our marker will be skeleton.Position.Z * PixelsPerMeter and the "left" value for our marker will be (canvas.Width / 2) + (skeleton.Position.X * PixelsPerMeter)

If the skeleton is already in our list of tracked skeletons then we simply update the position of the player's marker on the canvas.
If the skeleton is not currently being tracked, we add a new marker to the canvas and then set its position.

private void SetMarkerPosition(Skeleton skeleton, int index)
{         
    System.Windows.Shapes.Ellipse marker;
    var canvasCenter = canvas.Width / 2;
    var top = skeleton.Position.Z * PixelsPerMeter;
    var left = (canvas.Width / 2) + (skeleton.Position.X * PixelsPerMeter);

    if (!_skeletonTrackingIds.Contains(skeleton.TrackingId))
    {
        marker = AddToCanvas(skeleton.TrackingId, index);
        _skeletonTrackingIds.Add(skeleton.TrackingId);
    }
    else
    {
        marker = canvas.FindName(BaseMarkerName + skeleton.TrackingId) as System.Windows.Shapes.Ellipse;
    }

    if (marker != null)
    {
        Canvas.SetTop(marker, (skeleton.Position.Z * PixelsPerMeter));
        Canvas.SetLeft(marker, canvasCenter + (skeleton.Position.X * PixelsPerMeter));
    }
}

AddToCanvas

The AddToCanvas method dynamically adds a new ellipse shape to the canvas to represent our player.

private Ellipse AddToCanvas(int skeletonTrackingId, int skeletonIndex)
{
    var ellipse = new System.Windows.Shapes.Ellipse();
    ellipse.Name = BaseMarkerName + skeletonTrackingId;
    ellipse.Fill = GetMarkerColor(skeletonIndex);
    ellipse.Width = 30;
    ellipse.Height = 30;
            
    canvas.Children.Add(ellipse);
    canvas.RegisterName(ellipse.Name, ellipse);
          
    return ellipse;
}

GetMarkerColor

The GetMarkerColor method returns a different color brush for each possible player index.

private Brush GetMarkerColor(int playerIndex)
{
    if (playerIndex == 1) return Brushes.Blue;
    if (playerIndex == 2) return Brushes.Red;
    if (playerIndex == 3) return Brushes.Green;
    if (playerIndex == 4) return Brushes.Orange;
    if (playerIndex == 5) return Brushes.Purple;

    return Brushes.Turquoise;
}

RemoveUnusedMarkers

The RemoveUnusedMarkers method is called after our player positions have been set in order to remove markers for players that are no longer being tracked.

private void RemoveUnusedMarkers(Skeleton[] skeletons)
{
    _skeletonTrackingIds.ForEach(id =>
        {
            if (!skeletons.Select(s => s.TrackingId).Contains(id))
            {
                var marker = canvas.FindName(BaseMarkerName + id) as Ellipse;
                if (marker != null)
                {
                    canvas.Children.Remove(marker);
                }
            }
        });
}

That's pretty much all there is to it. Obviously this is a very basic example, but hopefully someone else out there might find it useful.

If you liked this article you can also find me on twitter.

Get the code from GitHub