--- title: Fingerprint door lock (RF) date: 2025-06-05 layout: post project: true thumbnail: thumb_sm.jpeg --- 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) |