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
|
---
title: Fingerprint door lock (RF)
date: 2025-06-05
layout: post
project: true
thumbnail: thumb_sm.jpeg
---
Wanted to unlock the door with fingerprint, wirelessly to avoid drilling.
2024-11: Started with basic 433MHz RF modules and two Arduinos. Connected the
data lines of the transceivers to the UART RXD/TXDs of the MCUs.
Unreliable—constant packet loss.
2025-01: Switched to RFM69 modules. Implemented the driver from scratch.
Checked the datasheet, audited code, cross-checked with RadioHead and RFM69
drivers. Driver non-functional.
ATmega328P chips run at 5V, while RFM69s run at 3.3V. Suspect logic-level
converter (LLC) issues. Not enough swing?
2025-04: Ditched the RFM69s with NRF24L01+ modules—data pins are 5V tolerant,
no LLC required. Implemented the driver over six weekends. Wireless modules are
now operational.
Encrypted the RF channel with XOR cipher—sufficient for the threat model; key
recycled to resist replay attacks:
```
static inline void keygen(char *buf, uint8_t n)
{
int i, imax;
uint8_t sreg;
uint16_t seed;
sreg = SREG;
cli();
seed = TCNT1;
SREG = sreg;
for (i = 0, imax = n - 1; i < imax; i++, seed++)
buf[i] = tab[(seed % tablen)];
buf[imax] = '\0';
}
```
Protocol: FPM sends SYN. Servo responds with session key. Both XOR-ed with a
static key. Session key is used thereafter. Private command set serves as an
authentication layer for the endpoints.
2025-05: Ported the Adafruit C++ drivers for R503 and FPM10A fingerprint
sensors to C. Chose R503 for the lock due to its built-in LEDs and better form
factor.
2025-06: Designed two PCBs for FPM (front) and servo (back) controllers:
<table style="border: none; width: 100%">
<tr style="border: none;">
<td style="border: none; width: 49.5%; vertical-align: top; text-align: center;">
<img src="front_design.jpeg" alt="Design (front)" style="width: 100%">
<p>Footprint (front)</p>
</td>
<td style="border: none; vertical-align: top; text-align: center;">
<img src="front.jpeg" alt="PCB (front)" style="width: 100%">
<p>PCB (front)</p>
</td>
</tr>
<tr style="border: none;">
<td style="border: none; width: 49.5%; vertical-align: top; text-align: center;">
<img src="back_design.jpeg" alt="Design (back)" style="width: 100%">
<p>Footprint (back)</p>
</td>
<td style="border: none; vertical-align: top; text-align: center;">
<img src="back.jpeg" alt="PCB (back)" style="width: 100%">
<p>PCB (back)</p>
</td>
</tr>
</table>
PCB specs: 2-layer, 1oz copper, 0.3mm traces (0.5mm for power). Ground plane.
2025-06: NRF24L01+ stopped working after mounting on the PCB. Too close to the
PWM line. Soldering a large 47uF (16V) electrolytic capacitor between VCC and
ground fixed it.
Power problems became clear. Linear regulators dissipated too much heat. The
sensor and the servo drew 13.8mA and 4.6mA quiescent currents—unacceptable for
a battery-powered device. Servo inrush current exceeds 1A. 0.3mm tracks cut it
too close.
Verdict: Functional but not practical. Battery died in under 24 hours. Led to
[redesign](../fpm-door-lock-lp/) with proper power management.
Commit: <a
href="https://git.asciimx.com/smart-home/commit/?id=f4b0b734a595919cf451ab9448b06274c8e609a4"
class="external" target="_blank" rel="noopener noreferrer">f4b0b73</a> |
Gerber: [gerber_back.zip](gerber_back.zip),
[gerber_front.zip](gerber_front.zip)
|