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.

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