106
Formal Report for SmartLock Prepared for: Robert Trost and Susan Woo Prepared by: Elliot Barer, James Esau, Albert Phan December 19, 2014

smartlock_final_report

Embed Size (px)

Citation preview

Page 1: smartlock_final_report

Formal Report for SmartLock Prepared for: Robert Trost and Susan Woo Prepared by: Elliot Barer, James Esau, Albert Phan December 19, 2014

Page 2: smartlock_final_report

Formal Report for SmartLock

Executive Summary 5 INTRODUCTION 5

ELECTROMECHANICAL ACTUATION 5

POWER 5

3D DESIGN 6

FIRMWARE 7

SOFTWARE 7

CONCLUSIONS 8

RECOMMENDATIONS 8

1. SmartLock 9 1.1. INTRODUCTION 9

1.1.1 DEADBOLT BACKGROUND 9

1.1.2 ORGANIZATION OF REPORT 10

1.2 GENERAL DESCRIPTION AND BLOCK DIAGRAM 10

FIGURE 1.1: SMARTLOCK BLOCK DIAGRAM 10

2. Electromechanical Actuation 12 2.1 SERVO MECHANICAL DESIGN REQUIREMENTS 12

2.1.1 DESIGN CONSIDERATIONS 12

2.1.2 SERVO ROTATION 13

2.1.3 ABSOLUTE POSITIONING 13

2.2 SERVO CONNECTION REQUIREMENTS 14

2.2.1 KEY AND TUMBLER DESIGN 14

2.2.2 EMULATING SIMILAR MECHANICS WITH A SERVO 15

FIGURE 2.1: AUTOMATION OF SMARTLOCK LOCKING 15

2.2.3 CONNECTING AND POSITIONING THE SERVO 16

FIGURE 2.2: SERVO HORN ATTACHMENT AND SERVO POSITION 16

2.3 DESIGNING THE SMARTLOCK MANUAL OVERRIDE 17

2.3.1 ADDING MANUAL POSITION DETECTION 17

FIGURE 2.3: MICROSWITCH MOUNTS IN SMARTLOCK HOUSING 17

2.3.2 UTILIZING MANUAL POSITION DETECTION 18

3. Power 19 3.1 DESIGN CONSIDERATIONS 19

3.2 OVERVIEW/SUMMARY 19

3.3 BATTERY SELECTION 20

�2

Page 3: smartlock_final_report

Formal Report for SmartLock

FIGURE 3.1: BATTERY DISCHARGE CURVE 20

3.4 ATMEGA328P MICROCONTROLLER REQUIREMENTS 21

FIGURE 3.2: ATMEGA328P: ACTIVE SUPPLY CURRENT VS. FREQUENCY 21

3.5 NRF8001 BLUETOOTH MODULE REQUIREMENTS 22

TABLE 3.1: NRF8001 CURRENT CONSUMPTION PARAMETERS 22

3.6 CC3000 WIFI MODULE REQUIREMENTS 23

TABLE 3.2: CC3000 POWER CONSUMPTION 23

3.7 HS-225BB SERVO REQUIREMENTS 23

3.8 AAT1217 SOT23-6 PACKAGE BOOST CONTROLLER 24

FIGURE 3.3: EFFICIENCY VS. OUTPUT CURRENT FOR 3.3V AND 5V OUTPUTS 24

3.8.1 OUTPUT CURRENT 25

FIGURE 3.4: MAXIMUM OUTPUT CURRENT VS. INPUT VOLTAGE 25

FIGURE 3.5: SCHEMATICS FOR 3.3V AND 5V BOOST CONVERTERS 26

4. 3D Design 27 4.1 MODELLING 27

FIGURE 4.1: BACKPLANE 27

FIGURE 4.2: TUMBLER 27

FIGURE 4.3: BODY HOUSING 28

FIGURE 4.4: TOP COVER 29

4.2 3D PRINTING 30

4.2.1 FIRST PROTOTYPE 30

FIGURE 4.5: FIRST PROTOTYPE, PRINTED IN RESIN 30

4.2.2 SECOND REVISION 31

FIGURE 4.6: SECOND PROTOTYPE, PRINTED IN ABS PLASTIC 31

5. Bluetooth Low Energy 32 5.1 GENERIC ACCESS PROFILE 32

5.2 GENERIC ATTRIBUTE PROFILE 33

5.3 PROFILE, SERVICES AND CHARACTERISTICS 33

6. Firmware 35 FIGURE 6.1: FLOWCHART FOR FIRMWARE LOCK AND UNLOCK FUNCTIONS 35

FIGURE 6.2: FLOWCHART FOR MICROCONTROLLER FIRMWARE 36

7. Software 37 7.1 SWIFT 37

7.2 SMARTLOCK CLASS 38

�3

Page 4: smartlock_final_report

Formal Report for SmartLock

7.3 SMARTLOCK MOBILE APP 39

FIGURE 7.1: PRIMARY VIEW AND DEBUG VIEW, RESPECTIVELY 39

FIGURE 7.2: FLOWCHART FOR CONNECTING TO SMARTLOCK 40

FIGURE 7.3: FLOWCHART FOR APP BUTTON CONTROLS 40

FIGURE 7.4: FLOWCHART FOR PROXIMITY DETECTION 41

8. Test Plans and Results 42 8.1 SERVO DRAIN AND BATTERY TEST 42

8.1.1 RESULTS 42

8.1.2 SOLUTIONS ATTEMPTED 42

8.1.3 RECOMMENDATIONS 42

8.2 FIRST ASSEMBLY OF 3D PRINTED PARTS 43

8.2.1 RESULTS 43

8.2.2 REVISIONS 43

8.3 SECOND ASSEMBLY OF 3D PRINTED PARTS 44

8.3.1 RESULTS 44

8.4 BLUETOOTH CONTROL TESTING 45

8.4.1 VERIFICATION OF HARDWARE 45

8.4.2 VERIFICATION OF FIRMWARE 45

8.4.3 VERIFICATION OF SOFTWARE 46

8.4.4 REVISIONS 46

9. Scope Changes 47 10. Analysis of Success and Failure 48

10.1 SUCCESSES 48

10.1.1 IOS APP 48

10.2 FAILURES 48

10.2.1 BOOST CONVERTERS 48

11. Conclusion 49 11.1 ELECTROMECHANICAL AND MANUAL OPERATION 49

11.2 BLUETOOTH CONTROL AND PROXIMITY DETECTION 50

11.3 LESSONS LEARNED 50

12. Recommendations 51 13. Documentation References 52

�4

Page 5: smartlock_final_report

Formal Report for SmartLock

EXECUTIVE SUMMARY

Introduction

For completion of the Computer Control option of the Electrical and Computer Engineering Technology program at the British Columbia Institute of Technology, we were tasked with designing, developing, implementing and testing a project as part of the ELEX 4330 Technical Project course. For our project, we created a Bluetooth controlled door lock, named SmartLock. This report serves to record the process of design, development and manufacturing of the SmartLock. It was requested by Robert Trost, ELEX 4330 Technical Project Instructor, and Susan Woo, COMM 2443 Communications Instructor, in order to evaluate the technical aspects and to adequately document the project.

Electromechanical Actuation

The SmartLock utilizes a servo to rotate the lock electronically. It was chosen for its high torque to size ratio. The servo actuates the door lock via a servo horn attachment that it uses to rotate the tumbler, which is in turn connected to the lock shaft. This system has 90 degrees of rotational freedom in it so as to allow the ability to manually override the electronic system without causing damage to any of the servo components.

Power

The various components of the SmartLock are powered using two AA batteries in series directly or via boost converters. Utilizing low power (sleep) modes of the microcontroller, we calculate approximately six months of battery life depending on usage. The ATMega328P microcontroller and the nRF8001 Bluetooth module are powered directly off the batteries, with the microcontroller’s main clock running at

�5

Page 6: smartlock_final_report

Formal Report for SmartLock

a low frequency to keep the supply current low. The CC3000 WiFi module has two voltage rails: VBAT_IN and VIO_HOST. VBAT_IN requires 3.3V which is sparingly supplied using a boost converter. VIO_HOST matches the interface voltage levels to that of the microcontroller, and as such will also be powered directly off the batteries. Finally, the servo requires 5V for normal operation which is supplied using a secondary boost converter. As with the 3.3V boost converter, their respective usages were minimized in order to maximize the efficiency of the power circuit and reduce overall power consumption.

3D Design

With 3D printing becoming more accessible and providing tremendous flexibility, the choice was made to have our prototype device 3D printed for quick production and reproduction when revision of the SmartLock was needed. Throughout the testing process the modelling was revised twice, achieving a design as close as possible to the desired final product. The first print was done by Integral Dental Labs, and was printed with a resin material. Unfortunately, this material proved to be too brittle for our applications and was unacceptable as a working prototype. The second revision was printed out of acrylonitrile butadiene styrene (ABS) plastic, a much stronger material, at the BCIT Tech Centre. The second revision was much more flexible for our operation; however, adjustments were required to correct some issues with tolerances. Unfortunately, there was not enough time for a third revision prior to our presentation; however, we have redesigned our 3D models to allow for a reprint if we so choose. Without the 3D printing technology we have today, we would not have been able to procure a working prototype.

�6

Page 7: smartlock_final_report

Formal Report for SmartLock

Firmware

The SmartLock is controlled using an Arduino Uno, specifically the ATMega328P microcontroller. Using the Arduino libraries and integrated development environment (IDE), the firmware was written in the C programming language. The firmware performs the setup of the Bluetooth module and the various I/O ports for the device, then keeps the device in an alternating loop of advertising itself as a peripheral Bluetooth device and going to sleep. When it receives a connection request from a central Bluetooth device (e.g. an iPhone), the device awaits an unlock or lock command and performs the appropriate actions, including toggling the correct LEDs and chirping the speaker to alert the user to the device’s activity. Upon completion of the correct action, the device sends a response to the central device alerting it of the successful operation of the command.

Software

The SmartLock app is written in Apple’s new programming language, Swift, and is developed to make use of the latest hardware and software. The app has a primary view for interacting with the SmartLock, allowing the user to toggle the state of the device with a large circular control, and a debug view allowing us to troubleshoot the device and test our proximity detection. Proximity detection allows the user to unlock the SmartLock by simply approaching the door, and have it lock automatically behind them as they walk away. This is performed by averaging the received signal strength indication (RSSI) of the peripheral device and comparing it against threshold values for lock and unlock. To prevent flipping rapidly between the locking and unlocking actions, hysteresis is introduced into the threshold values.

�7

Page 8: smartlock_final_report

Formal Report for SmartLock

Conclusions

Much to our delight, we were successful in creating a functional prototype of the SmartLock, achieving the majority of our goals including Bluetooth control, proximity detection, and manual locking/unlocking.

Bluetooth communication through the app was successful and there were no major issues with it. The mechanical aspect of locking and unlocking worked correctly. We experienced issues with the proximity detection due to variance in the returned RSSI values; however, these issues were largely out of our control. Our chief concern was the servo power consumption. Specifically, we saw much larger current spikes than we had anticipated and the torque on the servo was insufficient. These issues could be addressed by utilizing a boost converter capable of outputting greater current and a possible redesign of the mechanics of the automated locking and unlocking may also be required. However, by all accounts the prototype demonstration was successful proving that the SmartLock could be a legitimate product.

Recommendations

Prior to bringing the SmartLock to market, it will require further iteration including a re-evaluation of the mechanical aspects and the power mechanics. Specifically, the servo may need to be reconsidered, or replaced with a custom implementation. The power electronics will also be updated to supply higher current for the motor.

To improve the overall product design, consultation with mechanical engineers would be highly advisable in order to account for aspects we may have yet to consider. As for the ELEX 4330 Project Course, we would like to see a vastly improved lab as we were severely constrained in our ability to adequately test the device with the equipment supplied; specifically oscilloscopes, bench DMM’s and mechanical tools such as Dremel hand grinders, files and hacksaws.

�8

Page 9: smartlock_final_report

Formal Report for SmartLock

1. SMARTLOCK

1.1. Introduction

For completion of the Computer Control option of the Electrical and Computer Engineering Technology program at the British Columbia Institute of Technology, we were tasked with designing, developing, implementing and testing a project as part of the ELEX 4330 Technical Project course. For our project, we created a Bluetooth controlled door lock, named SmartLock. This report serves to record the process of design, development and manufacturing of the SmartLock. It was requested by Robert Trost, ELEX 4330 Technical Project Instructor, and Susan Woo, COMM 2443 Communications Instructor, in order to evaluate the technical aspects and to adequately document the project. During the development of the SmartLock, we referenced various datasheets and protocol specifications. For detailed information on these resources, refer to Appendix A.

1.1.1 Deadbolt Background

There are four important components to a standard household deadbolt. On the outside of the door, there is a keyhole allowing operation of the deadbolt with a key. Internal to the door is the deadbolt itself which moves between the locked and unlocked positions. The shaft runs perpendicularly through the door, actuating the deadbolt from within. On the rear of the door, connected to the shaft, is the thumbturn. Our project effectively replaces this component with an automated substitute allowing for remote control of the deadbolt.

�9

Page 10: smartlock_final_report

Formal Report for SmartLock

1.1.2 Organization of Report

The body of this report is divided into several sections, each referring to a specific aspect of the design process. We begin by describing the general functionality of the SmartLock including a block diagram of the device and its components. This is followed by a detailed description of each of the major blocks of the device. To demonstrate the various tests conducted throughout the development process, we have included our test plans and results followed by scope changes to the project. Finally, we analyze the successes and failures of the project with lessons learned, recommendations for future endeavours and a conclusion discussing our project’s accomplishments.

1.2 General Description and Block Diagram

As illustrated in Figure 1.1, the SmartLock is comprised of an Arduino Uno, utilizing an ATMega328P microcontroller, the nRF8001 Bluetooth Low Energy (BLE) module manufactured by Nordic, the CC3000 WiFI module manufactured by Texas Instruments, and a variety of electromechanical components, all of which can be found in Appendix B. Schematics detailing all connections for the SmartLock can be found in Appendix C.

FIGURE 1.1: SMARTLOCK BLOCK DIAGRAM

�10

Page 11: smartlock_final_report

Formal Report for SmartLock

The SmartLock uses the nRF8001 BLE module to communicate with its mobile app on any compatible smartphone, allowing it to be remotely controlled. When the user opens the SmartLock app on their smartphone, the app automatically connects to the SmartLock device, at which point it receives the status of the lock. The user can then tap on the lock or unlock button. This sends a command to the SmartLock using a BLE service designed to mimic universal asynchronous receiver/transmitter (UART). The SmartLock then activates the correct light-emitting diodes (LEDs), chirps the speaker, and rotates the servo according to the command sent and the status of the lock. Once it has successfully changed states, the SmartLock sends a reply over the same UART service to the phone, informing it that the command was completed successfully.

The SmartLock houses two LEDs to indicate the status of the lock: a red locked symbol, and a green unlocked symbol. These are illuminated according to the status of the lock. There is also a small speaker in the device that chirps once when the device is locked and twice when it is unlocked. The servo rotates 90 degrees in either direction in order to actuate the deadbolt to either the locked or unlocked position. When it has reached this endpoint, it returns to its neutral position so that the user can lock or unlock the door manually without damaging the internal components or fighting against the servo. As a result of this design, the user also has the ability to both lock and unlock the door manually: externally using their house key, or internally by rotating the SmartLock tumbler.

Were this product to be marketed commercially, we would have WiFi implemented in the device. The WiFi module would allow the SmartLock to communicate through a home router and the internet to a phone over long distances, allowing the user to perform various tasks remotely. Such tasks include remotely locking and unlocking the door, providing temporary guest access to visitors, logging door transactions, allowing the user to see when people have entered and exited, and viewing the battery life of the product.

�11

Page 12: smartlock_final_report

Formal Report for SmartLock

2. ELECTROMECHANICAL ACTUATION

2.1 Servo Mechanical Design Requirements

The primary goal for the SmartLock was the ability to lock and unlock the door electronically, while still permitting manual system override in case of battery failure, electromechanical failure, or lack of access to a phone. To achieve this goal, we required a mechanism that would have enough torque to rotate the deadbolt while also being able to disengage when in the neutral position. This feature serves the dual purpose of preventing damage to the device while allowing easier manual operation of the door lock. We also sought a small driver and mechanism to minimize the SmartLock footprint.

2.1.1 Design Considerations

In order to fulfill the aforementioned requirements, we chose to use a “mini-sized” hobby servo. This would give us the desired torque while reducing its footprint. Prior to making this decision, we considered several other options including stepper motors and standard DC motors. While stepper motors offer significant torque, they are generally quite large and would not fit inside our target design. In contrast, DC motors can be quite small; however, they provide low torque. In order to achieve an adequate torque, we would have required a significant reduction gear making the locking/unlocking process unacceptably slow.

DC motors and stepper motors also add additional complexity as they require separate controllers in order to deliver the power necessary to drive them but microcontrollers can only output minimal amounts of current from their I/O pins. In contrast, instead of relying on discrete drivers, as with DC or stepper motors, servos internally house all of the necessary driver circuitry and simply require connections to power, ground, and control signal. Additionally, the microcontroller outputs a pulse width modulated (PWM) signal to the servo’s control pin to actuate the servo horn.

�12

Page 13: smartlock_final_report

Formal Report for SmartLock

2.1.2 Servo Rotation

PWM is a method of encoding information in the duty cycle of a square wave. It is typically used to emulate an analog output from a device only capable of digital outputs. The device sets the duty cycle of a high frequency square wave according to the percentage of the output voltage that equates to the analog voltage required. This is typically then passed through a low-pass filter to convert it from a digital waveform to an analog voltage.

Servos use a modified version of PWM for their control system as their internal controllers are also digital and do not require an analog signal to operate. While PWM signals designed to output analog voltages can operate at any reasonably high frequency, servos require a very specific frequency of 50 Hz, which translates to a period of 20 ms. While standard PWM allows for manipulating the duty cycle between 0 and 100%, servo PWM requires a positive pulse width between 1 and 2 ms, which translates to a range of 5 to 10% of the signal waveform.

2.1.3 Absolute Positioning

Another design consideration was the need to know the current orientation of the lock mechanism. Neither a stepper motor, nor a DC motor, would provide us with absolute position control; they can only be moved relative to their previous position, requiring zeroing in order to ascertain their position. A servo, however, is capable of absolute position control once it has been initially calibrated. After the servo has been calibrated in the lab, achieved by measuring the degree of rotation acquired from a specific pulse width, it can easily be tuned to rotate a specific number of degrees with a high level of precision.

The servo accomplishes this by using a small geared motor which is connected to a potentiometer. The position of the servo’s shaft is recorded and this information is sent back to the built in controller. The controller uses this information, combined with the input PWM signal, to decide whether the servo needs to continue rotation or if it has already reached its desired location.

�13

Page 14: smartlock_final_report

Formal Report for SmartLock

2.2 Servo Connection Requirements

After making the decision to proceed with the design using a servo to drive the SmartLock, the best way to connect it to the rotating metal shaft that activates the deadbolt had to be determined. This shaft rotates approximately 90 degrees resulting in the deadbolt extending or retracting. Unfortunately, there is no simple way to directly connect the servo to the shaft, as that would prevent the user from manually operating the lock. Had the servo been connected directly to the shaft, manual operation would result in a struggle against the servo, stressing it and potentially resulting in a catastrophic failure.

2.2.1 Key and Tumbler Design

The solution to overcome this challenge was very similar to that of the existing key and tumbler. When a key is inserted into a lock, it is rotated in a direction consistent with locking or unlocking the door. It is then returned to a neutral position in order to remove it from the lock. This is made possible by connecting the tumbler and the shaft via a mechanism that allows the key to rotate freely in the range of 90 and 180 degrees.

When the key is turned initially, the lock is activated. When the key is returned to its neutral position, the tumbler is also rotated back to neutral. As a result of this limited slip and neutral position, a user on the other side of the door can both lock and unlock the door with the thumbturn without impediment from the key and tumbler mechanism. In summary, as long as the tumbler is in its neutral position, it does not affect the activation or deactivation of the deadbolt.

�14

Page 15: smartlock_final_report

Formal Report for SmartLock

2.2.2 Emulating Similar Mechanics with a Servo

To apply this technique to the electromechanical system of the SmartLock, the servo was required to rotate more than the 90 degrees required to activate the deadbolt into a locked position. In addition, the servo had to always return to a neutral position, allowing the user to operate the lock manually using either a key or the SmartLock’s tumbler. To meet these requirements, we required a servo that could rotate at least 180 degrees: 90 to actuate the deadbolt and an additional 90 degrees to allow for the necessary mechanical slippage.

When the SmartLock is idle, the servo sits in its neutral state. When a lock command is applied, the servo is rotated 90 degrees to its end point, rotating the tumbler and activating the locking mechanism. When the door has successfully been locked, the servo rotates 90 degrees back to its neutral position. See Figure 2.1 for a diagram illustrating the locking process. To unlock the door, the servo initially rotates in the opposite direction, before returning to neutral.

FIGURE 2.1: AUTOMATION OF SMARTLOCK LOCKING

1. A lock command is sent to the SmartLock 2. The servo, sitting in its neutral position, rotates 90 degrees thus actuating the deadbolt 3. Once the deadbolt is actuated, the servo rotates back 90 degrees to its neutral position

�15

Page 16: smartlock_final_report

Formal Report for SmartLock

2.2.3 Connecting and Positioning the Servo

Initial approaches for accomplishing the aforementioned design included lengthening the servo arm and adding two pegs, separated by 90 degrees, to the internal rotating portion of the lock. However, to reduce the size of the actuation mechanism, this design was scrapped. The enhanced design consisted of a modified servo horn attachment with a raised section equivalent to 90 degrees and a matching raised section inside the lock equivalent to 180 degrees, as see Figure 2.2.

This design allows the servo to rotate freely up to the remaining 90 degrees while still activating the lock 90 degrees in either direction. It also allows for placement of the servo directly over the shaft, as opposed to placing it beside the shaft, as seen in Figure 2.2. This allows for maximum torque output from the servo to the lock shaft.

FIGURE 2.2: SERVO HORN ATTACHMENT AND SERVO POSITION

�16

Page 17: smartlock_final_report

Formal Report for SmartLock

2.3 Designing the SmartLock Manual Override

As outlined previously, allowing the user to manually operate the lock from inside or out without relying on the electromechanical system was a fundamental requirement of the SmartLock. To facilitate the manual operation from inside the house, the SmartLock was designed so that its main housing is a tumbler attaching internally to the lock shaft. As a result, the user can simply rotate the tumbler, which directly translates the rotational movement to the lock shaft, locking or unlocking the door.

2.3.1 Adding Manual Position Detection

For all of the electromechanical components to work correctly, the system requires the ability to detect the orientation of the lock, particularly if it is manually operated. Otherwise, the device would light the inappropriate LED and the app would suggest the user perform the incorrect operation. Beyond the simple irritation factor such a flaw could present to the user, it would also represent a fundamental security flaw as the user could assume the door is locked when in reality it remains unlocked.

To solve this challenge, SmartLock employs the use of two microswitches to detect the present state of the SmartLock. As seen in Figure 2.3, these switches are located at either end of the mechanical range and are activated when the tumbler arm comes into contact. This allows the SmartLock to always determine the true orientation of the deadbolt, and update all electromechanical elements appropriately.

FIGURE 2.3: MICROSWITCH MOUNTS IN SMARTLOCK HOUSING

�17

Page 18: smartlock_final_report

Formal Report for SmartLock

2.3.2 Utilizing Manual Position Detection

As mentioned above, using manual position detection allows the SmartLock to always know the true state of the deadbolt regardless of whether it was manually or electronically actuated. This allows the system to update the SmartLock mobile app when it is operated manually. It also allows the device to keep a log of all door activity, including lock and unlock activity and how the activity was performed, through a simple web interface.

This information is also utilized when electronically actuating the deadbolt. It allows the SmartLock to confirm that a lock or unlock command had been completed successfully. If there were an impedance, or the operation did not complete successfully, the switch would not activate and the command would return an error. It would also allow the device to notify the user audibly using the speaker and through the SmartLock mobile app.

�18

Page 19: smartlock_final_report

Formal Report for SmartLock

3. POWER

3.1 Design Considerations

The SmartLock is powered using two AA batteries, therefore power consumption needed to be minimized to ensure maximum efficiency, and reasonable battery longevity. To achieve this, the majority of the SmartLock’s modules are connected directly to the batteries. In situations where the voltage supplied by the batteries is not great enough, boost converters are used sparingly to achieve the desired voltage levels. This is done by way of the shutdown pins on the boost controller, allowing the microcontroller to effectively turn it off whenever it is not in use. The ATMega328P microcontroller will spend the majority of its time in low power mode, only waking to communicate over Bluetooth or to control the electromechanical elements.

3.2 Overview/Summary

The two AA batteries will directly power the ATMega328P microcontroller, the nRF8001 Bluetooth module, and the VIO_HOST rail for the CC3000 WiFi module. A 5V boost converter will power the Servo and a 3.3V boost converter will power the VBAT_IN of the WiFi module. In standby mode, the SmartLock system has an expected current drain of less than 1mA.

�19

Page 20: smartlock_final_report

Formal Report for SmartLock

3.3 Battery Selection

The decision to power the SmartLock using two AA batteries was made primarily due to the common utilization of AA batteries in the average household, in addition to their ability to provide months of power before needing to be replaced. A single AA battery is advertised as providing between 1700 and 3000 mAh. The nominal voltage is 1.55V to 1.65V when fully charged and drops to between 0.7 and 1.0V when depleted. When the battery voltage drops below 1.3V a low battery warning is issued. See Figure 3.1 for a graph describing the nominal voltage of an AA battery over its lifespan.

FIGURE 3.1: BATTERY DISCHARGE CURVE

" (http://www.powerstream.com/AA-tests.htm)

As can be seen above, the battery voltage discharges linearly during its regular operating capacity but drops off rapidly at the end of its life around 2000mAh. To prevent abnormal behaviour, SmartLock ensures its batteries are operating in the linear region.

�20

Page 21: smartlock_final_report

Formal Report for SmartLock

3.4 ATMega328P Microcontroller Requirements

The ATMega328P microcontroller is the primary component of the SmartLock. For maximum efficiency, it is being powered directly from the batteries. As mentioned previously, two AA batteries in series provide a nominal voltage of approximately 3.0V and when fully discharged provide a voltage of approximately 1.4V. The microcontroller is capable of operation with voltages as low as 1.8V, allowing it to continue operating for an extended duration after the low voltage warning (2.6V). At low voltages, current drain is anticipated to be less than 1mA. See Figure 3.2 for a graph of supply current with respect to clock frequency.

FIGURE 3.2: ATMEGA328P: ACTIVE SUPPLY CURRENT VS. FREQUENCY

(ATMega328 Data sheet)

Powering the SmartLock via two AA batteries limits us to operating along the 2.7V curve. In order to be as efficient as possible, the ATMega328P will operate at a frequency less than 10MHz.

�21

Page 22: smartlock_final_report

Formal Report for SmartLock

3.5 nRF8001 Bluetooth Module Requirements

A primary factor in the decision to use the nRF8001 Bluetooth module is its ability to operate using 3V. As discussed above, the two AA batteries provide a nominal voltage of 3V allowing for direct connection to the nRF8001. As can be seen in Table 3.1, the Bluetooth module has a very low idle current of 2 uA and peaks at 14.6mA while receiving data.

TABLE 3.1: NRF8001 CURRENT CONSUMPTION PARAMETERS

(nRF8001 Datasheet)

�22

Page 23: smartlock_final_report

Formal Report for SmartLock

3.6 CC3000 WiFi Module Requirements

The WiFi Module has two voltage rails, VBAT_IN and VIO_HOST. VBAT_IN powers the chip and has a recommended voltage of 3.3V which is supplied using a boost converter. VIO_HOST sets the voltage levels for interfacing with the microcontroller and is powered directly from the batteries, as is the microcontroller. As shown in Table 3.2, of the various components, excluding the servo, the CC3000 WiFi module has the largest current drain when active at 275mA. However, the shut-down mode current drain is a minimal 5uA.

TABLE 3.2: CC3000 POWER CONSUMPTION

(CC3000 TI datasheet)

3.7 HS-225BB Servo Requirements

For regular operation the servo requires a nominal 5V and is supplied using a boost converter. To limit overall current draw, the boost converter is shutdown when the servo is not in use. While rotating with no load, the servo draws 300mAl however, under load it peaked around 800mA. See the datasheet in Appendix A for further specifications.

�23

Page 24: smartlock_final_report

Formal Report for SmartLock

3.8 AAT1217 SOT23-6 Package Boost Controller

The SmartLock uses the AAT1217 SOT23-6 Package Boost Controller for both the 3.3V and 5V boost converters. See Figure 3.3 for the efficiency of the package when generating 3.3V and 5V outputs, and Figure 3.5 for complete schematics of both boost converters. This package was chosen for the following features:

• Low current shutdown ability

• 400mA Output from a Dual AA Cell

• Provides 3.3V and 5V outputs

• High efficiency (up to 93%)

• Low cost: $0.50 on Digi-Key

FIGURE 3.3: EFFICIENCY VS. OUTPUT CURRENT FOR 3.3V AND 5V OUTPUTS

(AAT1217 Datasheet)

To predict the efficiency, the 2.4V line is used when considering a dual AA battery source. Recall that when active, the WiFi module uses approximately 275mA at 3.3V and the servo uses between 500mA and 1A when operating at 5V.

�24

Page 25: smartlock_final_report

Formal Report for SmartLock

3.8.1 Output Current

As previously discussed, the servo draws large spikes in current during operation. Initial estimates for peak servo current draw were approximately 500mA; however, measurements demonstrated peak currents of up to 800mA. As illustrated in Figure 3.4, when providing an input of 3V from dual AA batteries and an output of 5V, the design is limited to an output of approximately 450mA. This is insufficient, and as a result corrections to the power design are required to accommodate the higher current draw. Refer to Section 9, Scope Changes, for further details.

FIGURE 3.4: MAXIMUM OUTPUT CURRENT VS. INPUT VOLTAGE

(ATT1217 Datasheet)

�25

Page 26: smartlock_final_report

Formal Report for SmartLock

FIGURE 3.5: SCHEMATICS FOR 3.3V AND 5V BOOST CONVERTERS

As previously mentioned, the boost converters can be placed into shutdown mode via the !SHDN pin. This pin is connected to the microcontroller and pulled low when the boost converter is not in use.

�26

Page 27: smartlock_final_report

Formal Report for SmartLock

4. 3D DESIGN

In order to produce a prototype SmartLock, 3D printing was selected for manufacturing as it offers the flexibility to quickly revise designs with relatively low costs. Autodesk Inventor 2013 was used to model the 3D prototype.

4.1 Modelling

This section describes each component of the 3D printed enclosure, with illustrations of each and a brief description as to the purpose of the piece.

FIGURE 4.1: BACKPLANE

The backplane is the foundation of the SmartLock. It attaches to the deadbolt metal plate via two pre-existing bolts. It supports the body housing while providing a ring guide for the tumbler, holes for the door bolts, and mounts for the microswitches.

FIGURE 4.2: TUMBLER

The tumbler connects to the lock shaft through a rectangular cutout at the centre of its arm. When rotated, the tumbler actuates the lock shaft, locking and unlocking the door. The microswitches, as described previously, are mounted on the platforms at either end of the arm rotation. As illustrated on the right, the tumbler and SmartLock are presently in the unlocked position.

�27

Page 28: smartlock_final_report

Formal Report for SmartLock

FIGURE 4.3: BODY HOUSING

The body housing provides compartments for each AA battery and the servo, in addition to holes for the LEDs, supporting screw holes, a slot for programming and indentations for alignment of the top cover (to be discussed in the next section). Adjacent to the servo, the round PCB is mounted behind the battery compartments. The battery pins are soldered directly to the PCB and light pipes extend up towards the LED holes. The rectangular programming hole at the base is for a 6x1 pin header used during manufacturing and debugging of the device.

�28

Page 29: smartlock_final_report

Formal Report for SmartLock

FIGURE 4.4: TOP COVER

The top cover of the SmartLock is the cap of the device and transmits the glow from the LEDs and conceals the electromechanical components. The centre hole allows it to be screwed into the body housing. On the back of the top cover are three tabs which align the with the body housing. It was designed to be easily removable, allowing the user quick access to replace the batteries.

�29

Page 30: smartlock_final_report

Formal Report for SmartLock

4.2 3D Printing

As discussed earlier, the SmartLock prototype was constructed using 3D printing. The initial plan was to use Albert’s personal 3D printer; however, during the manufacturing process it encountered technical difficulties. As a result, we were forced to seek an alternative, and Integral Dental Lab generously offered to print the prototype.

4.2.1 First Prototype

The first prototype was constructed from resin using a process called stereolithography (SLA). While allowing for incredibly high resolution prints, the material proved to be extremely brittle and unsuitable for our applications. Figure 4.5 shows the initial prototype cracked in multiple places. Another disadvantage of the material was a tacky surface which inhibited rotation.

FIGURE 4.5: FIRST PROTOTYPE, PRINTED IN RESIN

�30

Page 31: smartlock_final_report

Formal Report for SmartLock

4.2.2 Second Revision

The second revision was printed with acrylonitrile butadiene styrene (ABS) plastic using the process fused deposition modelling (FDM) at the BCIT Tech Centre by Dan Leland. These parts were much stronger and more durable than our first prototype, while also having a much lower coefficient of friction. Figure 4.6 shows the printed ABS pieces screwed together into the door.

FIGURE 4.6: SECOND PROTOTYPE, PRINTED IN ABS PLASTIC

�31

Page 32: smartlock_final_report

Formal Report for SmartLock

5. BLUETOOTH LOW ENERGY

Bluetooth Low Energy (BLE), commonly referred to as Bluetooth Smart, is a subset of the Bluetooth standard and is marketed by the Bluetooth Special Interest Group (Bluetooth SIG, Inc., 2014). The standard was designed with high power efficiency in mind, making it an ideal candidate for devices with limited power.

We utilize BLE in the SmartLock for the following reasons:

1. It is power efficient which is of the utmost importance to our project as we must power all the components with two AA batteries.

2. It is implemented in the vast majority of current generation smartphones.

3. It is relatively simple to implement when compared to other wireless communications standards, including classic Bluetooth, expediting the development process.

The BLE stack defines two layers for communication: the Generic Access Profile (GAP) and the Generic Attribute Profile (GATT) (Texas Instruments Inc., 2013).

5.1 Generic Access Profile

According to Texas Instruments Inc. (2013), “The GAP layer of the BLE Protocol Stack is responsible for handling the device’s access modes and procedures, including device discovery, link establishment, link termination, initiation of security features, and device configuration” (p. 12).

The GAP layer defines two primary roles for devices: peripherals and centrals. Peripheral devices are defined as small, low power accessories; in this instance, the SmartLock. Central devices generally have much more processing power, such as a smartphone or tablet.

�32

Page 33: smartlock_final_report

Formal Report for SmartLock

During the GAP advertising process, the peripheral device advertises itself and waits for a response from a central device. At this point, the central device can send a scan response request for more information, or seek a connection with the peripheral. If it requests further information, the peripheral can send an optional scan response data packet. A peripheral device may advertise itself to multiple central devices concurrently, and can send scan response data packets to all of them.

5.2 Generic Attribute Profile

Once a central device has established a connection with a peripheral device, the GATT layer is utilized for all communication between the two devices (Texas Instruments Inc., 2013). When connected to a central device, a peripheral is exclusively connected to that specific central and ceases advertising itself to other centrals; however, a central device may have multiple peripheral connections.

When referring to the GATT layer of communication, the devices are no longer technically referred to as peripheral and central, but instead, client and server. Furthermore, there is no direct correlation between peripheral/central and client/server, as either a peripheral or a central can be a client or a server (Texas Instruments Inc., 2013). In our usage scenario, the SmartLock is acting as the GATT server as it has the data we are reading: the lock/unlock status of the device and door. As a result, our central device, the smartphone, is fulfilling the role of GATT client, which reads and writes data to the GATT server.

5.3 Profile, Services and Characteristics

A GATT server defines the terms of communication between itself and the GATT client by creating a profile for itself. This profile outlines all the services available for communication between the server and client, and each service’s characteristics.

�33

Page 34: smartlock_final_report

Formal Report for SmartLock

Services and characteristics are defined by Adafruit (2014) as follows:

Services are used to break data up into logic entities, and contain specific chunks of data called characteristics. A service can have one or more characteristics, and each service distinguishes itself from other services by means of a unique numeric ID called a UUID, which can be either 16-bit (for officially adopted BLE Services) or 128-bit (for custom services).

The lowest level concept in GATT transactions is the Characteristic, which encapsulates a single data point (though it may contain an array of related data, such as X/Y/Z values from a 3-axis accelerometer, etc.).

Similarly to Services, each Characteristic distinguishes itself via a pre-defined 16-bit or 128-bit UUID, and you're free to use the standard characteristics defined by the Bluetooth SIG (which ensures interoperability across and BLE-enabled HW/SW) or define your own custom characteristics which only your peripheral and SW understands.

The SmartLock has a single service that is a software implementation of UART for all communication between the SmartLock app and device. The service has two characteristics: TX for transmitting data and RX for receiving data. The UUIDs for the service and its characteristics are as follows:

UART Service: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E TX Characteristic: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E RX Characteristic: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E

�34

Page 35: smartlock_final_report

Formal Report for SmartLock

6. FIRMWARE

The SmartLock is controlled using an Arduino Uno, with an ATMega328P microcontroller. The firmware is written in C and compiled using the Arduino libraries and compiler. See Appendix D for the Firmware source code.

The firmware for the SmartLock initializes all of the I/O as well as the BLE module, and begins advertising the device. Once the SmartLock is connected to a central device, the firmware interprets all received commands and calls the appropriate functions. Please refer to the lock and unlock functions in Figure 6.1, and a high level flowchart for the firmware process in Figure 6.2.

FIGURE 6.1: FLOWCHART FOR FIRMWARE LOCK AND UNLOCK FUNCTIONS

�35

Page 36: smartlock_final_report

Formal Report for SmartLock

FIGURE 6.2: FLOWCHART FOR MICROCONTROLLER FIRMWARE

�36

Page 37: smartlock_final_report

Formal Report for SmartLock

7. SOFTWARE

We have designed a custom mobile app for SmartLock that runs on the iPhone making use of Apple’s latest hardware, operating system, and programming language (Swift). Using BLE, the app is able to lock and unlock the device using either button controls or proximity detection. Refer to Appendix E for the iOS source code.

7.1 Swift

At its World Wide Developers Conference in June of this year, Apple unveiled a brand new programming language for its desktop and mobile platforms. As described on Apple’s website (2014), “Swift is a powerful and intuitive new programming language created by Apple for building iOS and Mac apps. It’s designed to give advanced developers the freedom and capabilities they need to create a new generation of cutting-edge apps. It also opens up a whole new world of possibilities for everyone else. Swift is easy to learn and use — even if you’ve never coded before. So now anyone with an idea can create something incredible.”

By using the newest programming language, the SmartLock app is forward-looking, ensuring future compatibility with Apple products. Furthermore, Swift is a clean programming language and allows for quick prototyping using the storyboard feature. As the language is only six months old, there were limited resources available during development of the app. Consequently, most documentation was provided in Apple’s old programming language Objective-C, and had to be converted to the new language.

�37

Page 38: smartlock_final_report

Formal Report for SmartLock

7.2 SmartLock Class

The SmartLock app makes use of a SmartLock class which inherits from the NSObject base class and implements the protocols for CBCentralManagerDelegate and CBPeripheralDelegate. This allows a SmartLock object to implement all the necessary functions to act as a central manager while having functions to communicate with the SmartLock peripheral. In addition to these required functions, the SmartLock class also implements the functions to perform the following actions:

1. Locking and unlocking the door,

2. Determining the RSSI (signal strength),

3. Enabling/disabling the RSSI timer,

4. Generating console and view output strings.

The lock and unlock functions ensure the iPhone is still connected to a SmartLock and that it is in the correct lock position. If these conditions are met, they send the appropriate command to the SmartLock (as described previously in the SmartLock Firmware).

For more information on all of the functions, refer to the iOS app source code in Appendix E.

�38

Page 39: smartlock_final_report

Formal Report for SmartLock

7.3 SmartLock Mobile App

The SmartLock mobile app has two separate views. See Figure 7.1 for the primary view and the debug view. The app creates one instance of a SmartLock object which is shared between both views and handles all communication to the device. For detailed instructions on how to install the SmartLock and communicate to it using the SmartLock mobile app, refer to Appendix F.

FIGURE 7.1: PRIMARY VIEW AND DEBUG VIEW, RESPECTIVELY

In the following flowcharts, we illustrate the connection process (Figure 7.2), the flow of controlling the SmartLock using button controls (Figure 7.3), and the flow of controlling the SmartLock using proximity detection (Figure 7.4).

�39

Page 40: smartlock_final_report

Formal Report for SmartLock

FIGURE 7.2: FLOWCHART FOR CONNECTING TO SMARTLOCK

FIGURE 7.3: FLOWCHART FOR APP BUTTON CONTROLS

�40

Page 41: smartlock_final_report

Formal Report for SmartLock

FIGURE 7.4: FLOWCHART FOR PROXIMITY DETECTION

Proximity detection works by using the RSSI of the peripheral device with respect to the central device. When proximity mode is enabled (currently controlled through a toggle in the debug view) a half-second timer is engaged, which calls a function to update the RSSI values on timeout. This function stores the RSSI dBm values in an array which it then uses to determine the current average RSSI value, effectively eliminating inconsistencies in the readings. Once the values are averaged, that value is compared against threshold values to determine what actions to perform. The lock and unlock threshold are staggered similarly to voltage hysteresis to prevent rapid lock and unlock fluctuations. In testing, it was determined that an approximate hysteresis of 6dBm was sufficient to prevent this behaviour. The precise threshold values are dependent upon the environment in which the SmartLock resides.

�41

Page 42: smartlock_final_report

Formal Report for SmartLock

8. TEST PLANS AND RESULTS

8.1 Servo Drain and Battery Test

The purpose of the test was to measure the servo current draw.

8.1.1 Results

The servo was found to draw substantially more current than had been anticipated. This resulted in the Arduino resetting whenever the servo was engaged. The current draw was measured on an oscilloscope using a current sense resistor, and peak current was measured at 1.3A. The boost controller selected for the demo provided a maximum output of 600mA, which was insufficient.

8.1.2 Solutions Attempted

1. Used capacitors to minimize current spikes which did not have the desired effect.

2. Added an inductor in series with the servo which successfully prevented the Arduino from resetting; however, it reduced the speed of the servo.

8.1.3 Recommendations

Selecting a boost converter with a higher current output should resolve these issues. Further inquiry into the electromechanical actuation is also required to minimize current spikes caused by resistance in the deadbolt.

�42

Page 43: smartlock_final_report

Formal Report for SmartLock

8.2 First Assembly of 3D Printed Parts

The purpose of this test was to assemble the first version of the 3D printed pieces.

8.2.1 Results

1. Resin used was too brittle causing pieces to crack,

2. Tumbler ring tolerance was insufficient for smooth rotation against the ring guide,

3. Servo container was too shallow and narrow due to insufficient tolerance,

4. Backplane supports were insufficient for handling device torque,

5. Servo horn attachment required redesign for correct actuation.

8.2.2 Revisions

1. Changed to ABS printed pieces,

2. Updated all component tolerances, particularly the tumbler,

3. Increased the height of the SmartLock to accommodate the Servo,

4. Modified the supports from pillars to large blocks for increased rigidity.

�43

Page 44: smartlock_final_report

Formal Report for SmartLock

8.3 Second Assembly of 3D Printed Parts

The purpose of this test was to assemble the second revision of the printed parts and to ensure correct electromechanical actuation.

8.3.1 Results

1. The majority of parts fit together correctly; however, there was a slight issue with the tolerance on the body housing ring guide.

2. The servo horn attachment was attempting to translate laterally as opposed to expending all force in the rotation which was causing the tumbler ring to torque, thus preventing the deadbolt from actuating.

8.3.2 Revisions

1. The body housing ring guide was sanded, allowing all parts to seat correctly,

2. A channel was carved into the tumbler arm,

3. The servo horn attachment was outfitted with a ring.

When coupled with the channel in the tumbler arm, the servo horn attachment was forced to rotate exclusively resulting in correct electromechanical actuation of the deadbolt.

�44

Page 45: smartlock_final_report

Formal Report for SmartLock

8.4 Bluetooth Control Testing

The purpose of this test was to confirm successful wiring of the various modules and communication between the custom Arduino firmware and the custom iOS app.

8.4.1 Verification of Hardware

Procedure:

Test the Adafruit iOS app in conjunction with the Adafruit Arduino firmware to ensure working hardware.

Result:

With the Arduino wired correctly, we were able to control the LEDs.

8.4.2 Verification of Firmware

Procedure:

Upload the custom SmartLock firmware, and verify correct operation using the known-good Adafruit iOS app and hardware configuration.

Result:

We were able to verify correct operation when sending ‘L’ and ‘U’ through the UART view.

�45

Page 46: smartlock_final_report

Formal Report for SmartLock

8.4.3 Verification of Software

Procedure:

Run the custom SmartLock app on iPhone, and verify correct operation using the known-good SmartLock firmware and hardware configuration.

Result:

We were able to verify correct operation when sending lock and unlock commands. Verified proximity detection using debug mode also performed correctly.

8.4.4 Revisions

During proximity testing, we concluded that the RSSI readings provided by the peripheral fluctuated wildly. To accommodate this, we introduce hysteresis into our proximity thresholds and recorded four RSSI readings every half second to obtain an average.

�46

Page 47: smartlock_final_report

Formal Report for SmartLock

9. SCOPE CHANGES

The following scope changes were made to the project as development progressed or are suggestions for changes going forward.

1. WiFi was not implemented,

2. Encryption was not implemented,

3. Microswitches were not installed,

4. Boost controller selection needs to be revised.

Due to timing constraints, WiFi implementation was not possible; however, this is definitely a feature that would need to be implemented in a final product as it allows the SmartLock to truly differentiate itself from competitors. Similarly, proper encryption was not implemented for lack of time and experience with true encryption. This would also have to be implemented in the final product.

In the second revision of the prototype, adequate tolerance was not provided for the microswitches preventing us from successfully installing them. Modifications were made to the 3D model; however, we were unable to print a third revision.

After extensive testing, it was determined that the current requirements of the servo exceeded our initial estimates. As a result, it is necessary to select a boost controller capable of outputting a sufficient amount of current.

�47

Page 48: smartlock_final_report

Formal Report for SmartLock

10. ANALYSIS OF SUCCESS AND FAILURE

10.1 Successes

10.1.1 iOS App

The custom mobile app for iOS allows the user to successfully control the SmartLock using button controls and proximity detection. While the proximity detection is not perfect, improving it will be difficult without acquiring more accurate RSSI values which most likely involves sourcing a better BLE module.

10.1.2 3D Printed Parts

As with any prototyping, constant iteration is necessary to create a functioning product. With the SmartLock project, multiple revisions were required for correct electromechanical functionality and proper alignment of all 3D printed pieces. However, the final printed prototype, the second revision, functioned correctly and should be considered a success.

10.2 Failures

10.2.1 Boost Converters

As discussed in the test reports, the servo drew much more current than expected which resulted in the power electronics being inadequate. If provided the opportunity to reselect components, components with a larger tolerance would have been selected. Furthermore, additional testing of the power components should have been performed earlier as the mechanical components were largely irrelevant in this testing.

�48

Page 49: smartlock_final_report

Formal Report for SmartLock

11. CONCLUSION

With this project, we sought to create a replacement for the deadbolt thumbturn that could be controlled using Bluetooth on a mobile device. In this endeavour, we were successful. We were also exposed to the interplay of electromechanical components and software. Each team member was assigned a specific set of tasks relating to the global design of the device, and each was successful in implementing and testing his duties.

In the initial planning stages of the SmartLock, we had the following primary design goals:

1. Create a Bluetooth controlled thumbturn to electronically actuate a deadbolt,

2. Implement proximity detection to simplify locking and unlocking the door.

During our presentation of the SmartLock, we were able to provide an effective and successful demonstration of the product locking and unlocking using a mobile device. In addition, we were also able to demonstrate proximity detection and manual operation. As a result, we consider the SmartLock project to be a huge success and we are thrilled with the results.

11.1 Electromechanical and Manual Operation

Both electromechanical and manual operation of the SmartLock worked correctly. Specifically, manual operation proved to be a very kinaesthetically-pleasing experience when compared with a regular thumbturn. As mentioned previously, however, redesign of the mechanical system may be necessary to improve reliability.

�49

Page 50: smartlock_final_report

Formal Report for SmartLock

11.2 Bluetooth Control and Proximity Detection

Bluetooth communication through the iOS app was successful and worked consistently. The proximity detection was affected by errant RSSI readings; however, this was largely due to the Bluetooth module.

11.3 Lessons Learned

The primary lesson learned is that hardware development is substantially more difficult and time consuming than software development. While the firmware and mobile app were able to be tested easily until proper operation was achieved, mechanical testing required all components to be obtained prior to proceeding. As a result, testing of the electromechanical actuation was fairly late with respect to the presentation and due date of the project, and this limited the amount of revision possible. Furthermore, project risk could be reduced by limiting reliance on 3D printers as they are prone to problems. Specifically we encountered issues with print tolerance, and in the case of Albert’s printer, catastrophic failure.

Each member of the team was responsible for a section of the development of the project. As a result, we each learned a tremendous amount of new information about our specific areas of focus.

James spent the majority of his time learning about coupling servos to other mechanical devices, and powering servos from various power sources.

Albert learned about boost converters, 3D printing, and 3D modelling with Autodesk Inventor. He also discovered the difficulty in assembling a personal 3D printer.

Elliot conducted extensive research into the operation of Bluetooth Low Energy and WiFi, in addition to learning Apple’s programming languages Swift and Objective-C. He was exposed to the difficulties of troubleshooting and debugging mobile app development, particularly mobile communication.

�50

Page 51: smartlock_final_report

Formal Report for SmartLock

12. RECOMMENDATIONS

Throughout the course of this report, there have been many recommendations for further development of the SmartLock.

Mechanically, the SmartLock design needs to be smaller, as its current footprint is borderline excessive. This can be accomplished by re-evaluating different types of motors for electromechanical actuation, as the servo took up the majority of the existing space in the prototype. Ideally, a custom motor could be manufactured with a small footprint while providing an adequate amount of torque. Selecting a different motor would require redesigning the mechanical aspect to work with the new device, while also making it compact.

As discussed extensively in the Tests and Results section, to meet the demands of the servo during actuation, selecting a different boost converter that can provide higher current is required.

The firmware and software need further revision to introduce extensive security and to implement the SmartLock WiFi functionality. Development of a web server platform would also be required.

Recommendations for improving the learning experience offered by the ELEX 4330 project course include providing students with access to experts in various fields. Allowing students to interact with mechanical and material engineers would reduce some of the burden of having electrical engineering students trying to devise complex mechanical solutions. This would also expose them to other disciplines of engineering. Furthermore, the extensive workload through Level Four does not take into consideration the necessary time to work on the project, despite the project’s immense time requirements. Finally, the equipment provided in the project room is entirely insufficient for adequate development. The analog oscilloscopes return inconsistent information, and the power supplies’ output voltages fluctuate wildly causing significant issues during testing.

�51

Page 52: smartlock_final_report

Formal Report for SmartLock

13. DOCUMENTATION REFERENCES

Adafruit. (2014, March 20). Introduction to Bluetooth Low Energy. Retrieved December 18, 2014, from https://learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt

Apple Inc. (2014, June). Swift. A new language that lets everyone build amazing apps. Retrieved December 18, 2014, from http://www.apple.com/swift/

Bluetooth SIG, Inc. (2014). Bluetooth Smart Technology: Powering the Internet of Things. Retrieved December 17, 2014, from http://www.bluetooth.com/Pages/Bluetooth-Smart.aspx

Robotzone, LLC. (n.d.). HS-225BB Mighty Mini. Retrieved December 12, 2014, from https://www.servocity.com/html/hs-225bb_mighty_mini.html#.VJJdQTHF97U

Texas Instruments Inc. (2013). BLE Protocol Stack. In Texas Instruments CC2540/41 Bluetooth® Low Energy Software Developer’s Guide v1.3.2 (Vol. 1.3.2). Retrieved December 17, 2014, from http://www.ti.com/lit/ug/swru271f/swru271f.pdf

�52

Page 53: smartlock_final_report

Formal Report for SmartLock

Appendices

Appendix A: Resources Appendix B: Bill of Materials Appendix C: Device Schematics Appendix D: SmartLock Firmware Source Code Appendix E: SmartLock iOS APP Source Code Appendix F: User Manual Appendix G: Gantt Chart Appendix H: Style Guide

Page 54: smartlock_final_report

Formal Report for SmartLock

APPENDIX A: RESOURCES

The following are links to datasheets and API references which we have used throughout our SmartLock project.

Datasheets:

• AAT1217 SMD Boost Converter: http://www.skyworksinc.com/uploads/documents/AAT1217_202050B.pdf

• Arduino Configuration: https://learn.adafruit.com/getting-started-with-the-nrf8001-bluefruit-le-breakout/testing-uart

• ATMega328 Microcontroller: http://www.atmel.com/images/atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet.pdf

• CC3000 WiFi Module: http://www.ti.com/lit/ds/symlink/cc3000.pdf

• HS-225BB Servo: http://www.robotshop.com/media/files/pdf/hs225bb.pdf

• LT1302 Thru-hole Boost Converter (Demo): http://cds.linear.com/docs/en/datasheet/lt1302.pdf

• nRF8001 Bluetooth Module: http://www.nordicsemi.com/eng/content/download/2981/38488/file/nRF8001_PS_v1.2.pdf

Page 55: smartlock_final_report

Formal Report for SmartLock

Swift API References:

• Core Bluetooth Framework Reference: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CoreBluetooth_Framework/index.html

• Bluetooth LE Connection Sequence: https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/PerformingCommonCentralRoleTasks/PerformingCommonCentralRoleTasks.html

• CBCentralManager Class API: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBCentralManager_Class/index.html

• CBCentralManagerDelegate Protocol API: https://developer.apple.com/Library/mac/documentation/CoreBluetooth/Reference/CBCentralManagerDelegate_Protocol/index.html

• CBPeripheral Class API: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBPeripheral_Class/index.html

• CBPeripheralDelegate Protocol API: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/index.html

• CBService Class API: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBService_Class/index.html

• CBCharacteristic Class API: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/CBCharacteristic_Class/index.html

• NSData Class API: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html

Page 56: smartlock_final_report

Formal Report for SmartLock

APPENDIX B: BILL OF MATERIALS

The following parts were used in the creation of the SmartLock. Unless otherwise noted, all parts were ordered through Digi-Key.

Page 57: smartlock_final_report

Qty

Qty

to O

RD

ER

Par

tM

anuf

actu

rer P

art #

Dig

ikey

Par

t #P

acka

ge T

ype

Cos

t/Uni

tC

ost T

otal

Whe

reN

ote

Boo

st C

onve

rter P

arts

25

Boo

st C

onv

AD

JA

AT1

217I

CA

-1.2

-T1

863-

1495

-1-N

DS

OT2

3-6

$0.5

3$1

.06

Dig

ikey

2 B

oost

ers

210

4.7u

F 16

V C

aps

CL2

1A47

5KO

FNN

NE

1276

-106

5-1-

ND

805

$0.1

7$0

.34

Dig

ikey

Inpu

t and

O/P

Cap

s fo

r sw

itchi

ng C

ontro

ller

14

Sch

ottk

y 1A

Dio

deP

ME

G30

10E

R,1

1556

8-65

13-1

-ND

SO

D-1

23W

$0.5

8$0

.58

Dig

ikey

For s

witc

hing

30

10uH

indu

ctor

NR

6045

T100

M58

7-20

81-1

-ND

SM

D$0

.44

$1.3

2D

igik

eynr

6045

sm

d in

duct

or4

101.

02M

Res

isto

rE

RJ-

6EN

F102

4VP

1.02

BTC

T-N

D80

5$0

.13

$0.5

2D

igik

eyFe

edba

ck re

s an

d pu

lldow

ns1

1033

2k R

esis

tor

ER

J-6E

NF3

323V

P33

2KC

CT-

ND

805

$0.1

3$0

.13

Dig

ikey

5v fe

edba

ck re

s1

1060

4k R

esis

tor

ER

J-6E

NF6

043V

P60

4KC

CT-

ND

805

$0.1

3$0

.13

Dig

ikey

3.3v

feed

back

res

11

CC

3000

Wifi

$40.

00$4

0.00

Lees

Wifi

Mod

ule

brea

kout

11

Ser

voH

S-2

25B

B$1

9.99

$19.

99R

obot

shop

Tota

l$6

4.07

Thro

ughh

ole

pow

er e

lect

roni

csTh

ese

wer

e pu

rcha

sed

for p

roto

typi

ng o

nly

11

IC R

EG

BO

OS

T 5V

0.6

A 8

DIP

LT13

02C

N8-

5#P

BF-

ND

8-D

IP$7

.50

$7.5

0D

igik

ey1

1S

chot

tky

2A d

iode

SR

203-

TPC

T-N

DTH

$0.5

4$0

.54

Dig

ikey

11

10uH

2A

AIU

R-0

3-10

0K-N

DTH

$0.6

7$0

.67

Dig

ikey

22

100u

F 16

V C

apP

1629

2-N

DTH

$1.0

0$2

.00

Dig

ikey

11

1000

0pF

16V

Cap

399-

9794

-ND

TH$0

.37

$0.3

7D

igik

ey1

10.

1 uF

16V

Cap

399-

9796

-ND

TH$0

.37

$0.3

7D

igik

ey

Tota

l$1

1.45

Pric

es a

s of

Dec

embe

r 17,

201

4

Bill

of M

ater

ials

for t

he S

mar

tLoc

k

Page 58: smartlock_final_report

Formal Report for SmartLock

APPENDIX C: DEVICE SCHEMATICS

The following are device schematics for the overall project, including the ATMega328P microcontroller, headers for power, the nRF8001 Bluetooth module, and the CC3000 WiFi module. The attachments are as follows:

1. SmartLock Global Schematic: illustrates all module connections

2. Arduino Uno Schematic: illustrates all connections to the microcontroller

3. Power Schematic: illustrates both boost converters

4. Wireless Module Headers: illustrates connections to nRF8001 and CC3000

Page 59: smartlock_final_report

11

22

33

44

DD

CC

BB

AA

Title

Num

ber

Revisio

nSize A Date:

12/11/2014

Sheet of

File:

C:\Users\..\M

ain.SchD

ocDrawn By

:

A0

A1

A2

A3

A4

A5

A6

A7

D0/RX

DD1/TX

DD2/INT0

D3/INT1

D4

D5

D6

D7

D8

D9

D10/SS

D11/M

OSI

D12/M

ISO

D13/SCK

VCC

GND

ARE

F

RESE

T

D14/XTA

L1D15/XTA

L2

U_A

rduino

Arduino.SchDoc

VCC

GND

RSTb

IRQb

MISO

MOSI

SCLKCSb

CSw

IRQw

ENw

U_H

eaders

Headers.SchDoc

SERV

O

BAT+

BAT-

SERV

O+

SERV

O-

SW1aSW1b

SW2aSW2b

GND1 DSR2 VCC3 TX4 RX5 DTR6

JP0

1uF

C0

D11

D12

D13

68R

R11

68R

R12

68R

R13

GND

GND

LS1

Buzzer

GND

VBA

T

GND

aSD3V 5V 3V3

aSD5V

U_Pow

erPo

wer.SchDoc

PIC001

PIC002

COC0

PID1101

PID1102

COD11

PID1201

PID1202

COD12

PID1301

PID1302

COD13

PIJP001PIJP002PIJP003PIJP004PIJP005PIJP006 COJP0

PILS101

PILS101A

PILS102

PILS102A

COLS1

PIR110

1PIR

1102

COR11

PIR120

1PIR

1202

COR12

PIR130

1PIR

1302

COR13

POSERVO0

POSW1bPOSW2b

POSERVO

PID1102

PID1202

PID1302

PIJP001PIJP002

PILS101

PILS101A

POBAT0

POSERVO0

POSW1aPOSW2a

PIC001

PIJP006PIC

002

PID1101

PIR110

2 PID1201

PIR120

2 PID1301

PIR130

2

PIJP003PIJP004PIJP005

PILS102

PILS102A

PIR110

1

PIR120

1

PIR130

1

POBAT0

POBAT0

POSERVO

POSERVO0

POSW1APOSW1BPOSW2APOSW2B

Page 60: smartlock_final_report

11

22

33

44

DD

CC

BB

AA

Title

Num

ber

Revision

Size A Date:

12/11/2014

Sheet of

File:

C:\Users\..\Arduino.SchDoc

Drawn By:

PC6

aRES

ET/PCIN

T14)

29

PD0

aRXD/PCIN

T16)

30

PD1

aTXD/PCIN

T17)

31

PD2

aINT0

/PCIN

T18)

32

PD4

aPCIN

T20/XCK/T0)

2

VCC

6

GND

5PB

6 aPCIN

T6/XTA

L1/TOSC

1)7

PB7

aPCIN

T7/XTA

L2/TOSC

2)8

PD5

aPCIN

T21/OC0B

/T1)

9

PD6

aPCIN

T22/OC0A

/AIN

0)10

PD7

aPCIN

T23/AIN

1)11

PB0

aPCIN

T0/CLK

O/IC

P1)

12

PB1

aPCIN

T1/OC1A

)13

PB2

aPCIN

T2/SS/OC1B

)14

PB3

aPCIN

T3/OC2A

/MOSI)

15

PB4

aPCIN

T4/M

ISO)

16

PB5

aSCK/PCIN

T5)

17

AVCC

18

ARE

F20

GND

21

PC0

aADC0/PC

INT8

)23

PC1

aADC1/PC

INT9

)24

PC2

aADC2/PC

INT1

0)25

PC3

aADC3/PC

INT1

1)26

PC4

aADC4/SD

A/PCIN

T12)

27

PC5

aADC5/SC

L/PC

INT1

3)28

GND

3

VCC

4ADC6

19

ADC7

22

PD3

aPCIN

T19/OC2B

/INT1

)1

U1

ATmega328P-AU

A0

A1

A2

A3

A4

A5

A6

A7

D0/RXD

D1/TX

DD2/IN

T0D3/IN

T1D4

D5

D6

D7

D8

D9

D10/SS

D11/M

OSI

D12/M

ISO

D13/SCK

VCC

GND

ARE

F

100nF

C1

10K

R7

VCC

D3

RESE

T

D14/XTA

L1D15/XTA

L2

100nF

C2

GND

GND

GND

VCC

VCC

PIC101PIC102COC

1

PIC201PIC202COC

2PID301PID302 COD

3

PIR701PIR702 COR7

PIU101

PIU102

PIU103

PIU104

PIU105

PIU106

PIU107

PIU108

PIU109

PIU1010

PIU1011

PIU1012

PIU1013

PIU1014

PIU1015

PIU1016

PIU1017

PIU1018

PIU1019

PIU1020

PIU1021

PIU1022

PIU1023

PIU1024

PIU1025

PIU1026

PIU1027

PIU1028

PIU1029

PIU1030

PIU1031

PIU1032

COU1

PIC101PIC201

PIU103

PIU105

PIU1021

POGND

PIC202PIU1020

POAREF

PID301PIR701

PIU1029

PORESET

PIU101

POD30INT1

PIU102

POD4

PIU107

POD140XTAL1

PIU108

POD150XTAL2

PIU109

POD5

PIU1010

POD6

PIU1011

POD7

PIU1012

POD8

PIU1013

POD9

PIU1014

POD100SS

PIU1015

POD110MOSI

PIU1016

POD120MISO

PIU1017

POD130SCK

PIU1019

POA6

PIU1022

POA7

PIU1023

POA0

PIU1024

POA1

PIU1025

POA2

PIU1026

POA3

PIU1027

POA4

PIU1028

POA5

PIU1030

POD00RXD

PIU1031

POD10TXD

PIU1032

POD20INT0

PIC102

PID302PIR702

PIU104

PIU106

PIU1018

POVCC

POA0

POA1

POA2

POA3

POA4

POA5

POA6

POA7

POAREF

POD00RXD

POD10TXD

POD20INT0

POD30INT1

POD4

POD5

POD6

POD7

POD8

POD9

POD100SS

POD110MOSI

POD120MISO

POD130SCK

POD140XTAL1

POD150XTAL2

POGND

PORESET

POVCC

Page 61: smartlock_final_report

11

22

33

44

DD

CC

BB

AA

Title

Num

ber

Revision

Size A Date:

12/11/2014

Sheet of

File:

C:\Users\..\Pow

er.SchDoc

Drawn By:

SW1

GND

2FB

3

aSHDN

4

VOUT

5

VIN

6

IC1

AAT

1217

SW1

GND

2FB

3

aSHDN

4

VOUT

5

VIN

6

IC2

AAT

1217

VBA

T

GND

10uH

L1 10uH

L2

aSD3V

1.02M

R3

1.02M

R6

1.02M

R1

1.02M

R4

604k

R2

332k

R5

5V

3V3

D1

D2

aSD5V

PID101

PID102

COD1

PID201

PID202

COD2

PIIC101

PIIC102

PIIC103

PIIC104

PIIC105

PIIC106COI

C1

PIIC201

PIIC202

PIIC203

PIIC204

PIIC205

PIIC206COI

C2

PIL101

PIL102

COL1

PIL201

PIL202

COL2

PIR101PIR102 COR1

PIR201PIR202 COR2

PIR301

PIR302

COR3

PIR401PIR402 COR4

PIR501PIR502 COR5

PIR601

PIR602

COR6

PID101

PIIC101

PIL102

PID102

PIIC105 PIR102

PO5V

PID201

PIIC201

PIL202

PID202

PIIC205 PIR402

PO3V3

PIIC102

PIIC202

PIR201 PIR501

POGND

PIIC103PIR101 PIR202

PIIC104

PIR301

PO!SD5V

PIIC106

PIIC206

PIL101

PIL201

PIR302

PIR602

POVBAT

PIIC203PIR401 PIR502

PIIC204

PIR601

PO!SD3V

PO!SD3V

PO!SD5V

PO3V3

PO5V

POGND

POVBAT

Page 62: smartlock_final_report

1

1

2

2

3

3

4

4

D D

C C

B B

A A

Title

Number RevisionSizeA

Date: 12/11/2014 Sheet ofFile: C:\Users\aa\HeadersaSchDoc Drawn By:

IRQ1

VBEN2CS3

MOSI4MISO5

CLK6VIN7

3V38GND9

JP2

VIN1GND23Vo3RST4ACT5RDY6REQ7MOSI8

MISO9SCLK10

JP1VCCGND

RSTb

IRQb

MISOMOSI

SCLK

CSb

CSw

IRQwENw

PIJP101PIJP102PIJP103PIJP104PIJP105PIJP106PIJP107PIJP108PIJP109PIJP1010

COJP1

PIJP201PIJP202PIJP203PIJP204PIJP205PIJP206PIJP207PIJP208PIJP209

COJP2

PIJP101

PIJP208

POVCCPIJP102

PIJP209

POGNDPIJP103PIJP104PORSTbPIJP105PIJP106POIRQbPIJP107POCSbPIJP108

PIJP204

POMOSIPIJP109

PIJP205

POMISOPIJP1010

PIJP206

POSCLK

PIJP201POIRQwPIJP202POENwPIJP203POCSw

PIJP207

POCSB

POCSWPOENW

POGND

POIRQB

POIRQW

POMISOPOMOSI

PORSTB

POSCLK

POVCC

Page 63: smartlock_final_report

Formal Report for SmartLock

APPENDIX D: SMARTLOCK FIRMWARE SOURCE CODE

The following appendix is the source code for the SmartLock Firmware including the Adafruit BLE UART class. The attachments are as follows:

1. SmartLock Firmware

2. Adafruit BLE UART header (.h)

3. Adafruit BLE UART implementation (.cpp)

Page 64: smartlock_final_report

//// SmartLock.ino// SmartLock Firmware//// Created by Elliot Barer on 2014-10-09.// Copyright (c) 2014 Elliot Barer. All rights reserved.// Modified from Adafruit BLE UART example code//

#include <SPI.h>#include <Servo.h>#include "Adafruit_BLE_UART.h"

//*******************************************************// Pin Definitions//*******************************************************#define SCK 13#define MISO 12#define MOSI 11#define REQ 10#define RST 9#define RDY 2#define PIN_LOCK 0#define PIN_UNLOCK 1#define LED_UNLOCK 3#define LED_LOCK 4#define SPEAKER 5#define SERVO 6

//*******************************************************// Servo and Audio Definitions//*******************************************************#define SERVO_LOCK 2696#define SERVO_UNLOCK 556#define SERVO_NEUTRAL ((SERVO_LOCK - SERVO_UNLOCK) / 2 + SERVO_UNLOCK)#define SERVO_DELAY 500

#define VOLUME 100#define CHIRP_DELAY 100

//*******************************************************// Lock Status

Page 65: smartlock_final_report

//*******************************************************typedef enum { LOCK = 76, UNLOCK = 85} LockState;

LockState lockStatus = LOCK;

//*******************************************************// Objects//*******************************************************Adafruit_BLE_UART smartLock = Adafruit_BLE_UART(REQ, RDY, RST);Servo lockServo;

//*******************************************************// Configure the Arduino and begin advertising//*******************************************************void setup(void) { // Setup serial monitor Serial.begin(115200); Serial.println(F("SmartLock - Serial Debugger")); // Setup servo lockServo.attach(SERVO); // Setup control pins pinMode(LED_UNLOCK, OUTPUT); pinMode(LED_LOCK, OUTPUT); pinMode(SPEAKER, OUTPUT); pinMode(PIN_LOCK, INPUT); pinMode(PIN_UNLOCK, INPUT); // Setup BLE advertising smartLock.setDeviceName("SMRTLCK"); /* 7 characters max! */ smartLock.setACIcallback(aciCallback); smartLock.setRXcallback(rxCallback); smartLock.begin(); smartLock.flush(); // Lock the door (default, for safety) lockSmartLock();}

Page 66: smartlock_final_report

//*******************************************************// Constantly checks for new events on the nRF8001//*******************************************************void loop() { smartLock.pollACI();}

//*******************************************************// SmartLock Response//*******************************************************void smartLockResponse() { uint8_t buffer[20]; String response; switch(lockStatus) { case LOCK: response = "L"; break; case UNLOCK: response = "U"; break; } // Send lock status response.getBytes(buffer, 20); uint8_t buffer_size = min(20, response.length()); smartLock.write(buffer, buffer_size); // Clear buffer smartLock.flush();}

//*******************************************************// Mechanical Functions//*******************************************************void speakerChirp() { Serial.println("\tChirp"); analogWrite(SPEAKER, VOLUME); delay(CHIRP_DELAY); analogWrite(SPEAKER, 0); delay(CHIRP_DELAY);}

Page 67: smartlock_final_report

//*******************************************************// Lock SmartLock//*******************************************************void lockSmartLock() { Serial.println("Lock"); digitalWrite(LED_UNLOCK, LOW); digitalWrite(LED_LOCK, HIGH);

// Move servo to LOCK position lockServo.write(SERVO_LOCK); delay(SERVO_DELAY);

// Chirp once to acknolwedge lock speakerChirp(); // Move servo to NEUTRAL position lockServo.write(SERVO_NEUTRAL); delay(SERVO_DELAY); // Write status to SmartLock App lockStatus = LOCK; smartLockResponse();}

//*******************************************************// Unlock SmartLock//*******************************************************void unlockSmartLock() { Serial.println("Unlock"); digitalWrite(LED_UNLOCK, HIGH); digitalWrite(LED_LOCK, LOW); // Move servo to UNLOCK position lockServo.write(SERVO_UNLOCK); delay(SERVO_DELAY); // Chirp twice to acknolwedge unlock speakerChirp(); speakerChirp(); // Move servo to NEUTRAL position lockServo.write(SERVO_NEUTRAL);

Page 68: smartlock_final_report

delay(SERVO_DELAY); // Write status to SmartLock App lockStatus = UNLOCK; smartLockResponse();}

//*******************************************************// Handle ACI Events//*******************************************************void aciCallback(aci_evt_opcode_t event) { switch(event) { case ACI_EVT_DEVICE_STARTED: Serial.println(F("Advertising")); break; case ACI_EVT_CONNECTED: Serial.println(F("Connected")); break; case ACI_EVT_DISCONNECTED: smartLock.flush(); Serial.println(F("Disconnected")); break; default: Serial.println(F("Unknown")); break; }}

//*******************************************************// Handle RX Events//*******************************************************void rxCallback(uint8_t *buffer, uint8_t len) { // Get SmartLock App command switch(buffer[0]) { case LOCK: lockSmartLock(); break; case UNLOCK: unlockSmartLock(); break; }}

Page 69: smartlock_final_report

/********************************************************************* This is a library for our nRF8001 Bluetooth Low Energy Breakout Pick one up today in the adafruit shop! ------> http://www.adafruit.com/products/1697 These displays use SPI to communicate, 4 or 5 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Kevin Townsend/KTOWN for Adafruit Industries. MIT license, check LICENSE for more information All text above, and the splash screen below must be included in any

redistribution *********************************************************************/

#if ARDUINO >= 100#include "Arduino.h"#else#include "WProgram.h"#endif

#ifndef _ADAFRUIT_BLE_UART_H_#define _ADAFRUIT_BLE_UART_H_

#include "utility/aci_evts.h"

#define BLE_RW_DEBUG

extern "C" {/* Callback prototypes */typedef void (*aci_callback)(aci_evt_opcode_t event);typedef void (*rx_callback) (uint8_t *buffer, uint8_t len);

}

class Adafruit_BLE_UART : public Stream {public:

Adafruit_BLE_UART (int8_t req, int8_t rdy, int8_t rst);

bool begin ( uint16_t advTimeout = 0, uint16_t advInterval = 80 );void pollACI ( void );size_t write ( uint8_t * buffer, uint8_t len );size_t write ( uint8_t buffer);

size_t println(const char * thestr);size_t print(const char * thestr);size_t print(String thestr);size_t print(int theint);size_t print(const __FlashStringHelper *ifsh);

void setACIcallback(aci_callback aciEvent = NULL);void setRXcallback(rx_callback rxEvent = NULL);void setDeviceName(const char * deviceName);

Page 70: smartlock_final_report

// Stream compatibilityint available(void);int read(void);int peek(void);void flush(void);

aci_evt_opcode_t getState(void);

private:void defaultACICallback(aci_evt_opcode_t event);void defaultRX(uint8_t *buffer, uint8_t len);

// callbacks you can set with setCallback function for user extensionaci_callback aci_event;rx_callback rx_event;

bool debugMode;uint16_t adv_timeout;uint16_t adv_interval;char device_name[8];

aci_evt_opcode_t currentStatus;

// pins usdint8_t _REQ, _RDY, _RST;

};

#endif

Page 71: smartlock_final_report

/********************************************************************* This is a library for our nRF8001 Bluetooth Low Energy Breakout Pick one up today in the adafruit shop! ------> http://www.adafruit.com/products/1697 These displays use SPI to communicate, 4 or 5 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Kevin Townsend/KTOWN for Adafruit Industries. MIT license, check LICENSE for more information All text above, and the splash screen below must be included in any

redistribution *********************************************************************/#include <SPI.h>#include <avr/pgmspace.h>#include <util/delay.h>#include <stdlib.h>#include <ble_system.h>#include <lib_aci.h>#include <aci_setup.h>#include "uart/services.h"

#include "Adafruit_BLE_UART.h"

/* Get the service pipe data created in nRFGo Studio */#ifdef SERVICES_PIPE_TYPE_MAPPING_CONTENTstatic services_pipe_type_mapping_tservices_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;#else#define NUMBER_OF_PIPES 0static services_pipe_type_mapping_t * services_pipe_type_mapping = NULL;#endif

/* Length of the buffer used to store flash strings temporarily when printing. */#define PRINT_BUFFER_SIZE 20

/* Store the setup for the nRF8001 in the flash of the AVR to save on RAM */static const hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] PROGMEM =

SETUP_MESSAGES_CONTENT;

static struct aci_state_t aci_state; /* ACI state data */static hal_aci_evt_t aci_data; /* Command buffer */static bool timing_change_done = false;

// This is the Uart RX buffer, which we manage internally when data is available!#define ADAFRUIT_BLE_UART_RXBUFFER_SIZE 64uint8_t adafruit_ble_rx_buffer[ADAFRUIT_BLE_UART_RXBUFFER_SIZE];volatile uint16_t adafruit_ble_rx_head;volatile uint16_t adafruit_ble_rx_tail;

Page 72: smartlock_final_report

int8_t HAL_IO_RADIO_RESET, HAL_IO_RADIO_REQN, HAL_IO_RADIO_RDY, HAL_IO_RADIO_IRQ;

/**************************************************************************//*! Constructor for the UART service *//**************************************************************************/// default RX callback!

void Adafruit_BLE_UART::defaultRX(uint8_t *buffer, uint8_t len){

for(int i=0; i<len; i++){

uint16_t new_head = (uint16_t)(adafruit_ble_rx_head + 1) % ADAFRUIT_BLE_UART_RXBUFFER_SIZE;

// if we should be storing the received character into the location// just before the tail (meaning that the head would advance to the// current location of the tail), we're about to overflow the buffer// and so we don't write the character or advance the head.if (new_head != adafruit_ble_rx_tail) {

adafruit_ble_rx_buffer[adafruit_ble_rx_head] = buffer[i];

// debug echo print// Serial.print((char)buffer[i]);

adafruit_ble_rx_head = new_head;}

}

/* Serial.print("Buffer: "); for(int i=0; i<adafruit_ble_rx_head; i++)

{ Serial.print(" 0x"); Serial.print((char)adafruit_ble_rx_buffer[i], HEX); }

Serial.println(); */}

/* Stream stuff */

int Adafruit_BLE_UART::available(void){

return (uint16_t)(ADAFRUIT_BLE_UART_RXBUFFER_SIZE + adafruit_ble_rx_head - adafruit_ble_rx_tail)

% ADAFRUIT_BLE_UART_RXBUFFER_SIZE;}

int Adafruit_BLE_UART::read(void){

// if the head isn't ahead of the tail, we don't have any charactersif (adafruit_ble_rx_head == adafruit_ble_rx_tail) {

return -1;} else {

Page 73: smartlock_final_report

unsigned char c = adafruit_ble_rx_buffer[adafruit_ble_rx_tail];adafruit_ble_rx_tail ++;adafruit_ble_rx_tail %= ADAFRUIT_BLE_UART_RXBUFFER_SIZE;return c;

}}

int Adafruit_BLE_UART::peek(void){

if (adafruit_ble_rx_head == adafruit_ble_rx_tail) {return -1;

} else {return adafruit_ble_rx_buffer[adafruit_ble_rx_tail];

}}

void Adafruit_BLE_UART::flush(void){

// MEME: KTOWN what do we do here?}

//// more callbacks

void Adafruit_BLE_UART::defaultACICallback(aci_evt_opcode_t event){

currentStatus = event;}

aci_evt_opcode_t Adafruit_BLE_UART::getState(void) {return currentStatus;

}

/**************************************************************************//*! Constructor for the UART service *//**************************************************************************/Adafruit_BLE_UART::Adafruit_BLE_UART(int8_t req, int8_t rdy, int8_t rst){

debugMode = true;

HAL_IO_RADIO_REQN = req;HAL_IO_RADIO_RDY = rdy;HAL_IO_RADIO_RESET = rst;

rx_event = NULL;aci_event = NULL;

memset(device_name, 0x00, 8);

adafruit_ble_rx_head = adafruit_ble_rx_tail = 0;

Page 74: smartlock_final_report

currentStatus = ACI_EVT_DISCONNECTED;}

void Adafruit_BLE_UART::setACIcallback(aci_callback aciEvent) {aci_event = aciEvent;

}

void Adafruit_BLE_UART::setRXcallback(rx_callback rxEvent) {rx_event = rxEvent;

}

/**************************************************************************//*! Transmits data out via the TX characteristic (when available) *//**************************************************************************/size_t Adafruit_BLE_UART::println(const char * thestr){

uint8_t len = strlen(thestr),written = len ? write((uint8_t *)thestr, len) : 0;if(written == len) written += write((uint8_t *)"\r\n", 2);

return written;}

size_t Adafruit_BLE_UART::print(const char * thestr){

return write((uint8_t *)thestr, strlen(thestr));}

size_t Adafruit_BLE_UART::print(String thestr){

return write((uint8_t *)thestr.c_str(), thestr.length());}

size_t Adafruit_BLE_UART::print(int theint){

char message[4*sizeof(int)+1] = {0};itoa(theint, message, 10);return write((uint8_t *)message, strlen(message));

}

size_t Adafruit_BLE_UART::print(const __FlashStringHelper *ifsh){

// Copy bytes from flash string into RAM, then send them a buffer at a time.char buffer[PRINT_BUFFER_SIZE] = {0};const char PROGMEM *p = (const char PROGMEM *)ifsh;size_t written = 0;int i = 0;unsigned char c = pgm_read_byte(p++);// Read data from flash until a null terminator is found.while (c != 0) {

// Copy data to RAM and increase buffer index.buffer[i] = c;i++;if (i >= PRINT_BUFFER_SIZE) {

Page 75: smartlock_final_report

// Send buffer when it's full and reset buffer index.written += write((uint8_t *)buffer, PRINT_BUFFER_SIZE);i = 0;

}// Grab a new byte from flash.c = pgm_read_byte(p++);

}if (i > 0) {

// Send any remaining data in the buffer.written += write((uint8_t *)buffer, i);

}return written;

}

size_t Adafruit_BLE_UART::write(uint8_t * buffer, uint8_t len){

uint8_t bytesThisPass, sent = 0;

#ifdef BLE_RW_DEBUGSerial.print(F("\tWriting out to BTLE:"));for (uint8_t i=0; i<len; i++) {

Serial.print(F(" 0x")); Serial.print(buffer[i], HEX);}Serial.println();

#endif

while(len) { // Parcelize into chunksbytesThisPass = len;if(bytesThisPass > ACI_PIPE_TX_DATA_MAX_LEN)

bytesThisPass = ACI_PIPE_TX_DATA_MAX_LEN;

if(!lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX))

{pollACI();continue;

}

lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer[sent], bytesThisPass);

aci_state.data_credit_available--;

delay(35); // required delay between sends

if(!(len -= bytesThisPass)) break;sent += bytesThisPass;

}

return sent;}

size_t Adafruit_BLE_UART::write(uint8_t buffer){#ifdef BLE_RW_DEBUG

Serial.print(F("\tWriting one byte 0x")); Serial.println(buffer, HEX);#endif

Page 76: smartlock_final_report

if (lib_aci_is_pipe_available(&aci_state, PIPE_UART_OVER_BTLE_UART_TX_TX)){

lib_aci_send_data(PIPE_UART_OVER_BTLE_UART_TX_TX, &buffer, 1);aci_state.data_credit_available--;

delay(35); // required delay between sendsreturn 1;

}

pollACI();

return 0;}

/**************************************************************************//*! Update the device name (7 characters or less!) *//**************************************************************************/void Adafruit_BLE_UART::setDeviceName(const char * deviceName){

if (strlen(deviceName) > 7){

/* String too long! */return;

}else{

memcpy(device_name, deviceName, strlen(deviceName));}

}

/**************************************************************************//*! Handles low level ACI events, and passes them up to an application level callback when appropriate *//**************************************************************************/void Adafruit_BLE_UART::pollACI(){

// We enter the if statement only when there is a ACI event available to be processed

if (lib_aci_event_get(&aci_state, &aci_data)){

aci_evt_t * aci_evt;

aci_evt = &aci_data.evt;switch(aci_evt->evt_opcode){

/* As soon as you reset the nRF8001 you will get an ACI Device Started Event */

case ACI_EVT_DEVICE_STARTED:aci_state.data_credit_total = aci_evt->params.device_started.

credit_available;switch(aci_evt->params.device_started.device_mode){

Page 77: smartlock_final_report

case ACI_DEVICE_SETUP:/* Device is in setup mode! */if (ACI_STATUS_TRANSACTION_COMPLETE != do_aci_setup(&

aci_state)){

if (debugMode) {Serial.println(F("Error in ACI Setup"));

}}break;

case ACI_DEVICE_STANDBY:/* Start advertising ... first value is advertising time

in seconds, the *//* second value is the advertising interval in 0.625ms

units */if (device_name[0] != 0x00){

/* Update the device name */lib_aci_set_local_data(&aci_state,

PIPE_GAP_DEVICE_NAME_SET , (uint8_t *)&device_name, strlen(device_name));

}lib_aci_connect(adv_timeout, adv_interval);defaultACICallback(ACI_EVT_DEVICE_STARTED);if (aci_event)

aci_event(ACI_EVT_DEVICE_STARTED);}break;

case ACI_EVT_CMD_RSP:/* If an ACI command response event comes with an error -> stop

*/if (ACI_STATUS_SUCCESS != aci_evt->params.cmd_rsp.cmd_status){

// ACI ReadDynamicData and ACI WriteDynamicData will have status codes of

// TRANSACTION_CONTINUE and TRANSACTION_COMPLETE// all other ACI commands will have status code of

ACI_STATUS_SUCCESS for a successful commandif (debugMode) {

Serial.print(F("ACI Command "));Serial.println(aci_evt->params.cmd_rsp.cmd_opcode, HEX);Serial.println(F("Evt Cmd respone: Error. Arduino is in

an while(1); loop"));}while (1);

}if (ACI_CMD_GET_DEVICE_VERSION == aci_evt->params.cmd_rsp.

cmd_opcode){

// Store the version and configuration information of the nRF8001 in the Hardware Revision String Characteristic

lib_aci_set_local_data(&aci_state, PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET,

(uint8_t *)&(aci_evt->params.cmd_rsp.

Page 78: smartlock_final_report

params.get_device_version), sizeof(aci_evt_cmd_rsp_params_get_device_version_t));

}break;

case ACI_EVT_CONNECTED:aci_state.data_credit_available = aci_state.data_credit_total;/* Get the device version of the nRF8001 and store it in the

Hardware Revision String */lib_aci_device_version();

defaultACICallback(ACI_EVT_CONNECTED);if (aci_event)

aci_event(ACI_EVT_CONNECTED);

case ACI_EVT_PIPE_STATUS:if (lib_aci_is_pipe_available(&aci_state,

PIPE_UART_OVER_BTLE_UART_TX_TX) && (false == timing_change_done))

{lib_aci_change_timing_GAP_PPCP(); // change the timing on the

link as specified in the nRFgo studio -> nRF8001 conf. -> GAP.

// Used to increase or decrease bandwidth

timing_change_done = true;}break;

case ACI_EVT_TIMING:/* Link connection interval changed */break;

case ACI_EVT_DISCONNECTED:/* Restart advertising ... first value is advertising time in

seconds, the *//* second value is the advertising interval in 0.625ms units */

defaultACICallback(ACI_EVT_DISCONNECTED);if (aci_event)

aci_event(ACI_EVT_DISCONNECTED);

lib_aci_connect(adv_timeout, adv_interval);

defaultACICallback(ACI_EVT_DEVICE_STARTED);if (aci_event)

aci_event(ACI_EVT_DEVICE_STARTED);break;

case ACI_EVT_DATA_RECEIVED:defaultRX(aci_evt->params.data_received.rx_data.aci_data, aci_evt

->len - 2);if (rx_event)

rx_event(aci_evt->params.data_received.rx_data.aci_data,

Page 79: smartlock_final_report

aci_evt->len - 2);break;

case ACI_EVT_DATA_CREDIT:aci_state.data_credit_available = aci_state.data_credit_available

+ aci_evt->params.data_credit.credit;break;

case ACI_EVT_PIPE_ERROR:/* See the appendix in the nRF8001 Product Specication for

details on the error codes */if (debugMode) {

Serial.print(F("ACI Evt Pipe Error: Pipe #:"));Serial.print(aci_evt->params.pipe_error.pipe_number, DEC);Serial.print(F(" Pipe Error Code: 0x"));Serial.println(aci_evt->params.pipe_error.error_code, HEX);

}

/* Increment the credit available as the data packet was not sent */

aci_state.data_credit_available++;break;

}}else{

// Serial.println(F("No ACI Events available"));// No event in the ACI Event queue and if there is no event in the ACI

command queue the arduino can go to sleep// Arduino can go to sleep now// Wakeup from sleep from the RDYN line

}}

/**************************************************************************//*! Configures the nRF8001 and starts advertising the UART Service @param[in] advTimeout The advertising timeout in seconds (0 = infinite advertising) @param[in] advInterval The delay between advertising packets in 0.625ms units *//**************************************************************************/bool Adafruit_BLE_UART::begin(uint16_t advTimeout, uint16_t advInterval){

/* Store the advertising timeout and interval */adv_timeout = advTimeout; /* ToDo: Check range! */adv_interval = advInterval; /* ToDo: Check range! */

/* Setup the service data from nRFGo Studio (services.h) */if (NULL != services_pipe_type_mapping){

aci_state.aci_setup_info.services_pipe_type_mapping = &services_pipe_type_mapping[0];

}

Page 80: smartlock_final_report

else{

aci_state.aci_setup_info.services_pipe_type_mapping = NULL;}aci_state.aci_setup_info.number_of_pipes = NUMBER_OF_PIPES;aci_state.aci_setup_info.setup_msgs = (hal_aci_data_t*)setup_msgs;aci_state.aci_setup_info.num_setup_msgs = NB_SETUP_MESSAGES;

/* Pass the service data into the appropriate struct in the ACI */lib_aci_init(&aci_state);

/* ToDo: Check for chip ID to make sure we're connected! */

return true;}

Page 81: smartlock_final_report

Formal Report for SmartLock

APPENDIX E: SMARTLOCK IOS APP SOURCE CODE

The following appendix is the source code for the SmartLock iOS App. The attachments are as follows:

1. AppDelegate: backbone of the iOS app

2. SmartLock (Class): the SmartLock implementation

3. MainViewController: global view controller

4. SmartLockViewController: the primary view controller

5. LockViewControl: used to implement the animated circle class on the SmartLockViewController

6. DebugViewController: implement the debugging view

Page 82: smartlock_final_report

//// AppDelegate.swift// SmartLock iOS Application//// Created by Elliot Barer on 2014-10-09.// Copyright (c) 2014 Elliot Barer. All rights reserved.//

import UIKit

@UIApplicationMainclass AppDelegate: UIResponder, UIApplicationDelegate {

var window:UIWindow?var mainViewController:MainViewController?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {window?.tintColor = UIColor.greenColor()return true

}

func applicationWillResignActive(application: UIApplication) {// Sent when the application is about to move from active to inactive

state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

}

func applicationDidEnterBackground(application: UIApplication) {// Use this method to release shared resources, save user data,

invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

mainViewController?.gblSmartLock.discoverDevices()}

func applicationWillEnterForeground(application: UIApplication) {// Called as part of the transition from the background to the inactive

state; here you can undo many of the changes made on entering the background.

}

func applicationDidBecomeActive(application: UIApplication) {// Restart any tasks that were paused (or not yet started) while the

application was inactive. If the application was previously in the background, optionally refresh the user interface.

}

Page 83: smartlock_final_report

func applicationWillTerminate(application: UIApplication) {// Called when the application is about to terminate. Save data if

appropriate. See also applicationDidEnterBackground:.}

}

Page 84: smartlock_final_report

//// SmartLock.swift// SmartLock//// Created by Elliot Barer on 2014-12-03.// Copyright (c) 2014 Elliot Barer. All rights reserved.//

import UIKitimport CoreBluetooth

enum Status {case Lockingcase Lockedcase Unlockingcase Unlockedcase Unknown

}

class SmartLock: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {

// Prevent multiple instances of SmartLock from being createdclass var sharedInstance:SmartLock {

struct Static {static let instance:SmartLock = SmartLock()

}

return Static.instance}

// Bluetooth Peripheral Heirarchy://// CBPeripheral// |// |---- CBService// | |// | |---- CBCharacteristic// | |// | |---- CBCharacteristic// | |// | | ...// |// |---- CBService// |// | ...

//*******************************************************// Class members//*******************************************************

var centralManager:CBCentralManager! // Bluetooth central manager (iOS Device)

Page 85: smartlock_final_report

var smartLock:CBPeripheral! // Bluetooth peripheral device (SmartLock)

var rxCharacteristic:CBCharacteristic! // Bluetooth RX characteristic

var txCharacteristic:CBCharacteristic! // Bluetooth TX characteristic

var bluetoothState:Bool! // Bluetooth statusvar scanState:Bool! // Scan statusvar connectState:Bool! // Connection statusvar connectTimer:NSTimer! // Connection timeout

timervar lockStatus:Status! // Lock statusdynamic var activity:String! // Lock activitydynamic var debugActivity:String! // Lock activity (debug)

// Signal strength (RSSI) in dBmvar proximityEnable:Bool! // Proximity detection

statusvar rssiTimer:NSTimer! // RSSI update timervar rssiNow:Int! // Current RSSI valuevar rssiOld = [Int](count: 3, repeatedValue: 0) // Previous RSSI valuesvar lockThreshold = -73 // Locking RSSI thresholdvar unlockThreshold = -67 // Unlocking RSSI

threshold

// UUIDs for SmartLock UART Service and Characteristics (RX/TX)var smartLockNSUUID:NSUUID!let uartServiceUUID = CBUUID(string:"6E400001-B5A3-F393-E0A9-E50E24DCCA9E")let txCharacteristicUUID = CBUUID(string:"6E400002-B5A3-F393-E0A9-

E50E24DCCA9E")let rxCharacteristicUUID = CBUUID(string:"6E400003-B5A3-F393-E0A9-

E50E24DCCA9E")

override init() {super.init()

bluetoothState = falsescanState = falseconnectState = falselockStatus = .LockedproximityEnable = falserssiNow = 0

}

//*******************************************************// Central Manager (iPhone) Functions//*******************************************************

// Initializes the central manager with a specified delegate.func startUpCentralManager() {

centralManager = CBCentralManager(delegate: self, queue: nil)}

Page 86: smartlock_final_report

// Connect to SmarLockfunc connectToSmartLock(peripheral: CBPeripheral) {

centralManager.connectPeripheral(peripheral as CBPeripheral, options: [CBConnectPeripheralOptionNotifyOnNotificationKey: true])

}

// Disconnect from SmartLockfunc disconnectFromSmartLock() {

if(smartLock != nil) {centralManager.cancelPeripheralConnection(smartLock)smartLock = nil

}}

// Invoked when the central manager’s state is updated.func centralManagerDidUpdateState(central: CBCentralManager!) {

switch (central.state) {case .PoweredOff:

bluetoothState = falseoutput("Bluetooth Off")disconnectFromSmartLock()

case .PoweredOn:bluetoothState = trueoutput("Bluetooth On")discoverDevices()

default:bluetoothState = falseoutput("Bluetooth Unknown")

}}

// Scans for SmartLocks by searching for advertisements with UART services.func discoverDevices() {

// Avoid scanning by reconnecting to known good SmartLock// If not found, scan for other devicesif (bluetoothState == true && scanState == false) {

scanState = trueoutput("Searching...", UI: true)

if (smartLockNSUUID != nil) {var peripherals = centralManager.

retrievePeripheralsWithIdentifiers([smartLockNSUUID!])for peripheral in peripherals {

smartLock = peripheral as CBPeripheralconnectToSmartLock(peripheral as CBPeripheral)

}} else {

centralManager.scanForPeripheralsWithServices([uartServiceUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: false])

}}

}

// Invoked when the central manager discovers a SmartLock while scanning.func centralManager(central: CBCentralManager!, didDiscoverPeripheral

Page 87: smartlock_final_report

peripheral: CBPeripheral!, advertisementData: (NSDictionary), RSSI: NSNumber!) {// Conserve batterycentralManager.stopScan()scanState = false

// Connect to SmartLockoutput("Discovered", UI: true)smartLock = peripheralsmartLockNSUUID = peripheral.identifierconnectTimer = NSTimer.scheduledTimerWithTimeInterval(30.0, target: self,

selector: Selector("cancelConnect"), userInfo: nil, repeats: false)connectToSmartLock(peripheral)

}

// Invoked when a connection is successfully created with a SmartLock.func centralManager(central: CBCentralManager!, didConnectPeripheral

peripheral: CBPeripheral!) {// Set peripheral delegate so it can receive appropriate callbacks// Check peripheral RSSI value// Investigate UART ServiceconnectState = trueconnectTimer.invalidate()output("Connected", UI: true)

peripheral.delegate = selfperipheral.readRSSI()peripheral.discoverServices([uartServiceUUID])

}

// Invoked when an existing connection with a SmartLock failsfunc centralManager(central: CBCentralManager!, didDisconnectPeripheral

peripheral: CBPeripheral!, error: NSError!) {connectState = falsescanState = falseoutput("Disconnected", UI: true)

}

//*******************************************************// Peripheral (SmartLock) Functions//*******************************************************

// Invoked when the SmartLock's UART service has been discoveredfunc peripheral(peripheral: CBPeripheral!, didDiscoverServices error:

NSError!) {for service in peripheral.services {

// Investigate UART Service RX and TX Characteristicsperipheral.discoverCharacteristics([txCharacteristicUUID,

rxCharacteristicUUID], forService: service as CBService)}

}

// Invoked when the SmartLock's UART RX and TX characteristics have been discovered

Page 88: smartlock_final_report

// Setup notification for RX characteristicfunc peripheral(peripheral: CBPeripheral!,

didDiscoverCharacteristicsForService service: CBService!, error: NSError!) {for characteristic in service.characteristics as [CBCharacteristic] {

switch(characteristic.UUID) {case rxCharacteristicUUID:

rxCharacteristic = characteristicsmartLock.readValueForCharacteristic(rxCharacteristic)peripheral.setNotifyValue(true, forCharacteristic:

rxCharacteristic)case txCharacteristicUUID:

txCharacteristic = characteristicdefault:

break}

}}

// Invoked when the SmartLock receives a request to start or stop providing notifications for a specified characteristic’s value.

func peripheral(peripheral: CBPeripheral!, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {if (error != nil) {

output("Error: \(error.localizedDescription)")}

}

// Invoked when the SmartLock notifies the app that the RX characteristic's value has changed

func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {if var data:NSData = characteristic.value {

var response:String = NSString(data: data, encoding: NSUTF8StringEncoding)!

switch(response) {case "L":

lockStatus = .Lockedoutput("Locked", UI: true)

case "U":lockStatus = .Unlockedoutput("Unlocked", UI: true)

default:lockStatus = .Unknownoutput("Bad Data: \(data)")

}}

}

// Cancel connectionfunc cancelConnect() {

connectTimer.invalidate()output("Connection timeout", UI: true)disconnectFromSmartLock()

}

Page 89: smartlock_final_report

// Determine lock statusfunc getConnectionState() -> Bool {

if (smartLock != nil) {if (smartLock.state == CBPeripheralState.Connected) {

connectState = truereturn true

} else {discoverDevices()connectState = falsereturn false

}} else {

connectState = falsereturn false

}}

// Lock SmartLockfunc lockSmartLock() {

if(getConnectionState() == true) {if(lockStatus == .Unlocked) {

let txString = "L"let txData = txString.dataUsingEncoding(NSUTF8StringEncoding)lockStatus = Status.Lockingoutput("Locking...", UI: true)smartLock.writeValue(txData, forCharacteristic: txCharacteristic,

type: CBCharacteristicWriteType.WithoutResponse)}

}}

// Unlock SmartLockfunc unlockSmartLock() {

if(getConnectionState() == true) {if(lockStatus == .Locked) {

let txString = "U"let txData = txString.dataUsingEncoding(NSUTF8StringEncoding)lockStatus = Status.Unlockingoutput("Unlocking...", UI: true)smartLock.writeValue(txData, forCharacteristic: txCharacteristic,

type: CBCharacteristicWriteType.WithoutResponse)}

}}

// Enable the RSSI timer for proximity modefunc rssiTimerEnable() {

// Initialize a timer to check RSSI value every 0.5 seconds while connected

rssiTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("updateRSSI"), userInfo: nil, repeats: true)

proximityEnable = true}

// Disable the RSSI timer

Page 90: smartlock_final_report

func rssiTimerDisable() {if (rssiTimer != nil) {

rssiTimer.invalidate()proximityEnable = false

}}

// Proximity detectionfunc updateRSSI() {

var rssiAverage:Int

if (smartLock != nil && getConnectionState() == true) {smartLock.readRSSI()if(smartLock.RSSI != nil) {

// Take 4 values for accurate average of RSSI valuerssiOld[2] = rssiOld[1]rssiOld[1] = rssiOld[0]rssiOld[0] = rssiNowrssiNow = Int(smartLock.RSSI)rssiAverage = ((rssiNow + rssiOld[0] + rssiOld[1] + rssiOld[2])/

4)

// Output proximity equationif (lockStatus == .Locked) {

output("RSSI: \(rssiAverage) > \(unlockThreshold) = \(rssiAverage > unlockThreshold)")

} else {output("RSSI: \(rssiAverage) < \(lockThreshold) = \

(rssiAverage < lockThreshold)")}

// If locked, within range, and moving toward lock: unlockif ((lockStatus == .Locked) && (rssiAverage > unlockThreshold)) {

unlockSmartLock()}

// If unlocked, leaving range, and moving away from lock: lockif ((lockStatus == .Unlocked) && (rssiAverage < lockThreshold)) {

lockSmartLock()}

}}

}

//*******************************************************// Debug Functions//*******************************************************

func output(description: String, UI: Bool = false) {let timestamp = generateTimeStamp()

if (UI.boolValue == true) {activity = "\(description)"

}

Page 91: smartlock_final_report

println("[\(timestamp)] \(description)")debugActivity = "\(description)"

}

func generateTimeStamp() -> NSString {let timestamp = NSDateFormatter.localizedStringFromDate(NSDate(),

dateStyle: .NoStyle, timeStyle: .MediumStyle)return timestamp

}

}

Page 92: smartlock_final_report

//// MainViewController.swift// SmartLock//// Created by Elliot Barer on 2014-12-08.// Copyright (c) 2014 Elliot Barer. All rights reserved.//

import UIKit

class MainViewController: UITabBarController {

var gblSmartLock = SmartLock()

override func viewDidLoad() { super.viewDidLoad() }

override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // segue.destinationViewController. }

}

Page 93: smartlock_final_report

//// SmartLockViewController.swift// SmartLock iOS Application//// Created by Elliot Barer on 2014-10-09.// Copyright (c) 2014 Elliot Barer. All rights reserved.//

import UIKit

class SmartLockViewController: UIViewController {

var smrtLock = SmartLock()private var myContext = 0

// UI Elements@IBInspectable var lckControlView:LockControlView!@IBOutlet weak var activityLabel: UILabel!

// When application loads, and when view appears or disappearsoverride func viewDidLoad() {

super.viewDidLoad()self.setNeedsStatusBarAppearanceUpdate()

// Start Bluetooth Central ManagersmrtLock.startUpCentralManager()

// Add LockControlvar lockControlTap = UITapGestureRecognizer(target: self, action:

Selector("lockControlTapped:"))lckControlView = LockControlView(frame: CGRectMake(view.center.x - 150.0,

view.center.y - 150.0, 300.0, 300.0))lckControlView.addGestureRecognizer(lockControlTap)lckControlView.lockStatus = smrtLock.lockStatusview.addSubview(lckControlView)

// Watch for changes in "activity" from SmartLock modelsmrtLock.addObserver(self, forKeyPath: "activity", options: .New,

context: &myContext)}

override func viewDidAppear(animated: Bool) {smrtLock.discoverDevices()

}

override func viewDidDisappear(animated: Bool) {smrtLock.disconnectFromSmartLock()

}

// Set status bar to lightoverride func preferredStatusBarStyle() -> UIStatusBarStyle {

return UIStatusBarStyle.LightContent}

// Update lockControl text with activity changes in SmartLock model (MVC)override func observeValueForKeyPath(keyPath: String, ofObject object:

Page 94: smartlock_final_report

AnyObject, change: [NSObject: AnyObject], context: UnsafeMutablePointer<Void>) {if context == &myContext {

activityLabel.text = "\(smrtLock.activity)\n"lckControlView.determineColor(smrtLock.connectState, lockStatus:

smrtLock.lockStatus)} else {

super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)

}}

// Toggle lock/unlockfunc lockControlTapped(recognizer: UITapGestureRecognizer) {

let servoDelay = 1.25lckControlView.lockStatus = smrtLock.lockStatus

if (smrtLock.connectState == true) {if (smrtLock.lockStatus == Status.Locked) {

smrtLock.unlockSmartLock()lckControlView.determineColor(smrtLock.connectState, lockStatus:

smrtLock.lockStatus)lckControlView.animateLockControl(servoDelay)

} else if (smrtLock.lockStatus == Status.Unlocked) {smrtLock.lockSmartLock()lckControlView.determineColor(smrtLock.connectState, lockStatus:

smrtLock.lockStatus)lckControlView.animateLockControl(servoDelay)

}} else {

lckControlView.determineColor(smrtLock.connectState, lockStatus: smrtLock.lockStatus)

smrtLock.discoverDevices()}

}

}

Page 95: smartlock_final_report

//// LockControlView.swift// SmartLock//// Created by Elliot Barer on 2014-12-05.// Copyright (c) 2014 Elliot Barer. All rights reserved.//

import UIKit

class LockControlView: UIView {

let lockControlShape = CAShapeLayer()let ringAnimation = CABasicAnimation(keyPath: "strokeEnd")var lockStatus:Status!

override init(frame: CGRect) {super.init(frame: frame)self.backgroundColor = UIColor.clearColor()

lockControlShape.path = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: (frame.size.width - 10)/2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2.0), clockwise: true).CGPath

lockControlShape.fillColor = UIColor.clearColor().CGColor

lockControlShape.lineWidth = 6.0;lockControlShape.strokeEnd = 1.0

layer.addSublayer(lockControlShape)}

required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented")}

func animateLockControl(duration: NSTimeInterval) {

// Set the animation duration appropriatelyringAnimation.duration = duration

// Animate from 0 to 1, then set endpointringAnimation.fromValue = 0ringAnimation.toValue = 1lockControlShape.strokeEnd = 1.0

// Perform linear animationringAnimation.timingFunction = CAMediaTimingFunction(name:

kCAMediaTimingFunctionLinear)

// Add animation to objectlockControlShape.addAnimation(ringAnimation, forKey:

"animateLockControl")}

// Determine ring colour based on lock status

Page 96: smartlock_final_report

func determineColor(connectState: Bool, lockStatus: Status) {if(connectState == true) {

switch (lockStatus) {case .Locked:

lockControlShape.strokeColor = UIColor.redColor().CGColorcase .Locking:

lockControlShape.strokeColor = UIColor.redColor().CGColorcase .Unlocked:

lockControlShape.strokeColor = UIColor.greenColor().CGColorcase .Unlocking:

lockControlShape.strokeColor = UIColor.greenColor().CGColordefault:

lockControlShape.strokeColor = UIColor.grayColor().CGColor}

} else {lockControlShape.strokeColor = UIColor.grayColor().CGColor

}}

}

Page 97: smartlock_final_report

//// DebugViewController.swift// SmartLock iOS Application//// Created by Elliot Barer on 2014-10-09.// Copyright (c) 2014 Elliot Barer. All rights reserved.//

import UIKit

class DebugViewController: UIViewController {

var smrtLock = SmartLock()private var myContext = 0

// UI Elements@IBOutlet weak var textField:UITextView!@IBOutlet weak var proximitySwitch:UISwitch!@IBOutlet weak var lockThresholdSlider:UISlider!@IBOutlet weak var lockThresholdLabel:UILabel!@IBOutlet weak var unlockThresholdSlider:UISlider!@IBOutlet weak var unlockThresholdLabel:UILabel!

// When application loads, and when view appears or disappearsoverride func viewDidLoad() {

super.viewDidLoad()self.setNeedsStatusBarAppearanceUpdate()

// Start Bluetooth Central ManagersmrtLock.startUpCentralManager()

// Disable proximity (for demonstration)proximitySwitch.on = smrtLock.proximityEnablelockThresholdSlider.value = Float(smrtLock.lockThreshold)lockThresholdLabel.text = "Lock Threshold = \(smrtLock.lockThreshold)"unlockThresholdSlider.value = Float(smrtLock.unlockThreshold)unlockThresholdLabel.text = "Unlock Threshold = \(smrtLock.

unlockThreshold)"

// Watch for changes in "debugActivity" from SmartLock model (for debug console)

smrtLock.addObserver(self, forKeyPath: "debugActivity", options: .New, context: &myContext)

}

override func viewDidAppear(animated: Bool) {smrtLock.discoverDevices()proximitySwitch.on = smrtLock.proximityEnable

}

override func viewDidDisappear(animated: Bool) {smrtLock.disconnectFromSmartLock()

}

// Set status bar to lightoverride func preferredStatusBarStyle() -> UIStatusBarStyle {

Page 98: smartlock_final_report

return UIStatusBarStyle.LightContent}

// Update debug console with activity changes in SmartLock model (MVC)override func observeValueForKeyPath(keyPath: String, ofObject object:

AnyObject, change: [NSObject: AnyObject], context: UnsafeMutablePointer<Void>) {if context == &myContext {

textField.selectable = falsetextField.text = "\(smrtLock.debugActivity)\n" + textField.text

} else {super.observeValueForKeyPath(keyPath, ofObject: object, change:

change, context: context)}

}

// Toggle lock@IBAction func lockButton() {

smrtLock.lockSmartLock()}

// Toggle unlock@IBAction func unlockButton() {

smrtLock.unlockSmartLock()}

// Conncet to existing SmartLock, or search for new@IBAction func connectSmartLock(sender: UIButton) {

smrtLock.discoverDevices()}

// Diconncet SmartLock@IBAction func disconnectSmartLock(sender: UIButton) {

smrtLock.disconnectFromSmartLock()}

// Toggle proximity mode by enabling/disabling the RSSI timer@IBAction func toggleProximity(proximity: UISwitch) {

if (smrtLock.proximityEnable == false) {smrtLock.rssiTimerEnable()

} else {smrtLock.rssiTimerDisable()

}}

// Adjust lock threshold value for proximity mode@IBAction func adjustLockThreshold(threshold: UISlider) {

smrtLock.lockThreshold = Int(threshold.value)lockThresholdLabel.text = "Lock Threshold = \(Int(threshold.value))"

}

// Adjust unlock threshold value for proximity mode@IBAction func adjustUnlockThreshold(threshold: UISlider) {

smrtLock.unlockThreshold = Int(threshold.value)unlockThresholdLabel.text = "Unlock Threshold = \(Int(threshold.value))"

}

Page 99: smartlock_final_report

// Clear debug log@IBAction func clearLog(sender: UIButton) {

textField.text = ""}

}

Page 100: smartlock_final_report

Formal Report for SmartLock

APPENDIX F: USER MANUAL

This manual refers to the SmartLock as if it were a finished product.

Parts Included • The SmartLock Device

• 2 AA batteries

• SmartLock App (downloadable from the Apple App Store)

Installation 1. Remove your existing thumbturn

i. Unscrew the 2 bolts holding in the thumbturn of your existing dead bolt lock, save the screws

2. Remove the top cover from the SmartLock via the centre screw

3. Position the SmartLock over the metal plate of the lock

I. Ensure the lock and unlock symbols are at the top of the device for correct orientation

II. Align the tumbler arm with the lock shaft

4. Using the screws from Step 1, screw through the two holes in the backplane of the SmartLock

5. Install the AA batteries into the SmartLock

6. Reattach the top cover by tightening the screw in the centre

7. Open the SmartLock App on your iPhone and wait for a connection

8. Congratulations, you are now ready to use the SmartLock!

Page 101: smartlock_final_report

Formal Report for SmartLock

Electronically Locking and Unlocking 1. Open the SmartLock app, ensuring a connection with the SmartLock, and tap the unlock or lock

button.

2. The button context will change depending on the orientation of the device.

Manual Locking and Unlocking 1. Rotate the tumbler to the lock or unlock positions.

Calibrating Proximity Detection Mode 1. Tap the calibrate button in the SmartLock app.

2. Determine the radius in which you would like the door to unlock and move to the edge.

3. Tap the accept button.

4. Determine the radius in which you would like the door to lock and move to the edge.

5. Tap the accept button.

Page 102: smartlock_final_report

Formal Report for SmartLock

APPENDIX G: GANTT CHART

The following appendix contains the initial and revised gantt charts outlining the timeline for all activities related to this project. The attachments are as follows:

1. Initial Gantt Chart

2. Revised Gantt Chart

Page 103: smartlock_final_report

IDTa

sk N

ame

Dur

atio

nSt

art

Fini

shPr

edRe

sour

ce

Nam

es

0ELEX

 4330 Technical Project

74 days

Wed 9/3/14

Fri 12/19/14

1Prelim

inary Reports

31 days

Wed 9/3/14

Fri 10/17/14

Team

2Write "P

roject Propo

sal" Rep

ort

11 days

Wed

 9/3/14

Wed

 9/17/14

Team

3"Project Propo

sal" Due

0 days

Wed

 9/17/14

Wed

 9/17/14

2Team

4Write "F

unctional Req

uiremen

ts" R

eport

6 days

Thu 9/18

/14

Thu 9/25

/14

3Team

5"Fun

ctional Req

uiremen

ts" D

ue0 days

Thu 9/25

/14

Thu 9/25

/14

4Team

6Write "D

esign Specification

" Rep

ort

14 days

Fri 9/26/14

Thu 10/16/14

5Team

7"D

esign Specification

" Due

0 days

Fri 10/17

/14

Fri 10/17

/14

6Team

8Design

 Product

27 days

Fri 9/26/14

Wed 11/5/14

4Team

9Firm

ware

23 days

Fri 9/26/14

Wed 10/29/14

Elliot

10Re

search BLE and

 WiFi

12 days

Fri 9/26/14

Tue 10

/14/14

Elliot

11Im

plem

ent initializtion

7 days

Wed

 10/15

/14

Thu 10/23/14

10Elliot

12Im

plem

ent e

ncryption algorithm

4 days

Fri 10/24

/14

Wed

 10/29

/14

11Elliot

13Power

22 days

Fri 9/26/14

Tue 10/28/14

Albert

14Re

search m

odules

12 days

Fri 9/26/14

Tue 10

/14/14

Albert

15Design sche

matic fo

r boo

st con

verter

3 days

Wed

 10/15

/14

Fri 10/17

/14

14Albert

16Co

nstruct a

nd te

st circuit

0 days

Mon

 10/20/14

Mon

 10/20/14

15Albert

17Mod

ification

s to circuit

7 days

Mon

 10/20/14

Tue 10

/28/14

16Albert

18Lock Controller

27 days

Fri 9/26/14

Wed 11/5/14

James

19Re

search se

rvos and

 motors

12 days

Fri 9/26/14

Tue 10

/14/14

James

20Source com

pone

nts

5 days

Wed

 10/15

/14

Tue 10

/21/14

19James

21Im

plem

ent e

lectromechanical actuation

3 days

Wed

 10/22

/14

Fri 10/24

/14

20James

22Mod

ification

s to controller

7 days

Mon

 10/27/14

Wed

 11/5/14

21James

23Design

 enclosure

11 days

Thu 11/6/14

Fri 11/21/14

8Team

24Design PC

B4 days

Thu 11/6/14

Wed

 11/12

/14

Elliot,James

25Mod

el enclosure

4 days

Thu 11/6/14

Wed

 11/12

/14

Albert

26Print e

nclosure

1 day

Thu 11/13/14

Thu 11/13/14

25Albert

27Validate en

closure

1 day

Fri 11/14

/14

Fri 11/14

/14

26Team

28Mod

ification

s to de

sign

5 days

Mon

 11/17/14

Fri 11/21

/14

27Team

29Prepare fo

r Presentation 

6 days

Mon 12/8/14

Tue 12/16/14

23

Team

30Prep

are speaker n

otes & overheads 

2 days

Mon

 12/8/14

Tue 12

/9/14

Team

31Practice presentation 

2 days

Fri 12/12

/14

Mon

 12/15/14

30Team

32Presen

tation

 0 days

Tue 12

/16/14

Tue 12

/16/14

31Team

33Write "P

roject Rep

ort"

24 days

Thu 11/6/14

Wed

 12/10

/14

8Team

34"Project Rep

ort" Due

0 days

Fri 12/19

/14

Fri 12/19

/14

Team

Team

9/17

Team

9/25

Team

10/1

7

Ellio

t Ellio

t Ellio

t

Alb

ert

Alb

ert

10/2

0 Alb

ert

Jam

es Jam

esJa

mes

Jam

es Ellio

t,Jam

esA

lber

tA

lber

tTe

amTe

am

Team Te

am12

/16

Team

12/1

9

SW

ST

MF

TS

WS

TM

FT

SW

ST

MF

TS

WS

TM

FT

SW

ST

M17

, '14

Aug

31, '

14Se

p 14

, '14

Sep

28, '

14O

ct 1

2, '1

4O

ct 2

6, '1

4N

ov 9

, '14

Nov

23,

'14D

ec 7

, '14

Dec

21,

'1

Task

Split

Mile

ston

e

Sum

mar

y

Proj

ect S

umm

ary

Inac

tive

Task

Inac

tive

Mile

ston

e

Inac

tive

Sum

mar

y

Man

ual T

ask

Dur

atio

n-on

ly

Man

ual S

umm

ary

Rollu

p

Man

ual S

umm

ary

Star

t-on

ly

Fini

sh-o

nly

Exte

rnal

Tas

ks

Exte

rnal

Mile

ston

e

Dea

dlin

e

Criti

cal

Criti

cal S

plit

Prog

ress

Man

ual P

rogr

ess

Page

1

Proj

ect:

ELEX

433

0 Te

chni

cal P

rD

ate:

Fri

10/1

7/14

Team

Ellio

t Ba

rer,

Jam

es E

sau,

Alb

ert

Phan

Page 104: smartlock_final_report

,'7DVN�1

DPH

'XUDWLR

Q6WDUW

)LQLVK

3UH5HVRX

UFH�

1DPHV

��>�y

�ϰϯϯ

Ϭ�dĞ

ĐŚŶŝĐĂů�W

ƌŽũĞĐƚ

ϳϰ�ĚĂLJƐ

tĞĚ

�ϵϯϭϰ

&ƌŝ�ϭϮϭϵ

ϭϰ

�WƌĞůŝŵ

ŝŶĂƌLJ�ZĞ

ƉŽƌƚƐ

ϯϭ�ĚĂLJƐ

tĞĚ

�ϵϯϭϰ

&ƌŝ�ϭϬϭϳ

ϭϰ

dĞĂŵ

�tƌŝƚĞ�ΗWƌŽũĞĐƚ�WƌŽƉŽ

ƐĂůΗ�ZĞ

ƉŽƌƚ

ϭϭ�ĚĂLJƐ

tĞĚ

�ϵϯϭϰ

tĞĚ

�ϵϭϳϭϰ

dĞĂŵ

�ΗWƌŽũĞĐƚ�WƌŽƉŽ

ƐĂůΗ��Ƶ

ĞϬ�ĚĂ

LJƐtĞĚ

�ϵϭϳϭϰ

tĞĚ

�ϵϭϳϭϰ

ϮdĞ

Ăŵ�

tƌŝƚĞ�Η&ƵŶ

ĐƚŝŽŶĂ

ů�ZĞƋ

ƵŝƌĞŵĞŶ

ƚƐΗ�Z

ĞƉŽƌϲ�ĚĂ

LJƐdŚ

Ƶ�ϵϭϴ

ϭϰ

dŚƵ�ϵϮϱ

ϭϰ

ϯdĞ

Ăŵ�

Η&ƵŶ

ĐƚŝŽŶĂ

ů�ZĞƋ

ƵŝƌĞŵĞŶ

ƚƐΗ��

ƵĞϬ�ĚĂ

LJƐdŚ

Ƶ�ϵϮϱ

ϭϰ

dŚƵ�ϵϮϱ

ϭϰ

ϰdĞ

Ăŵ�

tƌŝƚĞ�Η�

ĞƐŝŐŶ�^Ɖ

ĞĐŝĨŝĐĂƚŝŽ

ŶΗ�ZĞƉ

Žƌƚ

ϭϰ�ĚĂLJƐ

&ƌŝ�ϵ

Ϯϲϭϰ

dŚƵ�ϭϬ

ϭϲϭϰ

ϱdĞ

Ăŵ�

Η�ĞƐŝŐŶ�^Ɖ

ĞĐŝĨŝĐĂƚŝŽ

ŶΗ��ƵĞ

Ϭ�ĚĂ

LJƐ&ƌŝ�ϭ

Ϭϭϳ

ϭϰ

&ƌŝ�ϭ

Ϭϭϳ

ϭϰ

ϲdĞ

Ăŵ�

�ĞƐŝŐ

Ŷ�WƌŽĚ

ƵĐƚ

ϱϱ�ĚĂLJƐ

&ƌŝ�ϵϮϲϭϰ

dƵĞ�ϭϮ

ϭϲϭϰ

ϰdĞ

Ăŵ�

&ŝƌŵ

ǁĂƌĞ

ϱϯ�ĚĂLJƐ

&ƌŝ�ϵϮϲϭϰ

&ƌŝ�ϭϮϭϮ

ϭϰ

�ůůŝŽ

ƚ��

ZĞƐĞĂƌĐŚ��>��ĂŶĚ

�tŝ&ŝ

ϰ�ĚĂ

LJƐ&ƌŝ�ϵ

Ϯϲϭϰ

tĞĚ

�ϭϬϭϭϰ

�ůůŝŽ

ƚ��

>ĞĂƌŶ�^ǁ

ŝĨƚ�ĂŶĚ

�KďũĞĐƚŝǀ

ĞͲ�

ϯϮ�ĚĂLJƐ

dŚƵ�ϭϬ

Ϯϭϰ

tĞĚ

�ϭϭϭϵ

ϭϰϭϬ

�ůůŝŽ

ƚ��

dĞƐƚ��>��ĐŽ

ŶŶĞĐƚŝŽ

Ŷϳ�ĚĂ

LJƐdŚ

Ƶ�ϭϭ

ϮϬϭϰ

&ƌŝ�ϭ

ϭϮϴ

ϭϰ

ϭϭ�ůůŝŽ

ƚ��

�ƌĞĂ

ƚĞ�^ŵĂƌƚ>ŽĐŬ��ůĂƐƐ

Ϯ�ĚĂ

LJƐdƵ

Ğ�ϭϮ

Ϯϭϰ

tĞĚ

�ϭϮϯϭϰ

ϭϮ�ůůŝŽ

ƚ��

�ƌĞĂ

ƚĞ��Ğď

ƵŐsŝĞǁ

�ŽŶƚƌŽůůĞƌ

Ϯ�ĚĂ

LJƐdŚ

Ƶ�ϭϮ

ϰϭϰ

&ƌŝ�ϭ

Ϯϱϭϰ

ϭϯ�ůůŝŽ

ƚ��

�ƌĞĂ

ƚĞ�^ŵĂƌƚ>ŽĐŬs

ŝĞǁ�Ž

ŶƚƌŽůůĞƌϭ

�ĚĂLJ

^Ăƚ�ϭ

Ϯϲϭϰ

^Ăƚ�ϭ

Ϯϲϭϰ

ϭϰ�ůůŝŽ

ƚ��

/ŵƉůĞŵ

ĞŶƚ�Ɖ

ƌŽdžŝŵŝƚLJ

�ĚĞƚĞĐƚŝŽ

Ŷϯ�ĚĂ

LJƐ^Ƶ

Ŷ�ϭϮ

ϳϭϰ

dƵĞ�ϭϮ

ϵϭϰ

ϭϱ�ůůŝŽ

ƚ��

�ĚĚ�ƉƌŽdžŝŵ

ŝƚLJ�ƚŚ

ƌĞƐŚŽůĚ�ŵŽĚ

ŝĨŝĐĂϯ�ĚĂ

LJƐtĞĚ

�ϭϮϭϬ

ϭϰ&ƌŝ�ϭ

ϮϭϮ

ϭϰ

ϭϲ�ůůŝŽ

ƚ��

WŽǁĞƌ

ϱϯ�ĚĂLJƐ

&ƌŝ�ϵϮϲϭϰ

&ƌŝ�ϭϮϭϮ

ϭϰ

�ůďĞ

ƌƚ��

ZĞƐĞĂƌĐŚ�ŵ

ŽĚƵůĞƐ

ϭϮ�ĚĂLJƐ

&ƌŝ�ϵ

Ϯϲϭϰ

dƵĞ�ϭϬ

ϭϰϭϰ

�ůďĞ

ƌƚ��

�ĞƐŝŐ

Ŷ�ƐĐŚĞ

ŵĂƚŝĐ�ĨŽƌ�ď

ŽŽƐƚ�ĐŽ

ŶǀĞƌƚĞ

ϯ�ĚĂ

LJƐtĞĚ

�ϭϬϭϱ

ϭϰ

&ƌŝ�ϭ

Ϭϭϳ

ϭϰ

ϭϵ�ůďĞ

ƌƚ��

^ŽƵƌĐĞ�ůĂƐƚ�ŵ

ŝŶƵƚĞ�ƚŚƌƵͲŚŽůĞ�ƉĂ

ƌƚƐ

ϭ�ĚĂ

LJdƵ

Ğ�ϭϮ

ϵϭϰ

dƵĞ�ϭϮ

ϵϭϰ

:ĂŵĞƐ

��Kƌ

ĚĞƌ�ůĂƐƚ�ŵ

ŝŶƵƚĞ�ƉĂ

ƌƚƐ

ϯ�ĚĂ

LJƐtĞĚ

�ϭϮϭϬ

ϭϰ

&ƌŝ�ϭ

ϮϭϮ

ϭϰ

Ϯϭ�ůůŝŽ

ƚ��

>ŽĐŬ��ŽŶ

ƚƌŽůůĞƌ

ϱϱ�ĚĂLJƐ

&ƌŝ�ϵϮϲϭϰ

dƵĞ�ϭϮ

ϭϲϭϰ

:ĂŵĞƐ

��ZĞ

ƐĞĂƌĐŚ�ƐĞ

ƌǀŽƐ�ĂŶĚ

�ŵŽƚŽƌƐ

ϭϮ�ĚĂLJƐ

&ƌŝ�ϵ

Ϯϲϭϰ

dƵĞ�ϭϬ

ϭϰϭϰ

:ĂŵĞƐ

��^Ž

ƵƌĐĞ�ĐŽ

ŵƉŽ

ŶĞŶƚƐ

ϱ�ĚĂ

LJƐtĞĚ

�ϭϬϭϱ

ϭϰ

dƵĞ�ϭϬ

Ϯϭϭϰ

Ϯϰ:ĂŵĞƐ

��/ŵ

ƉůĞŵ

ĞŶƚ�Ğ

ůĞĐƚƌŽŵĞĐŚĂ

ŶŝĐĂů�ĂĐƚƵĂ

ƚϯ�ĚĂLJƐ

tĞĚ

�ϭϬϮϮ

ϭϰ

&ƌŝ�ϭ

ϬϮϰ

ϭϰ

Ϯϱ:ĂŵĞƐ

��DŽĚ

ŝĨŝĐĂƚŝŽ

ŶƐ�ƚŽ

�ĐŽŶƚƌŽůůĞƌ

ϱ�ĚĂ

LJƐtĞĚ

�ϭϮϭϬ

ϭϰ

dƵĞ�ϭϮ

ϭϲϭϰ

ϯϭ:ĂŵĞƐ

���Ğ

ƐŝŐŶ�ĞŶ

ĐůŽƐƵƌĞ

ϱϯ�ĚĂLJƐ

&ƌŝ�ϵϮϲϭϰ

^ƵŶ�ϭϮ

ϭϰϭϰ

ϱdĞ

Ăŵ��

DŽĚ

Ğů�ĞŶĐůŽƐƵƌĞ

ϯϴ�ĚĂLJƐ

&ƌŝ�ϵ

Ϯϲϭϰ

&ƌŝ�ϭ

ϭϮϭ

ϭϰ

�ůďĞ

ƌƚ��

WƌŝŶƚ�Ğ

ŶĐůŽƐƵƌĞ

Ϯ�ĚĂ

LJƐ&ƌŝ�ϭ

Ϯϱϭϰ

DŽŶ

�ϭϮϴϭϰ

Ϯϵ�ůďĞ

ƌƚ��

sĂůŝĚ

ĂƚĞ�ĞŶ

ĐůŽƐƵƌĞ

ϭ�ĚĂ

LJdƵ

Ğ�ϭϮ

ϵϭϰ

dƵĞ�ϭϮ

ϵϭϰ

ϯϬdĞ

Ăŵ��

ZĞĚĞ

ƐŝŐŶ�ĞŶ

ĐůŽƐƵƌĞ

ϭ�ĚĂ

LJtĞĚ

�ϭϮϭϬ

ϭϰ

tĞĚ

�ϭϮϭϬ

ϭϰ

ϯϭdĞ

Ăŵ��

ZĞƉƌŝŶƚ�Ğ

ŶĐůŽƐƵƌĞ

Ϯ�ĚĂ

LJƐdŚ

Ƶ�ϭϮ

ϭϭϭϰ

&ƌŝ�ϭ

ϮϭϮ

ϭϰ

ϯϮdĞ

ĐŚ��ĞŶ

ƚĞ��

>ĂƐƚ�ŵ

ŝŶƵƚĞ�ĞŶ

ĐůŽƐƵƌĞ�ĂůƚĞ

ƌĂƚŝŽ

ŶƐϮ�ĚĂ

LJƐ^Ăƚ�ϭ

Ϯϭϯ

ϭϰ

^ƵŶ�ϭϮ

ϭϰϭϰ

ϯϯ:ĂŵĞƐ

7HDP ����

7HDP

����

7HDP

�����

(OOLR

W(OOLR

W(OOLR

W (OOLR

W(OOLR

W(OOLR

W(OOLR

W(OOLR

W

$OEH

UW$OEH

UW-DPHV (OOLR

W

-DPHV-DPHV -DPHV

-DPHV

$OEH

UW$OEH

UW7H

DP 7HDP 7HFK

�&HQ

WHU

-DPHV

6:

67

0)

76

:6

70

)7

6:

67

0)

76

:6

70

)7

6:

67

�����

$XJ���

����

6HS���

����

6HS���

����

2FW��

�����

2FW��

�����

1RY��

����

1RY��

�����

'HF��

����

'HF��

����

7DVN

6SOLW

0LOHVWR

QH

6XPPDU\

3URMHFW�6

XPPDU\

,QDFWLY

H�7D

VN

,QDFWLY

H�0LOHVWR

QH

,QDFWLY

H�6XP

PDU\

0DQ

XDO�7DVN

'XUDWLR

Q�RQ

O\

0DQ

XDO�6

XPPDU\�5

ROOXS

0DQ

XDO�6

XPPDU\

6WDUW�R

QO\

)LQLVK

�RQO\

([WHUQDO�7D

VNV

([WHUQDO�0LOHVWR

QH

'HDG

OLQH

&ULWLFDO

&ULWLFDO�6

SOLW

3URJ

UHVV

0DQ

XDO�3

URJUHVV

3DJH

��

3URMHFW��(/(;

����

��7H

FKQLFDO�3

U'D

WH��:

HG������

���d

ĞĂŵ

(OOLR

W�%DUHU��-DP

HV�(VDX�

$OEH

UW�3K

DQ

Page 105: smartlock_final_report

,'7DVN�1

DPH

'XUDWLR

Q6WDUW

)LQLVK

3UH5HVRX

UFH�

1DPHV

��WƌĞƉ

ĂƌĞ�ĨŽƌ�W

ƌĞƐĞŶƚĂƚŝŽŶ�

Ϯ�ĚĂ

LJƐDŽŶ

�ϭϮϭϱ

ϭϰ

dƵĞ�ϭϮ

ϭϲϭϰ

ϮϴdĞĂŵ

��WƌĞƉ

ĂƌĞ�ƐƉĞĂŬĞƌ�Ŷ

ŽƚĞƐ�Θ�ŽǀĞƌŚĞĂĚƐ�

ϭ�ĚĂ

LJDŽŶ

�ϭϮϭϱ

ϭϰ

DŽŶ

�ϭϮϭϱ

ϭϰ

dĞĂŵ

��WƌĂĐƚŝĐĞ�ƉƌĞƐĞŶ

ƚĂƚŝŽ

Ŷ�ϭ�ĚĂ

LJdƵ

Ğ�ϭϮ

ϭϲϭϰ

dƵĞ�ϭϮ

ϭϲϭϰ

ϯϲdĞĂŵ

��WƌĞƐĞŶ

ƚĂƚŝŽ

Ŷ�Ϭ�ĚĂ

LJƐdƵ

Ğ�ϭϮ

ϭϲϭϰ

dƵĞ�ϭϮ

ϭϲϭϰ

ϯϳdĞĂŵ

��tƌŝƚĞ�ΗWƌŽũĞĐƚ�ZĞƉ

ŽƌƚΗ

ϳ�ĚĂ

LJƐtĞĚ

�ϭϮϭϬ

ϭϰ

dŚƵ�ϭϮ

ϭϴϭϰ

dĞĂŵ

��ΗWƌŽũĞĐƚ�ZĞƉ

ŽƌƚΗ��ƵĞ

Ϭ�ĚĂ

LJƐ&ƌŝ�ϭϮϭϵ

ϭϰ

&ƌŝ�ϭϮϭϵ

ϭϰ

dĞĂŵ

7HDP 7HDP

�����

7HDP

�����

6:

67

0)

76

:6

70

)7

6:

67

0)

76

:6

70

)7

6:

67

�����

$XJ���

����

6HS���

����

6HS���

����

2FW��

�����

2FW��

�����

1RY��

����

1RY��

�����

'HF��

����

'HF��

����

7DVN

6SOLW

0LOHVWR

QH

6XPPDU\

3URMHFW�6

XPPDU\

,QDFWLY

H�7D

VN

,QDFWLY

H�0LOHVWR

QH

,QDFWLY

H�6XP

PDU\

0DQ

XDO�7DVN

'XUDWLR

Q�RQ

O\

0DQ

XDO�6

XPPDU\�5

ROOXS

0DQ

XDO�6

XPPDU\

6WDUW�R

QO\

)LQLVK

�RQO\

([WHUQDO�7D

VNV

([WHUQDO�0LOHVWR

QH

'HDG

OLQH

&ULWLFDO

&ULWLFDO�6

SOLW

3URJ

UHVV

0DQ

XDO�3

URJUHVV

3DJH

��

3URMHFW��(/(;

����

��7H

FKQLFDO�3

U'D

WH��:

HG������

���d

ĞĂŵ

(OOLR

W�%DUHU��-DP

HV�(VDX�

$OEH

UW�3K

DQ

Page 106: smartlock_final_report

Formal Report for SmartLock

APPENDIX H: STYLE GUIDE

Header & Footer (Helvetica Neue, Bold, 10pt, Gray)

Title (Helvetica Neue, UltraLight, 28pt)

HEADING 1 (HELVETICA NEUE, LIGHT, 18PT, GRAY) Heading 2 (Helvetica Neue, Bold, 15pt, Blue)

Heading 3 (Helvetica Neue, Bold, 13pt, Gray)

Body text will look like this, block format with 1.5x line spacing for paragraphs and a single line after each paragraph. There is one space following a period in a sentence. (Helvetica Neue, Light, 11pt, Black, Canadian English)

Block quotations have the same formatting as the body; however, they are inset by one tab (36pt) the entire way along the left side of the paragraph and are italicized.

Sample list, use of colon dependent on whether lead-in is a complete sentence:

• Point 1 • Point 2 • Point 3 (period at the end of each list item if it’s a complete sentence)

CAPTION FOR FIGURES AND TABLES, PLACED ABOVE (HELVETICA NEUE, BOLD, 11PT, GREY, ALL CAPS)

Footnote for Referencing Materials (Helvetica Neue, Light, 8pt, Right Justification)