summaryrefslogtreecommitdiffstats
path: root/_log
diff options
context:
space:
mode:
Diffstat (limited to '_log')
-rw-r--r--_log/fpm-door-lock-lp.md60
-rw-r--r--_log/fpm-door-lock-lp/breadboard.jpg (renamed from _log/fpm-door-lock/breadboard.jpg)bin46771 -> 46771 bytes
-rw-r--r--_log/fpm-door-lock-lp/footprint.png (renamed from _log/fpm-door-lock/footprint.png)bin198127 -> 198127 bytes
-rw-r--r--_log/fpm-door-lock-lp/gerber.zip (renamed from _log/fpm-door-lock/gerber.zip)bin89431 -> 89431 bytes
-rw-r--r--_log/fpm-door-lock-lp/pcb.jpg (renamed from _log/fpm-door-lock/pcb.jpg)bin68237 -> 68237 bytes
-rw-r--r--_log/fpm-door-lock-lp/pcb1.jpg (renamed from _log/fpm-door-lock/pcb1.jpg)bin37068 -> 37068 bytes
-rw-r--r--_log/fpm-door-lock-lp/source.tar.gz (renamed from _log/fpm-door-lock/source.tar.gz)bin29473 -> 29473 bytes
-rw-r--r--_log/fpm-door-lock-lp/thumb_sm.jpg (renamed from _log/fpm-door-lock/thumb_sm.jpg)bin18380 -> 18380 bytes
-rw-r--r--_log/fpm-door-lock-lp/video.mp4 (renamed from _log/fpm-door-lock/video.mp4)bin13264594 -> 13264594 bytes
-rw-r--r--_log/fpm-door-lock-rf.md (renamed from _log/my-first-pcb.md)2
-rw-r--r--_log/fpm-door-lock-rf/back.jpeg (renamed from _log/my-first-pcb/back.jpeg)bin34023 -> 34023 bytes
-rw-r--r--_log/fpm-door-lock-rf/back_design.jpeg (renamed from _log/my-first-pcb/back_design.jpeg)bin31946 -> 31946 bytes
-rw-r--r--_log/fpm-door-lock-rf/front.jpeg (renamed from _log/my-first-pcb/front.jpeg)bin28997 -> 28997 bytes
-rw-r--r--_log/fpm-door-lock-rf/front_design.jpeg (renamed from _log/my-first-pcb/front_design.jpeg)bin32174 -> 32174 bytes
-rw-r--r--_log/fpm-door-lock-rf/gerber_back.zip (renamed from _log/my-first-pcb/gerber_back.zip)bin48217 -> 48217 bytes
-rw-r--r--_log/fpm-door-lock-rf/gerber_front.zip (renamed from _log/my-first-pcb/gerber_front.zip)bin49605 -> 49605 bytes
-rw-r--r--_log/fpm-door-lock-rf/source.tar.gz (renamed from _log/my-first-pcb/source.tar.gz)bin6660 -> 6660 bytes
-rw-r--r--_log/fpm-door-lock-rf/thumb_sm.jpeg (renamed from _log/my-first-pcb/thumb_sm.jpeg)bin6181 -> 6181 bytes
-rw-r--r--_log/fpm-door-lock.md113
-rw-r--r--_log/matrix-digital-rain.md38
20 files changed, 81 insertions, 132 deletions
diff --git a/_log/fpm-door-lock-lp.md b/_log/fpm-door-lock-lp.md
new file mode 100644
index 0000000..1be2b76
--- /dev/null
+++ b/_log/fpm-door-lock-lp.md
@@ -0,0 +1,60 @@
+---
+title: Fingerprint door lock (LP)
+date: 2025-08-18
+layout: post
+project: true
+thumbnail: thumb_sm.jpg
+---
+
+Second iteration of the [RF door lock](../fpm-door-lock-rf). Old version worked
+but drew too much quiescent current. Sensor and servo pulled 13.8mA and 4.6mA
+idle. Linear regulators were a disaster. Battery didn't last 24 hours.
+
+<video style="max-width:100%;" controls="" poster="pcb.jpg">
+ <source src="video.mp4" type="video/mp4">
+</video>
+
+Redesigned the PCB completely. Tossed the RF modules and the second MCU.
+Connected R503 sensor directly to the ATmega328P. Sensor now mounts on door
+exterior, servo attaches to interior knob, MCU stays on the back to prevent
+tampering.
+
+<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>
+
+PCB specs: 2-layer, 1oz copper, 0.3mm traces (1mm for power and servo). Ground
+plane on bottom layer.
+
+Solved idle power draw with MOSFETs. 2N7000 and NDP6020P cut power to sensor
+and servo before deep sleep. Through-hole MOSFETs that switch at 3.3V are
+getting harder to find. NDP6020P already obsolete.
+
+Replaced linear regulators with MP1584EN DC-DC buck converters. No RF, noise
+isn't a big concern. Buck's pin breakout not great--wouldn't fit most
+commercial dev boards.
+
+Squeezed more power savings from the MCU by running it at 3.3V/8MHz. Combined
+with buck converters: 56% total power savings.
+
+Wake sequence: MCU activates sensor MOSFET, unlocks sensor over UART, scans and
+matches fingerprint. Match triggers blue LED, servo MOSFET, PWM signal to
+unlock. No match triggers red LED. MOSFETs off, back to sleep.
+
+Total power savings: 99.9% (30.6mA → 2.9μA). Verdict: Fixed.
+
+Commit:
+[7529094](https://git.asciimx.com/fpm-door-lock/commit/?id=75290945b2fd84b3bc108fd46419ee478eaac3ca)
+| Gerber: [gerber.zip](gerber.zip)
diff --git a/_log/fpm-door-lock/breadboard.jpg b/_log/fpm-door-lock-lp/breadboard.jpg
index 2bf47a9..2bf47a9 100644
--- a/_log/fpm-door-lock/breadboard.jpg
+++ b/_log/fpm-door-lock-lp/breadboard.jpg
Binary files differ
diff --git a/_log/fpm-door-lock/footprint.png b/_log/fpm-door-lock-lp/footprint.png
index 5511bf1..5511bf1 100644
--- a/_log/fpm-door-lock/footprint.png
+++ b/_log/fpm-door-lock-lp/footprint.png
Binary files differ
diff --git a/_log/fpm-door-lock/gerber.zip b/_log/fpm-door-lock-lp/gerber.zip
index 19a9d19..19a9d19 100644
--- a/_log/fpm-door-lock/gerber.zip
+++ b/_log/fpm-door-lock-lp/gerber.zip
Binary files differ
diff --git a/_log/fpm-door-lock/pcb.jpg b/_log/fpm-door-lock-lp/pcb.jpg
index fbd800b..fbd800b 100644
--- a/_log/fpm-door-lock/pcb.jpg
+++ b/_log/fpm-door-lock-lp/pcb.jpg
Binary files differ
diff --git a/_log/fpm-door-lock/pcb1.jpg b/_log/fpm-door-lock-lp/pcb1.jpg
index 367187d..367187d 100644
--- a/_log/fpm-door-lock/pcb1.jpg
+++ b/_log/fpm-door-lock-lp/pcb1.jpg
Binary files differ
diff --git a/_log/fpm-door-lock/source.tar.gz b/_log/fpm-door-lock-lp/source.tar.gz
index ef23422..ef23422 100644
--- a/_log/fpm-door-lock/source.tar.gz
+++ b/_log/fpm-door-lock-lp/source.tar.gz
Binary files differ
diff --git a/_log/fpm-door-lock/thumb_sm.jpg b/_log/fpm-door-lock-lp/thumb_sm.jpg
index a8fa534..a8fa534 100644
--- a/_log/fpm-door-lock/thumb_sm.jpg
+++ b/_log/fpm-door-lock-lp/thumb_sm.jpg
Binary files differ
diff --git a/_log/fpm-door-lock/video.mp4 b/_log/fpm-door-lock-lp/video.mp4
index a907a9b..a907a9b 100644
--- a/_log/fpm-door-lock/video.mp4
+++ b/_log/fpm-door-lock-lp/video.mp4
Binary files differ
diff --git a/_log/my-first-pcb.md b/_log/fpm-door-lock-rf.md
index eced7e4..b677591 100644
--- a/_log/my-first-pcb.md
+++ b/_log/fpm-door-lock-rf.md
@@ -1,5 +1,5 @@
---
-title: My first PCB
+title: Fingerprint door lock (RF)
date: 2025-04-26
layout: post
---
diff --git a/_log/my-first-pcb/back.jpeg b/_log/fpm-door-lock-rf/back.jpeg
index f458e69..f458e69 100644
--- a/_log/my-first-pcb/back.jpeg
+++ b/_log/fpm-door-lock-rf/back.jpeg
Binary files differ
diff --git a/_log/my-first-pcb/back_design.jpeg b/_log/fpm-door-lock-rf/back_design.jpeg
index b6c0f5d..b6c0f5d 100644
--- a/_log/my-first-pcb/back_design.jpeg
+++ b/_log/fpm-door-lock-rf/back_design.jpeg
Binary files differ
diff --git a/_log/my-first-pcb/front.jpeg b/_log/fpm-door-lock-rf/front.jpeg
index 2b2931f..2b2931f 100644
--- a/_log/my-first-pcb/front.jpeg
+++ b/_log/fpm-door-lock-rf/front.jpeg
Binary files differ
diff --git a/_log/my-first-pcb/front_design.jpeg b/_log/fpm-door-lock-rf/front_design.jpeg
index f81f09c..f81f09c 100644
--- a/_log/my-first-pcb/front_design.jpeg
+++ b/_log/fpm-door-lock-rf/front_design.jpeg
Binary files differ
diff --git a/_log/my-first-pcb/gerber_back.zip b/_log/fpm-door-lock-rf/gerber_back.zip
index 26659ad..26659ad 100644
--- a/_log/my-first-pcb/gerber_back.zip
+++ b/_log/fpm-door-lock-rf/gerber_back.zip
Binary files differ
diff --git a/_log/my-first-pcb/gerber_front.zip b/_log/fpm-door-lock-rf/gerber_front.zip
index 864334e..864334e 100644
--- a/_log/my-first-pcb/gerber_front.zip
+++ b/_log/fpm-door-lock-rf/gerber_front.zip
Binary files differ
diff --git a/_log/my-first-pcb/source.tar.gz b/_log/fpm-door-lock-rf/source.tar.gz
index c31aa22..c31aa22 100644
--- a/_log/my-first-pcb/source.tar.gz
+++ b/_log/fpm-door-lock-rf/source.tar.gz
Binary files differ
diff --git a/_log/my-first-pcb/thumb_sm.jpeg b/_log/fpm-door-lock-rf/thumb_sm.jpeg
index c275b12..c275b12 100644
--- a/_log/my-first-pcb/thumb_sm.jpeg
+++ b/_log/fpm-door-lock-rf/thumb_sm.jpeg
Binary files differ
diff --git a/_log/fpm-door-lock.md b/_log/fpm-door-lock.md
deleted file mode 100644
index 5b78b3e..0000000
--- a/_log/fpm-door-lock.md
+++ /dev/null
@@ -1,113 +0,0 @@
----
-title: Fingerprint door lock
-date: 2025-08-18
-layout: post
-project: true
-thumbnail: thumb_sm.jpg
----
-
-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 microcontroller, 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 and 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)
diff --git a/_log/matrix-digital-rain.md b/_log/matrix-digital-rain.md
index 8512208..f1553e1 100644
--- a/_log/matrix-digital-rain.md
+++ b/_log/matrix-digital-rain.md
@@ -16,44 +16,46 @@ than it needed to be.
</video>
Moved phosphor decay into the 4th byte of the RGB union--should’ve done this
-in 2022. What was I thinking.
+in 2022; What was I thinking.
Keeping the RGB union despite portability concerns. All my systems are
little-endian and the code is cleaner this way.
Fixed Unicode by introducing a charset array. UNICODE(min, max) packs Unicode
-ranges into uint64--low four bytes for start, high four bytes for end.
+ranges into uint64: low four bytes for start, high four bytes for end.
insert_code() unpacks a random block and picks a character from it:
```
+#define UNICODE(min, max) (((uint64_t)max << 32) | min)
+
static uint64_t glyphs[] = {
UNICODE(0x0021, 0x007E), /* ASCII */
UNICODE(0xFF65, 0xFF9F), /* Half-width Katakana */
};
-```
-
-Full-width Katakana breaks column alignment. Stick to half-width
-(U+FF61-U+FF9F) range. Compile with -DNOKANA to disable Katakana altogether.
-
-blend() simulates phosphor decay by eroding RGB channels toward
-background color:
-```
-static inline void blend(matrix *mat, size_t row, size_t col)
+static inline void insert_code(matrix *mat,
+ size_t row, size_t col)
{
- unsigned char *color = mat->rgb[index(mat, row, col)].color;
- color[R] = color[R] - (color[R] - RGB_BG_RED) / DECAY_MPLIER;
- color[G] = color[G] - (color[G] - RGB_BG_GRN) / DECAY_MPLIER;
- color[B] = color[B] - (color[B] - RGB_BG_BLU) / DECAY_MPLIER;
+ uint64_t blk;
+ uint32_t min, max;
+
+ blk = glyphs[(rand() % glyphlen)];
+ min = (uint32_t)blk;
+ max = (uint32_t)(blk >> 32);
+ mat->code[index(mat, row, col)] = rand() % (max - min) + min;
}
```
-That's still good. Leaving it alone.
+Full-width Katakana breaks column alignment. Stick to half-width
+(U+FF61-U+FF9F) range. Compile with -DNOKANA to disable Katakana altogether.
+
+blend() is still good. Leaving it alone.
Tossed license and automake cruft. Just `cc -O3 main.c -o matrix` now. Don't
need the ceremony.
-Runs at 2-3% CPU on OpenBSD (T490). No regressions. Fans are quiet.
+Runs at 2-3% CPU on OpenBSD (T490). No cause to measure performance more
+precisely. No regressions. Fans are quiet.
Commit:
-[03f8d87](https://git.asciimx.com/matrix-digital-rain/commit/?id=03f8d87ba7c2e46bd3f3cc4c772fb3a2ac740c92)
+[69a888a](https://git.asciimx.com/matrix-digital-rain/commit/main.c?id=69a888a5b0bc4ef4bce4f86c1556a06f0f131fda)