Arduino Roller Door

My Arduino Roller Door project has been something my colleague and I have been putting off for a while. Although riding to work is much more enjoyable and less stressful than driving, arriving outside the factory door and stopping our motorbikes to remove our keys, dismounting, and manually opening the roller door had gotten very irritating very quickly. We have both been interested in adding keyless entry to the office’s feature set for over a year now, and finally decided to do so with this quick and fun project early in 2016!

Our implementation was a graceless solution to the problem, but since the facility is used by other people, reliability and safety were of paramount importance; at the very least to avoid having to come back to the office after getting halfway home to fix a door that is stuck half way down. Jamie put the hardware together, mostly utilising knick-knacks and leftovers from around the office; only purchasing the break beam which we used to stop the door in case of obstruction, and the receiver with remote controls. He also put together a ‘sample’ unit, which I used to compose a simple sketch to run the implementation.

Simple representation of the hardware for development.
A simple representation of the hardware for development.

The break beam was an interesting unit, with actively powered components on either side of the passage. It featured 3 individual beams with some kind of diffuser covering each one, beam adjustability, and a concealing cover. The interface out of this was pretty simplistic; a relay that actuated once an obstruction was present and released once the obstruction was removed.

arduino-roller-door-5
Break Beam

The door’s existing componentry included a motor with electrical limit switches mechanically coupled to the gearbox, a simple latching relay circuit, and a control panel.
arduino-roller-door-4

The door had limit switches set to stop it half way open; this was presumably due to the lowered ceiling. The workshop area is over two stories tall, however, it has a ceiling at the standard height, supporting lighting and heating/cooling. It seemed logical to retain these limit switches as a final assurance measure to prevent overdriving in either direction. It would have been desirable to include limit switches in our implementation, and this is something I will likely add at a later date, either with aditional switches, or by incoorporating the existing switches without compromising their current function. The fritizing scetch below gives a breif idea of how everything hangs together – there isn’t much to it really.

arduino-roller-door-7

The software was splurged out sometime between 11pm and sleep, and didn’t take long at all. Using the test device my colleague put together simplified the process, and in an hour or so I had everything functional. I used Visual Micro, which is an exceptionally well featured add-in for Visual Studio, allowing for Arduino projects, and even deploying to the hardware. Interestingly the deployments are about 4 times quicker using Visual Micro than the Arduino IDE; I have been a relatively early adopter of Visual Micro, and this has always been the case.

My implementation to control the door is neither elegant, nor beautiful, but has worked reliably thus far (GitHub link and bottom of page). The code however is reasonably clean, and easy to follow. I have seperated input and output helpers to their own files, keeping the sketch slim and readable.

The input helpers simplify the process of evaluating the state of an input, without having to think about the logic (positive/negative logic) or invest much effort into tracking state for uperations, like ‘pressing’ and ‘releasing’. It also has some simple debouncing incorporated.

#include "inputFunctions.h"
#include <arduino.h>

void UpdateInput(Input * input, unsigned long * interval)
{
 input->previousState = input->currentState;

 // Check if a debounce is underway
 if (input->debounce <= 0)
 {
 // If not, update inputs
 input->currentState = digitalRead(input->pin) == input->activeState;

 // If state changed, so start a debounce
 if (input->previousState != input->currentState) input->debounce = DEBOUNCE_TIME;
 }
 else
 {
 // This accounts for irregularities in the time taken to loop through the main program
 int dTime = (int)(*interval);
 if (dTime > MAX_THRESHOLD || dTime < MIN_THRESHOLD) dTime = MIN_THRESHOLD;

 // Count the loop time towards the debounce
 input->debounce -= dTime;
 }
}

bool ButtonPressed(Input * input)
{
 return (!input->previousState) && input->currentState;
}

bool ButtonReleased(Input * input)
{
 return (!input->currentState) && input->previousState;
}

bool InputActive(Input * input)
{
 return input->currentState;
}

bool InputInactive(Input * input)
{
 return !(input->currentState);
}

void InitialiseInput(Input * input)
{
 pinMode(input->pin, INPUT);

 input->currentState = digitalRead(input->pin) && input->activeState;
 input->previousState = input->currentState;
}

The output helpers work towards the same simplification, by abstracting the active state from the application logic. Although this is generally wastefully of memory to a small degree, at this stage, there is plenty to spare.

#include "outputFunctions.h"
#include <arduino.h>

void UpdateOutput(Output * output)
{
 // Write the output buffer
 digitalWrite(output->pin, output->currentState == output->activeState);
}

void InitialiseOutput(Output * output)
{
 pinMode(output->pin, OUTPUT);
 UpdateOutput(output);
}

void SetOutput(Output * output, bool state)
{
 output->currentState = state;
}

These are underpinned by some simple types to track inputs and outputs:

#ifndef _ROLLERDOOR_TYPES_H_
#define _ROLLERDOOR_TYPES_H_

typedef struct {
 int pin;
 bool currentState;
 bool previousState;
 bool activeState;
 int debounce;
} Input;

typedef struct {
 int pin;
 bool currentState;
 bool activeState;
} Output;

#endif

This all contributes to simple uses throughout the main sketch, such as declaring an input, with some active state:

Input buttonUp = { 4<, false, false, LOW, 0 };

Initialising the input:

InitialiseInput(&buttonUp);

Updating the input (where the interval time is the time since the previous loop-pass):

UpdateInput(&buttonUp, &intervalTime);

And simple use:

if (ButtonPressed(&buttonUp) || ButtonPressed(&buttonStop))) doorState = DoorUp;

The code, although stable, has a few irritating aspects I would like to clear up, and will likely do so as time permits throughout the year. This includes:

  • Adding support for different types of doors.
  • Adding a web server, with simple endpoints to perform operations or query the door’s state.
  • Cleaning up the code and state management generally.
  • Adding simple configuration of options and accessories (such as enabling/disabling limit switches, break beams, and remote contol.
arduino-roller-door-8
Mocked up hardware, ready for its first day of use before formalising and tidying up the implementation.

You can download the source, or add to it on GitHub.

Getting started with Xamarin, Prism, Unity, and UWP – Part 1

Xamarin, Prism, Unity, and UWP are technologies that have been on my short list of technologies to embrace for a while. I initially tried to ease into UWP, and I met problem after problem which deterred me from progressing. After struggling to find libraries I needed from the traditional .Net collection, and struggling to make progress with the incomplete status of Prism 6 in UWP generally (coming from Prism 5 and WPF), I made the decision to shelve my project temporarily and move onto something else. Xamarin has a lot to offer, and Prism 6 seems to really complete the experience, but my first attempts to make progress were riddled with broken templates, superseded instructions, inaccurate information,  and unusual issues. I put this guide together to help anyone else that may find themselves in the same situation, lost in the current climate of these exciting technologies. Over the next couple of weeks, I hope to cover:

  • Project Setup
  • Navigation & Eventing
  • SQLite
  • Cross-Platform Deployment

Of course, all code below can be found in my public bitbucket blog repository under ‘GettingStartedWithXamarinPart1’.

Creating a Project

I am going to assume a complete Visual Studio 2015 installation is present, and Xamarin is installed, and I will be closely following this guide from the Prism Xamarin documentation to get started.

getting-started-with-xamarin-01

First of all, we need the Prism Template Pack. This is easy enough to procure from the Online Extensions Library. In Visual Studio, open ‘Tools’ > ‘Extensions and Updates’, select ‘Online’, and then search for “Prism Template Pack” and click ‘Download’ with it selected. You will need to restart visual studio afterwards.

getting-started-with-xamarin-02

Now you will be able to use the template pack to create a new solution. If you are as lucky as me, you will be greeted with these lovely messages:

getting-started-with-xamarin-03 getting-started-with-xamarin-04 getting-started-with-xamarin-05

…and your solution explorer will look rather incomplete, with only iOS and Android projects; if this is not the case for you however, skip to the next section.

getting-started-with-xamarin-06

To clean up this mess, we need to open the solution folder and delete the project folders of the projects that failed to load. In this case, “GettingStartedWithXamarin.UWP”, “GettingStartedWithXamarin.Windows”, and “GettingStartedWithXamarin.WinPhone”.

 

getting-started-with-xamarin-07a

Once this is complete, we can create a new Blank UWP project following the same naming convention. You will also need to select a target, and minimum supported platform, which can most likely be left as default.

To prepare this UWP project so that it is compatible with our Xamarin landscape, we will need to make some minor changes, as detailed in the Xamarin documentation here.

First, we need to add references to the new project. The Prism and Xamarin references can be added by right-clicking on the solution and selecting the “Xamarin.Forms” package from the list of installed packages, then selecting the new project on the right and clicking install. This process should be repeated for “Prism.Unity.Forms” which will also add the other dependencies it requires.

getting-started-with-xamarin-09

The final reference needed is to the shared project created by the template pack. Right-click on the UWP project’s references section in the solution explorer, and ‘Add Reference…’ to the shared project.

getting-started-with-xamarin-10

The solution build configurations should be updated to build and deploy this project when we build the solution, setting the build configuration up to do this now reduces an irritating nag screen later, and an additional steps of building and deploying before debugging. Right-click on the solution in the solution explorer and select ‘Properties’. Under ‘Configuration Properties’ > ‘Configuration’, ensure the adjacent ‘Build’ and ‘Deploy’ boxes are ticked for our new project.

getting-started-with-xamarin-11

In the UWP project, we now need to make some code changes to complete integration with Xamarin forms and Prism. In the App.xaml.cs file, locate the ‘OnLaunched’ method, and below ‘rootFrame.NavigationFailed += OnNavigationFailed;’ add:

Xamarin.Forms.Forms.Init (e);

In MainPage.xaml, add the following namespace to the Page:

xmlns:forms="using:Xamarin.Forms.Platform.UWP"

then delete the grid element contained within the page’s body, and finally, change the page tag to instead be ‘forms:WindowsPage’. This should look something like this:

<forms:WindowsPage
 x:Class="GettingStartedWithXamarin.UWP.MainPage"
 xmlns:forms="using:Xamarin.Forms.Platform.UWP"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="using:GettingStartedWithXamarin.UWP"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d">;
</forms:WindowsPage>;

The MainPage.xaml.cs file now must no longer inherit from ‘Page’, and in its constructor it needs the following added below ‘InitializeComponent’:

LoadApplication(new GettingStartedWithXamarin.App());

This should now look as follows:

 public sealed partial class MainPage
{
 public MainPage()
 {
 this.InitializeComponent();
 LoadApplication(new GettingStartedWithXamarin.App());
 }
}

Congratulations! You should now be able to build and run your new UWP project!

getting-started-with-xamarin-12

Adding Data Binding

I won’t go into detail explaining how the shared project hangs together, as this is very well covered in the initially linked tutorial from the Prism library. To demonstrate binding with a little more complexity, we will extend our MainPage now to allow a user to type two numbers into two text fields, and show the sum of the numbers in a label. Although this is petty, it is of value because the Xamarin markup is different to XAML, and the provided elements have different names to those of typical Xaml. We will do this work inside the project which is shared with all the platform-specific projects. Open MainPage.xaml. We can start by adding some labels and inputs.

A Label is expressed as follows:

<Label Text="Number A:" />

An Input:

<Entry Text="{Binding NumberA}" />

I have added two number inputs, and a result field with bindings to properties in the view model which are not yet implemented. This once complete should look something similar to this:

<?xml version="1.0" encoding="utf-8" ?>;
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
 prism:ViewModelLocator.AutowireViewModel="True"
 x:Class="GettingStartedWithXamarin.Views.MainPage"
 Title="MainPage">;
 <StackLayout HorizontalOptions="Center" VerticalOptions="Center">;
 <Label Text="{Binding Title}" />;
 <Label Text="Number A:" />;
 <Entry Text="{Binding NumberA}" />;
 <Label Text="Number B:" />;
 <Entry Text="{Binding NumberB}" />;
 <Label Text="Sum:" />;
 <Label Text="{Binding Result}" />;
 </StackLayout>;
</ContentPage>;

The view model needs fields to support these bindings, and a method to perform the summing operation on the two values.

A value for binding should be a property, even if it simply uses a backing field. The ‘SetProperty’ method is an important part of Prism, as it takes the burden out of notifying the view that a change has occurred.

private string _numberA;

public string NumberA
{
 get { return _numberA; }
 set 
 {
 SetProperty(ref _numberA, value);
 Sum();
 }
}

My ‘sum’ method is pretty simple too:

private void Sum()
{
 try
 {
 var a = int.Parse(_numberA);
 var b = int.Parse(_numberB);
 Result = $"{a} + {b} = {a + b}";
 }
 catch
 {
 Result = "Invalid Input.";
 }
}

The MainPageViewModel.cs looks like this with these mechanisms accounted for:

public class MainPageViewModel : BindableBase, INavigationAware
{
 private string _numberA;
 private string _numberB;
 private string _result;

 private string _title;

 public string NumberA
 {
 get { return _numberA; }
 set 
 {
 SetProperty(ref _numberA, value);
 Sum();
 }
 }
 public string NumberB
 {
 get { return _numberB; }
 set
 {
 SetProperty(ref _numberB, value);
 Sum();
 }
 }
 public string Result
 {
 get { return _result; }
 set { SetProperty(ref _result, value); }
 }

 public string Title
 {
 get { return _title; }
 set { SetProperty(ref _title, value); }
 }

 public MainPageViewModel()
 {

 }

 private void Sum()
 {
 try
 {
 var a = int.Parse(_numberA);
 var b = int.Parse(_numberB);
 Result = $"{a} + {b} = {a + b}";
 }
 catch
 {
 Result = "Invalid Input.";
 }
 }

 public void OnNavigatedFrom(NavigationParameters parameters)
 {

 }

 public void OnNavigatedTo(NavigationParameters parameters)
 {
 if (parameters.ContainsKey("title"))
 Title = (string)parameters["title"] + " and Prism";
 }
}

Our app now runs, and adds up numbers!

getting-started-with-xamarin-13

In the next part, we will expand on this implementation, to add navigation between pages and events.