morzel.net

.net, js, html, arduino, java... no rants or clickbaits.

Easy way to fix outdated links (URL rewrite rule in Web.config)

INTRO

I’ve recently moved my site from BlogEngine.NET 2.0 to 3.3 – thanks to the great work done by BlogEngine.NET team the migration was easy... The only serious problem I’ve noticed was with post links ending with .aspx. For example when Google or CodeProject had a link to such URL:

http://en.morzel.net/post/2014/09/24/OoB-Sonar-with-Arduino-C-JavaScript-and-HTML5-(Part-2).aspx

the post was not found. If .aspx suffix was removed from the address:

http://en.morzel.net/post/2014/09/24/OoB-Sonar-with-Arduino-C-JavaScript-and-HTML5-(Part-2) 

everything was working fine! Fortunately fixing it didn’t require any BlogEngine code changes – all thanks to URL Rewrite Module 2.0 (available since IIS 7) and system system.webServer/rewrite Web.config section.

URL Rewrite is a big topic. Checkout http://www.iis.net/learn/extensions/url-rewrite-module docs if you want to know all the details – you can even do things like setting HTTP headers or server variables! In this post I will focus on how to fix the .aspx link problem and I will also note some issues you might face while trying to setup you own URL rewrite rules…

 

SETTING THE RULES

I’ve added such rewrite section inside system.webServer node in Web.config file:

<rewrite>
    <rules>
        <rule name="FixOldAspxLinks" stopProcessing="true">
            <match url="^(.*post/.+)\.aspx$" />
            <action type="Redirect" url="{R:1}" redirectType="Permanent" />
        </rule>
    </rules>
</rewrite>

It has a single rule that matches all addresses that contain post/ and end with .aspx and triggers redirect action to the same address but with .aspx part dropped.

The rule

Rule has a name (something describing the purpose of the rule is welcome) and stopProcessing=”true” setting which instructs IIS to skip any further rules for matched URL (yes, there's only one rule but having stopProcessing=”true” makes our intention clear).

The match

If you are familiar with regular expressions the url="^(.*post/.+)\.aspx$" attribute should be obvious, if not - don’t worry, it’s simpler than it looks:

  • ^ – means beginning of URL
  • $ – means the end of URL
  • .* – means any character zero or more times
  • .+ – means any character at least once
  • \. – means a literal dot (in regexes . stands for any character so if we literally want to look for a dot we need to escape the special meaning by preceding it with backslash)
  • () – parentheses denote the text (capturing group) what we are going to reference in action element by using {R:1} 

The matching expression could be written in many ways but the one I’ve used solves the problem without going overboard with URL pattern recognition…

The action

We want the browser to look for a new address hence type="Redirect" is set.
New address is specified with url="{R:1}". The {R:1} is a reference to the group captured by matching expression – its value is the text found between parentheses. In our case it’s everything that preceded the .aspx suffix. redirectType="Permanent" instructs the server to issue a 301 Moved Permanently response to the browser. When HTTP client receives permanent redirect it will use the new URL each time it sees a link to the old URL…

Ok, so the above rewrite should be all that’s needed to make .apsx problem disappear! Doesn’t work on your machine? Read on!

 

POSSIBLE ISSUES

No URL Rewrite module installed

Before pushing any changes to remote server I wanted to check rewrite settings on my local IIS 7.5 on Windows 7 x64. I did it and instead of redirect I got HTTP Error 500.19 – Internal Server Error. The error page was useless as it didn’t show any hint on what was wrong with the config... If you face the same issue you probably don’t have IIS Rewrite module installed (it is not added by default). Quick way to find out if you have the module is to check if this file exists: 

%windir%\System32\inetsrv\config\schema\rewrite_schema.xml

I got the installer from here: https://www.microsoft.com/en-us/download/details.aspx?id=7435. After module was added to IIS the rewrite rule started to work :)

Redirect caching

Rewrite rule is setup to redirectType="Permanent" because we want to teach HTTP clients that the resource is moved for good, right? It's all ok unless you are during development and do some changes to the rule – if browser already received 301 response for particular URL your modified rule will not get a chance to work! To solve this problem you can clear the cache but I prefer to have Chrome's dev tools open (with caching disabled) or try to open the page in fresh incognito window…

Pattern testing

Regular expressions are powerful tool but it's very easy to make a mistake while working with them. Fortunately IIS Rewrite Module has it's own panel (snap-in) in IIS Manager:

URL Rewrite module in IIS Manager... Click to enlarge...

that lists rewrite rules used for the site:

Rewrite rule in IIS Manager... Click to enlarge...

If you double click a rule, you will see a window that lets you change rule properties without manual modifications to Web.config. Pressing "Test pattern..." button opens the window in which you can quickly test your regular expression:

Pattern test in IIS Manager... Click to enlarge...

Differences in Java and C#: protected

Java and C# are very similar languages so if you have to switch between the two it’s easy to overlook subtle differences. One of the tricky bits is the meaning of protected access modifier. 

In C#, if you mark a field with protected keyword it will be available to the class that owns it and to its derived classes. In Java access will be broader. Not only the owner and derived classes will be able to access the field but also all classes defined in the same package. In C# similar effect can be achieved by assigning protected internal access level. Member marked like that has access which is a union of internal (same assembly) and protected levels. Important thing to note is that concepts of Java package and C# assembly are not equivalent. C# assembly can span multiple namespaces and is related to physical unit (EXE, DLL) that keeps intermediate code and metadata. Package in Java is more similar to namespace in C# with key (not only) difference that it has an impact on accessibility…

Below are two projects that show protected access level differences between Java and C# (both are available in this GitHub repository). C# program was made in Visual Studio 2015 Community and targets .NET 4.5.2. Java program was made in IntelliJ IDEA 15 Community Edition and is set to use Java 8. Version of Java/.NET is not relevant and there’s nothing special in the projects - could’ve been easily done in notepad but isn’t it great that this days we can get such awesome IDEs for free? :) 

Java and C# projects... Click to enlarge...

Java

Base.java

package com.example;

public class Base {
    protected int someProtectedFiled = 123;

    public void testAccessInBaseClass() {
        // SAME BEHAVIOR IN JAVA AND C#
        // The class can access its own protected field
        System.out.println(someProtectedFiled);
    }
}

Derived.java

package com.example;

public class Derived extends Base {
    public void testAccessInDerivedClass() {
        // SAME BEHAVIOR IN JAVA AND C#
        // The class can access inherited protected field
        System.out.println(someProtectedFiled);

        // DIFFERENT BEHAVIOR IN JAVA AND C#!
        // Access to protected field is possible because classes are in the same package
        // (notice access through qualifier of type Base instead of Derived)
        System.out.println(new Base().someProtectedFiled);
        // In C# the field would have to be public or protected internal (otherwise CS1540 error is produced)
    }
}

NotDerived.java

package com.example;

public class NotDerived {
    public void testAccessInNotDerivedClass() {
        // DIFFERENT BEHAVIOR IN JAVA AND C#!
        // Access to protected field is possible because classes are in the same package
        System.out.println(new Base().someProtectedFiled);
        // In C# the field would have to be public or protected internal (otherwise CS0122 error is produced)
    }
}

DerivedInAnotherPackage.java

package com.example.another;

import com.example.Base;

public class DerivedInAnotherPackage extends Base {
    public void testAccessInDerivedClassFromAnotherPackage() {
        // SAME BEHAVIOR IN JAVA AND C#
        // The class can access inherited protected field even from another package
        System.out.println(someProtectedFiled);

        // SAME BEHAVIOR IN JAVA AND C#
        // For the below to work (instead of compilation error) the field would have to be public
        // (notice access through qualifier of type Base instead of DerivedInAnotherPackage):
        // System.out.println(new Base().someProtectedFiled);
    }
}

C#

Base.cs

namespace Protected
{
    public class Base
    {
        protected int someProtectedFiled = 123;

        public void TestAccessInBaseClass()
        {
            // SAME BEHAVIOR IN JAVA AND C#
            // The class can access its own protected field            
            System.Console.WriteLine(someProtectedFiled);
        }
    }
}

Derived.cs

namespace Protected
{
    public class Derived : Base
    {
        public void TestAccessInDerivedClass()
        {
            // SAME BEHAVIOR IN JAVA AND C#
            // The class can access inherited protected field           
            System.Console.WriteLine(someProtectedFiled);

            // DIFFERENT BEHAVIOR IN JAVA AND C#!
            // For the below to work (instead of CS1540 compilation error) the field would have to be public            
            // or protected internal (notice access through qualifier of type Base instead of Derived):
            // System.Console.WriteLine(new Base().someProtectedFiled);
        }
    }
}

NotDerived.cs

namespace Protected
{
    public class NotDerived
    {
        public void TestAccessInNotDerivedClass()
        {
            // DIFFERENT BEHAVIOR IN JAVA AND C#!
            // For the below to work (instead of CS0122 compilation error) the field would
            // have to be public or protected internal:
            // System.Console.WriteLine(new Base().someProtectedFiled);
        }
    }
}

DerivedInAnotherAssembly.cs

using Protected;

namespace AnotherAssembly // Namespace doesn't matter
{
    public class DerivedInAnotherAssembly: Base
    {
        public void TestAccessInDerivedClassFromAnotherAssembly()
        {
            // SAME BEHAVIOR IN JAVA AND C#
            // The class can access inherited protected field even from another assembly            
            System.Console.WriteLine(someProtectedFiled);

            // SAME BEHAVIOR IN JAVA AND C#
            // For the below to work (instead of CS1540 compilation error) the field would have to be public
            // (notice access through qualifier of type Base instead of DerivedInAnotherAssembly):
            // System.Console.WriteLine(new Base().someProtectedFiled);           
        }
    }
}

I hope that comments in the code make everything clear and this dry topic is exhausted... I've just orderd USB shield for my Arduino so if it works the next post will be about moving this thing with PlayStation controller :)

Update (2016-03-14):

Unfortunately I don’t have time to write the post mentioned above but the good news is that you definitely can use SparkFun USB Host Shield with USB Host Shield 2.0 library to steer servos with PS3 controller :) Here’s a short video of how it worked on my paintball turret. And here’s a clip of test circuit (hardware diagram).

Setting version of assemblies in ASP.NET MVC application with TeamCity build feature

INTRO

Last five posts (1, 2, 3, 4, 5) were all about fun stuff with Arduino. Now it’s time for something more mundane ;) In this post I will show you how to create TeamCity build that automatically sets version information in all assemblies produced by ASP.NET application. It's nothing new but I hope to give you some useful background info and note a few gotchas you may face...

Complete code of sample application is available in this GitHub repository.

TeamCity has a build feature called AssemblyInfo patcher that makes setting assembly version easy... This feature is usable on any type of .NET project because it works by updating AssemblyInfo files. Content of such files is used to create version information that .NET Framework uses for picking up correct version of referenced assemblies. Version data is also shown in Windows file properties... Here's a part of AssemblyInfo.cs file which is automatically added by Visual Studio when you create a new project:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

It contains two attributes: AssemblyVersion and AssemblyFileVersion along with a comment that describes numbering pattern recommended by Microsoft. We will also use another attribute: AssemblyInformationalVersion which is not added by default. AssemblyVersion sets version number that is recognized by .NET for dependency resolution. AssemblyFileVersion is used for file version as seen by Windows and AssemblyInformationalVersion is meant more for human consumption as it can contain strings (we will make use of it for holding Git commit hash)... Detailed description of the meaning of these attributes is outside scope of this post but check this great SO answer if you want to know more.

 

SAMPLE APPLICATION

My test application was created in Visual Studio Community 2013 by using ASP.NET Web Application / MVC project template (C#/.NET 4.5). Two additional projects of Class Library type were added. Here’s how the full solution looks:

Visual Studio solution... Click to enlarge...

Home/Index.cshtml view generated by VS was modified to present version information pulled from three .NET assemblies that are produced by the solution (one is for main web app project and two other are for class libraries). Such div was added to the view:

<div class="row text-primary">
    <div class="col-md-12">
        <dl>
            <dt>Core assembly info:</dt>
            <dd>@ViewBag.CoreAssemblyInfo</dd>
            <dt>DataAccess assembly:</dt>
            <dd>@ViewBag.DataAccessAssemblyInfo</dd>
            <dt>Web assembly info:</dt>
            <dd>@ViewBag.WebAssemblyInfo</dd>
        </dl>
    </div>
</div>

You can see some Bootstrap classes there since nowadays Visual Studio templates use Bootstrap framework for styling...

This is how rendered view looks before TeamCity processes AssemblyInfo.cs files:

Version information in web app before TC build... Click to enlarge...

And here's how version info looks after version attributes are modified by build feature:

Version information in web app after TC build... Click to enlarge...

If you wonder how the view gets version info here's HomeController.Index action method: 

public ActionResult Index()
{
    ViewBag.CoreAssemblyInfo = SomeCoreClass.GetAssemblyInfo();
    ViewBag.DataAccessAssemblyInfo = SomeDataAccessClass.GetAssemblyInfo();

    Assembly assembly = Assembly.GetExecutingAssembly();
    string webAsseblyInfo = string.Format("Full Name = \"{0}\"; Informational Version = \"{1}\"",
                            assembly.FullName, FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion);
    ViewBag.WebAssemblyInfo = webAsseblyInfo;

    return View();
}

You can see how the most important assembly version number (the one used by .NET and designated by AssemblyVersion attribute) is a part of assembly's FullName. Informational version (the one that can have strings) is taken with the help of FileVersionInfo class. You can get the number form AssemblyFileVersion attribute too - just check all the interesting stuff that GetVersionInfo method returns... The same kind of code is used in GetAssemblyInfo methods in SomeCoreClass and SomeDataAccessClass.

Ok, so we have our test application - full code is here. Note: I’ve pushed all used Nuget packages to the repository – that takes some space in the repo and might be against recommended way of using Git but it makes TeamCity setup easier. If packages folder is not committed you can expect this type of error during build:

[Csc] App_Start\BundleConfig.cs(2, 18): error CS0234: The type or namespace name 'Optimization' does not exist in the namespace 'System.Web' (are you missing an assembly reference?)

To solve it you would have to restore Nuget packages during build (here’s some info on how to do it).

 

TEAMCITY CONFIGURATION

Now time for build server config! I assume that you have some working knowledge about setting TeamCity build for .NET application so I will discuss only the steps relevant to versioning. I’ve used TeamCity 9.1.3 but don't worry if you have a bit older TC (AssemblyInfo patcher feature exists for a while). I used TC to build code from Git repository checkout on my local drive...

Before setting up AssemblyInfo patcher, add two new build parameters: Minor and Major. These are meant to represent two initial segments of version number and should be set manually - it's your (technical/marketing?) decision whether to name your next version 1.9 or 2.0, right? 

Major and Minor build parameters... Click to enlarge...

Next step is to add AssemblyInfo patcher build feature:

AssemblyInfo patcher build feature... Click to enlarge settings...

And set its properties:

AssemblyInfo patcher settings... Click to enlarge...

I've decided to use such settings:

  • AssemblyVersion:   %Major%.%Minor%.%build.number%
  • AssemblyFileVersion:   %Major%.%Minor%.%build.number%
  • AssemblyInformationalVersion:   %Major%.%Minor%.%build.number%.%build.vcs.number%

You can see that our Major and Minor parameters are used. You can also see the use of TeamCity built-in parameter named build.number. Last attribute contains another TeamCity param: build.vcs.number. It gets version control revision id. I'm using Git so this is a long alphanumerical SHA-1 hash. It means that it cannot be used in setting AssemblyVersion attribute. If you try to do so you will get an error like this:

[Csc] Properties\AssemblyInfo.cs(35, 12): error CS0647: Error emitting 'System.Reflection.AssemblyVersionAttribute' attribute -- 'The version specified '2.1.13.536ea0163412325ab7962957ce1cec777799d587' is invalid'

If you try to use it for AssemblyFileVersion you can expect a warning: 

[Csc] CSC warning CS1607: Assembly generation -- The version '2.1.12.536ea0163412325ab7962957ce1cec777799d587' specified for the 'file version' is not in the normal 'major.minor.build.revision' format

But you can safely use it in AssemblyInformationalVersion as .NET doesn't care if you put letters there... Note: If you work with SVN instead of Git you are lucky because value returned for build.vcs.number is an integer and can be used in all three version-related attributes. If you really need to set revision in AssemblyVersion while using Git you might need to add a custom build step for creating integer id... Let's keep it simple here and leave the last part of version number intact (as 0)...

Once you have AssemblyInfo patcher feature configured and you run the build, you can expect such entries in the build log: 

[22:46:02]Step 1/1: Visual Studio (sln) (2s)
[22:46:02][Step 1/1] Update assembly versions: Scanning checkout directory for assembly information related files to update version to 2.1.14
[22:46:02][Update assembly versions] Updating assembly version in C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\AssemblyInfoTest\Properties\AssemblyInfo.cs
[22:46:02][Update assembly versions] Updating assembly version in C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\Core\Properties\AssemblyInfo.cs
[22:46:02][Update assembly versions] Updating assembly version in C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\DataAccess\Properties\AssemblyInfo.cs

If all went ok your log should also contain something like this:

[22:46:05]Reverting patched assembly versions
[22:46:05][Reverting patched assembly versions] Restoring C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\AssemblyInfoTest\Properties\AssemblyInfo.cs
[22:46:05][Reverting patched assembly versions] Restoring C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\Core\Properties\AssemblyInfo.cs
[22:46:05][Reverting patched assembly versions] Restoring C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\DataAccess\Properties\AssemblyInfo.cs

Don't worry, reverting takes place only in build agent work files. The build artifacts contain properly versioned assemblies. You've seen a proof of that rendered on HTML page, you can also check DLL files properties:

File properties with version information... Click to enlarge...

Properties window shows version set by AssemblyFileVersion and AssemblyInformationalVersion. I have Polish Windows so the properties are labeled Wersja pliku (it means File version) and Wersja produktu (it means Product version).

Keep in mind that AssemblyInfo patcher will not work if version attribute has non-standard format (or AssemblyInfo files are in unusual locations).

Let's say you have something like this (because you keep information about your product in static class constants):

[assembly: AssemblyVersion(ProductInfo.Version)]

You can expect such warning during build:

[Update assembly versions] Assembly info version was specified, but couldn't be patched in file C:\TeamCity\buildAgent\work\8c2a410f7087e36b\.NET\AssemblyInfoTest\AssemblyInfoTest\Properties\AssemblyInfo.cs. Is necessary attribute missing?

 

SUMMARY

And that's all! We have a TeamCity build that sets version information in ASP.NET MVC application assemblies :) 

If somebody will be interested I can write a little supplement to this post in which I will describe how to add version info into zip package (artifact) and how to display it on Team City UI...

[OoB] Controlling gun turret with Spring Boot REST service (Java/Arduino)

This is the fifth post in my little "Out of Boredom" series dedicated to hobby projects with Arduino. Previous posts were all .NET based:

Now it's time for a bit of Java!

I will show you how to use Spring Boot framework to quickly create RESTful web service that can receive JSON requests and send commands to Arduino. The aim is to control a servo and relay based gun turret such as this one:

Gun turret prototype... Click to enlarge...

Click here to get an idea of how such turret operates. The video shows a prototype based on ASG pistol. Don't worry, my aim is quite peaceful: I want to build paintball gun turret :)

I will not discuss any electronics setup or Arduino code in this post. Take a look at the articles linked above to see information about PC-Arduino communication, controlling servos and building relay based circuit... I assume that you know what Spring Boot is, but advanced knowledge is not required to follow this post.

Full code of the project is available on GitHub (includes both Java application and Arduino sketch)...

The easiest way to create basic working Spring Boot project is to use Spring Initializr. I started my project by filling the form like this:

Spring Initializr settings... Click to enlarge...

Note that Gradle is used to create (fat) Jar package, Java 1.8 is used and the only required dependency is Web. This setup will produce an application running on Tomcat Embedded so there's no need for installing any web server. The app has support for REST controllers so we will be able to handle JSON based communication in a clean way with very little effort...

 

Without further ado, here is the piece of code responsible for receiving messages from clients:

package springarduino;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TurretController {
    private final ArduinoConnection arduino;

    @Autowired
    public TurretController(ArduinoConnection arduino) {
        this.arduino = arduino;
    }

    @RequestMapping(value = "turret/execute", method = RequestMethod.POST, consumes = "application/json")
    public TurretResponse executeTurretAction(@RequestBody TurretRequest request) {
        if (request.getPan() < 0 || request.getPan() > 180) {
            throw new IllegalArgumentException("Pan out of 0..180 range (" + request.getPan() + ")");
        }

        if (request.getTilt() < 0 || request.getTilt() > 180) {
            throw new IllegalArgumentException("Tilt out of 0..180 range (" + request.getTilt() + ")");
        }

        boolean sent = arduino.controlTurret(request.getPan(), request.getTilt(), request.isFire());
        if (!sent) {
            throw new RuntimeException("Command not sent :(");
        }

        return new TurretResponse(request.getId(), "Command sent :)");
    }
}

TurretController class has @RestController annotation and a public method marked with @RequestMapping. The mapping specifies that executeTurretAction method should be invoked whenever a client makes a POST request to .../turret/execute URL. Any HTTP client capable of sending POST with Content-Type="application/json" can communicate with such Spring controller method. It can be some desktop application or a simple HTML page with a bit of jQuery for example. I was using Postman Chrome App to prepare requests. In the next post I will describe how to communicate with such controller from smartphone that runs PhoneGap/AngularJS based application...

executeTurretAction methods expects one argument of type TurretRequest:

package springarduino;

public class TurretRequest {
    private int id;
    private int pan;
    private int tilt;
    private boolean fire;

    // public getters and setters hidden for brevity
}

If client sends JSON payload such as this:

{
    "id": "311",
    "pan": "111",
    "tilt": "99",
    "fire": "true"
}

Spring will take care of creating TurretRequest object. Our service method returns TurretResponse:

package springarduino;

public class TurretResponse {
    private int id;
    private String message;

    public TurretResponse(int id, String message) {
        this.id = id;
        this.message = message;
    }

    // public getters and setters hidden for brevity
}

If everything goes well, this kind of data will be sent back to client:

{
    "id": 19,
    "message": "Command sent :)"
}

You don't have to do anything special to make this happen. Spring chooses HttpMessageConverter implementation to create response in a format that is expected by the client. Another nice feature of our @RestController is the error handling. Let's say that client provides invalid value of tilt angle - this is what is sent back as response:

{
    "timestamp": 1424382893952,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "java.lang.IllegalArgumentException",
    "message": "Tilt out of 0..180 range (222)",
    "path": "/turret/execute"
}

Such message is easy to handle in error callbacks (thanks to 500 HTTP status code) and contains useful properties such as message and exception.

Notice that arduino object of ArduinoConnection type is used inside executeTurretAction method. ArduinoConnecton is a Spring bean responsible for communicating with Arduino over serial port.

Our controller gets reference to proper object thanks to Spring's IoC container. TurretController constructor is annotated with @Autowired so Spring knows that ArduinoConnection object needs to be injected.

This is the class responsible for talking to Arduino:

package springarduino;

import gnu.io.NRSerialPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.DataOutputStream;

@Component
public class ArduinoConnection {
    private static final int MESSAGE_SEPARATOR = 255;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Value("${arduinoPortName}")
    private String portName;

    @Value("${arduinoBaudRate}")
    private int baudRate;

    private NRSerialPort serial;


    @PostConstruct
    public void connect() {
        log.info("ArduinoConnection PostConstruct callback: connecting to Arduino...");

        serial = new NRSerialPort(portName, baudRate);
        serial.connect();

        if (serial.isConnected()) {
            log.info("Arduino connection opened!");
        }
    }

    @PreDestroy
    public void disconnect() {
        log.info("ArduinoConnection PreDestroy callback: disconnecting from Arduino...");

        if (serial != null && serial.isConnected()) {
            serial.disconnect();

            if (!serial.isConnected()) {
                log.info("Arduino connection closed!");
            }
        }
    }

    public boolean controlTurret(int pan, int tilt, boolean fire){
        try {
            // Actual values sent to Arduino will be in proper unsigned byte range (0..255)
            byte[] message = new byte[]{(byte) pan, (byte) tilt, (byte) (fire ? 1 : 0), (byte) MESSAGE_SEPARATOR};

            DataOutputStream stream = new DataOutputStream(serial.getOutputStream());
            stream.write(message);

            log.info("Turret control message sent (pan={}, tilt={}, fire={})!", pan, tilt, fire);
            return  true;
        } catch (Exception ex) {
            log.error("Error while sending control message: ", ex);
            return false;
        }
    }
}

@Component annotation is there to show Spring that ArduinoConnection is a bean and as such Spring should take care of its lifecycle and usage as dependency. By default Spring creates beans in singleton scope. This is fine for us - we only need one such object. connect method is marked with @PostConstruct. This makes the method an initialization callback that gets invoked when ArduinoConnection object is created (it will happen when application is started). @PreDestroy is used on disconnect method to make sure that connection to serial port is released when the program is closed.

controlTurret method is the piece of code that is responsible for sending gun turret action request to Arduino. That method is used in TurretController.executeTurretAction, remember? it uses instance of NRSerialPort to communicate over serial port (gnu.io.NRSerialPort package makes it possible). It comes form NeuronRobotics/nrjavaserial library which is a fork of RXTX that greatly simplifies serial port access. nrjavaserial takes care of loading proper native library needed to access the port (it worked well on my Windows 7 x64). As stated before, I'm not going to discuss Arduino communication and microcontroller code in this post. I will just note that you don't have to worry about casting int to byte while message array is created. It's sad but Java doesn't have unsigned bytes so it will show (byte)MESSAGE_SEPARATOR (which is 255) as -1 while debugging, but a correct value will go over wire to Arduino. Take a look at this screen shot from Free Device Monitoring Studio (you can use this tool to check what data is sent to Arduino through serial port):

Bytes sent to Arduino... Click to enlarge...

Let's get back to ArduinoConnection class: portName and baudRate properties are marked with @Value annotations. This way it is very easy to take the settings from configuration file. All you have to do is to create a file named application.properties in /src/main/resources directory and values will be automatically loaded from config. Here's the content of application.properties file: 

server.address = 192.168.0.17
server.port = 8090

arduinoPortName = COM3
arduinoBaudRate = 9600

Apart from aforementioned settings for Arduino, there are two other elements, namely: sever.address and server.port. By default Spring Boot runs the application on localhost:8080. I've changed this to custom settings to make it easy to access the application from devices connected to my WiFi network... Accessing TurretController from such devices is the reason why I added following CorsFilter class to the project:

package springarduino;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CorsFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}
}

Thanks to this Cross-Origin Resource Sharing filter it's easy to make ajax calls to executeTurretAction method without using some trickery like JSONP to circumvent same-origin policy restrictions.

And that's it! All interesting elements of the Java web app were discussed. Full code is accessible on GitHub. Since this is Gradle based project, running it is as easy as typing gradlew run. I've included Gradle Wrapper in the repo so you don't even need to have Gradle installed...

[OoB] Moving webcam with joystick and servos (Arduino/SharpDX/WinForms)

Time for the third episode of "Out of Boredom" series :) There was a Sonar project and something about shooting paintballs... This time you will learn how to use Arduino and .NET 4.5 to receive input from joystick and use it to control servos that move a webcam horizontally and vertically!

  • Here you can see a video of the project outcome: Vimeo
  • This repository contains all the code: GitHub

Controlling servos with joystick... Click to enlarge...

How it works? Short version: joystick (in my case Logitech Extreme 3D Pro) is connected to laptop with Windows 7 via USB. Desktop application (.NET 4.5/WinForms) uses SharpDX library (managed DirectX API) to pull position information from joystick. This info is presented in numerical and graphical way on UI (C# 5.0 async helps here). Joy position is then translated into desired pan&tilt servo angles and that data is sent to Arduino Uno through serial port. Arduino receives the data, and thanks to its Servo library, commands servos to move... 

Longer description is split into 2 parts. The first describes desktop app, the second shows Arduino sketch...

 

1. Desktop application

ServoJoy WinForms application... Click to enlarge...

Main task of the program is to read joystick position. This is easy thanks to SharpDX 2.6.2.0 library that wraps DirectX API so it can be conveniently operated with C#. SharpDX and SharpDX.DirectInput NuGet packages are used in the app. This is the class that contains all the code necessary to monitor joystick movements:

using SharpDX.DirectInput;
using System;
using System.Linq;
using System.Threading;

namespace ServoJoyApp
{
    public class JoystickMonitor
    {
        private string _joystickName;

        public JoystickMonitor(string joystickName)
        {
            _joystickName = joystickName;
        }

        public void PollJoystick(IProgress<JoystickUpdate> progress, CancellationToken cancellationToken)
        {
            var directInput = new DirectInput();
            
            DeviceInstance device = directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AttachedOnly)
                                        .SingleOrDefault(x => x.ProductName == _joystickName);

            if (device == null)
            {
                throw new Exception(string.Format("No joystick with \"{0}\" name found!", _joystickName));
            }
            
            var joystick = new Joystick(directInput, device.InstanceGuid);
            
            joystick.Properties.BufferSize = 128;
            joystick.Acquire();

            while (!cancellationToken.IsCancellationRequested)
            {
                joystick.Poll();
                JoystickUpdate[] states = joystick.GetBufferedData();
                
                foreach (var state in states)
                {
                    progress.Report(state);                    
                }
            }
        }
    }
}

DirectInput class lets us obtain access to joystick. Its GetDevices method is used to look for an attached joystick with particular name. If such device is found, object of Joystick class gets created. Joystick class has Poll method that fills a buffer containing information about joysticks states. State info comes in a form of JoystickUpdate structure. Such structure can be used to determine what button was pushed or what is the current position in y-axis for example.

Here's an example of reading current joystick position on x-axis:

if (state.Offset == JoystickOffset.X)
{
      int xAxisPosition = state.Value;
}

Position is kept in Value property but before using it you have to check what that value means. This can be done by comparing Offset property to desired JoystickOffset enum value. See the docs of JoystickOffset to see what kind of values you can read.

PollJoystick method presented earlier has fallowing signature:

public void PollJoystick(IProgress<JoystickUpdate> progress, CancellationToken cancellationToken)

IProgress generic interface was introduced in .NET 4.5 to allow methods to report task progress. PollJoystick method uses it to notify the rest of the program about changes in joystick state. This is done by progress.Report(state) call. The second parameter (with CancellationToken type) lets as stop joystick polling any time we want. PollJoystick method does it when IsCancellationRequested property of CancellationToken structure is set to true. Is it necessary to use this async-related stuff to poll joystick data? No - it's possible to put joystick polling loop directly in button event handler but then all the work will be executed in UI thread and it will make application unresponsive! Here's how you can run joystick monitoring in modern C#:

private async void btnJoystickMonitorStart_Click(object sender, EventArgs e)
{
    try
    {
        btnJoystickMonitorStart.Enabled = false;
        btnJoystickMonitorStop.Enabled = true;

        var joystickMonitor = new JoystickMonitor(txtJoystickName.Text.Trim());

        _joystickMonitorCancellation = new CancellationTokenSource();
        var progress = new Progress<JoystickUpdate>(s => ProcessJoystickUpdate(s));
        await Task.Run(() => joystickMonitor.PollJoystick(progress, _joystickMonitorCancellation.Token), _joystickMonitorCancellation.Token);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Oh no :(", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

Notice that button even handler is marked with async keyword. Before PollJoystick task is started a new cancellation token is created and ProcessJoystickUpdate is set as a handler for asynchronous task progress notifications. When this setup is done joystick monitoring task is started with await Task.Run call...

This is a part of code responsible for handling joystick state changes:

private void ProcessJoystickUpdate(JoystickUpdate state)
{
    if (state.Offset == JoystickOffset.X)
    {
        int xAxisPercent = GetAxisValuePercentage(XAxisMax, state.Value);
        pnlXAxisPercent.Width = (int)xAxisPercent;
        lblXAxisPercent.Text = xAxisPercent + "%";
        lblXAxisValue.Text = state.Value.ToString();

        if (rbPanOnXAxis.Checked)
        {
            _panServoPosition = MapAxisValueToPanServoPosition(state.Value, XAxisMax);         
            lblPanServoPosition.Text = _panServoPosition.ToString();
        }
    }
	
	// ... more ...

As you can see JoysticUpdate structure is used to determine current position in x-axis. UI elements are updated and desired servo position is calculated... If you've looked carefully you might be wondering why if (rbPanOnXAxis.Checked) exists. This is done because the app lets its users decide whether pan (horizontal movement) servo should be bound to x-axis (right-left stick movement) or to zRotation-axis (controlled by twisting wrist on joystick - not all joysticks have this feature).

private byte MapAxisValueToPanServoPosition(double axisValue, double axisMax)
{            
    byte servoValue = (byte)Math.Round((axisValue / axisMax) * (PanServoMax - PanServoMin) + PanServoMin);
    return chkPanInvert.Checked ? (byte)(PanServoMax - servoValue) : servoValue;
}

Values of my joystick position are reported in 0 to 65535 range but only numbers from 0 to 180 are meaningful for servos I've used. That's why method MapAxisValueToPanServoPosition presented above was created...

Ok, so we are done with detecting joystick movements! Now we need to send desired servo position to Arduino. Fortunately this is really simple thanks to SerialPort component that you can use in WinForms programs. Just drag this component from toolbox and use code as below to control connection with Arduino (spArduino is the name I've given to SerialPort component):

private void btnArduinoConnectionToggle_Click(object sender, EventArgs e)
{
    try
    {
        if (spArduino.IsOpen)
        {
            spArduino.Close();

            btnArduinoConnectionToggle.Text = "Connect";
        }
        else
        {
            spArduino.BaudRate = (int)nudBaudRate.Value;
            spArduino.PortName = txtPortName.Text;

            spArduino.Open();
            btnArduinoConnectionToggle.Text = "Disconnect";
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Oh no :(", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

In my case Arduino is accessible via COM3 port and baud rate of 9600 is sufficient. That's right - despite the fact that the device is connected to PC with USB cable it is accessible via COM port.

Sending servo position to Arduino is really easy:

private void tmServoPosition_Tick(object sender, EventArgs e)
{
    if (spArduino.IsOpen)
    {
        spArduino.Write(new byte[] { _panServoPosition, _tiltServoPosition, SerialPackagesSeparator }, 0, 3);
    }
}

spArduino.Write call is used to send an array of three bytes to Arduino. Two values are for requested servo potions and the last one is used to separate the pairs so servo controlling program can always distinguish between pan and tilt values. Writing over serial port is executed inside Tick method of Timer component. This time I didn't bothered with manual creation of background task. I just dragged Timer component and adjusted its Enabled and Interval properties to make the app communicate with Arduino every 10 milliseconds...

 

2. Arduino sketch

We've discussed an program that can detect joystick movements and send servo position requests over serial port. Now time for a piece of microcontroller software that can actually force servos to move. This is the whole code:

#include <Servo.h>  

const byte setupReadyLedPin = 8;
const byte panServoPin = 10;
const byte tiltServoPin = 12;
const byte separator = 255;

Servo panServo; 
Servo tiltServo; 

void setup() {  
    pinMode(setupReadyLedPin, OUTPUT);
         
    panServo.attach(panServoPin);   
    tiltServo.attach(tiltServoPin);   
    
    Serial.begin(9600); // Open connection with PC
    
    digitalWrite(setupReadyLedPin, HIGH);
}

void loop() {      
    if (Serial.available() > 2) {            
        byte panAngle = Serial.read();
        byte tiltAngle = Serial.read();
        byte thirdByte = Serial.read();
         
        if (panAngle != separator && tiltAngle != separator && thirdByte == separator) {         
            // Moving servos
            panServo.write(panAngle);
            tiltServo.write(tiltAngle);
        }
    }       
}

Yup, it's that easy! Servo library is included to allow for panServo and tiltServo objects to be created. These objects (of type Servo) make it possible to command servos to move into desired positions. This is done by calling write method with desired angle, like this:

panServo.write(panAngle);

Before it can be done however, servos have to be assigned to Arduino's output pins. This is achieved by calls to attach method seen in setup function. Digital servos are controlled by duration of ON pulse calculated in 20ms intervals, 1.5ms ON pulse should command a servo to move to the middle... But Servo library does all the heavy lifting for you so you don't have to create proper control signals manually. All you need to do is connect 3 cables each servo has. The servos I own use brown cable for ground, red for plus and orange for control signal. Sonar project used single micro servo so the only power supply needed was the one included in USB. This time two servos are utilized so you should add external power supply. I've connected 1A AC/DC power adapter through a plug that is included on Arduino Uno board and the servos worked really well. Arduino has a built-in fuse that protects USB port from overcurrent (it's a resettable fuse that doesn't allow current bigger than 500mA)...

Communication with .NET application is implemented with Serial class. First, in setup function, a connection is established with Serial.begin(9600) call. Then inside a loop Serial.available method is used to check if packet with servo positions request has arrived from PC. If so, pan&tilt servo angles are read and servos are ordered to move.

 

This is all that is necessary to control two servos with joystick connected to a computer :) In my project I've used DGServo S3003 servos with pan&tilt bracket to move A4tech PK-910H webcam and I'm really happy with the results! While watching the clip you may think that camera is moving to much compared to joystick movements. Keep in mind however, that servos move in 180 degrees but my joystick operates in smaller range. This is why small stick movement results in big camera swing. Despite that, I was able to control servos position with 1-degree precision quite easily... 

Update 2015-01-11: Click here to see a video of my recent project that has pan and tilt servos used to build gun turret!