What it does
This project enables administrators to remotely provide access to buildings by unlocking doors. It is intended to be used at my local makerspace (my second home) where managing physical keys have proven to be problematic with many members. The makerspace in question is accessable via two doors - one main door which is shared with other tenants, and one inner door for the makerspace itself. The shared door often gets locked by other tenants while members are inside the makerspace and new visitors are locked out if the keys have been brought inside. Further, it is hard to know who to call to have the outer door opened. With the remote lock in place visitors can contact administrators to gain access.
This is phase one of a larger project in which members and temporary visitors will be issued time constrained attests for access. The attests will be published to an immutable distributed ledger based on blockchain technology, IOTA, and shared with the visitor. This attest is then transmitted to the Azure Sphere device via NFC or QR-code and the device will verify the attest on the blockchain and open the lock.
What you can expect
Phase one is only concerned with controlling an electronic lock and communicating with Azure IoT Central. The power supply available at the door frames is yet undetermined, during this fase the board will be powered by USB and the electronic locks by a lab power supply. This guide goes through starting a new project based on the provided IoT Central sample and points to relevant guides and points of interest. This part of the project requires no soldering.
Future advancements
The next phase involves integrating the NFC clickboard, calling the Azure-hosted gRPC attestation web service via Azure Functions, finalizing the Blazor web app for administration an visitor application and installing the physical locks. This stage of the project is actually intended for use in home care and for medicine cabinets in hospitals.
Hardware
Bill of Materials
Azure Sphere MT3620 development board 2x
Electronic locks 2x
Relay clickboard 2x
Wires and test leads
The electronic locks used in this project require constant current due to safety reasons and so eliminates the possibility of a battery powered lpwan solution. The Azure Sphere MT3620 development board, with it's strong security architecture, is a perfect option for this scenario.
The electronic locks allows for remotely granting access to the location while still allowing the use of keys and inside lock knob. When powered the lock prevents visitors without a key to enter from outside. Should power fail, e.g. due to fire, the door will be open. The power grid in our part of the world is very stable, shortages being extremely rare.
Getting started with Azure Sphere MT3620
I have used the Azure Sphere MT3620 development board for a number of projects in the past, for details please explore:
https://www.hackster.io/eivholt/distributed-health-record-using-iot-and-iota-d4bd45
The last time I developed using this board was on version 19.11. At the time of writing the current version is 20.05 and a few things have changed. Starting a new project I create a new git repository and fetch the latest https://github.com/Azure/azure-sphere-samples
Make sure to fetch all submodules, as I make this mistake all the time!
This project was made over the course of two evenings including documentation, following these two guides:
https://github.com/Azure/azure-sphere-samples/blob/master/Samples/AzureIoT/README.md
https://github.com/Azure/azure-sphere-samples/blob/master/Samples/AzureIoT/IoTCentral.md
The guides were up to date, my only peril being not paying close attention or performing outdated actions. Notice that the latest Azure Sphere version 20.05 did not contain device changes. The device version should therefore be updated to 20.04:
azsphere show-version
20.04
azsphere device show-deployment-status
Your device is running Azure Sphere OS version 20.05.
The Azure Sphere Security Service is targeting this device with Azure Sphere OS version 20.05.
Your device has the expected version of the Azure Sphere OS: 20.05.
I did run into a snag with the second device where I was unable to upload code at first. I had to run the following command 3 times before success:
azsphere device enable-development
warn: The device already has the 'Enable App development' capability. No changes will be applied to its existing capabilities.
Application updates have already been disabled for this device.
Installing debugging server to device.
Deploying 'C:\Program Files (x86)\Microsoft Azure Sphere SDK\DebugTools\gdbserver.imagepackage' to the attached device.
error: Image package failed to transfer to the device. Check if the image is too large.
error: Failed to install debugging server to device.
azsphere device enable-development
warn: The device already has the 'Enable App development' capability. No changes will be applied to its existing capabilities.
Application updates have already been disabled for this device.
Installing debugging server to device.
Deploying 'C:\Program Files (x86)\Microsoft Azure Sphere SDK\DebugTools\gdbserver.imagepackage' to the attached device.
Image package 'C:\Program Files (x86)\Microsoft Azure Sphere SDK\DebugTools\gdbserver.imagepackage' has been deployed to the attached device.
Previous device capabilities retained. Ensure that you have the correct development capabilities installed before continuing.
Successfully set up device for application development, and disabled application updates.
The part involving authenticating the devices for the Azure IoT Central application by generating and verifying a certificate can be a bit tricky. If you follow the instructions to point it should be possible to accomplish.
Customizing the sample application
After setting up the sample IoT Central application and device code and authenticating the devices a test run I verified that everything was in working order.
Create new template
I made a new template for my devices, as making a new version does not seem to allow removing previous interfaces (Temperature). I added Lock1 to this. Find the template in the repository.
Clean up unused code
I removed anything related to Temperature, both from device code and IoT Central template. I kept the rest as I think they might get recycled. After customizing the template I made sure to migrate the two devices to use the new one.
Actuator
Relay Clickboard
Next, I implemented the Relay Clickboard. I have used this in previous projects utilizing the libraries ported by James Flynn at https://github.com/Avnet/clickboard_demos
More info here https://www.element14.com/community/blogs/JimFlynn/2019/07/12/using-mikroe-click-boards-with-microsoft-sphere#jive_conte…
Since last time Azure Sphere has moved from Visual Studio project structure to CMake. As I am new to this and had limited time I ditched trying to compile the modules for linking. Also, I did not want anything other than the relay library for my project. In the end I included only the relevant header and implementation code and explicitly referenced it in the CMakeLists.txt for my project:
add_executable(${PROJECT_NAME} main.c eventloop_timer_utilities.c parson.c clickmodules/RELAY/relay.c)
I know, this is not a sustainable method but I allowed it for this simple application. When I add NFC support I will learn the propert way to do this.
From the relay demo in the module repository I added the relevant code to initialize and clean up the File Descriptors: https://github.com/Avnet/clickboard_demos/blob/master/SPHERE_MT3620/relay_demo/main.c
I used the StatusLED as a template to synchronize the state of the relay, calling it Lock1. In IoT Central I added a property with the same name and same features as StatusLED. I added an event with values Lock1ClosedEvent and Lock1OpenEvent. I haven't used these in the console yet as the boolean values are sufficient.
JSON_Object* Lock1State = json_object_dotget_object(desiredProperties, "Lock1");
if (Lock1State != NULL) {
// ... with a "value" field which is a Boolean
bool tempStatusRelay = json_object_get_boolean(Lock1State, "value");
if (tempStatusRelay != relaystate(relaysState, relay1_rd)) {
relaystate(relaysState, tempStatusRelay ? relay1_set : relay1_clr);
SendTelemetry(relaystate(relaysState, relay1_rd) == 1 ? "Lock1ClosedEvent" : "Lock1OpenEvent");
}
}
// Report current Lock1 state
if (relaystate(relaysState, relay1_rd) == 1) {
TwinReportState("{\"Lock1\":{\"value\":true}}");
}
else {
TwinReportState("{\"Lock1\":{\"value\":false}}");
}
Electronic lock
I found a simple solenoid driven electronic lock. It seems to do what it's supposed to do, but I can not vouch for it in terms of quality or lifespan. I wanted a low commitment to prove if the concept would work, with the option to upgrade if needed. The particular model I am using can be found here https://www.banggood.com/Door-Electric-Strike-Lock-Fail-Safe-NO-Narrow-type-Electronic-Control-12V-DC-p-1040055.html
Operation is simple: The lock is mounted in the door frame, not the door itself. When powered a solenoid keeps a wedge from being able to move. This catches the door (lock) bolt. Unless the bolt is retracted, i.e. via turning the key or inside knob, the door is locked. When disengaged the wedge is free to move out of the way of the bolt and the door can open without the use of the key or turning the inside knob.
Lock specs:
Voltage: 12V ± 10%
Working Current: 110mA-250mA
Circuit
The lab power supply serves as a standin until the available power source by the doors are known. The negative wire of the power supply is fed directly to the lock's negative terminal. The positive wire from the power supply is fed to one of the relay's terminals. A second wire is attached between the other terminal of the relay to the lock's positive terminal. When the relay is engaged the circuit is closed and the lock is engaged, i.e. shut. The wiring is very temporary in this phase.
Demonstration
The two locks can independently be toggled, paving the way for the next phase of the project.
The image above is a screen grab of the power supply where channel 1 is active and channel 2 idle.
Tip
To omit adding private credentials to the source code repository I did the following: I used the default app_manifest.json from the sample project and added the relevant changes (Gpio) and commited and pushed this to the repo. I then ran the following command to ignore further changes:
git update-index --assume-unchanged app_manifest.json