IRJET- Smart Home Automation System using 8051 Micro-Controller
smartlock_final_report
1. Formal Report for SmartLock
Prepared for: Robert Trost and Susan Woo
Prepared by: Elliot Barer, James Esau, Albert Phan
December 19, 2014
2. 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
3. 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
4. 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
5. 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
6. 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
7. 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
8. 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
9. 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
10. 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
11. 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
12. 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
13. 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
14. 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
15. 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
16. 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
17. 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
18. 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
19. 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
20. 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
21. 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
22. 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
23. 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
24. 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
25. 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
26. 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
27. 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
28. 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
29. 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
30. 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
31. 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
32. 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
33. 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
34. 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
35. 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
36. Formal Report for SmartLock
FIGURE 6.2: FLOWCHART FOR MICROCONTROLLER FIRMWARE
36
37. 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
38. 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
39. 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
40. Formal Report for SmartLock
FIGURE 7.2: FLOWCHART FOR CONNECTING TO SMARTLOCK
FIGURE 7.3: FLOWCHART FOR APP BUTTON CONTROLS
40
41. 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
42. 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
43. 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
44. 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
45. 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
46. 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
47. 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
48. 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
49. 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
50. 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
51. 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
52. 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
54. 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
55. 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
56. 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.
58. 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
63. 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)
67. //*******************************************************
// 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);
68. 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;
}
}
69. /*********************************************************************
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);
70. // Stream compatibility
int 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 extension
aci_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 usd
int8_t _REQ, _RDY, _RST;
};
#endif
71. /*********************************************************************
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_CONTENT
static services_pipe_type_mapping_t
services_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;
#else
#define NUMBER_OF_PIPES 0
static 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 64
uint8_t adafruit_ble_rx_buffer[ADAFRUIT_BLE_UART_RXBUFFER_SIZE];
volatile uint16_t adafruit_ble_rx_head;
volatile uint16_t adafruit_ble_rx_tail;
72. 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 characters
if (adafruit_ble_rx_head == adafruit_ble_rx_tail) {
return -1;
} else {
73. 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;
74. 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 *)"rn", 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) {
75. // 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_DEBUG
Serial.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 chunks
bytesThisPass = 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
76. 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 sends
return 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)
{
77. 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 command
if (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.
78. 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,
79. 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];
}
81. 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
82. //
// AppDelegate.swift
// SmartLock iOS Application
//
// Created by Elliot Barer on 2014-10-09.
// Copyright (c) 2014 Elliot Barer. All rights reserved.
//
import UIKit
@UIApplicationMain
class 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.
}
84. //
// SmartLock.swift
// SmartLock
//
// Created by Elliot Barer on 2014-12-03.
// Copyright (c) 2014 Elliot Barer. All rights reserved.
//
import UIKit
import CoreBluetooth
enum Status {
case Locking
case Locked
case Unlocking
case Unlocked
case Unknown
}
class SmartLock: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
// Prevent multiple instances of SmartLock from being created
class 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)
85. var smartLock:CBPeripheral! // Bluetooth peripheral
device (SmartLock)
var rxCharacteristic:CBCharacteristic! // Bluetooth RX
characteristic
var txCharacteristic:CBCharacteristic! // Bluetooth TX
characteristic
var bluetoothState:Bool! // Bluetooth status
var scanState:Bool! // Scan status
var connectState:Bool! // Connection status
var connectTimer:NSTimer! // Connection timeout
timer
var lockStatus:Status! // Lock status
dynamic var activity:String! // Lock activity
dynamic var debugActivity:String! // Lock activity (debug)
// Signal strength (RSSI) in dBm
var proximityEnable:Bool! // Proximity detection
status
var rssiTimer:NSTimer! // RSSI update timer
var rssiNow:Int! // Current RSSI value
var rssiOld = [Int](count: 3, repeatedValue: 0) // Previous RSSI values
var lockThreshold = -73 // Locking RSSI threshold
var 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 = false
scanState = false
connectState = false
lockStatus = .Locked
proximityEnable = false
rssiNow = 0
}
//*******************************************************
// Central Manager (iPhone) Functions
//*******************************************************
// Initializes the central manager with a specified delegate.
func startUpCentralManager() {
centralManager = CBCentralManager(delegate: self, queue: nil)
}
86. // Connect to SmarLock
func connectToSmartLock(peripheral: CBPeripheral) {
centralManager.connectPeripheral(peripheral as CBPeripheral, options:
[CBConnectPeripheralOptionNotifyOnNotificationKey: true])
}
// Disconnect from SmartLock
func 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 = false
output("Bluetooth Off")
disconnectFromSmartLock()
case .PoweredOn:
bluetoothState = true
output("Bluetooth On")
discoverDevices()
default:
bluetoothState = false
output("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 devices
if (bluetoothState == true && scanState == false) {
scanState = true
output("Searching...", UI: true)
if (smartLockNSUUID != nil) {
var peripherals = centralManager.
retrievePeripheralsWithIdentifiers([smartLockNSUUID!])
for peripheral in peripherals {
smartLock = peripheral as CBPeripheral
connectToSmartLock(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
87. peripheral: CBPeripheral!, advertisementData: (NSDictionary), RSSI:
NSNumber!) {
// Conserve battery
centralManager.stopScan()
scanState = false
// Connect to SmartLock
output("Discovered", UI: true)
smartLock = peripheral
smartLockNSUUID = peripheral.identifier
connectTimer = 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 Service
connectState = true
connectTimer.invalidate()
output("Connected", UI: true)
peripheral.delegate = self
peripheral.readRSSI()
peripheral.discoverServices([uartServiceUUID])
}
// Invoked when an existing connection with a SmartLock fails
func centralManager(central: CBCentralManager!, didDisconnectPeripheral
peripheral: CBPeripheral!, error: NSError!) {
connectState = false
scanState = false
output("Disconnected", UI: true)
}
//*******************************************************
// Peripheral (SmartLock) Functions
//*******************************************************
// Invoked when the SmartLock's UART service has been discovered
func peripheral(peripheral: CBPeripheral!, didDiscoverServices error:
NSError!) {
for service in peripheral.services {
// Investigate UART Service RX and TX Characteristics
peripheral.discoverCharacteristics([txCharacteristicUUID,
rxCharacteristicUUID], forService: service as CBService)
}
}
// Invoked when the SmartLock's UART RX and TX characteristics have been
discovered