summaryrefslogtreecommitdiffstats
path: root/_projects/fpm-door-lock.md
blob: 41a2aec53455e0ce21c78b2ee75a0b78c2f14b48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
---
title: Fingerprint door lock
date: 2025-10-03
author: Wickramage Don Sadeep Madurange
thumbnail: pcb.jpg
layout: post
---

This project features a fingerprint door lock powered by an ATmega328P
microcontroller.

<video style="max-width:100%;" controls="" poster="pcb.jpg">
  <source src="video.mp4" type="video/mp4">
</video>

## Overview

The lock comprises three subsystems: the ATmega328P, an R503 fingerprint
sensor, and an FS5106B high-torque servo. The sensor mounted on the front
surface of the door enables users to unlock it from the outside. The servo is
attached to the interior door knob. The MCU must be installed at the back of
the door to prevent unauthorized users from tampering with it.

When no one is interacting with the lock, the MCU is in deep sleep. The sensor
and the servo each draw 13.8mA and 4.6mA of quiescent currents. To prevent this
idle current draw, the MCU employs MOSFETs to cut off power to them before
entering deep sleep. Doing so is crucial for conserving the battery.

Without power, the sensor remains in a low-power state, drawing approximately
2.9μA through a separate power rail. When a finger comes into contact with the
sensor, the sensor triggers a pin change interrupt, waking up the MCU. The MCU
activates a MOSFET, which in turn activates the sensor. Over UART, the MCU
unlocks the sensor and issues commands to scan and match the fingerprint.

If the fingerprint matches an enrolled fingerprint, the MCU activates the blue
LED on the sensor, turns on the MOSFET connected to the servo, and sends a PWM
signal to the servo to unlock the door. Otherwise, the MCU activates the red
LED on the sensor. Finally, the MCU deactivates the MOSFETS and goes back to
sleep.

## Embedded software

The embedded software, written in C, includes a driver for the sensor, servo
control routines, and a battery monitoring system.

In addition to controlling the sensor and the servo, the program strives to
maintain precise control over the microcontroller's sleep modes, as well as
when the peripherals are activated and for how long they remain active. I
thoroughly enjoyed writing the embedded software. There's something magical
about being able to alter the physical world around you by uttering a few lines
of C code.

The source code of the project, which includes a driver for the R503
fingerprint sensor module, is enclosed in the tarball linked at the end of the
page.

## The PCB

For this project, I designed a custom PCB and had it fabricated by JLCPCB. Like
the software, the circuit is primarily concerned with optimizing power
consumption and extending battery life.

<table style="border: none; width: 100%">
  <tr style="border: none;">
    <td style="border: none; width: 49.9%; background-color: transparent; text-align: center;">
      <img src="breadboard.jpg" alt="PCB" style="width: 100%">
    </td>
    <td style="border: none; background-color: transparent; text-align: center;">
      <img src="pcb1.jpg" alt="Design" style="width: 100%">
    </td>
  </tr>
  <tr style="border: none;">
    <td colspan="2" style="border: none; background-color: transparent; text-align: center;">
      <img src="footprint.png" alt="PCB footprint" style="width: 100%">
    </td>
  </tr>
</table>

Consequently, the principal components of the circuit are the 2N7000 and
NDP6020P field-effect transistors. They switch power electronically to the
servo and the fingerprint sensor, the two most power-hungry parts of the
circuit. The two MP1584EN buck converters play an axial role in efficiently
regulating power to the MCU and the sensor.

The ATmega328P typically operates at 5V with a 16MHz crystal oscillator. To
further reduce power consumption, I modified the ATmega328P's fuses to run at
3.3V with an 8MHz crystal oscillator.

The bottom right area of the PCB isolates the power supply of the servo from
the rest of the circuit. This shields components such as the MCU from the
servo's high current draw, which can exceed 1A. The IN4007 diode in slot U2
serves as a flyback diode, protecting the MOSFET from reverse currents
generated by the servo.

Lastly, the 56kΩ and 10kΩ resistors in slots R10 and R11 form a voltage divider
circuit. Its output is fed to the ADC of the MCU, which measures the supply
voltage by comparing it to the internal bandgap reference voltage. 

## Epilogue

This project began nearly a year ago when I attempted to unlock our door
wirelessly by writing to the UART ports of two MCUs connected to inexpensive
433MHz RF transceivers. Although I failed, it led me down a rabbit hole of RF
communications, MOSFETs, PCB design, and low-power circuits.

During the project, I reinvented the wheel many times. I implemented a
low-level network stack using only RF modules and an 8-bit microcontroller,
designed my first PCB, and developed drivers from scratch. The project was far
from a smooth sail. Bad electrical connections, soldering, desoldering, and the
heartache of purchasing the wrong parts were routine. It was a long but
rewarding journey from the messy breadboard to the shiny PCB. 

Files: [source.tar.gz](source.tar.gz), [gerber.zip](gerber.zip)