FINGERPRINT DOOR LOCK (RF)
05 JUNE 2025
Wanted to unlock door with fingerprint, wirelessly to avoid drilling.
2024-11: Started with basic 433MHz RF modules and two Arduinos. Connected data lines of the transceivers to UART RXD/TXD of an ATmega328P. Unreliable–constant packet loss.
2025-01: Switched to RFM69 modules. Complete ball-ache. Followed datasheet to the letter, audited code many times, cross-checked with RadioHead and RFM69 open-source drivers. No luck.
ATmega328P runs at 5V; RFM69 3.3V. Suspect logic-level converter (LLC) issues. High resistance. Not enough swing.
2025-04: Ditched RFM69s. Switched to NRF24L01+ modules–data pins 5V tolerant, no LLC required. Spent six weekends writing a clean-room driver from scratch. Works like a charm.
Basic security via xor cipher–good enough for a door behind a guard post and gate:
void xor(const char *k, const char *s, char *d, uint8_t n)
{
int i;
for (i = 0; i < n; i++)
d[i] = s[i] ^ k[i];
}
Resists replay attacks by cycling the key:
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 static key. Session key used thereafter. Private command set authenticates endpoints.
2025-05: Wrote FPM drivers for R503 and FPM10A. UART RX sequence was tricky–adopted Adafruit C++ FOSS implementation to C. R503 has built-in LEDs and better form factor. Chose it for the lock.
2025-06: Two PCBs for FPM (front) and servo (back) controllers.
Footprint (front) |
PCB (front) |
Footprint (back) |
PCB (back) |
PCB specs: 2-layer, 1oz copper, 0.3mm traces (0.5mm for power). Ground plane.
2025-06: NRF24L01+ on the back stopped working after mounting on PCB. Too close to servo’s 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. Sensor and servo drew 13.8mA and 4.6mA quiescent currents–unacceptable for battery. Servo inrush current exceeds 1A. 0.3mm tracks cuts it too close.
Verdict: Functional but not practical. Battery dead in under 24 hours. Led to redesign with proper power management.
Commit: f4b0b73 | Gerber: gerber_back.zip, gerber_front.zip