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.

Artificial ANPR/LPR Image Generation

A number of months ago, I was implementing some complex transaction forming functionality in a work project, and found I was spending more time creating test scenarios and testing my implementation than I could spend developing, as a consequence of the complex nature of the data, and real-time processing components. Traditionally, we would create data using real and configured  hardware, or load a video into one of our ANPR (Automatic Number Plate Recognition) engine providers, to simulate a camera. Although I had previously made tools to automatically create videos for simulation from a csv of licence plate data, it wasn’t practical to make synchronised videos for > 2 ANPR lanes.

artificial-image-generation-01

The transaction forming and read processing systems are idiosyncratic in the industry, and offer a lot of flexibility in ANPR applications. A number plate would typically be detected by our ANPR/LPR hardware in free flow (a vehicle passes through the camera and its presence is automatically acknowledged by the system), or triggered (another device or mechanism prompts the engine to analyse the currently buffered field of view and extract a licence plate read), and passed by its provider to the integrator, which would abstract the provider’s function and configuration, and facilitate a conduit to the processing hub and data repositories. The hub is then able to accept the read, analyse the circumstances from which it arrived, and determine the next stage to pass it to for further processing.

Stages could do anything, from post-correcting a numberplate (changing a low confidence ‘i’ to a ‘1’ in an Australian state with a plate format that has a higher probability of presenting a ‘1’ in this position), or transposing the read from its physical origin to a virtual lane or camera based on complex rules or traffic direction, to forming transactions and journeys from the existing reads in conjunction with this read, representing a visit in a car park, or passage through a defined zone.

When a stage is developed or modified, it typically relies on complex aggregated read data. Understandably using real hardware is quite burdensome to set up, configure, and track. The alternative is to artificially create data; this might otherwise result in setting up integration tests or seeding a data store. These again only go so far, especially whilst debugging in real time. I created a solution at home to simplify the end to end process, with a generation system that could create an artificial looking number plate and attach it to a drawn vehicle. Although petty, the image of the vehicle is important because this makes it easy to keep track of a certain car and notice greater system flaws during integration.

artificial-image-generation-02

My solution mounted as a provider inside our existing integrator, and was effortlessly absorbed by the IOC (inversion of control) resolver, (ensuring compatibility back to 2012!), and presented a WebAPI 2.0 set of endpoints. The endpoints permitted triggering a free flow read or queueing data at a camera/lane/engine level to be dequeued should a trigger arrive externally. This further extended to generate a random licence plate from the permissible stand-issue Victorian plates, or to generate a car for a known plate in the correct format, to providing the exact data desired for the read; including metadata, to images.

Note that most ANPR/LPR hardware uses two lenses. One to capture the vehicle in a nice format for display, and one through a lenses with an infrared filter applied, to improve accuracy with a higher contrast image.
Note that most ANPR/LPR hardware uses two lenses. One to capture the vehicle in a nice format for display, and one through a lenses with an infrared filter applied, to improve accuracy with a higher contrast image.

This ultimately allowed for running real-time scenarios from JavaScript or a tool like postman, with the exact data needed, whilst supporting end-to-end debugging of the entire transaction flow. This resulted in reducing a confusing and irritating 6 day job, to a 2 day task which was pleasurable to work on.

Although I haven’t updated this specific tool in a long time, I have expanded components for many other projects with features such as Taxi and Bus support, multiple state standard issue plate support, consistent car generation for any particular plate text, and fun value adds, like derelict looking vehicles to attach to watch lists, and people rendered driving the cars. I am now at a point where I would like to formalise the generation, rendering, and web interface components, to support my LEAP (LPR Engine Accuracy Platform) family of projects, which will eventually contribute towards developing my own ANPR/LPR engine from the ground up. This would include:

  • A portable definition file for a licence plate format, so that it can be created in an editor by a graphic designer or engineer, and integrated with any other LEAP component.
  • A portable definition file for a vehicle, or content generally. Supporting multiple colours, layers, and rules. Again, the goal would be to extract the engineering/design work so that it can be performed by someone more effective in this domain.
  • An ANPR/LPR virtual engine, with full metadata, such as plate coordinates, and an inaccuracy factor to simulate a real engine in software.
  • An abstracted ANPR/LPR Engine interface, with a provider to utilise my virtual implementation.
  • A presentable web interface to wrap and present all the virtual engine functions, and configure the instance.
  • Documentation.

As the study semester concludes and my free time becomes more available, this will be something I work towards, after first defining the shape of a generic ANPR/LPR read (LEAP.ReadIO). A new and exciting project has arisen at work which would largely benefit from such a system, and I’m confident time in orders of magnitude could be saved in development and testing.

artificial-image-generation-04

Arduino Tamagotchi – Part 2

This post details the final implementation of my Arduino Tamagochi as introduced in my previous post.

The aim of this project was to create a ‘Tamagochi like’ pocket friend based on the Arduino platform for a friend for her birthday, with the intention of making the creature inside the device, her. I will not delve into intimate detail of the construction and programming, but I will step through the overall build, and share the final result.

After receiving my enclosure from a friend, I was initially somewhat disappointed with the result. It was printed in PLA instead of my desired ABS, and exhibited signs of pitting; the back piece was also warped. Although hesitant, I took his advice on painting the enclosure which actually came up really well – far exceeding my expectations. If this was to have been ABS without imperfections I would have likely done minimal surface preparation and retained the 3D printed charm.

Projects-Tamagotchi-09

I primed the print initially with British Paints ‘Prep 4 in 1’ which was a poor choice for this application. It was easy to apply, and absorbed imperfections with ease, however it was soft once dry and not pleasant to sand. After realising this I immediately moved to spraying and sanding the enclosure with Dulux Duramax, and sanding after each layer had dried. Duramax is easily the most pleasant spray paint experience I have ever had; the result was not tacky like I expected, hard wearing, and dried really quickly with great adhesion. Although the coats where noticeably thinner by a large order of magnitude, after approximately 8 rounds of application and sanding the defects of printing become invisible and the finish began to look really beautiful and more like a nice plastic than painted surface. Using a paint of this quality has changed my perception of using canned spray paints.

Projects-Tamagotchi-08

The buttons where a little painful to install, however I anticipated this might be the case. I pressed in a spare tactile push button (with more force than I would apply to a button I intend to use) a few times to wear the enclosure sides down. It was a little tricky to keep the button head aligned with the enclosure hole as it descended the square shaft, but I was able to stabilise the opposing side using the rear of a drill bit of suitable size. Eventually the buttons would slide in and out of place with minimal effort, and no damage. I soldered fine wires to the rear of these buttons, daisy chaining them with a common endpoint and securely potting with hot glue and levelling off. The channels which I cut into the enclosure’s model worked well for managing the wires, and the dimensions printed suited the wire gauge used. If I was to do this again however I would use a finer gauge wire to make internal routing easier, or just bite the bullet and print a PCB.

I tested the input immediately after installing all buttons because with the hot glue and fitted shafts I would expect these to be tedious to remove. This yielded positive results and I moved on to the screen and microcontroller.

Projects-Tamagotchi-10

I performed a final test on the screen and re-secured the display on its breakout board before installing and temporarily securing with hot glue. I then prepared the Arduino Nano by removing all the header pins, LED circuitry, and filling the through holes with solder. Once complete I fixed this on top of the display board with a good quality double sided tape; thick enough to absorb the components dimensions and allow everything to sit parallel and neatly. I hastily mocked up the screens connections and tested the display again to ensure it was not exhibiting signs of insubordination.

The speaker was next, and this was something that I hadn’t prototyped at all. I connected this via a 100 ohm resistor to the Arduino and ran the Tutorial code proving everything worked, although the sounds where horrible. Luckily this was easy to fix in the implementation.

With all the user experience parts in place, I set about removing all the mocked up wiring and replacing with more attentive detailed work, and careful routing. I spent quite a lot of time getting this right, with the body firmly fastened in a vice, protected by an ugly rag which I can only assume was once someone’s much loved frog pyjamas. I used SMD resistors, FETs, and Capacitors where needed to implement pull-up/down practices, switch the display and backlight on and off from the micro to reduce power consumption, and manage power generally. There was a few engineering challenges to overcome with respect to power consumption and prolonging battery life using out of the box hardware, but it was more or less straight foreword to construe a solution by carefully selecting switching components and using interrupts and sleep on the Arduino.

I was really happy with how the final result was taking form however installing the rear panel proved to be my downfall.

After connecting the batteries, installing the plastic safety tab I had macgyvered from a plastic bottle, and testing the power switching components, I attempted to install the back cover. Despite the distortion, with a little pressure the parts aligned and it was easy to install the 4 screws. Unfortunately the pressure from the warped rear was enough to strip two of the screws threads as the printed case gave way. I have done this sort of thing without issue using ABS on my own printer, and believe it happened due to a combination of the material used, and the print settings applied limiting wall thicknesses and infill.

I decided to glue everything closed, as given its use the likelihood of wanting to replace batteries would be pretty low, there is a USB mini port for power, and realistically I could manufacture another and reuse expensive parts with minimal effort. The gluing was successful using epoxy. Unfortunately the clamps I used (despite my best efforts) damaged the enclosure where pressure was applied. Again, I believe this is due to the fill settings when the model was prepared for print. Irrespective, the results are still pleasing. I attempted to touch up the damage, carefully rewording the housing in situ.

With regards to the software, I overhauled my content compiling system to accept midi files, and it now produces a series of resource files with a references header file to permit name references and readability in the main program. I incorporated a sound player into the game loop which allowed tracks to be enqueued for play, queues to be swapped or cleared, and simplified dealing with sound overall. I didn’t quite get as far as full text support or better image support, but given the amount of interest I have received in this project, I speculate that avoiding doing so will be impossible.

Projects-Tamagotchi-11

The final sketch had a smaller than expected footprint, and relied on minimal library functions. The device allows the user to play rock paper scissors with the device, feed it an assortment of foods, and give it coffee. Pressing the middle button on the home screen changed states to show the birthday messages and resume normal operation when subsequently pressed. The creature increases in happiness as it wins games and gets what it wants. Repetitive losses, and undesired feedings sadden her. She also gets tired and enjoys her sleep.

I have been hesitant to share code and designs for this at present due to the amount of work I have invested, and the devices purpose. I have spent many hours designing, manufacturing, developing, writing tools, and testing this device for a really special friend. Since this is a gift, I don’t feel that it would be right to immediately share my work.

As mentioned above, I have received a lot of interest and support for this from friends who have seen it in various states of construction, and if I was to continue this project I would likely make a utility to generate software entirely rather than just content, with a simple user interface and storyboard. I would also expand the feature set a little more creatively. It has overall been a really fun project. I have learned a lot I wouldn’t have otherwise thought to investigate regarding the implementation of the Arduino platform, discovered a painting method which produces pleasing results, explored the composition of Midi files, and I have a deeper understanding of the XNA content pipeline which I investigated when looking for inspiration for my content compiler.

Projects-Tamagotchi-12