From 8cbe75f0047732c865f58e2f847a5ffafe066e71 Mon Sep 17 00:00:00 2001 From: Sadeep Madurange Date: Sat, 20 Dec 2025 11:25:26 +0800 Subject: Change projects to poc and blog to log. --- _site/projects/bumblebee/bee.mp4 | Bin 2352029 -> 0 bytes _site/projects/bumblebee/index.html | 103 -------------- _site/projects/bumblebee/poster.png | Bin 18024 -> 0 bytes _site/projects/bumblebee/thumb_sm.png | Bin 6189 -> 0 bytes _site/projects/e-reader/circuit.svg | 145 ------------------- _site/projects/e-reader/ereader.mp4 | Bin 3101166 -> 0 bytes _site/projects/e-reader/index.html | 148 -------------------- _site/projects/e-reader/poster.png | Bin 674187 -> 0 bytes _site/projects/e-reader/source.tar.gz | Bin 14304 -> 0 bytes _site/projects/e-reader/thumb_sm.png | Bin 240117 -> 0 bytes _site/projects/etlas/circuit.svg | 105 -------------- _site/projects/etlas/dash.jpg | Bin 85874 -> 0 bytes _site/projects/etlas/etlas_arch.png | Bin 47732 -> 0 bytes _site/projects/etlas/index.html | 166 ---------------------- _site/projects/etlas/pcb.jpg | Bin 75769 -> 0 bytes _site/projects/etlas/schematic.svg | 4 - _site/projects/etlas/source.tar.gz | Bin 46871 -> 0 bytes _site/projects/etlas/thumb_sm.jpg | Bin 55678 -> 0 bytes _site/projects/fpm-door-lock/breadboard.jpg | Bin 46771 -> 0 bytes _site/projects/fpm-door-lock/footprint.png | Bin 198127 -> 0 bytes _site/projects/fpm-door-lock/gerber.zip | Bin 89431 -> 0 bytes _site/projects/fpm-door-lock/index.html | 168 ----------------------- _site/projects/fpm-door-lock/pcb.jpg | Bin 68237 -> 0 bytes _site/projects/fpm-door-lock/pcb1.jpg | Bin 37068 -> 0 bytes _site/projects/fpm-door-lock/source.tar.gz | Bin 29473 -> 0 bytes _site/projects/fpm-door-lock/thumb_sm.jpg | Bin 18380 -> 0 bytes _site/projects/fpm-door-lock/video.mp4 | Bin 13264594 -> 0 bytes _site/projects/index.html | 120 ---------------- _site/projects/matrix-digital-rain/index.html | 148 -------------------- _site/projects/matrix-digital-rain/katakana.png | Bin 133709 -> 0 bytes _site/projects/matrix-digital-rain/matrix.mp4 | Bin 930430 -> 0 bytes _site/projects/matrix-digital-rain/poster.png | Bin 70901 -> 0 bytes _site/projects/matrix-digital-rain/source.tar.gz | Bin 2075 -> 0 bytes _site/projects/matrix-digital-rain/thumb_sm.png | Bin 22764 -> 0 bytes _site/projects/my-first-pcb/back.jpeg | Bin 34023 -> 0 bytes _site/projects/my-first-pcb/back_design.jpeg | Bin 31946 -> 0 bytes _site/projects/my-first-pcb/front.jpeg | Bin 28997 -> 0 bytes _site/projects/my-first-pcb/front_design.jpeg | Bin 32174 -> 0 bytes _site/projects/my-first-pcb/gerber_back.zip | Bin 48217 -> 0 bytes _site/projects/my-first-pcb/gerber_front.zip | Bin 49605 -> 0 bytes _site/projects/my-first-pcb/index.html | 120 ---------------- _site/projects/my-first-pcb/source.tar.gz | Bin 6660 -> 0 bytes _site/projects/my-first-pcb/thumb_sm.jpeg | Bin 6181 -> 0 bytes 43 files changed, 1227 deletions(-) delete mode 100644 _site/projects/bumblebee/bee.mp4 delete mode 100644 _site/projects/bumblebee/index.html delete mode 100644 _site/projects/bumblebee/poster.png delete mode 100644 _site/projects/bumblebee/thumb_sm.png delete mode 100644 _site/projects/e-reader/circuit.svg delete mode 100644 _site/projects/e-reader/ereader.mp4 delete mode 100644 _site/projects/e-reader/index.html delete mode 100644 _site/projects/e-reader/poster.png delete mode 100644 _site/projects/e-reader/source.tar.gz delete mode 100644 _site/projects/e-reader/thumb_sm.png delete mode 100644 _site/projects/etlas/circuit.svg delete mode 100644 _site/projects/etlas/dash.jpg delete mode 100644 _site/projects/etlas/etlas_arch.png delete mode 100644 _site/projects/etlas/index.html delete mode 100644 _site/projects/etlas/pcb.jpg delete mode 100644 _site/projects/etlas/schematic.svg delete mode 100644 _site/projects/etlas/source.tar.gz delete mode 100644 _site/projects/etlas/thumb_sm.jpg delete mode 100644 _site/projects/fpm-door-lock/breadboard.jpg delete mode 100644 _site/projects/fpm-door-lock/footprint.png delete mode 100644 _site/projects/fpm-door-lock/gerber.zip delete mode 100644 _site/projects/fpm-door-lock/index.html delete mode 100644 _site/projects/fpm-door-lock/pcb.jpg delete mode 100644 _site/projects/fpm-door-lock/pcb1.jpg delete mode 100644 _site/projects/fpm-door-lock/source.tar.gz delete mode 100644 _site/projects/fpm-door-lock/thumb_sm.jpg delete mode 100644 _site/projects/fpm-door-lock/video.mp4 delete mode 100644 _site/projects/index.html delete mode 100644 _site/projects/matrix-digital-rain/index.html delete mode 100644 _site/projects/matrix-digital-rain/katakana.png delete mode 100644 _site/projects/matrix-digital-rain/matrix.mp4 delete mode 100644 _site/projects/matrix-digital-rain/poster.png delete mode 100644 _site/projects/matrix-digital-rain/source.tar.gz delete mode 100644 _site/projects/matrix-digital-rain/thumb_sm.png delete mode 100644 _site/projects/my-first-pcb/back.jpeg delete mode 100644 _site/projects/my-first-pcb/back_design.jpeg delete mode 100644 _site/projects/my-first-pcb/front.jpeg delete mode 100644 _site/projects/my-first-pcb/front_design.jpeg delete mode 100644 _site/projects/my-first-pcb/gerber_back.zip delete mode 100644 _site/projects/my-first-pcb/gerber_front.zip delete mode 100644 _site/projects/my-first-pcb/index.html delete mode 100644 _site/projects/my-first-pcb/source.tar.gz delete mode 100644 _site/projects/my-first-pcb/thumb_sm.jpeg (limited to '_site/projects') diff --git a/_site/projects/bumblebee/bee.mp4 b/_site/projects/bumblebee/bee.mp4 deleted file mode 100644 index 835600d..0000000 Binary files a/_site/projects/bumblebee/bee.mp4 and /dev/null differ diff --git a/_site/projects/bumblebee/index.html b/_site/projects/bumblebee/index.html deleted file mode 100644 index a07dd5f..0000000 --- a/_site/projects/bumblebee/index.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - Bumblebee: browser automation - - - - - Bumblebee: browser automation - - - - - - - - - - - - - -
-
-
-

BUMBLEBEE: BROWSER AUTOMATION

-
02 APRIL 2025
-
-

Bumblebee is a tool I built for one of my employers to automate the generation -of web scraping scripts.

- - - -

In 2024, we were tasked with collecting market data using various methods, -including scraping data from authorized websites for traders’ use.

- -

Manual authoring of such scripts took time. The scripts were often brittle due -to the complexity of the modern web, and they lacked optimizations such as -bypassing the UI and retrieving the data files directly when possible, which -would have significantly reduced our compute costs.

- -

To alleviate these challenges, I, with the help of a colleague, Andy Zhang, -built Bumblebee: a web browser powered by C# Windows Forms, Microsoft Edge WebView2, and -the Scintilla.NET text editor.

- -

Bumblebee works by injecting a custom JavaScript program that intercepts -client-side events and sends them to Bumblebee for analysis. In addition to -front-end events, Bumblebee also captures internal browser events, which it -then interprets to generate code in real time. Note that we developed Bumblebee -before the advent of now-popular LLMs. Bumblebee supports dynamic websites, -pop-ups, developer tools, live manual override, event debouncing, and filtering -hidden elements and scripts.

- -

Before settling on a desktop application, we contemplated designing Bumblebee -as a browser extension. We chose the desktop app because extensions don’t offer -the deep, event-based control we needed. Besides, the company’s security -policy, which prohibited browser extensions, would have complicated the -deployment of an extension-based solution. My first prototype used a C# binding -of the Chromium project. WebView’s more intuitive API and its seamless -integration with Windows Forms led us to choose it over the Chromium wrapper.

- -

What began as a personal side project to improve my own workflow enabled us to -collectively improve the quality of our web scripts at a much larger scale. -Bumblebee predictably reduced the time we spent on authoring scripts from hours -to a few minutes.

- -
- -
-
-
- - - - - - diff --git a/_site/projects/bumblebee/poster.png b/_site/projects/bumblebee/poster.png deleted file mode 100644 index 6dc955e..0000000 Binary files a/_site/projects/bumblebee/poster.png and /dev/null differ diff --git a/_site/projects/bumblebee/thumb_sm.png b/_site/projects/bumblebee/thumb_sm.png deleted file mode 100644 index f7cfbf3..0000000 Binary files a/_site/projects/bumblebee/thumb_sm.png and /dev/null differ diff --git a/_site/projects/e-reader/circuit.svg b/_site/projects/e-reader/circuit.svg deleted file mode 100644 index fd7508b..0000000 --- a/_site/projects/e-reader/circuit.svg +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - 10 kΩ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - 2 - 3 - 4 - - - - - - - - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - - - - - 5 - 6 - 7 - 8 - BUS - E-Paper Display HAT - - - CS - - DC - - DIN - - CLK - - BUSY - - RST - - GND - - VCC - - ESP-WROOM-32 - - IO21 - - - IO5 - - - IO16 - - - IO23 - - - IO18 - - - IO22 - - - IO4 - - - IO2 - - - GND - - - 3V3 - - - GND - - - IO15 - - - - \ No newline at end of file diff --git a/_site/projects/e-reader/ereader.mp4 b/_site/projects/e-reader/ereader.mp4 deleted file mode 100644 index 89e05eb..0000000 Binary files a/_site/projects/e-reader/ereader.mp4 and /dev/null differ diff --git a/_site/projects/e-reader/index.html b/_site/projects/e-reader/index.html deleted file mode 100644 index fb48a9d..0000000 --- a/_site/projects/e-reader/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Experimental e-reader - - - - - Experimental e-reader - - - - - - - - - - - - - -
-
-
-

EXPERIMENTAL E-READER

-
24 OCTOBER 2023
-
-

This project features an experimental e-reader powered by an ESP-WROOM-32 -development board and a 7.5-inch Waveshare -e-paper display built with the intention of learning about e-paper displays.

- - - -

Introduction

- -

The prototype e-reader comprises an ESP32 microcontroller, an e-paper display -HAT, and three buttons: yellow, blue, and white for turning the page backwards, -forwards, and putting the device to sleep, respectively. The prototype does not -store books on the microcontroller. It streams books from a server over HTTP. -The e-reader employs RTC memory to record the reading progress between -sessions.

- -

The most formidable challenge when trying to build an e-reader with an ESP32 is -its limited memory and storage. My ESP-WROOM-32 has a total of 512KB of SRAM -and 4MB of flash memory, which the freeRTOS, ESP-IDF, and the e-reader -application must share. To put things into perspective, a Kindle Paperwhite has -at least 256MB of memory and 8GB of storage. That is 500x more memory than what -I’d have to work with.

- -

Despite its size, as microcontrollers go, ESP32 is a powerful system-on-a-chip -with a 160MHz dual-core processor and integrated WiFi. So, I thought it’d be -amusing to embrace the constraints and build my e-reader using a $5 MCU and the -power of C programming.

- -

The file format

- -

The file format dictates the complexity of the embedded software. So, I’ll -begin there. The e-reader works by downloading and rendering a rasterized -monochrome image of a page (a .ebm file).

- -

The EBM file contains a series of bitmaps, one for each page of the book. The -dimensions of each bitmap are equal to the size of the display. Each byte of -the bitmap encodes information for rendering eight pixels. For my display, -which has a resolution of 480x800, the bitmaps are laid out along 48KB -boundaries. This simple file format lends well to HTTP streaming, which is its -main advantage, as we will soon see.

- -

The pdftoebm.py script enclosed in the tarball at the end of the page converts -PDF documents to EBM files.

- -

How does it work?

- -

As the e-reader has no storage, it can’t store books locally. Instead, it -downloads pages of the EBM file over HTTP from the location pointed to by the -EBM_ARCH_URL setting in the Kconfig.projbuild file on demand. To read a -different book, we have to replace the old file with the new one or change the -EBM_ARCH_URL value. The latter requires us to recompile the embedded -software.

- -

Upon powering up, the e-reader checks the reading progress stored in the RTC -memory. It then downloads three pages (current, previous, and next) to a -circular buffer in DMA-capable memory. When the user turns a page by pressing a -button, one of the microprocessor’s two cores transfers it from the buffer to -the display over a Serial Peripheral Interface (SPI). The other downloads a new -page in the background. I used the ESP-IDF task API to schedule the two tasks -on different cores of the multicore processor to make the reader more -responsive.

- -

I designed the EBM format with HTTP streaming in mind. Since the pages are laid -out in the EBM file along predictable boundaries, the e-reader can request -pages by specifying the offset and the chunk size in the HTTP Range header. Any -web server will process this request without custom logic.

- -

Epilogue

- -

My fascination with e-paper began back in 2017, when I was tasked with -installing a few displays in a car park. Having no idea how they worked, I -remember watching the languid screens refresh like a Muggle witnessing magic. -This project was born out of that enduring curiosity and love of e-paper -technology.

- -

Why did I go to the trouble of building a rudimentary e-reader when I could -easily buy a more capable commercial e-reader? First of all, it’s to prove to -myself that I can. More importantly, there’s a quiet satisfaction to reading on -hardware you built yourself. You are no longer the powerless observer watching -the magic happen from the sidelines. You become the wizard who makes the -invisible particles swirl into form by whispering C to them. There’s only one -way to experience that.

- -

Files: source.tar.gz

-
- -
-
-
- - - - - - diff --git a/_site/projects/e-reader/poster.png b/_site/projects/e-reader/poster.png deleted file mode 100644 index 1e222d2..0000000 Binary files a/_site/projects/e-reader/poster.png and /dev/null differ diff --git a/_site/projects/e-reader/source.tar.gz b/_site/projects/e-reader/source.tar.gz deleted file mode 100644 index 3e343a7..0000000 Binary files a/_site/projects/e-reader/source.tar.gz and /dev/null differ diff --git a/_site/projects/e-reader/thumb_sm.png b/_site/projects/e-reader/thumb_sm.png deleted file mode 100644 index 7c971e8..0000000 Binary files a/_site/projects/e-reader/thumb_sm.png and /dev/null differ diff --git a/_site/projects/etlas/circuit.svg b/_site/projects/etlas/circuit.svg deleted file mode 100644 index 6255045..0000000 --- a/_site/projects/etlas/circuit.svg +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - AM2302 - - - DATA - - GND - - VCC - E-Paper display HAT - - - CS - - DC - - DIN - - CLK - - BUSY - - RST - - PWR - - GND - - VCC - - - - - - - - - - - - - - 1 - 2 - 3 - 4 - - - - - 1 - 2 - 3 - 4 - - ESP32 Mini NodeMCU D1 - - IO19 - - - IO15 - - - GND - - - IO27 - - - IO14 - - - IO13 - - - IO25 - - - IO26 - - - IO16 - - - GND - - - 3V3 - - - \ No newline at end of file diff --git a/_site/projects/etlas/dash.jpg b/_site/projects/etlas/dash.jpg deleted file mode 100644 index cf4efc6..0000000 Binary files a/_site/projects/etlas/dash.jpg and /dev/null differ diff --git a/_site/projects/etlas/etlas_arch.png b/_site/projects/etlas/etlas_arch.png deleted file mode 100644 index 241e9f1..0000000 Binary files a/_site/projects/etlas/etlas_arch.png and /dev/null differ diff --git a/_site/projects/etlas/index.html b/_site/projects/etlas/index.html deleted file mode 100644 index ae30cb6..0000000 --- a/_site/projects/etlas/index.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - Etlas: e-paper dashboard - - - - - Etlas: e-paper dashboard - - - - - - - - - - - - - -
-
-
-

ETLAS: E-PAPER DASHBOARD

-
05 SEPTEMBER 2024
-
-

Etlas is a news, stock market, and weather tracker powered by an ESP32 NodeMCU -D1, featuring a 7.5-inch Waveshare e-paper display and a -DHT22 sensor module.

- - - - - - -
frontback
- -

The top-left panel shows two weeks of end-of-day prices—the maximum the ESP32’s -SRAM can hold—from the Polygon.io API. The price feed is relayed through a -FastCGI-wrapped Flask app hosted on a VPS. This lets me configure stock symbols -in its application settings. The app cycles through them as requests come in -from the ESP32. Running the Flask app as a FastCGI process while exposing it -via httpd with htpasswd authentication keeps the server code simple and secure.

- -

The following diagram outlines the Etlas’s overall system architecture.

- -

architecture

- -

The more prominent panel on the right of the display shows local and world news -from Channel NewsAsia. The MCU downloads and parses XML data from the RSS feed -directly before rendering it to the display. The character glyphs used are -stored as bitmaps in the sprites directory. I skipped the proxy for news to -avoid writing more server code, but in hindsight it limits the feeds Etlas can -handle. I will fix this in a future version.

- -

The middle and bottom right panels display the temperature and relative -humidity from the DHT22 sensor. The DHT22 uses pulse-width modulation to -transmit data to the host. The 26µs, 50µs, and 70µs pulses are too fast for the -ESP32 to measure reliably with standard APIs. Instead, the driver compares -relative pulse widths to differentiate zeros from ones:

- -
static inline int dht_await_pin_state(int state, int timeout)
-{
-    int t;
-    static const uint16_t delta = 1;
-
-    for (t = 0; t < timeout; t += delta) {
-        ets_delay_us(delta);
-        if (gpio_get_level(DHT_PIN) == state)
-          return t;
-    }
-    return 0;
-}
-
-static inline int dht_get_raw_data(unsigned char buf[DHT_DATA_LEN])
-{
-    int rc;
-    unsigned char i, pwl, pwh;
-
-    gpio_set_level(DHT_PIN, 0);
-    ets_delay_us(1100);
-    gpio_set_level(DHT_PIN, 1);
-
-    if (!dht_await_pin_state(0, 40)) {
-        rc = 1;
-        xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
-        return 0;
-    }
-    if (!dht_await_pin_state(1, 80)) {
-        rc = 2;
-        xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
-        return 0;
-    }
-    if (!dht_await_pin_state(0, 80)) {
-        rc = 3;
-        xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
-        return 0;
-    }
-
-    for (i = 0; i < DHT_DATA_LEN; i++) {
-        if (!(pwl = dht_await_pin_state(1, 50))) {
-            rc = 4;
-            xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
-            return 0;
-        }
-        if (!(pwh = dht_await_pin_state(0, 70))) {
-            rc = 5;
-            xQueueSend(dht_evt_queue, &rc, (TickType_t) 0);
-            return 0;
-        }
-        buf[i] = pwh > pwl;
-    }
-    return 1;
-}
-
- -

I ported this implementation from ESP8266 -to ESP32—all credit for the algorithm belongs to them.

- -

Etlas is a networked embedded system. All acquisition, processing, and -rendering of data are performed on the ESP32’s 160MHz microprocessor using less -than 512KB of SRAM. The embedded software that makes this possible is written -in C using ESP-IDF v5.2.1. The e-paper display driver is derived from Waveshare -examples for Arduino and STM32 -platforms.

- -

Etlas has been running reliably for over a year since August 2024.

- -

Files: source.tar.gz

-
- -
-
-
- - - - - - diff --git a/_site/projects/etlas/pcb.jpg b/_site/projects/etlas/pcb.jpg deleted file mode 100644 index fcb40fa..0000000 Binary files a/_site/projects/etlas/pcb.jpg and /dev/null differ diff --git a/_site/projects/etlas/schematic.svg b/_site/projects/etlas/schematic.svg deleted file mode 100644 index 3070dd1..0000000 --- a/_site/projects/etlas/schematic.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -152726131425193V3GND
ESP32 Mini NodeMCU D1
ESP32 Mini NodeMCU D1
DHT22
DHT22
E-paper HAT
E-paper HAT
3.3V
3.3V
3.3V
3.3V
3.3V
3.3V
CS
CS
DC
DC
RST
RST
CLK
CLK
MOSY
MOSY
BUSY
BUSY
VCC
VCC
GND
GND
VCC
VCC
GND
GND
DATA
DATA
Text is not SVG - cannot display
\ No newline at end of file diff --git a/_site/projects/etlas/source.tar.gz b/_site/projects/etlas/source.tar.gz deleted file mode 100644 index 8b12cf6..0000000 Binary files a/_site/projects/etlas/source.tar.gz and /dev/null differ diff --git a/_site/projects/etlas/thumb_sm.jpg b/_site/projects/etlas/thumb_sm.jpg deleted file mode 100644 index a374879..0000000 Binary files a/_site/projects/etlas/thumb_sm.jpg and /dev/null differ diff --git a/_site/projects/fpm-door-lock/breadboard.jpg b/_site/projects/fpm-door-lock/breadboard.jpg deleted file mode 100644 index 2bf47a9..0000000 Binary files a/_site/projects/fpm-door-lock/breadboard.jpg and /dev/null differ diff --git a/_site/projects/fpm-door-lock/footprint.png b/_site/projects/fpm-door-lock/footprint.png deleted file mode 100644 index 5511bf1..0000000 Binary files a/_site/projects/fpm-door-lock/footprint.png and /dev/null differ diff --git a/_site/projects/fpm-door-lock/gerber.zip b/_site/projects/fpm-door-lock/gerber.zip deleted file mode 100644 index 19a9d19..0000000 Binary files a/_site/projects/fpm-door-lock/gerber.zip and /dev/null differ diff --git a/_site/projects/fpm-door-lock/index.html b/_site/projects/fpm-door-lock/index.html deleted file mode 100644 index 6256026..0000000 --- a/_site/projects/fpm-door-lock/index.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Fingerprint door lock - - - - - Fingerprint door lock - - - - - - - - - - - - - -
-
-
-

FINGERPRINT DOOR LOCK

-
03 OCTOBER 2025
-
-

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

- - - -

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.

- - - - - - - - - -
- PCB - - Design -
- PCB footprint -
- -

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, gerber.zip

-
- -
-
-
- - - - - - diff --git a/_site/projects/fpm-door-lock/pcb.jpg b/_site/projects/fpm-door-lock/pcb.jpg deleted file mode 100644 index fbd800b..0000000 Binary files a/_site/projects/fpm-door-lock/pcb.jpg and /dev/null differ diff --git a/_site/projects/fpm-door-lock/pcb1.jpg b/_site/projects/fpm-door-lock/pcb1.jpg deleted file mode 100644 index 367187d..0000000 Binary files a/_site/projects/fpm-door-lock/pcb1.jpg and /dev/null differ diff --git a/_site/projects/fpm-door-lock/source.tar.gz b/_site/projects/fpm-door-lock/source.tar.gz deleted file mode 100644 index ef23422..0000000 Binary files a/_site/projects/fpm-door-lock/source.tar.gz and /dev/null differ diff --git a/_site/projects/fpm-door-lock/thumb_sm.jpg b/_site/projects/fpm-door-lock/thumb_sm.jpg deleted file mode 100644 index a8fa534..0000000 Binary files a/_site/projects/fpm-door-lock/thumb_sm.jpg and /dev/null differ diff --git a/_site/projects/fpm-door-lock/video.mp4 b/_site/projects/fpm-door-lock/video.mp4 deleted file mode 100644 index a907a9b..0000000 Binary files a/_site/projects/fpm-door-lock/video.mp4 and /dev/null differ diff --git a/_site/projects/index.html b/_site/projects/index.html deleted file mode 100644 index f036081..0000000 --- a/_site/projects/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - Projects - - - - - - - - - - - - -
-
- - - - - - diff --git a/_site/projects/matrix-digital-rain/index.html b/_site/projects/matrix-digital-rain/index.html deleted file mode 100644 index 5218c10..0000000 --- a/_site/projects/matrix-digital-rain/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - The Matrix digital rain - - - - - The Matrix digital rain - - - - - - - - - - - - - -
-
-
-

THE MATRIX DIGITAL RAIN

-
12 JANUARY 2024
-
-

“All I see is blonde, brunette, red head.” The iconic digital rain from The -Matrix in C, with zero dependencies—not even ncurses.

- - - -

Overview

- -

This is my fork of Domsson’s beautiful Fakesteak. While going through his code, I -wondered what it would take to faithfully recreate the original Matrix from the -first movie without sacrificing its minimalism.

- -

My implementation supports:

- -
    -
  • Unicode characters.
  • -
  • 24-bit RGB colors (truecolor).
  • -
  • Glitches in the matrix.
  • -
  • Ghosting effect of old monochrome CRT displays.
  • -
  • Closely resembles the Matrix seen in the background during Neo and Cypher’s -conversation.
  • -
- -

With no dependencies, compilation is trivial:

- -
$ cc -O3 main.c -o matrix
-$ ./matrix
-
- -

How does it work?

- -

The program tracks the state of the terminal, such as code points, background -and foreground colors, and cursor position, using multiple internal data -buffers. On each frame, it updates these buffers and repaints the screen using -ANSI escape codes:

- -
static void term_print(const matrix *mat, size_t row, size_t col)
-{
-    size_t idx;
-    idx = mat_idx(mat, row, col);
-    wprintf(L"\x1b[%d;%dH\x1b[38;2;%d;%d;%dm%lc",
-        row, col,
-        mat->rgb[idx].color[R],
-        mat->rgb[idx].color[G],
-        mat->rgb[idx].color[B],
-        mat->code[idx]);
-}
-
- -

The ghosting effect is achieved by carefully scaling the RGB -channels before mixing them:

- -
static void mat_shade(matrix *mat, size_t row, size_t col) 
-{
-    unsigned char *color;
-    color = mat->rgb[mat_idx(mat, row, col)].color;
-    color[R] = color[R] - (color[R] - COLOR_BG_RED) / 2;
-    color[G] = color[G] - (color[G] - COLOR_BG_GRN) / 2;
-    color[B] = color[B] - (color[B] - COLOR_BG_BLU) / 2;
-}
-
- -

The ghosting function emulates the dim after glow by gradually transitioning -each raindrop’s color towards the background color. This approach provides two -key benefits: straightforward color configuration that integrates naturally -with (Unix) ricing and high-fidelity recreation of the Matrix aesthetic.

- -

Customization

- -

While you can alter almost every aspect, including speed, glitch frequency, and -rain density, the most common customizations are the color scheme and character -set.

- -

There are three color settings: head, tail, and background. You can configure -them using COLOR_*_RED, COLOR_*_GRN, and COLOR_*_BLU definitions found in -main.c.

- -

The UNICODE_MIN and UNICODE_MAX values control the Unicode block used. For -example, setting them to 0x30A1 and 0x30F6 rains Katakana, if a font that -supports Katakana is present on the system:

- -

- -

Files: source.tar.gz

-
- -
-
-
- - - - - - diff --git a/_site/projects/matrix-digital-rain/katakana.png b/_site/projects/matrix-digital-rain/katakana.png deleted file mode 100644 index b9df873..0000000 Binary files a/_site/projects/matrix-digital-rain/katakana.png and /dev/null differ diff --git a/_site/projects/matrix-digital-rain/matrix.mp4 b/_site/projects/matrix-digital-rain/matrix.mp4 deleted file mode 100644 index 84a9839..0000000 Binary files a/_site/projects/matrix-digital-rain/matrix.mp4 and /dev/null differ diff --git a/_site/projects/matrix-digital-rain/poster.png b/_site/projects/matrix-digital-rain/poster.png deleted file mode 100644 index 0321ad3..0000000 Binary files a/_site/projects/matrix-digital-rain/poster.png and /dev/null differ diff --git a/_site/projects/matrix-digital-rain/source.tar.gz b/_site/projects/matrix-digital-rain/source.tar.gz deleted file mode 100644 index fead280..0000000 Binary files a/_site/projects/matrix-digital-rain/source.tar.gz and /dev/null differ diff --git a/_site/projects/matrix-digital-rain/thumb_sm.png b/_site/projects/matrix-digital-rain/thumb_sm.png deleted file mode 100644 index d3f06c9..0000000 Binary files a/_site/projects/matrix-digital-rain/thumb_sm.png and /dev/null differ diff --git a/_site/projects/my-first-pcb/back.jpeg b/_site/projects/my-first-pcb/back.jpeg deleted file mode 100644 index f458e69..0000000 Binary files a/_site/projects/my-first-pcb/back.jpeg and /dev/null differ diff --git a/_site/projects/my-first-pcb/back_design.jpeg b/_site/projects/my-first-pcb/back_design.jpeg deleted file mode 100644 index b6c0f5d..0000000 Binary files a/_site/projects/my-first-pcb/back_design.jpeg and /dev/null differ diff --git a/_site/projects/my-first-pcb/front.jpeg b/_site/projects/my-first-pcb/front.jpeg deleted file mode 100644 index 2b2931f..0000000 Binary files a/_site/projects/my-first-pcb/front.jpeg and /dev/null differ diff --git a/_site/projects/my-first-pcb/front_design.jpeg b/_site/projects/my-first-pcb/front_design.jpeg deleted file mode 100644 index f81f09c..0000000 Binary files a/_site/projects/my-first-pcb/front_design.jpeg and /dev/null differ diff --git a/_site/projects/my-first-pcb/gerber_back.zip b/_site/projects/my-first-pcb/gerber_back.zip deleted file mode 100644 index 26659ad..0000000 Binary files a/_site/projects/my-first-pcb/gerber_back.zip and /dev/null differ diff --git a/_site/projects/my-first-pcb/gerber_front.zip b/_site/projects/my-first-pcb/gerber_front.zip deleted file mode 100644 index 864334e..0000000 Binary files a/_site/projects/my-first-pcb/gerber_front.zip and /dev/null differ diff --git a/_site/projects/my-first-pcb/index.html b/_site/projects/my-first-pcb/index.html deleted file mode 100644 index 412bfcf..0000000 --- a/_site/projects/my-first-pcb/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - My first PCB - - - - - My first PCB - - - - - - - - - - - - - -
-
-
-

MY FIRST PCB

-
14 JULY 2025
-
-

In 2023, I started tinkering with DIY electronics as a hobby. Until now, I’ve -been using development boards like the Arduino Uno and ESP-32-WROOM so that I -can focus on the software. Recently, I decided to step outside of my comfort -zone and design a PCB from scratch for a door lock I’m working on.

- -

The lock comprises two subsystems: a fingerprint sensor in front of the door -and a servo connected to the physical lock behind the door. The fingerprint -sensor authenticates the person and signals the servo behind the door to unlock -the door over an encrypted RF channel.

- - - - - - - - - - -
- Design (front) -

Footprint (front)

-
- PCB (front) -

PCB (front)

-
- Design (back) -

Footprint (back)

-
- PCB (back) -

PCB (back)

-
- -

The PCBs have two layers. A copper region serves as the ground plane. The 0.3mm -wide 1oz/ft2 copper traces can carry up to 500mA (the tracks -connecting the power source and the linear regulators have a width of 0.5mm). -Both subsystems were functional. I was able to control the servo reliably using -the fingerprint sensor.

- -

The designs aren’t without flaws, however. The main shortcoming of the circuits -is that they draw significant amounts of quiescent currents despite employing -sleep modes. The linear regulators were a poor choice as they dissipate too -much heat. The fingerprint sensor and the servo draw 13.8mA (3.3V) and 4.6mA -(5V) respectively, as long as they are connected to the power supply.

- -

Although the circuit didn’t draw more than 200mA without a load, the servo -under load could draw up to 600mA. I’m sailing too close to the wind with 0.3mm -copper traces. Instead, 0.4mm wide 2oz/ft2 traces would have been -safer.

- -

I’m working on improving the design to reduce idle current consumption and -extend the battery life. Despite its deficiencies, this was my first PCB -design, and I’m glad that it worked as well as it did. Custom PCB design marks -an important milestone in my DIY electronics journey.

- -

Files: gerber_back.zip, gerber_front.zip, - source.tar.gz

-
- -
-
-
- - - - - - diff --git a/_site/projects/my-first-pcb/source.tar.gz b/_site/projects/my-first-pcb/source.tar.gz deleted file mode 100644 index c31aa22..0000000 Binary files a/_site/projects/my-first-pcb/source.tar.gz and /dev/null differ diff --git a/_site/projects/my-first-pcb/thumb_sm.jpeg b/_site/projects/my-first-pcb/thumb_sm.jpeg deleted file mode 100644 index c275b12..0000000 Binary files a/_site/projects/my-first-pcb/thumb_sm.jpeg and /dev/null differ -- cgit v1.2.3