Every where I go looking for some Azure Sphere resources I see that it's always secure in every possible aspect. Looks like the creators of the chip are focused on this task the most. And I'm not really surprised. Currently majority of IoT connected devices are open source or not ESP based devices that leave the configuration to the (mostly amateur) users. When I see how creators want to make the board secure I, too wanted to create something secure and so I've come with simple yet configurable lock that can be used in homes and offices and of course, is IoT connected.
Design of the lock is really simple, it only consists of ready to use modules and some pull up resistors. Nothing fancy here to be honest.
To create such lock you would only need:
- 0.95 inch 96x64 oled display or similar (SPI controlled)
- 4x4 matrix keypad
- Magnetic switch
- Double relay module
- 7 10k pull-up resistors
The lock uses pretty much every available GPIO of Azure Sphere board so even if I had more ideas(the buzzer!) to add to the lock I'm out of luck, okay it would be possible to expand the board width registers and expanders but I wanted to make it simple.
We'll start with the main culprint of GPIO absence, the matrix keypad. The keypad uses every button of the pad except 'A' and 'D' so it's not possible to disconnect any of the pins sadly. But if we look how useful is the keypad then it's justified as it's the main component of the circut. It's used to communicate with the user to give him access to locked doors or to change configuration of the lock. The keypad uses eight pins of Click Module #2 of the Azure Sphere board: four as inputs with pull-up resistors connected to 3.3V and four push-pull outputs.
Click Module #1 consists of magnetic switch, lcd and double relay module. The magnetic switch is just treated as input with 3.3V pull up resistor. It's used to track the state of the door to check whether someone broke into locked doors and trigger the alarm in some central alarm connected through relay. It's also used to report state of the doors to Azure IoT Central. LCD is used to display current state of the lock. For standard operation it would display 'locked', 'unlocked' or 'alarm' state, for config it displays 'config' or currently edited parameter and available options to it. Double relay module is connected to 5V so the config for the gpios must be output, open drain. In this configuration, the high state is driven by pull up resistor connected to 5v. One of the relays is used to drive electromagnet that controls the access to the doors. It can be configured either as Normal open or Normal closed. The second relay is used as alarm gpio for some central alarm system. The alarm is configured as Normal open relay to ensure maximum safety. When lock is working, the circuit connected to the alarm relay is closed, but when Azure Sphere goes out of power, someone destroyed the lock or someone cut the cables connected to central alarm system, then alarm circuit opens and central alarm system should raise alarm. In this state Azure IoT Central is informed about alarm state in telemetry tab as big bad red Error event and by "Is Alarm?" property in properties tab. Also as you can see, I had to solder UART/BLE connector to use one remaining GPIO: CTS.
Nothing really to write here, just screw components to provided 3d-printable parts and connect with jumper cables.
That cable management.
The code is based on AzureIoT sample (https://github.com/Azure/azure-sphere-samples/tree/master/Samples/AzureIoT) from which i took functions to talk with Azure IoT Central. I've also used samples from https://github.com/Azure/azure-iot-sdk-c. My code is available here https://github.com/Tai-Min/Azure-Sphere-IoT-Lock. The code consists of some header files such as display.h or keyboard.h but I think those are self-describing. Logic of the lock is in the main.c file. I've tried to comment the main file as much as possible leaving obvious parts uncommented. The logic for this program is in my opinion really simple, biggest part of the code is just one big state machine that reacts to button presses on the keyboard, but there are also some timing functions for monostable mode of the lock, invalid tries counter reset, device lock reset and inactivity timer. The most importart part of the code is the runApp function that is invoked by epoll timer:
Before anything, the lock must be synced with Azure IoT Central to load it's config. When this happens "Sync in progress..." appears on the screen.
After sync, passwords and config is loaded into device.
I've tried to squash as much usability as I can and it resulted in pretty useful lock in my opinion. Firstly, there are two passwords for the lock, one for user and one for config. When any of the passwords is typed and confirmed by hash '#' button, then the lock reacts: for monostable mode it opens for configured time, for bistable, when lock is locked then it opens and vice versa. In this video I've shown both ways to control the lock (the blue screen is the config where I change mode from monostable to bistable).
Next, when user enters his password and confirms it with star '*' button blue screen 'Change password appears' where user can enter new password (only numeric) and confirm it with hash button. User's password can't be the same as config password.
When config password is typed and confirmed with star, config menu appears.
In config mode blue screen with 'config' appears and in there confing functions can be selected by typing a number and confirming it with hash button.
1# - Change password for config
Type numeric password and confirm with hash
2# - Change lock mode
Type 1 and confirm with hash to set lock to monostable state (unlock for some time and then lock).
Type 2 and confirm with hash to set lock to bistable state (type password to unlock and type again to lock).
3# - Change contact mode
Type 1 and confirm with hash to set lock relay to normal open.
Type 2 and confirm with hash to set lock relay to normal closed.
4# - Change open time for monostable state
Type number from 1 to 999 and confirm with hash.
5# - Change display backlight mode
Type 1 and confirm with hash to disable display.
Type 2 and confirm with hash to set display to auto (when action is performed (user input/network/alarm/azure) the screen will be enabled and will go off after some time (it will not go off it it's in alarm state).
Type 3 and confirm with hash to set display to be always on (I've already burned one of those oleds so I wouldn't recommend it. D:).
6# - Set factory values
If invalid value is typed to any of the config options then nothing happens to those commands after hash.
Here I show every config function
Every operation from Usage and Config can be cancelled by going back using button 'B' (back).
If mistake was made then previous keystrokes can be cleared by using button 'C' (clear).
The alarm is triggered when door's magnetic sensor changes state from closed to open when the lock is locked. Then alarm relay opens the circuit connected to it. The alarm is also reported to Azure IoT Central via telemetry and properties tabs. Alarm can be cleared by typing one of the passwords and confirming it with hash or star, through Azure IoT Central "Reset alarm" command, or when Always open or Always closed setting is passed from Azure IoT Central's settings tab.
Here I show how to trigger the alarm and clear it through keypad and Azure.
Due to IoT nature of Azure Sphere board I tried to use the "Internet" part of it as much as I can without overdoing it. To control the lock I've choosen Azure IoT Central which offers ability to track the changes made on the lock, issue commands, save and reload configuration and control the state of the lock directly.
The locks only sends events, there is no telemetry, state or location. But when it comes to events there is a lot of these! Events are giving the ability to track pretty much everything that happens to the lock. In example Config event is sent when someone accesses the config menu or some change was made to the config. Door event is sent when door is opened or closed, Lock critical event when alarm is triggered, Lock event when lock is opened or closed, Lock warning when invalid password was typed or three invalid attempts happened in some small period of time, User event when user changed the password.
In settings app there are two options: Always open and Always closed, when set, the lock is locked in one of these two states and can't be used until these are cleared.
In properties there are listed three toggles that show current state of the lock and six text fields that show current config.
There are two commands for the board: Factory reset and Reset alarm. I think these are self describing.
The Reset alarm command is shown in Alarms part of the blog.
There is only one rule in this project: send email when alarm state is triggered.
I think the lock is in nice, completed state, I've tried to predict most of invalid uses and bypasses. Of course there is a lot of there I've missed but for now I'm kinda pleased with the result.
I think the Azure Sphere board is really nice board that offers a lot of functionality. I kinda regret that i started so late with it but when I received the kit only GPIO module was working and most of working peripherals were in beta state so it scared me away a bit from it. The Azure IoT Central and I can see potential for some big data stuff in it but in my opinion it lacks basic tutorials. But when I look how fast the libraries and sapmpes for Azure Sphere were developed I'm positive that same thing will happen with Azure IoT Central!.